org.n52.svalbard.encode.SamplingEncoderv20 Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2015-2022 52°North Spatial Information Research 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.svalbard.encode;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.n52.shetland.ogc.OGCConstants;
import org.n52.shetland.ogc.SupportedType;
import org.n52.shetland.ogc.gml.AbstractFeature;
import org.n52.shetland.ogc.gml.AbstractMetaData;
import org.n52.shetland.ogc.gml.GmlConstants;
import org.n52.shetland.ogc.om.NamedValue;
import org.n52.shetland.ogc.om.OmConstants;
import org.n52.shetland.ogc.om.features.SfConstants;
import org.n52.shetland.ogc.om.features.samplingFeatures.AbstractSamplingFeature;
import org.n52.shetland.ogc.sos.FeatureType;
import org.n52.shetland.ogc.sos.Sos2Constants;
import org.n52.shetland.ogc.sos.SosConstants;
import org.n52.shetland.util.CollectionHelper;
import org.n52.shetland.util.OMHelper;
import org.n52.shetland.w3c.SchemaLocation;
import org.n52.svalbard.ConformanceClass;
import org.n52.svalbard.ConformanceClasses;
import org.n52.svalbard.encode.exception.EncodingException;
import org.n52.svalbard.encode.exception.UnsupportedEncoderInputException;
import org.n52.svalbard.util.CodingHelper;
import org.n52.svalbard.util.XmlHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import net.opengis.gml.x32.AbstractFeatureDocument;
import net.opengis.gml.x32.FeaturePropertyType;
import net.opengis.sampling.x20.SFSamplingFeatureType;
import net.opengis.samplingSpatial.x20.SFSpatialSamplingFeatureDocument;
import net.opengis.samplingSpatial.x20.SFSpatialSamplingFeatureType;
import net.opengis.samplingSpatial.x20.ShapeType;
/**
* @since 1.0.0
*
*/
public class SamplingEncoderv20
extends AbstractGmlEncoderv321
implements ConformanceClass {
private static final Logger LOGGER = LoggerFactory.getLogger(SamplingEncoderv20.class);
private static final Set ENCODER_KEYS =
CollectionHelper.union(CodingHelper.encoderKeysForElements(SfConstants.NS_SAMS, AbstractFeature.class),
CodingHelper.encoderKeysForElements(SfConstants.NS_SF, AbstractFeature.class));
private static final Set CONFORMANCE_CLASSES =
Sets.newHashSet(ConformanceClasses.OM_V2_SPATIAL_SAMPLING, ConformanceClasses.OM_V2_SAMPLING_POINT,
ConformanceClasses.OM_V2_SAMPLING_CURVE, ConformanceClasses.OM_V2_SAMPLING_SURFACE);
private static final Set SUPPORTED_TYPES =
ImmutableSet. builder().add(new FeatureType(OGCConstants.UNKNOWN))
.add(new FeatureType(SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_POINT))
.add(new FeatureType(SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_CURVE))
.add(new FeatureType(SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_SURFACE)).build();
public SamplingEncoderv20() {
LOGGER.debug("Encoder for the following keys initialized successfully: {}!",
Joiner.on(", ").join(ENCODER_KEYS));
}
@Override
public Set getKeys() {
return Collections.unmodifiableSet(ENCODER_KEYS);
}
@Override
public Set getSupportedTypes() {
return Collections.unmodifiableSet(SUPPORTED_TYPES);
}
@Override
public Set getConformanceClasses(String service, String version) {
if (SosConstants.SOS.equals(service) && Sos2Constants.SERVICEVERSION.equals(version)) {
return Collections.unmodifiableSet(CONFORMANCE_CLASSES);
}
return Collections.emptySet();
}
@Override
public void addNamespacePrefixToMap(final Map nameSpacePrefixMap) {
nameSpacePrefixMap.put(SfConstants.NS_SAMS, SfConstants.NS_SAMS_PREFIX);
nameSpacePrefixMap.put(SfConstants.NS_SF, SfConstants.NS_SF_PREFIX);
}
@Override
public Set getSchemaLocations() {
return Sets.newHashSet(SfConstants.SF_SCHEMA_LOCATION, SfConstants.SAMS_SCHEMA_LOCATION);
}
@Override
public XmlObject encode(final AbstractFeature abstractFeature, final EncodingContext ctx)
throws EncodingException {
final XmlObject encodedObject;
if (!ctx.isEmpty() && ctx.has(XmlBeansEncodingFlags.PROPERTY_TYPE)) {
XmlObject tmp = createFeature(abstractFeature);
if (tmp instanceof SFSpatialSamplingFeatureDocument) {
encodedObject = ((SFSpatialSamplingFeatureDocument) tmp).getSFSamplingFeature();
} else {
encodedObject = ((AbstractFeatureDocument) tmp).getAbstractFeature();
}
} else {
encodedObject = createFeature(abstractFeature);
}
// LOGGER.debug("Encoded object {} is valid: {}",
// encodedObject.schemaType().toString(),
// XmlHelper.validateDocument(encodedObject));
return encodedObject;
}
protected XmlObject createFeature(final AbstractFeature absFeature) throws EncodingException {
if (absFeature instanceof AbstractSamplingFeature) {
final AbstractSamplingFeature sampFeat = (AbstractSamplingFeature) absFeature;
final SFSpatialSamplingFeatureDocument xbSampFeatDoc =
SFSpatialSamplingFeatureDocument.Factory.newInstance(getXmlOptions());
if (sampFeat.isSetXml()) {
try {
final XmlObject feature = XmlObject.Factory.parse(sampFeat.getXml(), getXmlOptions());
if (XmlHelper.getNamespace(feature).equals(SfConstants.NS_SAMS)) {
XmlHelper.updateGmlIDs(feature.getDomNode().getFirstChild(), absFeature.getGmlId(), null);
if (feature instanceof SFSpatialSamplingFeatureType) {
xbSampFeatDoc.setSFSpatialSamplingFeature((SFSpatialSamplingFeatureType) feature);
encodeShape(xbSampFeatDoc.getSFSpatialSamplingFeature().getShape(), sampFeat);
addNameDescription(xbSampFeatDoc.getSFSpatialSamplingFeature(), sampFeat);
return xbSampFeatDoc;
}
encodeShape(
((SFSpatialSamplingFeatureDocument) feature).getSFSpatialSamplingFeature().getShape(),
sampFeat);
addNameDescription(((SFSpatialSamplingFeatureDocument) feature).getSFSpatialSamplingFeature(),
sampFeat);
sampFeat.wasEncoded();
return feature;
} else {
return encodeObjectToXml(XmlHelper.getNamespace(feature), absFeature);
}
} catch (final XmlException xmle) {
throw new EncodingException(
"Error while encoding GetFeatureOfInterest response, invalid samplingFeature description!",
xmle);
}
}
final SFSpatialSamplingFeatureType xbSampFeature = xbSampFeatDoc.addNewSFSpatialSamplingFeature();
// TODO: CHECK for all fields set gml:id
addId(xbSampFeature, sampFeat);
addIdentifier(xbSampFeature, sampFeat);
// set type
addFeatureType(xbSampFeature, sampFeat);
// set type
addNameDescription(xbSampFeature, sampFeat);
setMetaDataProperty(xbSampFeature, sampFeat);
// set sampledFeatures
// TODO: CHECK
addSampledFeatures(xbSampFeature, sampFeat);
addParameter(xbSampFeature, sampFeat);
// set position
encodeShape(xbSampFeature.addNewShape(), sampFeat);
sampFeat.wasEncoded();
return xbSampFeatDoc;
}
throw new UnsupportedEncoderInputException(this, absFeature);
}
@Override
protected XmlObject createFeature(FeaturePropertyType featurePropertyType, AbstractFeature abstractFeature,
EncodingContext context) throws EncodingException {
if (abstractFeature instanceof AbstractSamplingFeature) {
final AbstractSamplingFeature samplingFeature = (AbstractSamplingFeature) abstractFeature;
String namespace;
if (context.has(XmlEncoderFlags.ENCODE_NAMESPACE)
&& context.get(XmlEncoderFlags.ENCODE_NAMESPACE).isPresent()
&& context.get(XmlEncoderFlags.ENCODE_NAMESPACE).get() instanceof String) {
namespace = (String) context.get(XmlEncoderFlags.ENCODE_NAMESPACE).get();
} else {
namespace = OMHelper.getNamespaceForFeatureType(samplingFeature.getFeatureType());
}
final XmlObject encodedXmlObject = encodeObjectToXml(namespace, samplingFeature);
if (encodedXmlObject != null) {
return encodedXmlObject;
} else {
if (samplingFeature.isSetXml()) {
try {
// TODO how set gml:id in already existing
// XmlDescription? <-- XmlCursor
return XmlObject.Factory.parse(samplingFeature.getXml());
} catch (final XmlException xmle) {
throw new EncodingException("Error while encoding featurePropertyType!", xmle);
}
} else {
featurePropertyType.setHref(samplingFeature.getIdentifierCodeWithAuthority().getValue());
if (samplingFeature.isSetName()) {
featurePropertyType.setTitle(samplingFeature.getFirstName().getValue());
}
return featurePropertyType;
}
}
}
return featurePropertyType;
}
protected void addSampledFeatures(SFSamplingFeatureType sfsft, AbstractSamplingFeature sampFeat)
throws EncodingException {
if (sampFeat.isSetSampledFeatures()) {
for (AbstractFeature sampledFeature : sampFeat.getSampledFeatures()) {
XmlObject encodeObjectToXml = encodeObjectToXml(GmlConstants.NS_GML_32, sampledFeature,
new EncodingContext().with(XmlBeansEncodingFlags.REFERENCED));
sfsft.addNewSampledFeature().set(encodeObjectToXml);
}
} else {
sfsft.addNewSampledFeature().setHref(OGCConstants.UNKNOWN);
}
}
protected void addFeatureType(SFSamplingFeatureType sfsft, AbstractSamplingFeature sampFeat) {
if (sampFeat.isSetFeatureType() && !OGCConstants.UNKNOWN.equals(sampFeat.getFeatureType())) {
sfsft.addNewType().setHref(sampFeat.getFeatureType());
} else {
if (sampFeat.isSetGeometry()) {
addFeatureTypeForGeometry(sfsft, sampFeat.getGeometry());
}
}
}
private void addFeatureTypeForGeometry(SFSamplingFeatureType xbSampFeature, Geometry geometry) {
xbSampFeature.addNewType().setHref(getFeatureType(geometry));
}
private String getFeatureType(Geometry geometry) {
if (geometry instanceof Point || geometry instanceof MultiPoint) {
return SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_POINT;
} else if (geometry instanceof LineString || geometry instanceof MultiLineString) {
return SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_CURVE;
} else if (geometry instanceof Polygon || geometry instanceof MultiPolygon) {
return SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_SURFACE;
} else {
return SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_FEATURE;
}
}
private void encodeShape(ShapeType xbShape, AbstractSamplingFeature sampFeat) throws EncodingException {
Encoder encoder = getEncoder(GmlConstants.NS_GML_32, sampFeat.getGeometry());
if (encoder != null) {
XmlObject xmlObject = encoder.encode(sampFeat.getGeometry(),
EncodingContext.of(XmlBeansEncodingFlags.GMLID, sampFeat.getGmlId()));
if (xbShape.isSetAbstractGeometry()) {
xbShape.getAbstractGeometry().set(xmlObject);
} else {
xbShape.addNewAbstractGeometry().set(xmlObject);
}
XmlHelper.substituteElement(xbShape.getAbstractGeometry(), xmlObject);
} else {
throw new EncodingException("Error while encoding geometry for feature, needed encoder is missing!");
}
}
protected void addParameter(SFSamplingFeatureType xbSampFeature, AbstractSamplingFeature sampFeat)
throws EncodingException {
for (NamedValue> namedValuePair : sampFeat.getParameters()) {
XmlObject encodeObjectToXml = encodeObjectToXml(OmConstants.NS_OM_2, namedValuePair);
if (encodeObjectToXml != null) {
xbSampFeature.addNewParameter().addNewNamedValue().set(encodeObjectToXml);
}
}
}
protected void addNameDescription(SFSamplingFeatureType xbSamplingFeature, AbstractSamplingFeature samplingFeature)
throws EncodingException {
addName(xbSamplingFeature, samplingFeature);
addDescription(xbSamplingFeature, samplingFeature);
}
protected void setMetaDataProperty(SFSamplingFeatureType sfssft, AbstractSamplingFeature sampFeat)
throws EncodingException {
if (sampFeat.isSetMetaDataProperty()) {
for (AbstractMetaData abstractMetaData : sampFeat.getMetaDataProperty()) {
XmlObject encodeObject = encodeObjectToXml(GmlConstants.NS_GML_32, abstractMetaData);
XmlObject substituteElement = XmlHelper
.substituteElement(sfssft.addNewMetaDataProperty().addNewAbstractMetaData(), encodeObject);
substituteElement.set(encodeObject);
}
}
}
}