From dcb99618c8bf3653c830bba098276b1291f8eafa Mon Sep 17 00:00:00 2001 From: Alessia Bardi Date: Thu, 30 Jun 2022 15:23:37 +0200 Subject: [PATCH] #23447: Add centroids of polygons to indexed records --- dnet-ariadneplus-graphdb-publisher/pom.xml | 5 +++ .../ariadneplus/elasticsearch/BulkUpload.java | 33 ++++++++++++-- .../elasticsearch/model/Spatial.java | 9 ++++ .../elasticsearch/BulkUploadTest.java | 43 +++++++++++++++++++ 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 dnet-ariadneplus-graphdb-publisher/test/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUploadTest.java diff --git a/dnet-ariadneplus-graphdb-publisher/pom.xml b/dnet-ariadneplus-graphdb-publisher/pom.xml index 3c0e10d..a4c97c3 100644 --- a/dnet-ariadneplus-graphdb-publisher/pom.xml +++ b/dnet-ariadneplus-graphdb-publisher/pom.xml @@ -133,6 +133,11 @@ 1.5.0 test + + org.locationtech.jts + jts-core + 1.19.0 + diff --git a/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUpload.java b/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUpload.java index a69d2f6..0446ea7 100644 --- a/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUpload.java +++ b/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUpload.java @@ -14,9 +14,16 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.xcontent.XContentType; +import org.locationtech.jts.algorithm.Centroid; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.util.GeometryTransformer; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -41,6 +48,8 @@ public class BulkUpload { private RestHighLevelClient client; + private WKTReader wktReader = new WKTReader(); + public void init(String elasticSearchHostName, String elasticSearchIndexName) throws IOException { this.elasticSearchIndexName = elasticSearchIndexName; client = new RestHighLevelClient( @@ -58,6 +67,7 @@ public class BulkUpload { } public int index(ResourceManager manager, boolean isCollection) { + BulkRequest request = new BulkRequest(); int esResponseCode = 0; while (manager.hasNext()){ @@ -88,6 +98,7 @@ public class BulkUpload { double lon = Double.parseDouble(s.getLon()); org.elasticsearch.common.geo.GeoPoint geopoint = new org.elasticsearch.common.geo.GeoPoint(lat, lon); s.setGeopoint(geopoint); + s.setCentroid(geopoint); }); } if (isCollection) { @@ -98,6 +109,7 @@ public class BulkUpload { .filter(s -> Objects.nonNull(s.getWkt())) .forEach(s -> { s.setPolygon(s.getWkt()); + s.setCentroid(calculateCentroid(s.getWkt())); }); } } @@ -132,11 +144,13 @@ public class BulkUpload { PolygonBuilder polygonBuilder = new PolygonBuilder(coordinatesBuilder); String wkt = polygonBuilder.toWKT(); s.setBoundingbox(wkt); + s.setCentroid(calculateCentroid(wkt)); }); ace.getSpatial() .stream() - .filter(s -> Objects.nonNull(s.getPolygonGeoPoints())&&s.getPolygonGeoPoints().size()>=4) + .filter(s -> Objects.nonNull(s.getPolygonGeoPoints()) && s.getPolygonGeoPoints().size() >= 4) .forEach(s -> { + //FIXME: What did you want to do? Nothing is set anywhere CoordinatesBuilder coordinatesBuilder = new CoordinatesBuilder(); s.getPolygonGeoPoints().forEach(p -> { coordinatesBuilder.coordinate( @@ -149,11 +163,12 @@ public class BulkUpload { .filter(s -> Objects.nonNull(s.getWkt())) .forEach(s -> { s.setPolygon(s.getWkt()); + s.setCentroid(calculateCentroid(s.getWkt())); }); } } - if (ace.getSpatial()!=null) { - if (ace.getSpatial().size()==2) { + if (ace.getSpatial() != null) { + if (ace.getSpatial().size() == 2) { Spatial uniqueSpatial = new Spatial(); boolean uniquePlaceNameFound = ace.getSpatial().stream().filter(s -> s.getPlaceName()!=null).count()==1; boolean uniqueLocationFound = ace.getSpatial().stream().filter(s -> s.getGeopoint()!=null).count()==1; @@ -163,6 +178,7 @@ public class BulkUpload { }); ace.getSpatial().stream().filter(s -> s.getGeopoint()!=null).forEach(s -> { uniqueSpatial.setGeopoint(s.getGeopoint()); + uniqueSpatial.setCentroid(s.getGeopoint()); }); ace.getSpatial().clear(); ace.setSpatial(Arrays.asList(uniqueSpatial)); @@ -204,6 +220,17 @@ public class BulkUpload { return esResponseCode; } + protected GeoPoint calculateCentroid(final String wkt){ + try { + Geometry geo = wktReader.read(wkt); + Coordinate coord = Centroid.getCentroid(geo); + return new org.elasticsearch.common.geo.GeoPoint(coord.getY(), coord.getX()); + } catch (ParseException e) { + log.fatal("Cannot calculate centroid for WKT "+wkt+"\n Cause: "+e.getCause().getMessage()); + return null; + } + } + public static List removeDuplicates(List spatialList) { Map> duplicatesMap = getDuplicatesMap(spatialList); return duplicatesMap.values().stream() diff --git a/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/model/Spatial.java b/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/model/Spatial.java index 9b6c4ce..70ee7db 100644 --- a/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/model/Spatial.java +++ b/dnet-ariadneplus-graphdb-publisher/src/main/java/eu/dnetlib/ariadneplus/elasticsearch/model/Spatial.java @@ -15,6 +15,7 @@ public class Spatial { private String polygon; private String spatialPrecision; private String coordinatePrecision; + private GeoPoint centroid; private transient String boundingBoxMaxLat; private transient String boundingBoxMaxLon; @@ -145,6 +146,14 @@ public class Spatial { this.wkt = wkt; } + public GeoPoint getCentroid() { + return centroid; + } + + public void setCentroid(GeoPoint centroid) { + this.centroid = centroid; + } + public Spatial() { } diff --git a/dnet-ariadneplus-graphdb-publisher/test/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUploadTest.java b/dnet-ariadneplus-graphdb-publisher/test/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUploadTest.java new file mode 100644 index 0000000..add90cc --- /dev/null +++ b/dnet-ariadneplus-graphdb-publisher/test/java/eu/dnetlib/ariadneplus/elasticsearch/BulkUploadTest.java @@ -0,0 +1,43 @@ +package eu.dnetlib.ariadneplus.elasticsearch; + +import org.elasticsearch.common.geo.GeoPoint; +import org.junit.Before; +import org.junit.Test; + +public class BulkUploadTest { + + private BulkUpload bu; + + @Before + public void setup(){ + bu = new BulkUpload(); + } + + @Test + public void testCalculateCentroidPoint(){ + String wkt = "POINT (30 10)"; + GeoPoint centroid = bu.calculateCentroid(wkt); + System.out.println("Long: "+centroid.getLon()+", Lat: "+centroid.getLat()); + } + + @Test + public void testCalculateCentroidMultiPolygon(){ + String wkt = "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20)))"; + GeoPoint centroid = bu.calculateCentroid(wkt); + System.out.println("Long: "+centroid.getLon()+", Lat: "+centroid.getLat()); + } + + @Test + public void testCalculateCentroidPolygon(){ + String wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"; + GeoPoint centroid = bu.calculateCentroid(wkt); + System.out.println("Long: "+centroid.getLon()+", Lat: "+centroid.getLat()); + } + + @Test + public void testCalculateCentroidBB(){ + String wkt = "polygon ((-1.42173131195844 51.778172135497, -1.42173131195844 51.7692537152273, -1.40712262768071 51.7692537152273, -1.40712262768071 51.778172135497, -1.42173131195844 51.778172135497))"; + GeoPoint centroid = bu.calculateCentroid(wkt); + System.out.println("Long: "+centroid.getLon()+", Lat: "+centroid.getLat()); + } +}