2011-05-11 3 views
5

worldwind java를 사용하여 레이어를 설정하려고하는데 맵의 특정 위치에 아이콘을 렌더링하고 싶습니다. 그 일을하고 있지만 모든 아이콘이있는 곳을 확대 할 수 있기를 원합니다. 쉽게 할 수있는 방법이 있습니까? 실제로 어디서부터 시작해야하는지 모르겠다. 포인트 그룹을 확대하기위한 기존 방법이 있습니까?월드 윈드 맵의 확대/축소 수준 설정

답변

9

먼저 모든 포인트가 포함 된 섹터를 계산해야합니다. 예 :

Sector boundingSector = Sector.boundingSector(points); 
//public static Sector boundingSector(Iterable<? extends LatLon> itrbl) 

지금 여기에 당신이 화면에 전체 분야에 맞게 필요 줌을 계산하는 ScankortDenmark의 예에서 가져온 일부 코드입니다 :

// From ScankortDenmark example 
public static double computeZoomForExtent(Sector sector) 
{ 
    Angle delta = sector.getDeltaLat(); 
    if (sector.getDeltaLon().compareTo(delta) > 0) 
     delta = sector.getDeltaLon(); 
    double arcLength = delta.radians * Earth.WGS84_EQUATORIAL_RADIUS; 
    double fieldOfView = Configuration.getDoubleValue(AVKey.FOV, 45.0); 
    return arcLength/(2 * Math.tan(fieldOfView/2.0)); 
} 
+0

지도에서 어떻게 사용합니까? getView(). goTo() 메서드를 사용하여 위치로 이동 한 다음 computeZoomForExtent를 사용하여 고도를 가져옵니다. – MBU

+0

알았습니다. 감사!! – MBU

1

182Much의 대답은 어떤 조건 하에서 작업을 수행합니다. 그러나 더 나은 해결책은 수평 FOV (시야)가 항상 45.0 도로 고정되는 것은 아니라는 점입니다. 수직 FOV도 고려해야합니다. 클러스터링의 포지션 종료가 어떻게 고려되어야 하는지를 고려해야합니다. 의미, 위치가 서쪽 또는 북쪽과 남쪽으로 더 동쪽으로 퍼져 나갔는가. 글로브 (WorldWindow)의 사용자보기가 실제로 더 가늘고 그 다음 높이입니다. 모든 요인을보기 위해 필요한 줌 레벨을 계산할 때 이러한 모든 요소가 고려됩니다. 위의 나열된 모든 위치를 설명하기 위해이 정적 메서드를 만들었습니다. 중요한 점은 지구의 실제 반경을 계산할 때 지구가 아닌 지구상의 위치가 클러스터되는 경향이있는 경우 약간 더 우수한 정밀도를 얻을 수 있습니다 .GS84_EQUATORIAL_RADIUS. 하지만이 부분은 거의 무시해도 좋습니다.

/** 
* Calculates the altitude in meters needed to view all of the given points. 
* This method is safe for any window sizing configurations. If the 
* WorldWindor arg is null then a static max altitude value of 1,0667,999 
* meters is returned. if the WorldWindow is good but the list of Positions 
* is null or empty then the current zoom level of the WorldWindow is 
* returned. If the list of positions cannot all be seen on the globe 
* because some positions are on the other side of the globe then a static 
* max altitude value of 1,0667,999 meters is returned. 
* 
* @param positions 
*   - a list of positions wanted to view 
* @return the altitude in meters needed to view all of the given points. 
*/ 
public static double getZoomAltitude(List<Position> positions, WorldWindow wwd) { 
    double zoom = 10667999; 
    if (wwd != null) { 
     // Gets the current zoom as a fail safe to return 
     BasicOrbitView orbitView = (BasicOrbitView) wwd.getView(); 
     zoom = orbitView.getZoom(); 

     // zoom is in meters and and is limited the max zoom out to 10,667,999 meters 
     int MAX_ZOOM = 10667999; 

     if (positions != null && !positions.isEmpty()) { 
      Sector sector = Sector.boundingSector(positions); 
      if (sector != null) { 

       // This calculation takes into account the window sizing configuration of the map in order to accurately 
       // display the list of positions. 
       double meanRadius = Earth.WGS84_EQUATORIAL_RADIUS; 

       // Next we must calculate the zoom levels for both delta latitude viewing and delta longitude viewing. 
       // generally, a group of positions that spread out more Longitudenal viewing (wider viewing width) 
       // holds a constant 45.0 degree field of view (FOV). The horizontal FOV can be changed so this input 
       // must handle dynamically as well. The latitudenal (positon group runs more East to West then North and South) 
       // position group have a dynamic FOV that changes depending on the users sizing of the map. These have 
       // to be handled any time the group of positions has a greater delta latitude than delta longitude. 
       // Also if the user has a skinny map this will effect the output calculation and must be handled. 
       // Here we take all the dynamic variables into account for both types of possibilities and choose 
       // the larger zoom level of them. 
       int deltaLon = new BigDecimal(sector.getDeltaLon().radians * meanRadius).intValue(); 
       int deltaLat = new BigDecimal(sector.getDeltaLat().radians * meanRadius).intValue(); 
       System.out.println("deltaLonAL Wider: " + deltaLon + "\tdeltaLatAL Taller: " + deltaLat); 

       double horizontalFOV = orbitView.getFieldOfView().getDegrees(); 
       double verticalFOV = ViewUtil.computeVerticalFieldOfView(orbitView.getFieldOfView(), 
         orbitView.getViewport()).getDegrees(); 

       double lonZoomLevel = new BigDecimal((deltaLon/2.0)/(Math.tan(horizontalFOV/2.0))).intValue(); 
       double latZoomLevel = new BigDecimal((deltaLat/2.0) 
         /(Math.tan(Math.toRadians(verticalFOV)/2.0))).intValue(); 
       System.out 
         .println("LonZoomLevel Wider: " + lonZoomLevel + "\tLatZoomLevel Taller: " + latZoomLevel); 

       double zoomLevel = Math.max(lonZoomLevel, latZoomLevel); 
       System.out.println("zoomLevel meters: " + zoomLevel + "\tfeet: " 
         + new BigDecimal(zoomLevel * 3.2808)); 

       // zoom is the altitude measured in meters to view a given area calculated to fit the viewing 
       // window edge to edge. A buffer is needed around the area for visual appeal. The bufferedZoom 
       // is a calculated linear equation (y = 1.0338x + 96177 where R² = 1) It gives the same buffer 
       // boundary around a group of position depending on the calculated zoom altitude. 
       double bufferedZoom = 1.0338 * zoomLevel + 96177; 
       zoom = new BigDecimal(bufferedZoom).intValue(); 

       if (zoom > MAX_ZOOM) { 
        zoom = MAX_ZOOM; 
        System.out.println("MAX_ZOOM applied"); 
       } 
      } 
     } else { 
      System.out.println("getZoomAltitude method cannot calculate the zoom because the points passed in was null and the current zoom was returned."); 
     } 
    } 
    return zoom; 
}