/** * Copyright (C) 2012 52°North Initiative for Geospatial Open Source Software GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.n52.sos.encoder; import java.io.IOException; import java.util.Collection; import javax.activation.UnsupportedDataTypeException; import org.n52.om.sampling.AQDSample; import org.n52.om.sampling.Feature; import com.esri.arcgis.geometry.IGeometry; import com.esri.arcgis.geometry.Point; /** * @author <a href="mailto:broering@52north.org">Arne Broering</a> */ public class OGCFeatureEncoder extends AbstractEncoder { /* * definition of anchor variables within template files: */ private static String FEATURES = "@features@"; private static String FEATURE_GML_ID = "@feature-gml-id@"; private static String FEATURE_POINT = "@feature-point-location@"; private static String FEATURE_NAME = "@feature-name@"; private static String FEATURE_SAMPLED = "@feature-sampled-href@"; private static String FEATURE_DESCRIPTION = "@feature-description@"; private static String FEATURE_GEOMETRY = "@feature-geometry@"; private static String FEATURE_NAMESPACE = "@feature-namespace@"; private static String FEATURE_LOCALID = "@feature-local-id@"; private static String FEATURE_INLET_HEIGHT = "@feature-inlet-height@"; private static String FEATURE_BUILDING_DISTANCE = "@feature-building-distance@"; private static String FEATURE_KERB_DISTANCE = "@feature-kerb-distance@"; private String responseTemplate; private String featureTemplate; public OGCFeatureEncoder () throws IOException { super(); responseTemplate = readText(OGCFeatureEncoder.class.getResourceAsStream("template_getfeatureofinterest_response.xml")); featureTemplate = readText(OGCFeatureEncoder.class.getResourceAsStream("template_feature.xml")); } public String encodeFeatures(Collection<Feature> featureCollection) throws IOException { StringBuilder allFeatures = new StringBuilder(); for (Feature feature : featureCollection) { StringBuilder featureString = new StringBuilder(); featureString.append(featureTemplate); if (feature.getGmlId() != null) { replace(featureString, FEATURE_GML_ID, "gml:id=\"" + feature.getGmlId() + "\""); } else { replace(featureString, FEATURE_GML_ID, ""); } if (feature.getGmlId() != null) { replace(featureString, FEATURE_LOCALID, feature.getGmlId()); } else { replace(featureString, FEATURE_LOCALID, ""); } if (feature.getUri() != null) { // take the feature URI without everything after '#' as the namespace: String featureNamespace = feature.getUri().toASCIIString(); int indexOfDash = featureNamespace.indexOf("#"); if (indexOfDash != -1) { featureNamespace = featureNamespace.substring(0, indexOfDash + 1); } replace(featureString, FEATURE_NAMESPACE, featureNamespace); } else { replace(featureString, FEATURE_NAMESPACE, ""); } if (feature.getShape() != null) { IGeometry geometry = feature.getShape(); int dimension = feature.getShape().getSpatialReference().getZCoordinateUnit() == null ? 2 : 3; int epsgCode = geometry.getSpatialReference().getFactoryCode(); String epsgUrn = "urn:ogc:def:crs:EPSG::" + epsgCode; if (geometry instanceof Point) { Point p = (Point)geometry; replace(featureString, FEATURE_POINT, p.getX() + " " + p.getY()); String featureGeometry = "<sams:shape>" + "<gml:Point gml:id=\"SamplingFeaturePoint_" + feature.getLocalId() + "\" srsDimension=\"" + dimension + "\" srsName=\"" + epsgUrn + "\">" + "<gml:pos>" + p.getX() + " " + p.getY() + "</gml:pos>" + "</gml:Point>" +"</sams:shape>"; replace(featureString, FEATURE_GEOMETRY, featureGeometry); } else { throw new UnsupportedDataTypeException("Cannot encode geometry of feature."); } } else { /* * TODO resolve Feature Geometry via referenced Stations */ replace(featureString, FEATURE_GEOMETRY, "<sams:shape />"); } if (feature.getSampledFeature() != null) { replace(featureString, FEATURE_SAMPLED, "<sam:sampledFeature xlink:href=\""+ feature.getSampledFeature() + "\" />"); } else { replace(featureString, FEATURE_SAMPLED, "<sam:sampledFeature nilReason=\"inapplicable\" />"); } if (feature.getName() != null) { replace(featureString, FEATURE_NAME, "<gml:name>" + feature.getName() + "</gml:name>"); } else { replace(featureString, FEATURE_NAME, ""); } if (feature.getDescription() != null) { replace(featureString, FEATURE_DESCRIPTION, "<gml:description>" + feature.getDescription() +"</gml:description>"); } else { replace(featureString, FEATURE_DESCRIPTION, ""); } if (feature instanceof AQDSample) { AQDSample aqdSample = (AQDSample) feature; replace(featureString, FEATURE_INLET_HEIGHT, aqdSample.getInletHeight()+""); replace(featureString, FEATURE_BUILDING_DISTANCE, aqdSample.getBuildingDistance()+""); replace(featureString, FEATURE_KERB_DISTANCE, aqdSample.getKerbDistance()+""); } // add features to the allFeatures String allFeatures.append(featureString); } String response = responseTemplate.replace(FEATURES, allFeatures); return response; } }