All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.n52.svalbard.decode.OmDecoderv20 Maven / Gradle / Ivy
/*
* Copyright 2015-2020 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.svalbard.decode;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import net.opengis.om.x20.NamedValuePropertyType;
import net.opengis.om.x20.OMObservationDocument;
import net.opengis.om.x20.OMObservationType;
import net.opengis.om.x20.TimeObjectPropertyType;
import org.apache.xmlbeans.XmlBoolean;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlInteger;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlString;
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.shetland.ogc.SupportedType;
import org.n52.shetland.ogc.gml.AbstractFeature;
import org.n52.shetland.ogc.gml.AbstractGeometry;
import org.n52.shetland.ogc.gml.GmlMeasureType;
import org.n52.shetland.ogc.gml.ReferenceType;
import org.n52.shetland.ogc.gml.time.IndeterminateValue;
import org.n52.shetland.ogc.gml.time.Time;
import org.n52.shetland.ogc.gml.time.Time.NilReason;
import org.n52.shetland.ogc.gml.time.TimeInstant;
import org.n52.shetland.ogc.gml.time.TimePeriod;
import org.n52.shetland.ogc.om.AbstractPhenomenon;
import org.n52.shetland.ogc.om.ObservationValue;
import org.n52.shetland.ogc.om.OmConstants;
import org.n52.shetland.ogc.om.OmObservableProperty;
import org.n52.shetland.ogc.om.OmObservation;
import org.n52.shetland.ogc.om.OmObservationConstellation;
import org.n52.shetland.ogc.om.SingleObservationValue;
import org.n52.shetland.ogc.om.values.BooleanValue;
import org.n52.shetland.ogc.om.values.CategoryValue;
import org.n52.shetland.ogc.om.values.ComplexValue;
import org.n52.shetland.ogc.om.values.CountValue;
import org.n52.shetland.ogc.om.values.GeometryValue;
import org.n52.shetland.ogc.om.values.NilTemplateValue;
import org.n52.shetland.ogc.om.values.QuantityValue;
import org.n52.shetland.ogc.om.values.ReferenceValue;
import org.n52.shetland.ogc.om.values.SweDataArrayValue;
import org.n52.shetland.ogc.om.values.TextValue;
import org.n52.shetland.ogc.sensorML.SensorML;
import org.n52.shetland.ogc.sos.Sos2Constants;
import org.n52.shetland.ogc.sos.SosConstants;
import org.n52.shetland.ogc.swe.SweDataArray;
import org.n52.shetland.ogc.swe.SweDataRecord;
import org.n52.shetland.w3c.Nillable;
import org.n52.svalbard.ConformanceClasses;
import org.n52.svalbard.decode.exception.DecodingException;
import org.n52.svalbard.util.CodingHelper;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.locationtech.jts.geom.Geometry;
/**
* @since 1.0.0
*
*/
public class OmDecoderv20 extends AbstractOmDecoderv20 {
private static final Logger LOGGER = LoggerFactory.getLogger(OmDecoderv20.class);
private static final Set DECODER_KEYS =
CodingHelper.decoderKeysForElements(OmConstants.NS_OM_2, OMObservationType.class,
NamedValuePropertyType.class, OMObservationDocument.class, NamedValuePropertyType[].class);
private static final Set SUPPORTED_TYPES = ImmutableSet.of(
OmConstants.OBS_TYPE_SWE_ARRAY_OBSERVATION_TYPE, OmConstants.OBS_TYPE_COMPLEX_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_GEOMETRY_OBSERVATION_TYPE, OmConstants.OBS_TYPE_CATEGORY_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_COUNT_OBSERVATION_TYPE, OmConstants.OBS_TYPE_MEASUREMENT_TYPE,
OmConstants.OBS_TYPE_TEXT_OBSERVATION_TYPE, OmConstants.OBS_TYPE_TRUTH_OBSERVATION_TYPE);
private static final Set CONFORMANCE_CLASSES = ImmutableSet.of(ConformanceClasses.OM_V2_MEASUREMENT,
ConformanceClasses.OM_V2_CATEGORY_OBSERVATION, ConformanceClasses.OM_V2_COUNT_OBSERVATION,
ConformanceClasses.OM_V2_TRUTH_OBSERVATION, ConformanceClasses.OM_V2_GEOMETRY_OBSERVATION,
ConformanceClasses.OM_V2_COMPLEX_OBSERVATION, ConformanceClasses.OM_V2_TEXT_OBSERVATION);
public OmDecoderv20() {
LOGGER.debug("Decoder for the following keys initialized successfully: {}!",
Joiner.on(", ").join(DECODER_KEYS));
}
@Override
public Set getKeys() {
return Collections.unmodifiableSet(DECODER_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 Object decode(Object object) throws DecodingException {
// validate document
// XmlHelper.validateDocument((XmlObject) object);
if (object instanceof OMObservationDocument) {
OMObservationDocument omObservationDocument = (OMObservationDocument) object;
return parseOmObservation(omObservationDocument.getOMObservation());
} else if (object instanceof OMObservationType) {
return parseOmObservation((OMObservationType) object);
}
return super.decode(object);
}
private OmObservation parseOmObservation(OMObservationType omObservation) throws DecodingException {
Map featureMap = Maps.newHashMap();
OmObservation sosObservation = new OmObservation();
// parse identifier, description
parseAbstractFeatureType(omObservation, sosObservation);
OmObservationConstellation observationConstallation = getObservationConstellation(omObservation, featureMap);
sosObservation.setObservationConstellation(observationConstallation);
sosObservation.setResultTime(getResultTime(omObservation));
sosObservation.setValidTime(getValidTime(omObservation));
if (omObservation.getParameterArray() != null) {
sosObservation.setParameter(parseNamedValueTypeArray(omObservation.getParameterArray()));
}
sosObservation.setValue(getObservationValue(omObservation));
// TODO: later for spatial filtering profile
// omObservation.getParameterArray();
return sosObservation;
}
private OmObservationConstellation getObservationConstellation(OMObservationType omot,
Map featureMap) throws DecodingException {
OmObservationConstellation observationConstellation = new OmObservationConstellation();
observationConstellation.setObservationType(getObservationType(omot));
observationConstellation.setProcedure(createProcedure(omot));
observationConstellation.setObservableProperty(getObservableProperty(omot));
observationConstellation.setFeatureOfInterest(createFeatureOfInterest(omot, featureMap));
return observationConstellation;
}
private String getObservationType(OMObservationType omObservation) {
if (omObservation.getType() != null) {
return omObservation.getType().getHref();
}
return null;
}
private AbstractPhenomenon getObservableProperty(OMObservationType omObservation) {
if (omObservation.getObservedProperty() != null) {
return new OmObservableProperty(omObservation.getObservedProperty().getHref());
}
return null;
}
private Time getPhenomenonTime(OMObservationType omObservation) throws DecodingException {
TimeObjectPropertyType phenomenonTime = omObservation.getPhenomenonTime();
if (phenomenonTime.isSetHref() && phenomenonTime.getHref().startsWith("#")) {
TimeInstant timeInstant = new TimeInstant();
timeInstant.setGmlId(phenomenonTime.getHref());
return timeInstant;
} else if (phenomenonTime.isSetNilReason() && phenomenonTime.getNilReason() instanceof String
&& ((String) phenomenonTime.getNilReason()).equals(IndeterminateValue.TEMPLATE.getValue())) {
return new TimeInstant(IndeterminateValue.TEMPLATE);
} else if (phenomenonTime.isSetAbstractTimeObject()) {
Object decodedObject = decodeXmlObject(phenomenonTime.getAbstractTimeObject());
if (decodedObject instanceof Time) {
return (Time) decodedObject;
}
// FIXME else
}
throw new DecodingException(Sos2Constants.InsertObservationParams.observation,
"The requested phenomenonTime type is not supported by this service!");
}
private TimeInstant getResultTime(OMObservationType omObservation) throws DecodingException {
if (omObservation.getResultTime().isSetHref()) {
TimeInstant timeInstant = new TimeInstant();
timeInstant.setGmlId(omObservation.getResultTime().getHref());
if (omObservation.getResultTime().getHref().charAt(0) == '#') {
// document internal link
// TODO parse linked element
timeInstant.setReference(Sos2Constants.EN_PHENOMENON_TIME);
} else {
timeInstant.setReference(omObservation.getResultTime().getHref());
}
return timeInstant;
} else if (omObservation.getResultTime().isSetNilReason()
&& omObservation.getResultTime().getNilReason() instanceof String && NilReason.template
.equals(NilReason.getEnumForString((String) omObservation.getResultTime().getNilReason()))) {
TimeInstant timeInstant = new TimeInstant();
timeInstant
.setNilReason(NilReason.getEnumForString((String) omObservation.getResultTime().getNilReason()));
return timeInstant;
} else if (omObservation.getResultTime().isSetTimeInstant()) {
Object decodedObject = decodeXmlObject(omObservation.getResultTime().getTimeInstant());
if (decodedObject instanceof TimeInstant) {
return (TimeInstant) decodedObject;
}
throw unsupportedResultTimeType();
} else {
throw unsupportedResultTimeType();
}
}
private TimePeriod getValidTime(OMObservationType omObservation) throws DecodingException {
if (omObservation.isSetValidTime()) {
Object decodedObject = decodeXmlObject(omObservation.getValidTime().getTimePeriod());
if (decodedObject instanceof TimePeriod) {
return (TimePeriod) decodedObject;
}
throw new DecodingException(Sos2Constants.InsertObservationParams.observation,
"The requested validTime type is not supported by this service!");
}
return null;
}
private ObservationValue> getObservationValue(OMObservationType omObservation) throws DecodingException {
Time phenomenonTime = getPhenomenonTime(omObservation);
ObservationValue> observationValue;
if (!omObservation.getResult().getDomNode().hasChildNodes() && phenomenonTime.isSetNilReason()
&& phenomenonTime.getNilReason().equals(NilReason.template)) {
observationValue = new SingleObservationValue<>(new NilTemplateValue());
} else {
observationValue = getResult(omObservation);
}
observationValue.setPhenomenonTime(phenomenonTime);
return observationValue;
}
private ObservationValue> getResult(OMObservationType omObservation) throws DecodingException {
XmlObject xbResult = omObservation.getResult();
if (xbResult.schemaType() == XmlAnyTypeImpl.type) {
// Template observation for InsertResultTemplate operation
if (!xbResult.getDomNode().hasChildNodes()) {
return new SingleObservationValue<>(new NilTemplateValue());
} else {
try {
xbResult = XmlObject.Factory.parse(xbResult.xmlText(getXmlOptions()).trim());
} catch (XmlException e) {
LOGGER.error("Error while parsing NamedValueValue", e);
}
}
}
// // Template observation for InsertResultTemplate operation
// if (omObservation.getResult().schemaType() == XmlAnyTypeImpl.type &&
// !omObservation.getResult().getDomNode().hasChildNodes()) {
// return new SingleObservationValue(new NilTemplateValue());
// }
if (xbResult.schemaType() == XmlBoolean.type) {
// TruthObservation
XmlBoolean xbBoolean = (XmlBoolean) xbResult;
BooleanValue booleanValue = new BooleanValue(xbBoolean.getBooleanValue());
return new SingleObservationValue<>(booleanValue);
} else if (xbResult.schemaType() == XmlInteger.type) {
// CountObservation
XmlInteger xbInteger = (XmlInteger) xbResult;
CountValue countValue = new CountValue(Integer.parseInt(xbInteger.getBigIntegerValue().toString()));
return new SingleObservationValue<>(countValue);
} else if (xbResult.schemaType() == XmlString.type) {
// TextObservation
XmlString xbString = (XmlString) xbResult;
TextValue stringValue = new TextValue(xbString.getStringValue());
return new SingleObservationValue<>(stringValue);
} else {
// result elements with other encoding like SWE_ARRAY_OBSERVATION
Object decodedObject = decodeXmlObject(xbResult);
if (decodedObject instanceof ObservationValue) {
return (ObservationValue>) decodedObject;
} else if (decodedObject instanceof GmlMeasureType) {
GmlMeasureType measureType = (GmlMeasureType) decodedObject;
QuantityValue quantitiyValue = new QuantityValue(measureType.getValue(), measureType.getUnit());
return new SingleObservationValue<>(quantitiyValue);
} else if (decodedObject instanceof ReferenceType) {
if (omObservation.isSetType() && omObservation.getType().isSetHref()
&& omObservation.getType().getHref().equals(OmConstants.OBS_TYPE_REFERENCE_OBSERVATION)) {
return new SingleObservationValue<>(new ReferenceValue((ReferenceType) decodedObject));
}
return new SingleObservationValue<>(new CategoryValue(((ReferenceType) decodedObject).getHref()));
} else if (decodedObject instanceof Geometry) {
return new SingleObservationValue<>(new GeometryValue((Geometry) decodedObject));
} else if (decodedObject instanceof AbstractGeometry) {
SingleObservationValue result = new SingleObservationValue<>();
result.setValue(new GeometryValue(((AbstractGeometry) decodedObject).getGeometry()));
return result;
} else if (decodedObject instanceof SweDataArray) {
return new SingleObservationValue<>(new SweDataArrayValue((SweDataArray) decodedObject));
} else if (decodedObject instanceof SweDataRecord) {
return new SingleObservationValue<>(new ComplexValue((SweDataRecord) decodedObject));
}
throw new DecodingException(Sos2Constants.InsertObservationParams.observation,
"The requested result type '%s' is not supported by this service!",
decodedObject.getClass().getSimpleName());
}
}
private AbstractFeature checkFeatureWithMap(AbstractFeature featureOfInterest,
Map featureMap) {
if (featureOfInterest.getGmlId() != null && !featureOfInterest.getGmlId().isEmpty()) {
if (featureMap.containsKey(featureOfInterest.getGmlId())) {
return featureMap.get(featureOfInterest.getGmlId());
} else {
featureMap.put(featureOfInterest.getGmlId(), featureOfInterest);
}
}
return featureOfInterest;
}
private Nillable createProcedure(OMObservationType omObservation) {
if (omObservation.getProcedure().isNil() || omObservation.getProcedure().isSetNilReason()) {
if (omObservation.getProcedure().isSetNilReason()) {
return Nillable. nil(omObservation.getProcedure().getNilReason().toString());
}
} else if (omObservation.getProcedure().isSetHref()) {
SensorML procedure = new SensorML();
procedure.setIdentifier(omObservation.getProcedure().getHref());
return Nillable. of(procedure);
}
return Nillable. nil();
}
private Nillable createFeatureOfInterest(OMObservationType omot,
Map featureMap) throws DecodingException {
if (omot.getFeatureOfInterest().isNil() || omot.getFeatureOfInterest().isSetNilReason()) {
if (omot.getFeatureOfInterest().isSetNilReason()) {
return Nillable. nil(omot.getFeatureOfInterest().getNilReason().toString());
}
} else {
Object decodeXmlElement = decodeXmlElement(omot.getFeatureOfInterest());
if (decodeXmlElement instanceof AbstractFeature) {
AbstractFeature featureOfInterest = (AbstractFeature) decodeXmlElement;
return Nillable.of(checkFeatureWithMap(featureOfInterest, featureMap));
}
}
return Nillable. nil();
}
private static DecodingException unsupportedResultTimeType() {
return new DecodingException(Sos2Constants.InsertObservationParams.observation,
"The requested resultTime type is not supported by this service!");
}
}