Search in sources :

Example 16 with CRSDefinition

use of eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition in project hale by halestudio.

the class StreamGmlHelper method parseInstance.

/**
 * Parses an instance with the given type from the given XML stream reader.
 *
 * @param reader the XML stream reader, the current event must be the start
 *            element of the instance
 * @param type the definition of the instance type
 * @param indexInStream the index of the instance in the stream or
 *            <code>null</code>
 * @param strict if associating elements with properties should be done
 *            strictly according to the schema, otherwise a fall-back is
 *            used trying to populate values also on invalid property paths
 * @param srsDimension the dimension of the instance or <code>null</code>
 * @param crsProvider CRS provider in case no CRS is specified, may be
 *            <code>null</code>
 * @param parentType the type of the topmost instance
 * @param propertyPath the property path down from the topmost instance, may
 *            be <code>null</code>
 * @param allowNull if a <code>null</code> result is allowed
 * @param ignoreNamespaces if parsing of the XML instances should allow
 *            types and properties with namespaces that differ from those
 *            defined in the schema
 * @param ioProvider the I/O Provider to get value
 * @param crs The <code>CRSDefinition</code> to use for geometries
 * @return the parsed instance, may be <code>null</code> if allowNull is
 *         <code>true</code>
 * @throws XMLStreamException if parsing the instance failed
 */
public static Instance parseInstance(XMLStreamReader reader, TypeDefinition type, Integer indexInStream, boolean strict, Integer srsDimension, CRSProvider crsProvider, TypeDefinition parentType, List<QName> propertyPath, boolean allowNull, boolean ignoreNamespaces, IOProvider ioProvider, CRSDefinition crs) throws XMLStreamException {
    checkState(reader.getEventType() == XMLStreamConstants.START_ELEMENT);
    if (propertyPath == null) {
        propertyPath = Collections.emptyList();
    }
    if (srsDimension == null) {
        String dim = reader.getAttributeValue(null, "srsDimension");
        if (dim != null)
            srsDimension = Integer.parseInt(dim);
    }
    // extract additional settings from I/O provider
    boolean suppressParsingGeometry = ioProvider.getParameter(StreamGmlReader.PARAM_SUPPRESS_PARSE_GEOMETRY).as(Boolean.class, false);
    MutableInstance instance;
    if (indexInStream == null) {
        // not necessary to associate data set
        instance = new DefaultInstance(type, null);
    } else {
        instance = new StreamGmlInstance(type, indexInStream);
    }
    // If the current instance has an srsName attribute, try to resolve the
    // corresponding CRS and pass it down the hierarchy and use it for
    // nested geometries that don't have their own srsName.
    CRSDefinition lastCrs = crs;
    String srsName = reader.getAttributeValue(null, "srsName");
    if (srsName != null) {
        lastCrs = CodeDefinition.tryResolve(srsName);
        if (lastCrs == null && crsProvider != null) {
            // In case the srsName value could not be resolved to a CRS, try
            // to resolve the CRS via the crsProvider.
            CRSDefinition unresolvedCrs = new CodeDefinition(srsName);
            CRSDefinition resolvedCrs = crsProvider.getCRS(parentType, propertyPath, unresolvedCrs);
            // unresolvedCrs unchanged
            if (resolvedCrs != null && !resolvedCrs.equals(unresolvedCrs)) {
                lastCrs = resolvedCrs;
            }
        }
    // If the provided CRS could not be resolved, it will be ignored
    // here silently, so that use cases that don't need the CRS will not
    // fail.
    }
    boolean mixed = type.getConstraint(XmlMixedFlag.class).isEnabled();
    if (!mixed) {
        // mixed types are treated special (see else)
        // check if xsi:nil attribute is there and set to true
        String nilString = reader.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
        boolean isNil = nilString != null && "true".equalsIgnoreCase(nilString);
        // instance properties
        parseProperties(reader, instance, strict, srsDimension, crsProvider, lastCrs, parentType, propertyPath, false, ignoreNamespaces, ioProvider);
        // nil instance w/o properties
        if (allowNull && isNil && Iterables.isEmpty(instance.getPropertyNames())) {
        // no value should be created
        /*
				 * XXX returning null here then results in problems during
				 * adding other properties to the parent group, as mandatory
				 * elements are expected to appear, and it will warn about
				 * possible invalid data loaded
				 */
        // return null;
        }
        // instance value
        if (!hasElements(type)) {
            /*
				 * Value can only be determined if there are no documents,
				 * because otherwise elements have already been processed in
				 * parseProperties and we are already past END_ELEMENT.
				 */
            if (type.getConstraint(HasValueFlag.class).isEnabled()) {
                // try to get text value
                String value = reader.getElementText();
                if (!isNil && value != null) {
                    instance.setValue(convertSimple(type, value));
                }
            }
        }
    } else {
        /*
			 * XXX For a mixed type currently ignore elements and parse only
			 * attributes and text.
			 */
        // instance properties (attributes only)
        parseProperties(reader, instance, strict, srsDimension, crsProvider, lastCrs, parentType, propertyPath, true, ignoreNamespaces, ioProvider);
        // combined text
        String value = readText(reader);
        if (value != null) {
            instance.setValue(convertSimple(type, value));
        }
    }
    // augmented value XXX should this be an else if?
    if (!suppressParsingGeometry && type.getConstraint(AugmentedValueFlag.class).isEnabled()) {
        // add geometry as a GeometryProperty value where applicable
        GeometryFactory geomFactory = type.getConstraint(GeometryFactory.class);
        Object geomValue = null;
        // the default value for the srsDimension
        int defaultValue = 2;
        try {
            if (srsDimension != null) {
                geomValue = geomFactory.createGeometry(instance, srsDimension, ioProvider);
            } else {
                // srsDimension is not set
                geomValue = geomFactory.createGeometry(instance, defaultValue, ioProvider);
            }
        } catch (Exception e) {
            /*
				 * Catch IllegalArgumentException that e.g. occurs if a linear
				 * ring has to few points. NullPointerExceptions may occur
				 * because an internal geometry could not be created.
				 * 
				 * XXX a problem is that these messages will not appear in the
				 * report
				 */
            log.error("Error creating geometry", e);
        }
        if (geomValue != null && crsProvider != null && propertyPath != null) {
            // check if CRS are set, and if not, try determining them using
            // the CRS provider
            Collection<?> values;
            if (geomValue instanceof Collection) {
                values = (Collection<?>) geomValue;
            } else {
                values = Collections.singleton(geomValue);
            }
            List<Object> resultVals = new ArrayList<Object>();
            for (Object value : values) {
                if (value instanceof Geometry || (value instanceof GeometryProperty<?> && ((GeometryProperty<?>) value).getCRSDefinition() == null)) {
                    // try to resolve value of srsName attribute
                    CRSDefinition geometryCrs = crsProvider.getCRS(parentType, propertyPath, lastCrs);
                    if (geometryCrs != null) {
                        Geometry geom = (value instanceof Geometry) ? ((Geometry) value) : (((GeometryProperty<?>) value).getGeometry());
                        resultVals.add(new DefaultGeometryProperty<Geometry>(geometryCrs, geom));
                        continue;
                    }
                }
                resultVals.add(value);
            }
            if (resultVals.size() == 1) {
                geomValue = resultVals.get(0);
            } else {
                geomValue = resultVals;
            }
        }
        if (geomValue != null) {
            instance.setValue(geomValue);
        }
    }
    return instance;
}
Also used : DefaultGeometryProperty(eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty) GeometryProperty(eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty) GeometryFactory(eu.esdihumboldt.hale.io.gml.geometry.constraint.GeometryFactory) CRSDefinition(eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition) HasValueFlag(eu.esdihumboldt.hale.common.schema.model.constraint.type.HasValueFlag) ArrayList(java.util.ArrayList) XMLStreamException(javax.xml.stream.XMLStreamException) Geometry(com.vividsolutions.jts.geom.Geometry) CodeDefinition(eu.esdihumboldt.hale.common.instance.geometry.impl.CodeDefinition) XmlMixedFlag(eu.esdihumboldt.hale.io.xsd.constraint.XmlMixedFlag) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) Collection(java.util.Collection)

Example 17 with CRSDefinition

use of eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition in project hale by halestudio.

the class StreamGmlWriter method writeElement.

/**
 * Write a property element.
 *
 * @param value the element value
 * @param propDef the property definition
 * @param report the reporter
 * @throws XMLStreamException if writing the element fails
 */
private void writeElement(Object value, PropertyDefinition propDef, IOReporter report) throws XMLStreamException {
    Group group = null;
    if (value instanceof Group) {
        group = (Group) value;
        if (value instanceof Instance) {
            // extract value from instance
            value = ((Instance) value).getValue();
        }
    }
    if (group == null) {
        if (value == null) {
            // null value
            if (propDef.getConstraint(Cardinality.class).getMinOccurs() > 0) {
                // write empty element
                GmlWriterUtil.writeEmptyElement(writer, propDef.getName());
                // mark as nil
                writeElementValue(null, propDef);
            }
        // otherwise just skip it
        } else {
            GmlWriterUtil.writeStartElement(writer, propDef.getName());
            Pair<Geometry, CRSDefinition> pair = extractGeometry(value, true, report);
            if (pair != null) {
                String srsName = extractCode(pair.getSecond());
                // write geometry
                writeGeometry(pair.getFirst(), propDef, srsName, report);
            } else {
                // simple element with value
                // write value as content
                writeElementValue(value, propDef);
            }
            writer.writeEndElement();
        }
    } else {
        // children and maybe a value
        GmlWriterUtil.writeStartElement(writer, propDef.getName());
        boolean hasValue = propDef.getPropertyType().getConstraint(HasValueFlag.class).isEnabled();
        Pair<Geometry, CRSDefinition> pair = extractGeometry(value, true, report);
        // handle about annotated geometries
        if (!hasValue && pair != null) {
            String srsName = extractCode(pair.getSecond());
            // write geometry
            writeGeometry(pair.getFirst(), propDef, srsName, report);
        } else {
            boolean hasOnlyNilReason = hasOnlyNilReason(group);
            // write no elements if there is a value or only a nil reason
            boolean writeElements = !hasValue && !hasOnlyNilReason;
            boolean isNil = !writeElements && (!hasValue || value == null);
            // write all children
            writeProperties(group, group.getDefinition(), writeElements, isNil, report);
            // write value
            if (hasValue) {
                writeElementValue(value, propDef);
            } else if (hasOnlyNilReason) {
                // complex element with a nil value -> write xsi:nil if
                // possible
                /*
					 * XXX open question: should xsi:nil be there also if there
					 * are other attributes than nilReason?
					 */
                writeElementValue(null, propDef);
            }
        }
        writer.writeEndElement();
    }
}
Also used : Geometry(com.vividsolutions.jts.geom.Geometry) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup) Group(eu.esdihumboldt.hale.common.instance.model.Group) Instance(eu.esdihumboldt.hale.common.instance.model.Instance) CRSDefinition(eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition) HasValueFlag(eu.esdihumboldt.hale.common.schema.model.constraint.type.HasValueFlag)

Example 18 with CRSDefinition

use of eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition in project hale by halestudio.

the class OrdinatesToPoint method evaluate.

/**
 * @see eu.esdihumboldt.hale.common.align.transformation.function.impl.AbstractPropertyTransformation#evaluate(java.lang.String,
 *      eu.esdihumboldt.hale.common.align.transformation.engine.TransformationEngine,
 *      com.google.common.collect.ListMultimap,
 *      com.google.common.collect.ListMultimap, java.util.Map,
 *      eu.esdihumboldt.hale.common.align.transformation.report.TransformationLog)
 */
@Override
protected Object evaluate(String transformationIdentifier, TransformationEngine engine, ListMultimap<String, PropertyValue> variables, String resultName, PropertyEntityDefinition resultProperty, Map<String, String> executionParameters, TransformationLog log) throws TransformationException {
    // get x, y and z properties
    PropertyValue x = variables.get("x").get(0);
    PropertyValue y = variables.get("y").get(0);
    PropertyValue z = null;
    if (!variables.get("z").isEmpty())
        z = variables.get("z").get(0);
    // get crs definition if srs is specified
    CRSDefinition crsDef = null;
    String srs = getOptionalParameter(PARAMETER_REFERENCE_SYSTEM, null).as(String.class);
    if (srs != null)
        crsDef = new CodeDefinition(srs, null);
    // convert values to double and create a point
    double xValue = x.getValueAs(Double.class);
    double yValue = y.getValueAs(Double.class);
    Point resultPoint;
    GeometryFactory geomFactory = new GeometryFactory();
    if (z == null)
        resultPoint = geomFactory.createPoint(new Coordinate(xValue, yValue));
    else
        resultPoint = geomFactory.createPoint(new Coordinate(xValue, yValue, z.getValueAs(Double.class)));
    // pack result into geometry property and return it
    GeometryProperty<Point> result = new DefaultGeometryProperty<Point>(crsDef, resultPoint);
    return result;
}
Also used : GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) DefaultGeometryProperty(eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty) CRSDefinition(eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition) CodeDefinition(eu.esdihumboldt.hale.common.instance.geometry.impl.CodeDefinition) Coordinate(com.vividsolutions.jts.geom.Coordinate) PropertyValue(eu.esdihumboldt.hale.common.align.transformation.function.PropertyValue) Point(com.vividsolutions.jts.geom.Point)

Example 19 with CRSDefinition

use of eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition in project hale by halestudio.

the class ReprojectGeometry method evaluate.

@Override
protected Object evaluate(String transformationIdentifier, TransformationEngine engine, ListMultimap<String, PropertyValue> variables, String resultName, PropertyEntityDefinition resultProperty, Map<String, String> executionParameters, TransformationLog log) throws TransformationException, NoResultException {
    // Get input geometry
    PropertyValue input = variables.get("source").get(0);
    Object inputValue = input.getValue();
    InstanceTraverser traverser = new DepthFirstInstanceTraverser(true);
    GeometryFinder geoFind = new GeometryFinder(null);
    traverser.traverse(inputValue, geoFind);
    List<GeometryProperty<?>> geoms = geoFind.getGeometries();
    Geometry sourceGeometry = geoms.get(0).getGeometry();
    CRSDefinition crsDef = geoms.get(0).getCRSDefinition();
    if (crsDef == null) {
        throw new TransformationException("Geometry does not have an associated Coordinate Reference System");
    }
    CoordinateReferenceSystem sourceCRS = crsDef.getCRS();
    Geometry resultGeometry = sourceGeometry;
    CoordinateReferenceSystem targetCRS = sourceCRS;
    // Get input parameter
    String srs = getParameterChecked(PARAMETER_REFERENCE_SYSTEM).as(String.class);
    if (srs != null) {
        try {
            targetCRS = parseReferenceSystemParamter(srs);
        } catch (Exception e) {
            throw new TransformationException("Error determining destination Cordinate Reference System.", e);
        }
        // Retrieve transformation from cell context, or create a new
        // instance
        Map<Object, Object> cellContext = getExecutionContext().getCellContext();
        MathTransform transform = getOrCreateMathTransform(sourceCRS, targetCRS, cellContext);
        // Apply transformation
        try {
            resultGeometry = JTS.transform(sourceGeometry, transform);
        } catch (MismatchedDimensionException | TransformException e) {
            throw new TransformationException("Problem on execute transformation from: " + sourceCRS + " to " + targetCRS, e);
        }
    }
    return new DefaultGeometryProperty<Geometry>(new CodeDefinition(CRS.toSRS(targetCRS), targetCRS), resultGeometry);
}
Also used : InstanceTraverser(eu.esdihumboldt.hale.common.instance.helper.InstanceTraverser) DepthFirstInstanceTraverser(eu.esdihumboldt.hale.common.instance.helper.DepthFirstInstanceTraverser) DefaultGeometryProperty(eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty) GeometryProperty(eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty) TransformationException(eu.esdihumboldt.hale.common.align.transformation.function.TransformationException) MathTransform(org.opengis.referencing.operation.MathTransform) GeometryFinder(eu.esdihumboldt.hale.common.instance.geometry.GeometryFinder) CRSDefinition(eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition) TransformException(org.opengis.referencing.operation.TransformException) PropertyValue(eu.esdihumboldt.hale.common.align.transformation.function.PropertyValue) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) FactoryException(org.opengis.referencing.FactoryException) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) TransformationException(eu.esdihumboldt.hale.common.align.transformation.function.TransformationException) TransformException(org.opengis.referencing.operation.TransformException) NoResultException(eu.esdihumboldt.hale.common.align.transformation.function.impl.NoResultException) DepthFirstInstanceTraverser(eu.esdihumboldt.hale.common.instance.helper.DepthFirstInstanceTraverser) Geometry(com.vividsolutions.jts.geom.Geometry) DefaultGeometryProperty(eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty) CodeDefinition(eu.esdihumboldt.hale.common.instance.geometry.impl.CodeDefinition) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 20 with CRSDefinition

use of eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition in project hale by halestudio.

the class AggregateTransformation method aggregateGeometries.

/**
 * Aggregates geometries contained in the provided objects.
 *
 * @param geometries the geometries or instances containing geometries
 * @param cell the currently process cell or <code>null</code>
 * @param log the transformation log or <code>null</code>
 * @return the aggregated geometry
 * @throws TransformationException if source geometries don't have a common
 *             CRS
 * @throws NoResultException if the result extent would be <code>null</code>
 */
public static GeometryProperty<?> aggregateGeometries(Iterable<?> geometries, @Nullable TransformationLog log, @Nullable Cell cell) throws NoResultException, TransformationException {
    InstanceTraverser traverser = new DepthFirstInstanceTraverser(true);
    GeometryFinder geoFind = new GeometryFinder(null);
    CRSDefinition commonCrs = null;
    Class<? extends Geometry> commonGeometryType = null;
    List<Geometry> collectedGeometries = new ArrayList<>();
    for (Object value : geometries) {
        // find contained geometries
        traverser.traverse(value, geoFind);
        for (GeometryProperty<?> geom : geoFind.getGeometries()) {
            // no CRS or one common CRS is OK
            if (commonCrs == null) {
                commonCrs = geom.getCRSDefinition();
            } else {
                if (geom.getCRSDefinition() != null && !geom.getCRSDefinition().equals(commonCrs)) {
                    // CRS doesn't match
                    throw new TransformationException("Source geometries don't have a common CRS.");
                }
            }
            Geometry g = geom.getGeometry();
            // determine common geometry type: point / line / polygon
            if (commonGeometryType == null) {
                commonGeometryType = getContainedGeometryType(g.getClass());
            } else {
                Class<? extends Geometry> currentType = getContainedGeometryType(g.getClass());
                if (!commonGeometryType.isAssignableFrom(currentType)) {
                    if (currentType.isAssignableFrom(commonGeometryType)) {
                        commonGeometryType = currentType;
                    } else {
                        commonGeometryType = Geometry.class;
                    }
                }
            }
            // collect geometry
            for (int i = 0; i < g.getNumGeometries(); i++) {
                collectedGeometries.add(g.getGeometryN(i));
            }
        }
        geoFind.reset();
    }
    if (commonGeometryType != null && commonGeometryType.equals(Geometry.class)) {
        if (log != null && cell != null) {
            log.warn(new TransformationMessageImpl(cell, "Could not find common geometry type for aggregation", null));
        }
    }
    if (commonGeometryType != null) {
        Geometry combined = combineGeometries(collectedGeometries, commonGeometryType);
        return new DefaultGeometryProperty<Geometry>(commonCrs, combined);
    }
    throw new NoResultException();
}
Also used : InstanceTraverser(eu.esdihumboldt.hale.common.instance.helper.InstanceTraverser) DepthFirstInstanceTraverser(eu.esdihumboldt.hale.common.instance.helper.DepthFirstInstanceTraverser) TransformationException(eu.esdihumboldt.hale.common.align.transformation.function.TransformationException) GeometryFinder(eu.esdihumboldt.hale.common.instance.geometry.GeometryFinder) CRSDefinition(eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition) ArrayList(java.util.ArrayList) NoResultException(eu.esdihumboldt.hale.common.align.transformation.function.impl.NoResultException) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint) TransformationMessageImpl(eu.esdihumboldt.hale.common.align.transformation.report.impl.TransformationMessageImpl) DepthFirstInstanceTraverser(eu.esdihumboldt.hale.common.instance.helper.DepthFirstInstanceTraverser) Geometry(com.vividsolutions.jts.geom.Geometry) DefaultGeometryProperty(eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty)

Aggregations

CRSDefinition (eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition)30 DefaultGeometryProperty (eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty)20 Geometry (com.vividsolutions.jts.geom.Geometry)13 Point (com.vividsolutions.jts.geom.Point)9 CodeDefinition (eu.esdihumboldt.hale.common.instance.geometry.impl.CodeDefinition)8 GeometryProperty (eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty)8 GeometryNotSupportedException (eu.esdihumboldt.hale.io.gml.geometry.GeometryNotSupportedException)8 ArrayList (java.util.ArrayList)8 Instance (eu.esdihumboldt.hale.common.instance.model.Instance)7 Coordinate (com.vividsolutions.jts.geom.Coordinate)6 GeometryFinder (eu.esdihumboldt.hale.common.instance.geometry.GeometryFinder)6 DepthFirstInstanceTraverser (eu.esdihumboldt.hale.common.instance.helper.DepthFirstInstanceTraverser)6 InstanceTraverser (eu.esdihumboldt.hale.common.instance.helper.InstanceTraverser)6 LineString (com.vividsolutions.jts.geom.LineString)5 TransformationException (eu.esdihumboldt.hale.common.align.transformation.function.TransformationException)5 WKTDefinition (eu.esdihumboldt.hale.common.instance.geometry.impl.WKTDefinition)5 ParseException (java.text.ParseException)5 GeometryFactory (com.vividsolutions.jts.geom.GeometryFactory)3 LinearRing (com.vividsolutions.jts.geom.LinearRing)3 NoResultException (eu.esdihumboldt.hale.common.align.transformation.function.impl.NoResultException)3