2011-05-11 79 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 2011-05-11 20:37:14

+0

明白了。谢谢!! – MBU 2011-05-11 21:05:47

1

182Much的答案确实在一定条件下下工作。但是,更好的解决方案必须考虑到水平FOV(视场)不总是固定在45.0度。它还需要考虑垂直视场。即使聚类的位置如何结束也必须考虑在内。意思是说,这些职位的分布情况是东西向还是南北向。用户对地球的看法(WorldWindow)实际上比较高而不是高度。在计算所需的缩放级别以查看所有位置时,所有这些因素都会被考虑在内。我创建了这个静态方法来考虑上面列出的所有位置。作为一个方面说明,如果您计算地球的实际平均半径,那么您的位置可能会聚集在一起,而不是采取地球.WGS84_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; 
}