2015-10-28 5 views
1

Я столкнулся с очень сложной проблемой с Google Maps APIv2: я хочу нарисовать круг вокруг маркера (ничто не отличается до сих пор), но радиус cirle должен масштабируется в соответствии с уровнем масштабирования, поэтому размер маркера и круг всегда сохраняют ту же пропорцию.Android: Карты v2: нарисуйте масштабируемый круг вокруг маркера

Я попытался выполнить вычисления, связанные с текущим уровнем масштабирования, максимальным и минимальным уровнем масштабирования, а также размером значка маркера, но оказалось (по моим расчетам), что способ увеличения/уменьшения масштаба карты уровень в зависимости от взаимодействия пользователя не является линейным (я думаю, что это как-то экспоненциально).

У кого-нибудь есть идеи, как это сделать?

         **UPDATE** 

Частичное решение предлагается в качестве ответа, вы можете предложить улучшения

+0

[Если вы обратитесь к документации] (https://developers.google. com/maps/documentation/javascript/reference? hl = en # Circle) радиус находится в метрах, и он уже изменяет (во время масштабирования), чтобы соответствовать пикселям, чтобы преобразовать метры .... так что 500 метров с максимальным увеличением имеют x пикселей , но в минимальном увеличении, имеет y пикселей – Bonatti

+0

да, но я хочу изменить радиус круга! Я хочу, чтобы круг всегда находился вокруг маркера, поэтому, когда пользователь уменьшает масштаб, я хочу изменить радиус соответственно, так как маркер будет «покрывать» большую площадь карты по мере уменьшения масштаба. –

+0

[Тогда, пожалуйста, проверьте здесь конверсию ставки] (http://gis.stackexchange.com/questions/7430/what-ratio-scales-do-google-maps-zoom-levels-correspond-to) – Bonatti

ответ

0

Я не могу комментировать из-за своей репутации, но вы должны попытаться использовать zoomChangeListener, я нахожу это в другой вопрос ..

Создать реализацию OnCameraChangeListener и передать экземпляр, чтобы setOnCameraChangeListener() вашего GoogleMap. Ваш слушатель должен вызываться с onCameraChange() всякий раз, когда пользователь изменяет масштаб, центр или наклон. Вы узнаете новый уровень масштабирования из объекта CameraPosition, который вы передали.

И каждый раз, когда это произойдет, вам нужно:

  1. ClearTheMap
  2. Установите маркер снова
  3. Читать zoomLevel
  4. Нарисуйте круг в соответствии с уровнем масштабирования

Вам просто нужно сделать математическую работу для различных масштабирования.

public OnCameraChangeListener getCameraChangeListener() 
{ 
    new OnCameraChangeListener() 
    { 
     @Override 
     public void onCameraChange(CameraPosition position) 
     { 
      googleMap.clear(); 
      setMarkers(); 
      float actualZoom = position.zoom; 
      drawCircle(actualZoom); 
    } 
}; 
} 
+1

Проблема заключается не в том, чтобы получить уровень масштабирования, а при вычислении радиуса окружности в соответствии с ним –

0

Я произвел частичное решение:

  • Я беру BoundingBox в настоящее время видно на карте
  • получить расстояние между углами одной из сторон
  • получить карту размер в пикселях
  • вычислить количество метров на пиксель
  • умножить это значение на размер значка маркера

К сожалению, он хорошо работает только для уровней масштабирования> 5.5. Это вызвано расчетом, который дает другой результат в зависимости от положения камеры из-за сферической формы земли.

Вот код, если кто-то есть какая-то идея, как улучшить его:

public double getRadius(){ 
     mapWidth = (double) mapFragment.getView().getWidth(); 
     LatLngBounds bb = map.getProjection().getVisibleRegion().latLngBounds; 

     double distance = distance((bb.northeast.latitude - bb.southwest.latitude)/2, bb.northeast.longitude, (bb.northeast.latitude - bb.southwest.latitude)/2, bb.southwest.longitude); 
     double metersPerPixel = distance/mapWidth; 
     return 70*metersPerPixel; 
    } 

    private static double distance(double lat1, double lon1, double lat2, double lon2) { 
     double theta = lon1 - lon2; 
     double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)); 
     dist = Math.acos(dist); 
     dist = rad2deg(dist); 
     dist = dist * 60 * 1.1515; 
     dist = (dist * 1.609344)*1000; 

     return (dist); 
    } 

    private static double deg2rad(double deg) { 
     return (deg * Math.PI/180.0); 
    } 

    private static double rad2deg(double rad) { 
     return (rad * 180/Math.PI); 
    } 

код для вычисления расстояния найдено here