diff --git a/io/plugins/eu.esdihumboldt.hale.io.csv/META-INF/MANIFEST.MF b/io/plugins/eu.esdihumboldt.hale.io.csv/META-INF/MANIFEST.MF
index 960bb14853..38424958d4 100644
--- a/io/plugins/eu.esdihumboldt.hale.io.csv/META-INF/MANIFEST.MF
+++ b/io/plugins/eu.esdihumboldt.hale.io.csv/META-INF/MANIFEST.MF
@@ -30,6 +30,7 @@ Import-Package: au.com.bytecode.opencsv;version="2.3.0",
eu.esdihumboldt.hale.common.lookup,
eu.esdihumboldt.hale.common.lookup.impl,
eu.esdihumboldt.hale.common.schema,
+ eu.esdihumboldt.hale.common.schema.geometry,
eu.esdihumboldt.hale.common.schema.io,
eu.esdihumboldt.hale.common.schema.io.impl,
eu.esdihumboldt.hale.common.schema.model,
diff --git a/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/AbstractTableInstanceWriter.java b/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/AbstractTableInstanceWriter.java
index 2e1bc318e6..f89b504497 100644
--- a/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/AbstractTableInstanceWriter.java
+++ b/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/AbstractTableInstanceWriter.java
@@ -22,7 +22,13 @@
import javax.xml.namespace.QName;
-import eu.esdihumboldt.hale.common.instance.io.impl.AbstractInstanceWriter;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryCollection;
+
+import eu.esdihumboldt.hale.common.core.io.report.IOReporter;
+import eu.esdihumboldt.hale.common.instance.geometry.DefaultGeometryProperty;
+import eu.esdihumboldt.hale.common.instance.io.impl.AbstractGeoInstanceWriter;
+import eu.esdihumboldt.hale.common.instance.io.util.EnumWindingOrderTypes;
import eu.esdihumboldt.hale.common.instance.model.Group;
import eu.esdihumboldt.hale.common.instance.model.Instance;
import eu.esdihumboldt.hale.common.instance.model.InstanceCollection;
@@ -36,7 +42,7 @@
*
* @author Patrick Lieb
*/
-public abstract class AbstractTableInstanceWriter extends AbstractInstanceWriter {
+public abstract class AbstractTableInstanceWriter extends AbstractGeoInstanceWriter {
/**
* @see eu.esdihumboldt.hale.common.core.io.IOProvider#isCancelable()
@@ -57,11 +63,12 @@ public boolean isCancelable() {
* @param useSchema true
if properties should be defined from
* the schema, otherwise false
and properties are
* defined from the Instances
+ * @param reporter IOReporter
* @return a map of properties with string of localpart of the QName of the
* property as key
*/
protected Map getPropertyMap(Instance instance, List headerRow,
- boolean useSchema, boolean solveNestedProperties) {
+ boolean useSchema, boolean solveNestedProperties, IOReporter reporter) {
// properties of current instance
Iterable allProperties;
if (!useSchema) {
@@ -88,16 +95,16 @@ protected Map getPropertyMap(Instance instance, List hea
// if property is an OInstance or OGroup, it's a nested property
if (solveNestedProperties && property instanceof Group) {
Group nextInstance = (Group) property;
- iterateBuild(nextInstance, qname, headerRow, row, cellValue);
+ iterateBuild(nextInstance, qname, headerRow, row, cellValue, reporter);
}
else {
// add property with corresponding cellValue (localpart) to
// map
if (property instanceof Group && shouldBeDisplayed(property)) {
- checkValue((Group) property, headerRow, row, cellValue);
+ checkValue((Group) property, headerRow, row, cellValue, reporter);
}
else {
- addProperty(headerRow, row, property, cellValue);
+ addProperty(headerRow, row, property, cellValue, reporter);
}
}
@@ -115,17 +122,17 @@ else if (useSchema) {
// property
if (solveNestedProperties && property instanceof Group) {
Group nextInstance = (Group) property;
- iterateBuild(nextInstance, qname, headerRow, row, cellValue);
+ iterateBuild(nextInstance, qname, headerRow, row, cellValue, reporter);
}
else {
// add property with corresponding cellValue (localpart)
// to
// map
if (property instanceof Group && shouldBeDisplayed(property)) {
- checkValue((Group) property, headerRow, row, cellValue);
+ checkValue((Group) property, headerRow, row, cellValue, reporter);
}
else {
- addProperty(headerRow, row, property, cellValue);
+ addProperty(headerRow, row, property, cellValue, reporter);
}
}
}
@@ -135,7 +142,7 @@ else if (useSchema) {
if (shouldBeDisplayed(property)) {
cellValue = qname.getLocalPart();
}
- addProperty(headerRow, row, property, cellValue);
+ addProperty(headerRow, row, property, cellValue, reporter);
} // close else
} // close else-if
@@ -155,8 +162,8 @@ else if (useSchema) {
* @return a map of properties with string of localpart of the QName of the
* property as key
*/
- protected Map getPropertyMap(TypeDefinition definition,
- List headerRow) {
+ protected Map getPropertyMap(TypeDefinition definition, List headerRow,
+ IOReporter reporter) {
Iterable allProperties = DefinitionUtil.getAllProperties(definition).stream()
.map(def -> def.getName()).collect(Collectors.toList());
Map row = new HashMap();
@@ -167,7 +174,7 @@ protected Map getPropertyMap(TypeDefinition definition,
if (shouldBeDisplayed(property)) {
cellValue = qname.getLocalPart();
}
- addProperty(headerRow, row, property, cellValue);
+ addProperty(headerRow, row, property, cellValue, reporter);
}
@@ -184,11 +191,11 @@ protected Map getPropertyMap(TypeDefinition definition,
* instance name/path
*/
private void iterateBuild(Group instance, QName qNameOfTheInstance, List headerRow,
- Map row, String propertyPath) {
+ Map row, String propertyPath, IOReporter reporter) {
if (shouldBeDisplayed(instance)) {
// check if the actual instance has a value an add it
- checkValue(instance, headerRow, row, propertyPath);
+ checkValue(instance, headerRow, row, propertyPath, reporter);
}
// children properties of current instance
Iterable children = instance.getPropertyNames();
@@ -198,17 +205,19 @@ private void iterateBuild(Group instance, QName qNameOfTheInstance, List
// only the first instance
Object child = instance.getProperty(qname)[0];
if (child instanceof Group && shouldBeDisplayed(child)) {
+
iterateBuild((Group) instance.getProperty(qname)[0], qname, headerRow, row,
- propertyPath + "." + qname.getLocalPart());
+ propertyPath + "." + qname.getLocalPart(), reporter);
}
else if (child instanceof Group) {
// the child is a choice or packege, etc.
iterateBuild((Group) instance.getProperty(qname)[0], qname, headerRow, row,
- propertyPath);
+ propertyPath, reporter);
}
else {
// child is an attribute
- addProperty(headerRow, row, child, propertyPath + "." + qname.getLocalPart());
+ addProperty(headerRow, row, child, propertyPath + "." + qname.getLocalPart(),
+ reporter);
}
}
@@ -225,20 +234,40 @@ private boolean shouldBeDisplayed(Object obj) {
}
private void addProperty(List headerRow, Map row, Object property,
- String propertyTypeName) {
+ String propertyTypeName, IOReporter reporter) {
if (!headerRow.contains(propertyTypeName)) {
headerRow.add(propertyTypeName);
}
+
+ if (property instanceof DefaultGeometryProperty>) {
+ // Property is an instance of DefaultGeometryProperty
+ DefaultGeometryProperty> geometryProperty = (DefaultGeometryProperty>) property;
+
+ Geometry geometry = geometryProperty.getGeometry();
+
+ // correct winding order as per right-hand rule, i.e.,
+ // exterior rings are counterclockwise, and holes are
+ // clockwise.
+ setWindingOrder(EnumWindingOrderTypes.counterClockwise);
+ property = unifyGeometry(geometry, reporter,
+ geometryProperty.getCRSDefinition().getCRS());
+
+ if (geometry instanceof GeometryCollection
+ && ((GeometryCollection) geometry).getNumGeometries() == 1) {
+ property = geometryProperty.getGeometry().getGeometryN(0);
+ }
+ }
+
row.put(propertyTypeName, property);
}
// check if value of current property isn't null and add it
private void checkValue(Group group, List headerRow, Map row,
- String propertyTypeName) {
+ String propertyTypeName, IOReporter reporter) {
if (group instanceof Instance) {
Object value = ((Instance) group).getValue();
if (value != null) {
- addProperty(headerRow, row, value, propertyTypeName);
+ addProperty(headerRow, row, value, propertyTypeName, reporter);
}
}
}
diff --git a/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/internal/CSVInstanceWriter.java b/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/internal/CSVInstanceWriter.java
index 89bcde0b94..0a120fd6df 100644
--- a/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/internal/CSVInstanceWriter.java
+++ b/io/plugins/eu.esdihumboldt.hale.io.csv/src/eu/esdihumboldt/hale/io/csv/writer/internal/CSVInstanceWriter.java
@@ -177,13 +177,13 @@ private void addCSVFileByQName(IOReporter reporter, OutputStream outputStream,
// try to be sure resources are all closed after try-block
try (CSVWriter writer = new CSVWriter(
new OutputStreamWriter(new FileOutputStream(tempFile)), sep, quote, esc);) {
- writeLine(solveNestedProperties, headerRow, instance, writer);
+ writeLine(solveNestedProperties, headerRow, instance, writer, reporter);
while (instanceIterator.hasNext()) {
Instance nextInst = instanceIterator.next();
if (nextInst.getDefinition().equals(definition)) {
- writeLine(solveNestedProperties, headerRow, nextInst, writer);
+ writeLine(solveNestedProperties, headerRow, nextInst, writer, reporter);
}
}
}
@@ -203,12 +203,12 @@ public boolean isPassthrough() {
// write current instance to csv file
private void writeLine(boolean solveNestedProperties, List headerRow, Instance instance,
- CSVWriter writer) {
+ CSVWriter writer, IOReporter reporter) {
boolean useSchema = getParameter(InstanceTableIOConstants.USE_SCHEMA).as(Boolean.class,
true);
List line = new ArrayList();
Map row = super.getPropertyMap(instance, headerRow, useSchema,
- solveNestedProperties);
+ solveNestedProperties, reporter);
for (String key : headerRow) {
Object entry = row.get(key);
line.add(getValueOfProperty(entry));
diff --git a/io/plugins/eu.esdihumboldt.hale.io.json.test/src/eu/esdihumboldt/hale/io/json/test/InstanceToJsonTest.groovy b/io/plugins/eu.esdihumboldt.hale.io.json.test/src/eu/esdihumboldt/hale/io/json/test/InstanceToJsonTest.groovy
index 924a6c963b..63a1e60a6a 100644
--- a/io/plugins/eu.esdihumboldt.hale.io.json.test/src/eu/esdihumboldt/hale/io/json/test/InstanceToJsonTest.groovy
+++ b/io/plugins/eu.esdihumboldt.hale.io.json.test/src/eu/esdihumboldt/hale/io/json/test/InstanceToJsonTest.groovy
@@ -176,12 +176,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 49.8728337,
- 8.651
- ]
+ 49.8728337,
+ 8.651
]
],
properties: [
@@ -200,12 +198,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 48.13722,
- 11.5755
- ]
+ 48.13722,
+ 11.5755
]
],
properties: [
@@ -272,12 +268,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 49.8728337891123,
- 8.65122278912346
- ]
+ 49.8728337891123,
+ 8.65122278912346
]
],
properties: [
@@ -296,12 +290,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 48.13722289876544,
- 11.57555687654323
- ]
+ 48.13722289876544,
+ 11.57555687654323
]
],
properties: [
@@ -368,12 +360,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 49.87283378911236,
- 8.65122278912346
- ]
+ 49.87283378911236,
+ 8.65122278912346
]
],
properties: [
@@ -392,12 +382,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 48.13722289876544,
- 11.57555687654323
- ]
+ 48.13722289876544,
+ 11.57555687654323
]
],
properties: [
@@ -464,12 +452,10 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
+ type: "Point",
coordinates: [
- [
- 49.8728337891123,
- 8.651222789123
- ]
+ 49.8728337891123,
+ 8.651222789123
]
],
properties: [
@@ -488,8 +474,8 @@ class InstanceToJsonTest {
type: "Feature",
"@type": "city",
geometry: [
- type: "MultiPoint",
- coordinates: [[48.137222, 11.575556]]
+ type: "Point",
+ coordinates: [48.137222, 11.575556]
],
properties: [
population: 1471508,
diff --git a/io/plugins/eu.esdihumboldt.hale.io.json/src/eu/esdihumboldt/hale/io/json/internal/InstanceToJson.java b/io/plugins/eu.esdihumboldt.hale.io.json/src/eu/esdihumboldt/hale/io/json/internal/InstanceToJson.java
index f888aae72b..82ac222594 100644
--- a/io/plugins/eu.esdihumboldt.hale.io.json/src/eu/esdihumboldt/hale/io/json/internal/InstanceToJson.java
+++ b/io/plugins/eu.esdihumboldt.hale.io.json/src/eu/esdihumboldt/hale/io/json/internal/InstanceToJson.java
@@ -31,6 +31,7 @@
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTS;
import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryCollection;
import org.opengis.referencing.operation.MathTransform;
import com.fasterxml.jackson.core.JsonFactory;
@@ -652,6 +653,11 @@ protected void writeGeometryValue(JsonGenerator jsonGen, GeometryProperty> geo
geom = WindingOrder.unifyWindingOrder(geomProp.getGeometry(), true,
geomProp.getCRSDefinition().getCRS());
+ if (geomProp.getGeometry() instanceof GeometryCollection
+ && ((GeometryCollection) geomProp.getGeometry()).getNumGeometries() == 1) {
+ geom = geomProp.getGeometry().getGeometryN(0);
+ }
+
// FIXME what to do in case of an invalid geometry?
jsonGen.writeRawValue(geometryJson.toString(geom));
diff --git a/io/plugins/eu.esdihumboldt.hale.io.xls/src/eu/esdihumboldt/hale/io/xls/writer/XLSInstanceWriter.java b/io/plugins/eu.esdihumboldt.hale.io.xls/src/eu/esdihumboldt/hale/io/xls/writer/XLSInstanceWriter.java
index a2b5e82a35..244733bf36 100644
--- a/io/plugins/eu.esdihumboldt.hale.io.xls/src/eu/esdihumboldt/hale/io/xls/writer/XLSInstanceWriter.java
+++ b/io/plugins/eu.esdihumboldt.hale.io.xls/src/eu/esdihumboldt/hale/io/xls/writer/XLSInstanceWriter.java
@@ -111,7 +111,7 @@ else if (getContentType().getId().equals("eu.esdihumboldt.hale.io.xls.xlsx")) {
for (TypeDefinition type : exportTypes) {
// get all instances of the selected Type
InstanceCollection instances = getInstances().select(new TypeFilter(type));
- addSheetByQName(type, instances);
+ addSheetByQName(type, instances, reporter);
}
try (FileOutputStream out = new FileOutputStream(getTarget().getLocation().getPath());) {
@@ -156,7 +156,8 @@ else if (reporter != null) {
* @param selectedTypeName selected QName
* @param instances InstanceCollection available
*/
- private void addSheetByQName(TypeDefinition selectedTypeName, InstanceCollection instances) {
+ private void addSheetByQName(TypeDefinition selectedTypeName, InstanceCollection instances,
+ IOReporter reporter) {
boolean solveNestedProperties = getParameter(
InstanceTableIOConstants.SOLVE_NESTED_PROPERTIES).as(Boolean.class, false);
@@ -179,7 +180,7 @@ private void addSheetByQName(TypeDefinition selectedTypeName, InstanceCollection
if (!ignoreEmptyFeaturetypes) {
Sheet sheet = workbook.createSheet(selectedTypeName.getDisplayName());
Row headerRow = sheet.createRow(0);
- super.getPropertyMap(selectedTypeName, headerRowStrings);
+ super.getPropertyMap(selectedTypeName, headerRowStrings, reporter);
writeHeaderRow(headerRow, headerRowStrings);
setCellStyle(sheet, headerRowStrings.size());
resizeSheet(sheet);
@@ -200,14 +201,14 @@ private void addSheetByQName(TypeDefinition selectedTypeName, InstanceCollection
int rowNum = 1;
Row row = sheet.createRow(rowNum++);
writeRow(row, super.getPropertyMap(instance, headerRowStrings, useSchema,
- solveNestedProperties), headerRowStrings);
+ solveNestedProperties, reporter), headerRowStrings);
while (instanceIterator.hasNext()) {
Instance nextInst = instanceIterator.next();
if (nextInst.getDefinition().equals(definition)) {
row = sheet.createRow(rowNum++);
writeRow(row, super.getPropertyMap(nextInst, headerRowStrings, useSchema,
- solveNestedProperties), headerRowStrings);
+ solveNestedProperties, reporter), headerRowStrings);
}
}