From 1b8534417c3d128a2c72e2222c53ad9d41af1837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kinen?= Date: Fri, 22 Nov 2024 14:40:08 +0200 Subject: [PATCH 1/2] Add GeoJSONStringReader to service-map to keep geotools-ext cleaner --- .../oskari/maplayer/GeoJSONStringReader.java | 68 +++++++++++++++++++ .../maplayer/GeoJSONStringReaderTest.java | 38 +++++++++++ 2 files changed, 106 insertions(+) create mode 100644 service-map/src/main/java/org/oskari/maplayer/GeoJSONStringReader.java create mode 100644 service-map/src/test/java/org/oskari/maplayer/GeoJSONStringReaderTest.java diff --git a/service-map/src/main/java/org/oskari/maplayer/GeoJSONStringReader.java b/service-map/src/main/java/org/oskari/maplayer/GeoJSONStringReader.java new file mode 100644 index 0000000000..1144c4e3b6 --- /dev/null +++ b/service-map/src/main/java/org/oskari/maplayer/GeoJSONStringReader.java @@ -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> TYPE_REF = new TypeReference>() {}; + + 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 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 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 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 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"); + } + } +} diff --git a/service-map/src/test/java/org/oskari/maplayer/GeoJSONStringReaderTest.java b/service-map/src/test/java/org/oskari/maplayer/GeoJSONStringReaderTest.java new file mode 100644 index 0000000000..1fbf9e3667 --- /dev/null +++ b/service-map/src/test/java/org/oskari/maplayer/GeoJSONStringReaderTest.java @@ -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()); + } +} \ No newline at end of file From 5e3dc770eb62ca7b5b5e227aa620e9bbe0deec85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kinen?= Date: Fri, 22 Nov 2024 14:40:49 +0200 Subject: [PATCH 2/2] Read regionset resources with same code as WFS/OAPIF features --- .../control/statistics/RegionSetHelper.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/service-statistics-common/src/main/java/fi/nls/oskari/control/statistics/RegionSetHelper.java b/service-statistics-common/src/main/java/fi/nls/oskari/control/statistics/RegionSetHelper.java index b3b1695841..5ac104d690 100755 --- a/service-statistics-common/src/main/java/fi/nls/oskari/control/statistics/RegionSetHelper.java +++ b/service-statistics-common/src/main/java/fi/nls/oskari/control/statistics/RegionSetHelper.java @@ -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 { @@ -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 it = FJ.streamFeatureCollection(utf8Reader)) { + try (FeatureIterator 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); } } }