5

worldwind javaを使用してレイヤーをセットアップしようとしていますが、マップ上の特定の地理的位置にアイコンをレンダリングしたいと思います。私はそれを機能させていますが、すべてのアイコンがある場所にズームできるようにしたいと思います。それを行う簡単な方法はありますか?どこから始めればよいのかよくわかりません。ポイントのグループを拡大するための既存の方法はありますか?

4

2 に答える 2

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));
}
于 2011-05-11T20:06:50.787 に答える
1

182多くの答えは、いくつかの条件下で機能します。ただし、より良いソリューションでは、水平FOV(視野)が常に45.0度に固定されているとは限らないことを考慮に入れる必要があります。また、垂直視野も考慮する必要があります。クラスタリングの位置の終わりをどのように考慮しなければならないかさえ。つまり、ポジションは東から西、または北と南に広がっていますか。地球(WorldWindow)のユーザービューは、実際には高さよりも薄くなっていますか。すべての位置を表示するために必要なズームレベルを計算するときに、これらすべての要素が考慮されます。上記のすべての位置を説明するために、この静的メソッドを作成しました。ちなみに、Earth.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;
}
于 2016-02-04T17:18:14.250 に答える