Skip to content

Commit

Permalink
Merge pull request #1085 from ZakarFin/type-discovery
Browse files Browse the repository at this point in the history
Support mixed geometry types when reading region sets from resources / statistical data
  • Loading branch information
ZakarFin authored Nov 22, 2024
2 parents 5619161 + 5e3dc77 commit 48387ac
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.oskari.maplayer;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.oskari.geojson.GeoJSONReader2;
import org.oskari.geojson.GeoJSONSchemaDetector;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class GeoJSONStringReader {

private static final ObjectMapper OM = new ObjectMapper();
private static final TypeReference<HashMap<String, Object>> TYPE_REF = new TypeReference<HashMap<String, Object>>() {};

public static SimpleFeatureCollection readGeoJSON(InputStream in, CoordinateReferenceSystem crs) throws Exception {
if (in == null) {
throw new IllegalArgumentException("InputStream was null");
}
try (Reader utf8Reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
Map<String, Object> geojsonAsMap = loadJSONResource(utf8Reader);
boolean ignoreGeometryProperties = true;
SimpleFeatureType schema = GeoJSONSchemaDetector.getSchema(geojsonAsMap, crs, ignoreGeometryProperties);
return GeoJSONReader2.toFeatureCollection(geojsonAsMap, schema);
}
}

public static SimpleFeatureCollection readGeoJSON(String geojson, String srs) throws Exception{
CoordinateReferenceSystem sourceCRS = CRS.decode(srs);
return readGeoJSON(geojson, sourceCRS);
}

public static SimpleFeatureCollection readGeoJSON(String geojson, CoordinateReferenceSystem crs) throws Exception {
Map<String, Object> geojsonAsMap = loadJSONResource(geojson);
boolean ignoreGeometryProperties = true;
try {
SimpleFeatureType schema = GeoJSONSchemaDetector.getSchema(geojsonAsMap, crs, ignoreGeometryProperties);
return GeoJSONReader2.toFeatureCollection(geojsonAsMap, schema);
} catch (NullPointerException e) {
throw new IllegalArgumentException("Input was not GeoJSON");
}
}



private static Map<String, Object> loadJSONResource(Reader utf8Reader) throws Exception {
try {
return OM.readValue(utf8Reader, TYPE_REF);
} catch (MismatchedInputException e) {
throw new IllegalArgumentException("Input couldn't be parsed as JSON Object");
}
}

private static Map<String, Object> loadJSONResource(String geojson) throws Exception {
try {
return OM.readValue(geojson, TYPE_REF);
} catch (MismatchedInputException e) {
throw new IllegalArgumentException("Input couldn't be parsed as JSON Object");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.oskari.maplayer;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.referencing.CRS;
import org.junit.Test;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import java.io.InputStream;

import static org.junit.Assert.*;

public class GeoJSONStringReaderTest {

@Test (expected = IllegalArgumentException.class)
public void testGeoJSONasNull() throws Exception {
GeoJSONStringReader.readGeoJSON((String) null, "EPSG:4326");
}
@Test (expected = IllegalArgumentException.class)
public void testInputStreamasNull() throws Exception {
CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
GeoJSONStringReader.readGeoJSON((InputStream) null, sourceCRS);
}

@Test (expected = IllegalArgumentException.class)
public void testGeoJSONasEmptyString() throws Exception {
GeoJSONStringReader.readGeoJSON("", "EPSG:4326");
}
@Test (expected = IllegalArgumentException.class)
public void testGeoJSONasEmptyObject() throws Exception {
GeoJSONStringReader.readGeoJSON("{}", "EPSG:4326");
}
@Test (expected = IllegalArgumentException.class)
public void testGeoJSONWithEmptyFeatures() throws Exception {
SimpleFeatureCollection col = GeoJSONStringReader.readGeoJSON("{ \"type\": \"FeatureCollection\"}", "EPSG:4326");
assertNotNull("Parse should complete", col);
assertTrue("Should get an empty collection", col.isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import fi.nls.oskari.service.ServiceRuntimeException;
import fi.nls.oskari.util.IOHelper;
import fi.nls.oskari.util.JSONHelper;
import org.oskari.maplayer.GeoJSONStringReader;

public class RegionSetHelper {

Expand Down Expand Up @@ -84,21 +85,22 @@ protected static SimpleFeatureCollection getRegionsResourcesGeoJSON(RegionSet re
}
LOG.debug("Trying to read GeoJSON resource file from:", path);
DefaultFeatureCollection fc = new DefaultFeatureCollection();

try (InputStream in = RegionSetHelper.class.getResourceAsStream(path);
Reader utf8Reader = new InputStreamReader(in, IOHelper.CHARSET_UTF8)) {
if (in == null) {
LOG.warn("Could not find resource for path:", path);
throw new FileNotFoundException("Could not find resource");
SimpleFeatureCollection sfc;
CoordinateReferenceSystem sourceCRS = CRS.decode(regionset.getSrs_name());
try (InputStream in = RegionSetHelper.class.getResourceAsStream(path)) {
try {
sfc = GeoJSONStringReader.readGeoJSON(in, sourceCRS);
} catch (Exception e) {
throw new IOException("Error reading geojson to feature collection for region set: " + regionset.getId(), e);
}
try (FeatureIterator<SimpleFeature> it = FJ.streamFeatureCollection(utf8Reader)) {
try (FeatureIterator<SimpleFeature> it = sfc.features()) {
while (it.hasNext()) {
SimpleFeature f = it.next();
try {
transform(f, transform);
fc.add(f);
} catch (Exception e) {
LOG.debug(e, "Invalid region", f);
LOG.debug(e, "Invalid region in region set: " + regionset.getId(), f);
}
}
}
Expand Down

0 comments on commit 48387ac

Please sign in to comment.