Search in sources :

Example 1 with Descent

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent in project hale by halestudio.

the class XsltGenerator method writeContainerFragment.

/**
 * Write the container fragment.
 *
 * @param templateFile the file to write to
 * @param groupedResults the result variable names grouped by associated
 *            target type
 * @param targetElements an empty map that is populated with variable names
 *            mapped to target element names
 * @throws IOException if an error occurs writing the template
 * @throws XMLStreamException if an error occurs writing XML content to the
 *             template
 */
private void writeContainerFragment(File templateFile, Multimap<TypeDefinition, String> groupedResults, Map<String, QName> targetElements) throws XMLStreamException, IOException {
    XMLStreamWriter writer = XslTransformationUtil.setupXMLWriter(new BufferedOutputStream(new FileOutputStream(templateFile)), prefixes);
    try {
        // write container
        GmlWriterUtil.writeStartElement(writer, targetContainer.getName());
        // generate an eventual required identifier on the container
        GmlWriterUtil.writeRequiredID(writer, targetContainer.getType(), null, false);
        writeContainerIntro(writer, context);
        // cache definition paths
        Map<TypeDefinition, DefinitionPath> paths = new HashMap<TypeDefinition, DefinitionPath>();
        Descent lastDescent = null;
        for (Entry<TypeDefinition, String> entry : groupedResults.entries()) {
            TypeDefinition type = entry.getKey();
            // get stored definition path for the type
            DefinitionPath defPath;
            if (paths.containsKey(type)) {
                // get the stored path, may be null
                defPath = paths.get(type);
            } else {
                // determine a valid definition path in the container
                defPath = findMemberAttribute(targetContainer, type);
                // store path (may be null)
                paths.put(type, defPath);
            }
            if (defPath != null) {
                // insert xsl:for-each at the appropriate position in
                // the path
                defPath = pathInsertForEach(defPath, entry.getValue(), targetElements);
                lastDescent = Descent.descend(writer, defPath, lastDescent, false, true);
                // write single target instance from variable
                GmlWriterUtil.writeEmptyElement(writer, new QName(NS_URI_XSL, "copy-of"));
                writer.writeAttribute("select", ".");
            } else {
                reporter.warn(new IOMessageImpl(MessageFormat.format("No compatible member attribute for type {0} found in root element {1}, one instance was skipped", type.getDisplayName(), targetContainer.getName().getLocalPart()), null));
            }
        }
        if (lastDescent != null) {
            lastDescent.close();
        }
        // end container
        writer.writeEndElement();
    } finally {
        writer.close();
    }
}
Also used : HashMap(java.util.HashMap) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) QName(javax.xml.namespace.QName) FileOutputStream(java.io.FileOutputStream) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath) BufferedOutputStream(java.io.BufferedOutputStream) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition)

Example 2 with Descent

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent in project hale by halestudio.

the class StreamGmlWriter method write.

/**
 * Write the given instances to an {@link XMLStreamWriter}.<br>
 * <br>
 * Use {@link #createWriter(OutputStream, IOReporter)} to create a properly
 * configured writer for this method.
 *
 * @param instances the instance collection
 * @param writer the writer to write the instances to
 * @param reporter the reporter
 * @param progress the progress
 * @see #createWriter(OutputStream, IOReporter)
 */
protected void write(InstanceCollection instances, PrefixAwareStreamWriter writer, ProgressIndicator progress, IOReporter reporter) {
    this.writer = writer;
    try {
        final SubtaskProgressIndicator sub = new SubtaskProgressIndicator(progress) {

            @Override
            protected String getCombinedTaskName(String taskName, String subtaskName) {
                return taskName + " (" + subtaskName + ")";
            }
        };
        progress = sub;
        progress.begin(getTaskName(), instances.size());
        XmlElement container = findDefaultContainter(targetIndex, reporter);
        TypeDefinition containerDefinition = (container == null) ? (null) : (container.getType());
        QName containerName = (container == null) ? (null) : (container.getName());
        if (containerDefinition == null) {
            XmlElement containerElement = getConfiguredContainerElement(this, getXMLIndex());
            if (containerElement != null) {
                containerDefinition = containerElement.getType();
                containerName = containerElement.getName();
                container = containerElement;
            } else {
                // this is the last option, so we can throw a specific error
                throw new IllegalStateException("Configured container element not found");
            }
        }
        if (containerDefinition == null || containerName == null) {
            throw new IllegalStateException("No root element/container found");
        }
        /*
			 * Add schema for container to validation schemas, if the namespace
			 * differs from the main namespace or additional schemas.
			 * 
			 * Needed for validation based on schemaLocation attribute.
			 */
        if (container != null && !containerName.getNamespaceURI().equals(targetIndex.getNamespace()) && !additionalSchemas.containsKey(containerName.getNamespaceURI())) {
            try {
                final URI containerSchemaLoc = stripFragment(container.getLocation());
                if (containerSchemaLoc != null) {
                    addValidationSchema(containerName.getNamespaceURI(), new Locatable() {

                        @Override
                        public URI getLocation() {
                            return containerSchemaLoc;
                        }
                    }, null);
                }
            } catch (Exception e) {
                reporter.error("Could not determine location of container definition", e);
            }
        }
        // additional schema namespace prefixes
        for (Entry<String, String> schemaNs : additionalSchemaPrefixes.entrySet()) {
            GmlWriterUtil.addNamespace(writer, schemaNs.getKey(), schemaNs.getValue());
        }
        writer.writeStartDocument();
        if (documentWrapper != null) {
            documentWrapper.startWrap(writer, reporter);
        }
        GmlWriterUtil.writeStartElement(writer, containerName);
        // generate mandatory id attribute (for feature collection)
        String containerId = getParameter(PARAM_CONTAINER_ID).as(String.class);
        GmlWriterUtil.writeID(writer, containerDefinition, null, false, containerId);
        // write schema locations
        StringBuffer locations = new StringBuffer();
        String noNamespaceLocation = null;
        if (targetIndex.getNamespace() != null && !targetIndex.getNamespace().isEmpty()) {
            locations.append(targetIndex.getNamespace());
            // $NON-NLS-1$
            locations.append(" ");
            locations.append(targetIndex.getLocation().toString());
        } else {
            noNamespaceLocation = targetIndex.getLocation().toString();
        }
        for (Entry<String, Locatable> schema : additionalSchemas.entrySet()) {
            if (schema.getKey() != null && !schema.getKey().isEmpty()) {
                if (locations.length() > 0) {
                    // $NON-NLS-1$
                    locations.append(" ");
                }
                locations.append(schema.getKey());
                // $NON-NLS-1$
                locations.append(" ");
                locations.append(schema.getValue().getLocation().toString());
            } else {
                noNamespaceLocation = schema.getValue().getLocation().toString();
            }
        }
        if (locations.length() > 0) {
            // $NON-NLS-1$
            writer.writeAttribute(SCHEMA_INSTANCE_NS, "schemaLocation", locations.toString());
        }
        if (noNamespaceLocation != null) {
            // $NON-NLS-1$
            writer.writeAttribute(// $NON-NLS-1$
            SCHEMA_INSTANCE_NS, // $NON-NLS-1$
            "noNamespaceSchemaLocation", noNamespaceLocation);
        }
        writeAdditionalElements(writer, containerDefinition, reporter);
        // write the instances
        ResourceIterator<Instance> itInstance = instances.iterator();
        try {
            Map<TypeDefinition, DefinitionPath> paths = new HashMap<TypeDefinition, DefinitionPath>();
            long lastUpdate = 0;
            int count = 0;
            Descent lastDescent = null;
            while (itInstance.hasNext() && !progress.isCanceled()) {
                Instance instance = itInstance.next();
                TypeDefinition type = instance.getDefinition();
                /*
					 * Skip all objects that are no features when writing to a
					 * GML feature collection.
					 */
                boolean skip = useFeatureCollection && !GmlWriterUtil.isFeatureType(type);
                if (skip) {
                    progress.advance(1);
                    continue;
                }
                // get stored definition path for the type
                DefinitionPath defPath;
                if (paths.containsKey(type)) {
                    // get the stored path, may be null
                    defPath = paths.get(type);
                } else {
                    // determine a valid definition path in the container
                    defPath = findMemberAttribute(containerDefinition, containerName, type);
                    // store path (may be null)
                    paths.put(type, defPath);
                }
                if (defPath != null) {
                    // write the feature
                    lastDescent = Descent.descend(writer, defPath, lastDescent, false);
                    writeMember(instance, type, reporter);
                } else {
                    reporter.warn(new IOMessageImpl(MessageFormat.format("No compatible member attribute for type {0} found in root element {1}, one instance was skipped", type.getDisplayName(), containerName.getLocalPart()), null));
                }
                progress.advance(1);
                count++;
                long now = System.currentTimeMillis();
                // only update every 100 milliseconds
                if (now - lastUpdate > 100 || !itInstance.hasNext()) {
                    lastUpdate = now;
                    sub.subTask(String.valueOf(count) + " instances");
                }
            }
            if (lastDescent != null) {
                lastDescent.close();
            }
        } finally {
            itInstance.close();
        }
        // FeatureCollection
        writer.writeEndElement();
        if (documentWrapper != null) {
            documentWrapper.endWrap(writer, reporter);
        }
        writer.writeEndDocument();
        writer.close();
        reporter.setSuccess(reporter.getErrors().isEmpty());
    } catch (Exception e) {
        reporter.error(new IOMessageImpl(e.getLocalizedMessage(), e));
        reporter.setSuccess(false);
    } finally {
        progress.end();
    }
}
Also used : Instance(eu.esdihumboldt.hale.common.instance.model.Instance) HashMap(java.util.HashMap) QName(javax.xml.namespace.QName) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) SubtaskProgressIndicator(eu.esdihumboldt.hale.common.core.io.impl.SubtaskProgressIndicator) URI(java.net.URI) IOProviderConfigurationException(eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException) XMLStreamException(javax.xml.stream.XMLStreamException) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) IOException(java.io.IOException) FactoryException(org.opengis.referencing.FactoryException) URISyntaxException(java.net.URISyntaxException) TransformException(org.opengis.referencing.operation.TransformException) Point(org.locationtech.jts.geom.Point) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) XmlElement(eu.esdihumboldt.hale.io.xsd.model.XmlElement) DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent) Locatable(eu.esdihumboldt.hale.common.core.io.supplier.Locatable)

Example 3 with Descent

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent in project hale by halestudio.

the class MultiPointWriter method write.

/**
 * @see GeometryWriter#write(XMLStreamWriter, Geometry, TypeDefinition,
 *      QName, String, DecimalFormat)
 */
@Override
public void write(XMLStreamWriter writer, MultiPoint geometry, TypeDefinition elementType, QName elementName, String gmlNs, DecimalFormat decimalFormatter) throws XMLStreamException {
    for (int i = 0; i < geometry.getNumGeometries(); i++) {
        if (i > 0) {
            writer.writeStartElement(elementName.getNamespaceURI(), elementName.getLocalPart());
        }
        Descent descent = descend(// $NON-NLS-1$
        writer, // $NON-NLS-1$
        Pattern.parse("*/Point"), elementType, elementName, gmlNs, false);
        Point point = (Point) geometry.getGeometryN(i);
        pointWriter.write(writer, point, descent.getPath().getLastType(), descent.getPath().getLastElement().getName(), gmlNs, decimalFormatter);
        descent.close();
        if (i < geometry.getNumGeometries() - 1) {
            writer.writeEndElement();
        }
    }
}
Also used : Point(org.locationtech.jts.geom.Point) MultiPoint(org.locationtech.jts.geom.MultiPoint) Point(org.locationtech.jts.geom.Point) MultiPoint(org.locationtech.jts.geom.MultiPoint) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent)

Example 4 with Descent

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent in project hale by halestudio.

the class AbstractMultiPolygonWriter method write.

/**
 * @see GeometryWriter#write(XMLStreamWriter, Geometry, TypeDefinition,
 *      QName, String, DecimalFormat)
 */
@Override
public void write(XMLStreamWriter writer, MultiPolygon geometry, TypeDefinition elementType, QName elementName, String gmlNs, DecimalFormat decimalFormatter) throws XMLStreamException {
    for (int i = 0; i < geometry.getNumGeometries(); i++) {
        if (i > 0) {
            writer.writeStartElement(elementName.getNamespaceURI(), elementName.getLocalPart());
        }
        Descent descent = descend(// $NON-NLS-1$
        writer, // $NON-NLS-1$
        Pattern.parse("*/Polygon"), elementType, elementName, gmlNs, false);
        Polygon poly = (Polygon) geometry.getGeometryN(i);
        polygonWriter.write(writer, poly, descent.getPath().getLastType(), descent.getPath().getLastElement().getName(), gmlNs, decimalFormatter);
        descent.close();
        if (i < geometry.getNumGeometries() - 1) {
            writer.writeEndElement();
        }
    }
}
Also used : Polygon(org.locationtech.jts.geom.Polygon) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent)

Example 5 with Descent

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent in project hale by halestudio.

the class LegacyMultiPolygonWriter method write.

/**
 * @see GeometryWriter#write(XMLStreamWriter, Geometry, TypeDefinition,
 *      QName, String, DecimalFormat)
 */
@Override
public void write(XMLStreamWriter writer, MultiPolygon geometry, TypeDefinition elementType, QName elementName, String gmlNs, DecimalFormat decimalFormatter) throws XMLStreamException {
    for (int i = 0; i < geometry.getNumGeometries(); i++) {
        if (i > 0) {
            writer.writeStartElement(elementName.getNamespaceURI(), elementName.getLocalPart());
        }
        Descent descent = descend(// $NON-NLS-1$
        writer, // $NON-NLS-1$
        Pattern.parse("*/Polygon"), elementType, elementName, gmlNs, false);
        Polygon poly = (Polygon) geometry.getGeometryN(i);
        polygonWriter.write(writer, poly, descent.getPath().getLastType(), descent.getPath().getLastElement().getName(), gmlNs, decimalFormatter);
        descent.close();
        if (i < geometry.getNumGeometries() - 1) {
            writer.writeEndElement();
        }
    }
}
Also used : Polygon(org.locationtech.jts.geom.Polygon) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent)

Aggregations

Descent (eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent)8 IOMessageImpl (eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl)2 TypeDefinition (eu.esdihumboldt.hale.common.schema.model.TypeDefinition)2 DefinitionPath (eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath)2 HashMap (java.util.HashMap)2 QName (javax.xml.namespace.QName)2 LineString (org.locationtech.jts.geom.LineString)2 MultiLineString (org.locationtech.jts.geom.MultiLineString)2 MultiPolygon (org.locationtech.jts.geom.MultiPolygon)2 Point (org.locationtech.jts.geom.Point)2 Polygon (org.locationtech.jts.geom.Polygon)2 IOProviderConfigurationException (eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException)1 SubtaskProgressIndicator (eu.esdihumboldt.hale.common.core.io.impl.SubtaskProgressIndicator)1 Locatable (eu.esdihumboldt.hale.common.core.io.supplier.Locatable)1 Instance (eu.esdihumboldt.hale.common.instance.model.Instance)1 XmlElement (eu.esdihumboldt.hale.io.xsd.model.XmlElement)1 BufferedOutputStream (java.io.BufferedOutputStream)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 URI (java.net.URI)1