Package org.vfny.geoserver.wms.responses.map.kml

Source Code of org.vfny.geoserver.wms.responses.map.kml.EncodeKML

/* Copyright (c) 2001, 2003 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 java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Logger;

import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureReader;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureType;
import org.geotools.feature.GeometryAttributeType;
import org.geotools.filter.Expression;
import org.geotools.filter.FilterFactory;
import org.geotools.filter.FilterType;
import org.geotools.filter.GeometryFilter;
import org.geotools.map.MapLayer;
import org.vfny.geoserver.wms.WMSMapContext;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.Point;


/**
*
*/
public class EncodeKML {
    /** Standard Logger */
    private static final Logger LOGGER = Logger.getLogger(
            "org.vfny.geoserver.responses.wms.map.kml");
   
    /** the XML and KML header */
    private static final String KML_HEADER =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t"
            +"<kml xmlns=\"http://earth.google.com/kml/2.0\">\n";
   
    /** the KML closing element */
    private static final String KML_FOOTER = "</kml>\n";
   
    /** Map context document - layers, styles aoi etc. */
    private WMSMapContext mapContext;
   
    /** Actualy writes the KML out */
    private KMLWriter writer;
   
    /** Flag to be monotored by writer loops */
    private boolean abortProcess;
   
    /**
     * Creates a new EncodeKML object.
     *
     * @param mapContext A full description of the map to be encoded.
     */
    public EncodeKML(WMSMapContext mapContext) {
        this.mapContext = mapContext;
    }
   
    /**
     * Sets the abort flag.  Active encoding may be halted, but this is not garanteed.
     */
    public void abort() {
        abortProcess = true;
    }
   
    /**
     * Perform the actual encoding.  May return early if abort it called.
     *
     * @param out Ouput stream to send the data to.
     *
     * @throws IOException Thrown if anything goes wrong whilst writing
     */
    public void encode(final OutputStream out) throws IOException {
        Envelope env = this.mapContext.getAreaOfInterest();
        this.writer = new KMLWriter(out, mapContext);
        //once KML supports bbox queries against WMS this can be used to
        //decimate the geometries based on zoom level.
        //writer.setMinCoordDistance(env.getWidth() / 1000);
       
        abortProcess = false;
       
        long t = System.currentTimeMillis();
        try {
            writeHeader();
            writeLayers();
            writeFooter();
           
            this.writer.flush();
            t = System.currentTimeMillis() - t;
            LOGGER.fine("KML generated, it took" + t + " ms");
        } catch (IOException ioe) {
            if (abortProcess) {
                LOGGER.fine("KML encoding aborted");
                return;
            } else {
                throw ioe;
            }
        } catch (AbortedException ex) {
            return;
        }
    }
   
    /**
     * writes out standard KML header
     *
     * @throws IOException
     */
    private void writeHeader() throws IOException {
        writer.write(KML_HEADER);
    }
  
    /**
     * writes out standard KML footer
     *
     * @throws IOException DOCUMENT ME!
     */
    private void writeFooter() throws IOException {
        writer.write(KML_FOOTER);
    }
   
   
    /**
     * Processes each of the layers within the current mapContext in turn.
     *
     * @throws IOException
     * @throws AbortedException
     *
     * @task TODO: Wrap each layer in a 'Folder' tag
     */
    private void writeLayers() throws IOException, AbortedException {
        MapLayer[] layers = mapContext.getLayers();
        int nLayers = layers.length;
        int defMaxDecimals = writer.getMaximunFractionDigits();
       
        FilterFactory fFac = FilterFactory.createFilterFactory();
        for (int i = 0; i < nLayers; i++) {
            MapLayer layer = layers[i];
            FeatureReader featureReader = null;
            FeatureSource fSource = layer.getFeatureSource();
            FeatureType schema = fSource.getSchema();
            try {
                Expression bboxExpression = fFac.createBBoxExpression(mapContext
                        .getAreaOfInterest());
                GeometryFilter bboxFilter = fFac.createGeometryFilter(FilterType.GEOMETRY_INTERSECTS);
                bboxFilter.addLeftGeometry(bboxExpression);
                bboxFilter.addRightGeometry(fFac.createAttributeExpression(
                        schema, schema.getDefaultGeometry().getName()));
               
                Query bboxQuery = new DefaultQuery(schema.getTypeName(),
                        bboxFilter);
               
                featureReader = fSource.getFeatures(bboxQuery).reader();
                FeatureCollection fc = fSource.getFeatures(bboxQuery);
                writer.writeFeatures(fc, layer.getStyle());
                LOGGER.fine("finished writing");
            } catch (IOException ex) {
                LOGGER.info("process failed: " + ex.getMessage());
                throw ex;
            } catch (AbortedException ae) {
                LOGGER.info("process aborted: " + ae.getMessage());
                throw ae;
            } catch (Throwable t) {
                LOGGER.warning("UNCAUGHT exception: " + t.getMessage());
               
                IOException ioe = new IOException("UNCAUGHT exception: "
                        + t.getMessage());
                ioe.setStackTrace(t.getStackTrace());
                throw ioe;
            } finally {
                if (featureReader != null) {
                    try{
                        featureReader.close();
                    }catch(IOException ioe){
                        //featureReader was probably closed already.
                    }
                }
            }
        }
    }
}
TOP

Related Classes of org.vfny.geoserver.wms.responses.map.kml.EncodeKML

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.