2011-05-11 15 views
5

Estoy tratando de configurar una capa usando worldwind java y quiero representar iconos en el mapa en sus ubicaciones geográficas específicas. Lo tengo funcionando pero quiero poder acercarme a donde están todos los íconos. ¿Hay una manera fácil de hacer eso? No estoy seguro de por dónde empezar. ¿Existen métodos existentes para acercarse a un grupo de puntos?Configuración del nivel de zoom del mapa de worldwind

Respuesta

9

Primero debe calcular el Sector que contiene todos sus puntos. p.ej.

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

Ahora aquí hay un código tomado de ejemplo ScankortDenmark para calcular el zoom que necesita para adaptarse a todo el sector en la pantalla:

// 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

¿cómo uso esto en el mapa? ¿uso los métodos getView(). goTo() para ir a la ubicación y uso el computeZoomForExtent para obtener las elevaciones? – MBU

+0

lo tengo. ¡¡Gracias!! – MBU

1

respuesta de 182Much funciona bajo bajo ciertas condiciones. Sin embargo, una mejor solución debe tener en cuenta que el FOV horizontal (campo de visión) no siempre se fija a 45.0 grados. También debe tener en cuenta el campo de visión vertical. Incluso cómo deben tenerse en cuenta las posiciones al final de la agrupación. Es decir, las posiciones se extienden más de Este a Oeste o del Norte y del Sur. Es la vista de los usuarios del mundo (WorldWindow) realmente más delgada que la altura. Todos estos factores se tienen en cuenta al calcular el nivel de zoom necesario para ver todas las posiciones. Creé este método estático para dar cuenta de todas las posiciones mencionadas anteriormente. Como nota al margen, puede tener una precisión ligeramente mejor si calcula el radio medio real de la Tierra donde sus posiciones tienden a agruparse en lugar de tomar Earth.WGS84_EQUATORIAL_RADIUS. Pero esto es casi insignificante, así que dejo esa parte aquí.

/** 
* 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; 
} 
Cuestiones relacionadas