Package org.geowebcache.service.kml

Source Code of org.geowebcache.service.kml.KMLSiteMap

/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* @author Arne Kepp, The Open Planning Project, Copyright 2008
*/
package org.geowebcache.service.kml;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.geowebcache.GeoWebCacheException;
import org.geowebcache.conveyor.ConveyorKMLTile;
import org.geowebcache.grid.GridSetBroker;
import org.geowebcache.grid.GridSubset;
import org.geowebcache.layer.TileLayer;
import org.geowebcache.layer.TileLayerDispatcher;
import org.geowebcache.mime.MimeType;
import org.geowebcache.mime.XMLMime;
import org.geowebcache.storage.StorageBroker;

public class KMLSiteMap {
    private ConveyorKMLTile tile = null;
    private TileLayerDispatcher tLD = null;
    private StorageBroker storageBroker;
    private GridSetBroker gridSetBroker;
   
    public KMLSiteMap(ConveyorKMLTile tile, TileLayerDispatcher tLD, GridSetBroker gridSetBroker) {
        this.tile = tile;
        this.tLD = tLD;
        this.storageBroker = tile.getStorageBroker();
        this.gridSetBroker = gridSetBroker;
    }
   
    public void write() throws GeoWebCacheException, IOException {
        tile.servletResp.setCharacterEncoding("utf-8");
        tile.servletResp.setContentType("application/xml");
        tile.servletResp.setStatus(200);
       
        if(tile.getHint() == KMLService.HINT_SITEMAP_LAYER) {
            writeSiteMap();
        } else {
            writeSiteMapIndex();
        }
    }
   
    private void writeSiteMapIndex() throws IOException {
        OutputStream os = tile.servletResp.getOutputStream();
       
        String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
        os.write(header.getBytes());
       
        writeSiteMapIndexLoop();
       
        String footer = "</sitemapindex>";
        os.write(footer.getBytes());
    }
   
    private void writeSiteMapIndexLoop() throws IOException {
        OutputStream os = tile.servletResp.getOutputStream();
        String urlPrefix = tile.getUrlPrefix();
       
        Iterable<TileLayer> iter = tLD.getLayerList();
       
        for (TileLayer tl : iter) {
            if (!tl.isEnabled()) {
                continue;
            }
            Map<String, GridSubset> grids = tl.getGridSubsets();
            List<MimeType> mimeTypes = tl.getMimeTypes();
           
            if( grids != null && grids.containsKey(gridSetBroker.WORLD_EPSG4326.getName())
                    && mimeTypes != null && mimeTypes.contains(XMLMime.kml) ) {
                String smStr = "<sitemap><loc>"+urlPrefix+tl.getName()+"/sitemap.xml</loc></sitemap>";
                os.write(smStr.getBytes());
            }
        }
    }

    private void writeSiteMap() throws GeoWebCacheException, IOException {
        TileLayer layer = tile.getLayer();
       
        GridSubset gridSubset = layer.getGridSubset(gridSetBroker.WORLD_EPSG4326.getName());
       
        writeSiteMapHeader();
       
        long[] gridRect = gridSubset.getCoverageBestFit();
       
        // Check whether we need two tiles for world bounds or not
        if(gridRect[4] > 0 && (gridRect[2] != gridRect[0] || gridRect[3] != gridRect[1])) {
            throw new GeoWebCacheException(
                    layer.getName() + " is too big for the sub grid set for "
                    + gridSubset.getName() + ", allow for smaller zoom levels.");
        } else if(gridRect[0] != gridRect[2]) {
            long[] gridLocWest = {0,0,0};
            long[] gridLocEast = {1,0,0};

           
            writeSiteMapLoop(gridLocWest);
            writeSiteMapLoop(gridLocEast);
           
        } else {
            long[] gridLoc = {gridRect[0], gridRect[1], gridRect[4]};
            writeSiteMapLoop(gridLoc);
        }
       
        writeSiteMapFooter();
    }
   
    private void writeSiteMapHeader() throws IOException {
        String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:geo=\"http://www.google.com/geo/schemas/sitemap/1.0\">\n";
        tile.servletResp.getOutputStream().write(header.getBytes());
    }

    private void writeSiteMapFooter() throws IOException {
        String footer = "</urlset>";
        tile.servletResp.getOutputStream().write(footer.getBytes());      
    }

    public void writeSiteMapLoop(long[] gridLoc) throws GeoWebCacheException, IOException {
        OutputStream os = tile.servletResp.getOutputStream();
        TileLayer tileLayer = tile.getLayer();
        String urlPrefix = tile.getUrlPrefix();
       
        // Add a link to the super overlay first
        String  superOverlayLoc =
            "<url><loc>" + urlPrefix.substring(0, urlPrefix.length() - 1)
            + ".kml.kml</loc><geo:geo><geo:format>kml</geo:format></geo:geo></url>\n";
        os.write(superOverlayLoc.getBytes());
       
       
        LinkedList<long[]> subTileList = new LinkedList<long[]>();
           
        subTileList.addFirst(gridLoc);
       
        while(subTileList.peek() != null) {
            String gridSetId = gridSetBroker.WORLD_EPSG4326.getName();
            long[] curLoc = subTileList.removeFirst();
            long[][] linkGridLocs = tileLayer.getGridSubset(gridSetId).getSubGrid(curLoc);
            linkGridLocs = KMZHelper.filterGridLocs(storageBroker, tileLayer, gridSetId, XMLMime.kml, linkGridLocs);
        
            // Save the links we still need to follow for later
            for(long[] subTile : linkGridLocs) {
                if(subTile[2] > 0) {
                    subTileList.addLast(subTile);
                }
            }
           
            // We need to link to the data tiles only, for now
            String tmp = "<url><loc>" + urlPrefix + KMLService.gridLocString(curLoc) +".kml" + "</loc><geo:geo><geo:format>kml</geo:format></geo:geo></url>\n";
            os.write(tmp.getBytes());
           
            // Could add priority as 1 / (zoomlevel + 1)
        }
     }
}
TOP

Related Classes of org.geowebcache.service.kml.KMLSiteMap

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.