2013-05-07 3 views
4

Gooogle Maps API v2를 사용하는 Android 애플리케이션에서 작업하고 있습니다. 내지도에 마커가 있으며 그 중 하나를 선택하고 싶습니다. Circle and Circle Options 클래스를 사용하여 쉽게 관리 할 수있었습니다. 그러나 마커처럼 확대 또는 축소 할 때도 화면에 동일한 크기를 유지하도록 내 서클을 원합니다. 원이 픽셀 단위로 일정한 반경을 가져야 함을 의미합니다. 안타깝게도 API v2에서는 반경을 픽셀 단위로 설정할 수 없습니다.Google지도 API v2에서 일정 크기의 원을 화면에 그립니다.

몇 가지 해결책을 시도했지만 만족스럽지 않습니다. 첫 번째에서

, 난 그냥 곱 또는 반경을 분할 : 처음 일 듯

@Override 
public void onCameraChange(CameraPosition position) 
{ 
    if(previousZoom > position.zoom) { 
     mSelectionCircle.setRadius(Math.abs(position.zoom - previousZoom)*2*mSelectionCircle.getRadius()); 
    } 
    else if(previousZoom < position.zoom) { 
     mSelectionCircle.setRadius(Math.abs(position.zoom - previousZoom)*mSelectionCircle.getRadius()/2); 
    } 

    previousZoom = position.zoom; 
} 

,하지만 빠르게 확대 또는 손가락으로 확대 할 때 잘못된 결과를 얻을 수 있습니다. 또한, 화면에 스케일링이 선명하게 표시됩니다.

두 번째 해결책은 픽셀 - 미터 변환을 사용합니다. 이 아이디어는 확대/축소 할 때 반지름을 미터 단위로 다시 계산하기 때문에 화면의 원 크기가 일정합니다.

Point p2 = new Point(p1.x + radiusInPixels, p1.y); 

int radiusInPixels = 40; 
:

Point p1 = mMap.getProjection().toScreenLocation(mSelectionCircle.getCenter()); 

그런 다음 내가 원의 가장자리에 또 다른 지점을 만들 :이를 위해, 나는 화면에 원형의 현재 위치를 얻을 수

그 후,이 두 점 사이의 거리를 미터로 반환하는 함수를 사용합니다.

private double convertPixelsToMeters(Point point1, Point point2) { 

    double angle = Math.acos(Math.sin(point1.x) * Math.sin(point2.x) 
        + Math.cos(point1.x) * Math.cos(point2.x) * Math.cos(point1.y- point2.y)); 
    return angle * Math.PI * 6378100.0; // distance in meters 
} 

6378100은 평균 지구 반지름이다. 마지막으로, 나는 원의 새로운 반경 설정 : (! 10^7m)

mSelectionCircle.setRadius(convertPixelsToMeters(p1, p2)); 

그것은 이론적으로 작동해야하지만 말도 반경 값을 얻을 수 있습니다. 변환 함수가 잘못되었을 수 있습니까?

이렇게하는 것이 더 간단한 방법일까요, 그렇지 않다면 제 2의 soluton이 작동하지 않는 이유를 이해하도록 도와 주시겠습니까?

감사합니다.

+0

아마도 Maps Circle을 사용하지 않고 대신 캔버스를 그리는 것이 더 편리할까요? – FWeigl

답변

1

Marker 대신 사용자 정의 아이콘을 사용하십시오. 당신은 후자에 그릴과 Marker 아이콘으로 사용, BitmapCanvas 만들 수 있습니다 자신을

new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(bitmap))... 
+0

사실 이것은 처음에 시도한 것이지만 마커를 제거/교체하는 데 어려움을 겪었습니다. 실제로 나는 마커를 오직 클릭만으로 동그라미 표시하고, 더 이상 선택하지 않으면 마커를 감추고 싶습니다. 마커가 있으면 아이콘을 변경할 수 없습니다. 클릭 한 마커를 제거하고 동일한 옵션으로 새 마커를 만들고 새 마커 아이콘을 변경 한 다음지도에 추가해야합니다. 해시 맵을 사용하여 Marker를 MarkerOptions과 연결 시켰고, 원하는대로 할 수 없었습니다 ... 그래서 포기하고 별도로 원을 그리기로했습니다. 나는 Ascorbin이 제안한대로 Canvas를 사용하려고 노력할 것입니다. –

+0

@ChristopheLongeanie 캔버스 소재로 좋은 결과를 얻을 수 있다고는 생각하지 않습니다. 패닝 할 때, 그려진 서클 위치를 업데이트해야하며, 시간이 지나면 onCameraChange를 얻으면서 작동하지 않습니다. 그것은 뒤떨어져 보일 것입니다. 다른 아이콘으로'Marker'를 바꾸는 것이 좋습니다. 이것은 까다로워 질 것이지만, 제대로 수행되면 괜찮아 보일 것입니다. –

+0

비트 맵을 사용하는 경우 원 이미지 센터가 latlng에 배치되어야하지만 원의 하단 가장자리는 latlng pos에 배치됩니다. –

1

내가 같은 문제가 건너 와서 해결책을 찾을 수 없습니다, 그래서 내가 그것을했다, 나는에 게시 할 예정입니다 다른 사람들에게 도움이되기를 바랍니다.

서클을 특정 lat/lng의 중심에 배치하고 싶기 때문에 "마커"접근 방식이 작동하지 않았습니다. 마커를 사용하여 원을 그릴 수 없기 때문에 마커에 대한 원 아이콘을 설정하면 원호 모서리 lat/lng를 터치하지만 원은 lat/lng의 가운데에 위치하지 않습니다.

위도와 카메라 줌 레벨을 기준으로 원의 크기를 미터 단위로 계산하는 함수를 만든 다음지도에 카메라 리스너를 추가하여 카메라가 변경 될 때마다 원의 크기를 업데이트합니다. 수평. 결과는 크기가 변경되지 않는 원형입니다 (최소한 맨눈으로).여기

내 코드입니다 : MaciejGórski이 suggessted으로

public static double calculateCircleRadiusMeterForMapCircle(final int _targetRadiusDip, final double _circleCenterLatitude, 
    final float _currentMapZoom) { 
    //That base value seems to work for computing the meter length of a DIP 
    final double arbitraryValueForDip = 156000D; 
    final double oneDipDistance = Math.abs(Math.cos(Math.toRadians(_circleCenterLatitude))) * arbitraryValueForDip/Math.pow(2, _currentMapZoom); 
    return oneDipDistance * (double) _targetRadiusDip; 
} 

public void addCircleWithConstantSize(){ 
    final GoogleMap googleMap = ...//Retrieve your GoogleMap object here 

    //Creating a circle for the example 
    final CircleOptions co = new CircleOptions(); 
    co.center(new LatLng(0,0)); 
    co.fillColor(Color.BLUE); 
    final Circle circle = googleMap.addCircle(co); 

    //Setting a listener on the map camera to monitor when the camera changes 
    googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { 
     @Override 
     public void onCameraMove() { 
      //Use the function to calculate the radius 
      final double radius = calculateCircleRadiusMeterForMapCircle(12, co.getCenter().latitude, googleMap.getCameraPosition().zoom); 
      //Apply the radius to the circle 
      circle.setRadius(radius); 
     } 
    }); 
} 
+0

고맙습니다. 저는 여러분의 기능을지면 오버레이와 함께 사용했으며 완벽하게 작동했습니다. –

0

, 갈 수있는 정확하고 쉬운 방법입니다; 하지만 Google지도에 마커가 많이있는 경우 예를 들어 5k 마커라고 말하면 성능이 크게 저하됩니다. 이 문제를 보여주는 몇 가지 제안 사항은 다음과 같습니다.

1) 구글 안드로이드 맵 API의 검색 마커 클러스터링 유틸리티를 보자. 2) 그러나 마커 클러스터링은 목적에 완전히 맞지 않을 수 있습니다. 그래서 당신은 스스로 그것을 사용자 정의 할 수 있습니다. 이 문제에 대해 논의하는 스레드는 다음과 같습니다. https://github.com/googlemaps/android-maps-utils/issues/29

Polyline을 사용하여 내 용도 (경로 표시)를 찾았 기 때문에 미안하지만 시도하지 않았습니다.

희망이 도움말, Mttdat.

관련 문제