/* (c) 2016 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.gwc.wmts; import com.vividsolutions.jts.geom.*; import org.geoserver.gwc.wmts.dimensions.Dimension; import org.geoserver.gwc.wmts.dimensions.DimensionsUtils; import org.geoserver.wms.WMS; import org.geotools.feature.FeatureIterator; import org.geotools.gml3.GMLConfiguration; import org.geotools.xml.Encoder; import org.geotools.xml.transform.TransformerBase; import org.geotools.xml.transform.Translator; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.type.GeometryDescriptor; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import javax.xml.namespace.QName; import java.util.List; /** * XML transformer for the get feature operation. */ class FeaturesTransformer extends TransformerBase { public FeaturesTransformer(WMS wms) { setIndentation(2); setEncoding(wms.getCharSet()); } @Override public Translator createTranslator(ContentHandler handler) { return new TranslatorSupport(handler); } class TranslatorSupport extends TransformerBase.TranslatorSupport { public TranslatorSupport(ContentHandler handler) { super(handler, null, null); } @Override public void encode(Object object) throws IllegalArgumentException { if (!(object instanceof Domains)) { throw new IllegalArgumentException("Expected domains info but instead got: " + object.getClass().getCanonicalName()); } Domains domains = (Domains) object; Attributes nameSpaces = createAttributes(new String[]{ "xmlns:xs", "http://www.w3.org/2001/XMLSchema", "xmlns:gml", "http://www.opengis.net/gml", "xmlns:wmts", "http://www.opengis.net/wmts/1.0" }); start("wmts:FeatureCollection", nameSpaces); FeatureIterator iterator = domains.getFeatureCollection().features(); try { while (iterator.hasNext()) { SimpleFeature simpleFeature = (SimpleFeature) iterator.next(); handleFeature(simpleFeature, domains.getDimensions()); } } finally { iterator.close(); } end("wmts:FeatureCollection"); } /** * Encodes a feature in the XML. */ private void handleFeature(SimpleFeature feature, List<Dimension> dimensions) { Attributes attributes = createAttributes(new String[]{ "gml:id", feature.getID() }); start("wmts:feature", attributes); start("wmts:footprint"); // encode the geometry GeometryDescriptor geometryDescriptor = feature.getFeatureType().getGeometryDescriptor(); Geometry geometry = (Geometry) feature.getAttribute(geometryDescriptor.getName()); handleGeometry(geometry); // encode the dimensions end("wmts:footprint"); for (Dimension dimension : dimensions) { handleDimension(feature, dimension); } end("wmts:feature"); } /** * Encodes a Geometry in GML. */ private void handleGeometry(Geometry geometry) { try { QName elementName = org.geotools.gml2.GML._Geometry; if (geometry instanceof Point) { elementName = org.geotools.gml2.GML.Point; } else if (geometry instanceof LineString) { elementName = org.geotools.gml2.GML.LineString; } else if (geometry instanceof Polygon) { elementName = org.geotools.gml2.GML.Polygon; } else if (geometry instanceof MultiPoint) { elementName = org.geotools.gml2.GML.MultiPoint; } else if (geometry instanceof MultiLineString) { elementName = org.geotools.gml2.GML.MultiLineString; } else if (geometry instanceof MultiPolygon) { elementName = org.geotools.gml2.GML.MultiPolygon; } Encoder encoder = new Encoder(new GMLConfiguration()); encoder.encode(geometry, elementName, contentHandler); } catch (Exception exception) { throw new RuntimeException("Cannot transform the specified geometry in GML.", exception); } ; } /** * Encodes a dimension extracting the dimension value from the feature. */ private void handleDimension(SimpleFeature feature, Dimension dimension) { Object value = feature.getAttribute(dimension.getAttributes().first); Attributes attributes = createAttributes(new String[]{ "name", dimension.getDimensionName() }); element("wmts:dimension", DimensionsUtils.formatDomainValue(value), attributes); } } }