Package org.geoserver.wms.georss

Source Code of org.geoserver.wms.georss.GeoRSSTransformerBase$GeoRSSTranslatorSupport

/* 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.geoserver.wms.georss;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.namespace.QName;

import org.geoserver.feature.ReprojectingFeatureCollection;
import org.geoserver.wms.WMSMapContext;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.gml3.GMLConfiguration;
import org.geotools.map.MapLayer;
import org.geotools.referencing.CRS;
import org.geotools.xml.Configuration;
import org.geotools.xml.Encoder;
import org.geotools.xml.transform.TransformerBase;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;

/**
* Base class for RSS/Atom xml transformers
*
*
* @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
* @author Andrea Aime - GeoSolutions
*/
public abstract class GeoRSSTransformerBase extends TransformerBase {
    /** logger */
    protected static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.georss");
   
    static final Configuration GML_CONFIGURATION = new GMLConfiguration();

    /**
     * Enumeration for geometry encoding.
     *
     * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
     *
     */
    public static class GeometryEncoding {
        private GeometryEncoding() {
        }

        public String getPrefix() {
            return null;
        }

        public String getNamespaceURI() {
            return null;
        }

        public void encode(Geometry g, GeoRSSTranslatorSupport translator) {
        }

        /**
         * "simple" encoding:
         *
         *  ex:
         *  <georss:point>45.256 -71.92</georss:point>,<georss:line>...</georss:line>,...
         */
        public static GeometryEncoding SIMPLE = new GeometryEncoding() {
                public String getPrefix() {
                    return "georss";
                }

                public String getNamespaceURI() {
                    return "http://www.georss.org/georss";
                }

                public void encode(Geometry g, GeoRSSTranslatorSupport t) {
                    if (g instanceof Point) {
                        Point p = (Point) g;
                        t.element("georss:point", p.getY() + " " + p.getX());
                    }

                    if (g instanceof LineString) {
                        LineString l = (LineString) g;

                        StringBuffer sb = new StringBuffer();

                        for (int i = 0; i < l.getNumPoints(); i++) {
                            Coordinate c = l.getCoordinateN(i);
                            sb.append(c.y).append(" ").append(c.x).append(" ");
                        }

                        sb.setLength(sb.length() - 1);

                        t.element("georss:line", sb.toString());
                    }

                    if (g instanceof Polygon) {
                        Polygon p = (Polygon) g;
                        LineString line = p.getExteriorRing();

                        StringBuffer sb = new StringBuffer();

                        for (int i = 0; i < line.getNumPoints(); i++) {
                            Coordinate c = line.getCoordinateN(i);
                            sb.append(c.y).append(" ").append(c.x).append(" ");
                        }

                        sb.setLength(sb.length() - 1);

                        t.element("georss:polygon", sb.toString());
                    }
                }
            };

        /**
         * gml encoding:
         *
         * ex:
         * <gml:Point>
         *   <gml:pos>45.256 -71.92</gml:pos>
         * </gml:Point>
         */
        public static GeometryEncoding GML = new GeometryEncoding() {
                public String getPrefix() {
                    return "gml";
                }

                public String getNamespaceURI() {
                    return "http://www.opengis.net/gml";
                }
               
                public void encode(Geometry g, final GeoRSSTranslatorSupport translator) {
                    try {
                        // get the proper element name
                        QName elementName = null;
                        if (g instanceof Point) {
                            elementName = org.geotools.gml2.GML.Point;
                        } else if (g instanceof LineString) {
                            elementName = org.geotools.gml2.GML.LineString;
                        } else if (g instanceof Polygon) {
                            elementName = org.geotools.gml2.GML.Polygon;
                        } else if (g instanceof MultiPoint) {
                            elementName = org.geotools.gml2.GML.MultiPoint;
                        } else if (g instanceof MultiLineString) {
                            elementName = org.geotools.gml2.GML.MultiLineString;
                        } else if (g instanceof MultiPolygon) {
                            elementName = org.geotools.gml2.GML.MultiPolygon;
                        } else {
                            elementName = org.geotools.gml2.GML._Geometry;
                        }
                       
                        // encode in GML3
                        Encoder encoder = new Encoder(GML_CONFIGURATION);
                        encoder.encode(g, elementName, translator);
                    } catch(Exception e) {
                        throw new RuntimeException("Cannot transform the specified geometry in GML", e);
                    }
                };
            };

        /**
         * lat/long encoding:
         *
         * ex:
         * <geo:lat>45.256</geo:lat>
         * <geo:long>-71.92</geo:long>
         *
         */
        public static GeometryEncoding LATLONG = new GeometryEncoding() {
                public String getPrefix() {
                    return "geo";
                }

                public String getNamespaceURI() {
                    return "http://www.w3.org/2003/01/geo/wgs84_pos#";
                }

                public void encode(Geometry g, GeoRSSTranslatorSupport t) {
                    //encode the centroid
                    Point p = g.getCentroid();
                    t.element("geo:lat", "" + p.getY());
                    t.element("geo:long", "" + p.getX());
                }
            };
    }
    ;

    /**
     * Geometry encoding to use.
     */
    protected GeometryEncoding geometryEncoding = GeometryEncoding.LATLONG;

    public void setGeometryEncoding(GeometryEncoding geometryEncoding) {
        this.geometryEncoding = geometryEncoding;
    }

    abstract class GeoRSSTranslatorSupport extends TranslatorSupport implements ContentHandler {
        public GeoRSSTranslatorSupport(ContentHandler contentHandler, String prefix, String nsURI) {
            super(contentHandler, prefix, nsURI);

            nsSupport.declarePrefix(geometryEncoding.getPrefix(), geometryEncoding.getNamespaceURI());
        }

        /**
         * Encodes the geometry of a feature.
         *
         */
        protected void encodeGeometry(SimpleFeature feature) {
            if (feature.getDefaultGeometry() != null) {
                Geometry g = (Geometry) feature.getDefaultGeometry();

                //handle case of multi geometry with a single geometry in it
                if (g instanceof GeometryCollection) {
                    GeometryCollection mg = (GeometryCollection) g;

                    if (mg.getNumGeometries() == 1) {
                        g = mg.getGeometryN(0);
                    }
                }

                geometryEncoding.encode(g, this);
            }
        }

        //overrides to increase visiblity
        public void start(String element) {
            super.start(element);
        }

        public void element(String element, String content) {
            super.element(element, content);
        }
       
        @SuppressWarnings("unchecked")
        protected List loadFeatureCollections(WMSMapContext map) throws IOException {
            ReferencedEnvelope mapArea = map.getAreaOfInterest();
            CoordinateReferenceSystem wgs84 = null;
            FilterFactory ff = CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
            try {
                // this should never throw an exception, but we have to deal with it anyways
                wgs84 = CRS.decode("EPSG:4326");
            } catch(Exception e) {
                throw (IOException) (new IOException("Unable to decode WGS84...").initCause(e));
            }
           
            List featureCollections = new ArrayList();
            for (int i = 0; i < map.getLayerCount(); i++) {
                MapLayer layer = map.getLayer(i);
                Query query = new Query(layer.getQuery());

                SimpleFeatureCollection features = null;
                try {
                    SimpleFeatureSource source;
                    source = (SimpleFeatureSource) layer.getFeatureSource();
                   
                    GeometryDescriptor gd = source.getSchema().getGeometryDescriptor();
                    if(gd == null) {
                        // geometryless layers...
                        features = source.getFeatures(query);
                    } else {
                        // make sure we are querying the source with the bbox in the right CRS, if
                        // not, reproject the bbox
                        ReferencedEnvelope env = new ReferencedEnvelope(mapArea);
                        CoordinateReferenceSystem sourceCRS = gd.getCoordinateReferenceSystem();
                        if(sourceCRS != null &&
                            !CRS.equalsIgnoreMetadata(mapArea.getCoordinateReferenceSystem(), sourceCRS)) {
                            env = env.transform(sourceCRS, true);
                        }
                       
                        // build the mixed query
                        Filter original = query.getFilter();
                        Filter bbox = ff.bbox(gd.getLocalName(), env.getMinX(), env.getMinY(), env.getMaxX(), env.getMaxY(), null);
                        query.setFilter(ff.and(original, bbox));

                        // query and eventually reproject
                        features = source.getFeatures(query);
                        if(sourceCRS != null && !CRS.equalsIgnoreMetadata(wgs84, sourceCRS)) {
                            ReprojectingFeatureCollection coll = new ReprojectingFeatureCollection(features, wgs84);
                            coll.setDefaultSource(sourceCRS);
                            features = coll;
                        }
                       
                        if (features == null)
                            throw new NullPointerException();
                       
                        featureCollections.add(features);
                      
                    }
                } catch (Exception e) {
                    String msg = "Unable to encode map layer: " + layer;
                    LOGGER.log(Level.SEVERE, msg, e);
                }
            }

            return featureCollections;
        }
       
        public void characters(char[] ch, int start, int length) throws SAXException {
            String string = new String(ch, start, length);
            chars(string);
        }
       
        public void endElement(String uri, String localName, String qName) throws SAXException {
            // working around a bug in the GML encoder, it won't properly setup the qName
            end("gml:" + localName);           
        }
       
        public void startElement(String uri, String localName, String qName, Attributes atts)
                throws SAXException {
            start(qName, atts);
        }


        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
            if(getIndentation() > 0) {
                characters(ch, start, length);
            }
        }

        public void endDocument() throws SAXException {
            // nothing to do
        }
       
        public void endPrefixMapping(String prefix) throws SAXException {
            // nothing to do
        }

        public void processingInstruction(String target, String data) throws SAXException {
            // nothing do do
        }

        public void setDocumentLocator(Locator locator) {
            // nothing do do
        }

        public void skippedEntity(String name) throws SAXException {
            // nothing to do
           
        }

        public void startDocument() throws SAXException {
            // nothing to do
           
        }

        public void startPrefixMapping(String prefix, String uri) throws SAXException {
            // nothing to do
        }
       
    }

}
TOP

Related Classes of org.geoserver.wms.georss.GeoRSSTransformerBase$GeoRSSTranslatorSupport

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.