2012-02-24 2 views
4

Google과 SO에서이 점을 연구했지만 계속 빠져 나갔다. Most examples 내가 본 것은 임의의 mapWidth와 단일 점, 오버레이의 스팬을 다루지 않는 것입니다.Android : MapController.zoomToSpan : 거리와 중심점이 지정된 스팬 만들기

지도 지점 데이터베이스 인 MapViewGeocoder이 있습니다. 내 앱에서 우편 번호를 검색 할 수 있으며 Address이 내 Geocoder으로 반환됩니다.

Address을 사용하여 GeoPoint을 구축하고 내 DB를 검색하여 주변 포인트 목록을 얻을 수 있습니다. 문제는 반환 된 Address 지점에서 생성 된 범위와 데이터베이스의 가장 가까운 지점까지의 거리를 사용하여 zoomToSpan을 시도 할 때 발생합니다.

해당 스팬에 가장 가까운 두 점 (가능한 경우) 만 포함하도록하겠습니다. 여기에 관련 코드입니다 :

Collections.sort(listingDisplay, mComparator); 
    listingDisplayAdapter.notifyDataSetChanged(); 

    float spanWidth =0; 

    if (listingDisplay.size() > 1) { 

     spanWidth = (float) (2 * distanceFromPoint(listingDisplay.get(1), 
       current)); 

    } else if (listingDisplay.size() == 1) { 

     spanWidth = (float) (2 * distanceFromPoint(listingDisplay.get(0), 
       current)); 

    } 

    Log.v(TAG, "SpanWidth: " + spanWidth); 

    // Create span 
    int minLat = (int) (current.getLatitudeE6() - (spanWidth * 1E6)/2); 
    int maxLat = (int) (current.getLatitudeE6() + (spanWidth * 1E6)/2); 
    int minLong = (int) (current.getLongitudeE6() - (spanWidth * 1E6)/2); 
    int maxLong = (int) (current.getLongitudeE6() + (spanWidth * 1E6)/2); 

     // Zoom against span. This appears to create a very small region that doesn't encompass the points 
mapController.setCenter(current); 
mapController.zoomToSpan(Math.abs(minLat - maxLat), Math.abs(minLong - maxLong)); 

ListingDisplay 가장 가까운 지점의 목록이 포함은 비교기, mComparator가 가장 가까운 위치에이 목록을 정렬로, 내 반환 Address합니다 (GeoPoint 전화 : current)를 목록의 맨 위에 .

그런 다음 가장 가까운 값을 기준으로 spanWidth의 값을 설정하고이 범위를 계산해보십시오.

내 질문은 주어진 거리와 중심점에서 스팬을 구성하는 방법?

답변

5

매우 오랜 시간이 지난 후에 나는 중요한 정보를 고려하지 않고 있다는 사실을 깨달았습니다. 그 중 중요한 것은 안드로이드의 거리가 WGS84 타원체를 사용하여 계산된다는 사실이었습니다.

나는 매우와 관련된 개념에 대한 철저한 설명과 함께 Jan Matuschek's excellent and simple GeoLocation class 내부의 도우미 방법을 사용하여 끝냈다.

내 방법은 기본적으로 다음과 같이 요약됩니다. 아마도 단순한 SQL 쿼리로 최적화 될 수 있지만 여기서는 제 목적을 위해서입니다. listingDisplay은 데이터베이스에서 가져온 사용자 지정 LocationNode 개체의 배열이고 GeoPoint은 현재 반환 된 Address에서 직접 생성됩니다. 표준 안드로이드 지오 코더.

public void setRegionForGeoPoint(GeoPoint current) { 

    // Earth radius in KM 
    final double EARTH_RADIUS = 6371.01; 

    // Dummy span distance in KM for initial search; distance buffer is in M 
    final double DISTANCE_BUFFER = 50; 
    final double dummyDistance = 100.0; 
//Create a list to store distances 
    List<Double> distancesList = new ArrayList<Double>(); 


    // Loop through and modify LocationNodes with distance from user 
    for (LocationNode location : listingDisplay) { 
     location.setDistance((float) distanceFromUser(location)); 

     // Dynamically calculate distance from our current point (epicentre) 
     distancesList.add(distanceFromPoint(location, current)); 
    } 

    // Sort distances 
    Collections.sort(distancesList); 

    // Calculate regional span 
    float spanWidth = (float) dummyDistance; 
    double distance = 0; 

    if (distancesList.size() > 0) { 
     if (distancesList.size() > 1) { 

      distance = distancesList.get(1); 
      spanWidth = (float) (distance + DISTANCE_BUFFER); 

     } else if (distancesList.size() == 1) { 

      distance = distancesList.get(0); 
      spanWidth = (float) (distance + DISTANCE_BUFFER); 

     } 

     //Obtain the spanwidth in metres. 
     double spanWidthInKM = (double) spanWidth/1000; 

     // Create span 
     GeoLocation[] boundingBoxSpan = currentGeoLocation 
       .boundingCoordinates(spanWidthInKM, EARTH_RADIUS); 

     //Create min/max values for final span calculation 
     int minLatSpan = (int) (boundingBoxSpan[0].getLatitudeInDegrees() * 1E6); 
     int maxLatSpan = (int) (boundingBoxSpan[1].getLatitudeInDegrees() * 1E6); 
     int minLongSpan = (int) (boundingBoxSpan[0].getLongitudeInDegrees() * 1E6); 
     int maxLongSpan = (int) (boundingBoxSpan[1].getLongitudeInDegrees() * 1E6); 

     //Finally calculate span 
     int latSpanE6 = Math.abs(minLatSpan - maxLatSpan); 
     int lonSpanE6 = Math.abs(minLongSpan - maxLongSpan); 

     // Set center 
     mapController.setCenter(current); 

     // Zoom to span 
     mapController.zoomToSpan(latSpanE6, lonSpanE6); 

    } else { 

     //TODO: Handle the case when we have no distance values to use 
    } 
} 


public double distanceFromPoint(LocationNode location, GeoPoint point) { 

    // Calculate distance from user via result 
    Location locationA = new Location("point A"); 
    locationA.setLatitude(location.getLatitude()); 
    locationA.setLongitude(location.getLongitude()); 

    Location locationB = new Location("point B"); 
    locationB.setLatitude((double) (point.getLatitudeE6()/1E6)); 
    locationB.setLongitude((double) (point.getLongitudeE6()/1E6)); 
    double distance = locationA.distanceTo(locationB); 
    Log.v(TAG, "Calculated Distance: " + distance); 
    return distance; 
} 
관련 문제