⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmlsuperoverlaytransformer.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
字号:
/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
 * This code is licensed under the GPL 2.0 license, availible at the root
 * application directory.
 */
package org.vfny.geoserver.wms.responses.map.kml;

import com.vividsolutions.jts.geom.Envelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.MapLayer;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.xml.transform.TransformerBase;
import org.geotools.xml.transform.Translator;
import org.vfny.geoserver.global.WMS;
import org.vfny.geoserver.util.Requests;
import org.vfny.geoserver.wms.WMSMapContext;
import org.xml.sax.ContentHandler;
import java.util.Map;
import java.util.logging.Logger;


public class KMLSuperOverlayTransformer extends KMLTransformerBase {
    /**
     * logger
     */
    static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.kml");

    /**
     * the world bounds
     */
    final static ReferencedEnvelope world = new ReferencedEnvelope(-180, 180, -90, 90,
            DefaultGeographicCRS.WGS84);

    /**
     * resolutions
     */
    final static double[] resolutions = new double[100];

    static {
        for (int i = 0; i < resolutions.length; i++) {
            resolutions[i] = world.getWidth() / ((0x01 << i) * 256);
        }
    }

    /**
     * The map context
     */
    final WMSMapContext mapContext;

    public KMLSuperOverlayTransformer(WMSMapContext mapContext) {
        this.mapContext = mapContext;
        setNamespaceDeclarationEnabled(false);
    }

    public Translator createTranslator(ContentHandler handler) {
        return new KMLSuperOverlayerTranslator(handler);
    }

    class KMLSuperOverlayerTranslator extends KMLTranslatorSupport {
        public KMLSuperOverlayerTranslator(ContentHandler contentHandler) {
            super(contentHandler);
        }

        public void encode(Object o) throws IllegalArgumentException {
            MapLayer mapLayer = (MapLayer) o;

            //calculate closest resolution
            ReferencedEnvelope extent = mapContext.getAreaOfInterest();
            double resolution = Math.max(extent.getWidth() / 256d, extent.getHeight() / 256d);

            //calculate the closest zoom level
            int i = 1;

            for (; i < resolutions.length; i++) {
                if (resolution > resolutions[i]) {
                    i--;

                    break;
                }
            }

            LOGGER.fine("resolution = " + resolution);
            LOGGER.fine("zoom level = " + i);

            //zoom out until the entire bounds requested is covered by a 
            //single tile
            Envelope top = null;

            while (i > 0) {
                resolution = resolutions[i];

                double tilelon = resolution * 256;
                double tilelat = resolution * 256;

                double lon0 = extent.getMinX() - world.getMinX();
                double lon1 = extent.getMaxX() - world.getMinX();

                int col0 = (int) Math.floor(lon0 / tilelon);
                int col1 = (int) Math.floor((lon1 / tilelon) - 1E-9);

                double lat0 = extent.getMinY() - world.getMinY();
                double lat1 = extent.getMaxY() - world.getMinY();

                int row0 = (int) Math.floor(lat0 / tilelat);
                int row1 = (int) Math.floor((lat1 / tilelat) - 1E-9);

                if ((col0 == col1) && (row0 == row1)) {
                    double tileoffsetlon = world.getMinX() + (col0 * tilelon);
                    double tileoffsetlat = world.getMinY() + (row0 * tilelat);

                    top = new Envelope(tileoffsetlon, tileoffsetlon + tilelon, tileoffsetlat,
                            tileoffsetlat + tilelat);

                    break;
                } else {
                    i--;
                }
            }

            if (top == null) {
                top = world;
            }

            LOGGER.fine("request = " + extent);
            LOGGER.fine("top level = " + top);

            //start document
            if (isStandAlone()) {
                start( "kml" );
            }
            
            start("Document");

            //encode top level region
            encodeRegion(top, 256, 1024);

            //encode the network links
            if (top != world) {
                //top left
                Envelope e00 = new Envelope(top.getMinX(), top.getMinX() + (top.getWidth() / 2d),
                        top.getMaxY() - (top.getHeight() / 2d), top.getMaxY());

                //top right
                Envelope e01 = new Envelope(e00.getMaxX(), top.getMaxX(), e00.getMinY(),
                        e00.getMaxY());

                //bottom left
                Envelope e10 = new Envelope(e00.getMinX(), e00.getMaxX(), top.getMinY(),
                        e00.getMinY());

                //bottom right
                Envelope e11 = new Envelope(e01.getMinX(), e01.getMaxX(), e10.getMinY(),
                        e10.getMaxY());

                encodeNetworkLink(e00, "00", mapLayer);
                encodeNetworkLink(e01, "01", mapLayer);
                encodeNetworkLink(e10, "10", mapLayer);
                encodeNetworkLink(e11, "11", mapLayer);
            } else {
                //divide up horizontally by two
                Envelope e0 = new Envelope(top.getMinX(), top.getMinX() + (top.getWidth() / 2d),
                        top.getMinY(), top.getMaxY());
                Envelope e1 = new Envelope(e0.getMaxX(), top.getMaxX(), top.getMinY(), top.getMaxY());

                encodeNetworkLink(e0, "0", mapLayer);
                encodeNetworkLink(e1, "1", mapLayer);
            }

            //encode the ground overlay(s)
            if (top == world) {
                //special case for top since it does not line up as a propery
                // tile -> split it in two
                encodeGroundOverlay(mapLayer, i, new Envelope(-180, 0, -90, 90));
                encodeGroundOverlay(mapLayer, i, new Envelope(0, 180, -90, 90));
            } else {
                //encode straight up
                encodeGroundOverlay(mapLayer, i, top);
            }

            //end document
            end("Document");
            
            if (isStandAlone()) {
                end( "kml" );
            }
        }

        void encodeGroundOverlay(MapLayer mapLayer, int drawOrder, Envelope box) {
            start("GroundOverlay");
            element("drawOrder", "" + drawOrder);

            start("Icon");

            String href = KMLUtils.getMapUrl(mapContext, mapLayer, box,
                    new String[] { "width", "256", "height", "256" }, true);
            element("href", href);
            LOGGER.fine(href);
            end("Icon");

            encodeLatLonBox(box);
            end("GroundOverlay");
        }

        void encodeRegion(Envelope box, int minLodPixels, int maxLodPixels) {
            //top level region
            start("Region");

            start("Lod");
            element("minLodPixels", "128");
            //element("minLodPixels", "" + minLodPixels );
            element("maxLodPixels", "" + maxLodPixels);
            //element("maxLodPixels", "-1" );
            end("Lod");

            encodeLatLonAltBox(box);

            end("Region");
        }

        void encodeNetworkLink(Envelope box, String name, MapLayer mapLayer) {
            start("NetworkLink");
            element("name", name);

            encodeRegion(box, 512, 2048);

            start("Link");

            String getMap = KMLUtils.getMapUrl(mapContext, mapLayer, box,
                    new String[] {
                        "format", KMLMapProducerFactory.MIME_TYPE, "width", "256", "height", "256",
                        "superoverlay", "true"
                    }, false);

            element("href", getMap);
            LOGGER.fine("Network link " + name + ":" + getMap);

            element("viewRefreshMode", "onRegion");

            end("Link");

            end("NetworkLink");
        }

        void encodeLatLonAltBox(Envelope box) {
            start("LatLonAltBox");
            encodeBox(box);
            end("LatLonAltBox");
        }

        void encodeLatLonBox(Envelope box) {
            start("LatLonBox");
            encodeBox(box);
            end("LatLonBox");
        }

        void encodeBox(Envelope box) {
            element("north", String.valueOf(box.getMaxY()));
            element("south", String.valueOf(box.getMinY()));
            element("east", String.valueOf(box.getMaxX()));
            element("west", String.valueOf(box.getMinX()));
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -