From 7b42195e02d0c939860f1a2b3f6d80fee13c2240 Mon Sep 17 00:00:00 2001 From: David Fauth Date: Mon, 1 May 2023 22:22:05 -0400 Subject: [PATCH] Updated for Neo4j 5.7 Updated for Neo4j 5.7 Changed Multilinestring from function to procedure --- CHANGELOG.md | 7 + dependency-reduced-pom.xml | 10 +- pom.xml | 6 +- src/main/java/com/neo4jh3/uber/Uberh3.java | 174 ++++++++++++++++----- src/test/java/com/neo4jh3/Neo4jH3Test.java | 21 ++- 5 files changed, 163 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2929c5d..f522879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG - Neo4jH3 +## 5.7 2023-05-01 + +* [Added] Tested through Neo4j versions 5.7 +* [Modified] Converted com.neo4jh3.multilineash3 from a function to a procedure. This procedure returns a list of H3 numbers that are along the line using the H3 gridpathcells feature. +* [Modified] Converted com.neo4jh3.multilineash3String from a function to a procedure. This procedure returns a list of H3 numbers that are along the line using the H3 gridpathcells feature. + + ## 5.5 2023-02-24 * [Added] Tested through Neo4j versions 5.5 diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 0bbee44..f5c0bf3 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.neo4jh3 neo4jh3 - 5.3.1 + 5.7.0 @@ -43,7 +43,7 @@ org.neo4j neo4j - 5.5.0 + 5.7.0 provided @@ -119,7 +119,7 @@ org.neo4j.test neo4j-harness - 5.5.0 + 5.7.0 test @@ -179,7 +179,7 @@ junit junit - 4.12 + 4.13.2 test @@ -190,7 +190,7 @@ - 5.5.0 + 5.7.0 4.1 1.2 3.7 diff --git a/pom.xml b/pom.xml index 4986730..98864d6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,10 +6,10 @@ com.neo4jh3 neo4jh3 - 5.3.1 + 5.7.0 - 5.5.0 + 5.7.0 1.2 3.7 4.0.2 @@ -82,7 +82,7 @@ junit junit - 4.12 + 4.13.2 test diff --git a/src/main/java/com/neo4jh3/uber/Uberh3.java b/src/main/java/com/neo4jh3/uber/Uberh3.java index e8b8b9b..6b0707f 100755 --- a/src/main/java/com/neo4jh3/uber/Uberh3.java +++ b/src/main/java/com/neo4jh3/uber/Uberh3.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -738,45 +739,27 @@ public String pointash3String( return h3Address; } - // Geography Functions - @UserFunction(name = "com.neo4jh3.multilineash3") + // New Geo Functions + @Procedure(name = "com.neo4jh3.multilineash3", mode = Mode.READ) @Description("com.neo4jh3.multilineash3(wktString, resolution) - Provides the distance in grid cells between the two indexes.") - public Long multilineash3( + public Stream multilineash3( @Name("wktString") String wktString, @Name("h3Res") Long h3Res) throws InterruptedException { + List listh3Address = new ArrayList(); + List gpCells = new ArrayList(); Long h3Address = 0L; - if (h3 == null) { - throw new InterruptedException("h3 failed to initialize"); - } - - final int h3Resolution = h3Res == null ? DEFAULT_H3_RESOLUTION : h3Res.intValue(); + Long h3StartAddress = 0L; + Long h3MidAddress = 0L; + Long h3EndAddress = 0L; + Double fromLat = 0.0; + Double fromLon = 0.0; + Double toLat = 0.0; + Double toLon = 0.0; + Double midLat = 0.0; + Double midLon = 0.0; + String mls = ""; - try { - if (h3Resolution > 0 && h3Resolution <= 15) { - Geometry geometry = GeometryReader.readGeometry(wktString); - //System.out.println(geometry.getGeometryType()); - if (geometry.getGeometryType().toString().equalsIgnoreCase("MultiLineString")){ - h3Address=h3.latLngToCell(geometry.getEnvelope().getMinX(), geometry.getEnvelope().getMinY(), h3Resolution); - } - } else { - h3Address = -2L; - } - } catch (Exception e) { - //System.out.println(e); - h3Address = -1L; - // TODO Auto-generated catch block - //e.printStackTrace(); - } - return h3Address; - } - @UserFunction(name = "com.neo4jh3.multilineash3String") - @Description("com.neo4jh3.multilineash3String(wktString, resolution) - Provides the distance in grid cells between the two indexes.") - public String multilineash3String( - @Name("wktString") String wktString, - @Name("h3Res") Long h3Res) throws InterruptedException - { - String h3Address = ""; if (h3 == null) { throw new InterruptedException("h3 failed to initialize"); } @@ -785,22 +768,132 @@ public String multilineash3String( try { if (h3Resolution > 0 && h3Resolution <= 15) { - Geometry geometry = GeometryReader.readGeometry(wktString); - if (geometry.getGeometryType().toString().equalsIgnoreCase("MultiLineString")){ - h3Address=h3.latLngToCellAddress(geometry.getEnvelope().getMinX(), geometry.getEnvelope().getMinY(), h3Resolution); - } + mls = wktString.replace("MULTILINESTRING((", ""); + mls = mls.replace(" (",""); + mls = mls.replace(")",""); + mls = mls.replace("(",""); + String[] latlonPairs = mls.split(","); + for (int i = 0; i < latlonPairs.length; i++) { + if (i > 0){ + fromLat = Double.valueOf(latlonPairs[i-1].split(" ")[0]); + fromLon = Double.valueOf(latlonPairs[i-1].split(" ")[1]); + toLat = Double.valueOf(latlonPairs[i].split(" ")[0]); + toLon = Double.valueOf(latlonPairs[i].split(" ")[1]); + midLat = (fromLat + toLat) / 2; + midLon = (fromLon + toLon) / 2; + h3StartAddress = h3.latLngToCell(fromLat, fromLon, h3Resolution); + h3MidAddress = h3.latLngToCell(midLat, midLon, h3Resolution); + h3EndAddress = h3.latLngToCell(toLat, toLon, h3Resolution); + try { + gpCells = h3.gridPathCells(h3StartAddress, h3MidAddress); + for (int j = 0; j < gpCells.size(); j++) { + listh3Address.add(gpCells.get(j)); + } + gpCells.clear(); + } catch (Exception e1){ + } + try { + gpCells = h3.gridPathCells((h3MidAddress), h3EndAddress); + for (int j = 0; j < gpCells.size(); j++) { + listh3Address.add(gpCells.get(j)); + } + gpCells.clear(); + } catch (Exception e1){ + + } + + } + } } else { - h3Address = "-2"; + listh3Address = Collections.singletonList(-2L); + } } catch (Exception e) { //System.out.println(e); - h3Address = "-1"; + listh3Address = Collections.singletonList(-1L); // TODO Auto-generated catch block //e.printStackTrace(); } - return h3Address; + return listh3Address.stream().map(H3LongAddress::of); } + // New Geo Functions + @Procedure(name = "com.neo4jh3.multilineash3String", mode = Mode.READ) + @Description("com.neo4jh3.multilineash3String(wktString, resolution) - Provides the distance in grid cells between the two indexes.") + public Stream multilineash3String( + @Name("wktString") String wktString, + @Name("h3Res") Long h3Res) throws InterruptedException + { + List listh3Address = new ArrayList(); + List gpCells = new ArrayList(); + String h3StartAddress = ""; + String h3MidAddress = ""; + String h3EndAddress = ""; + Double fromLat = 0.0; + Double fromLon = 0.0; + Double toLat = 0.0; + Double toLon = 0.0; + Double midLat = 0.0; + Double midLon = 0.0; + String mls = ""; + + if (h3 == null) { + throw new InterruptedException("h3 failed to initialize"); + } + + final int h3Resolution = h3Res == null ? DEFAULT_H3_RESOLUTION : h3Res.intValue(); + + try { + if (h3Resolution > 0 && h3Resolution <= 15) { + mls = wktString.replace("MULTILINESTRING((", ""); + mls = mls.replace(" (",""); + mls = mls.replace(")",""); + mls = mls.replace("(",""); + String[] latlonPairs = mls.split(","); + for (int i = 0; i < latlonPairs.length; i++) { + if (i > 0){ + fromLat = Double.valueOf(latlonPairs[i-1].split(" ")[0]); + fromLon = Double.valueOf(latlonPairs[i-1].split(" ")[1]); + toLat = Double.valueOf(latlonPairs[i].split(" ")[0]); + toLon = Double.valueOf(latlonPairs[i].split(" ")[1]); + midLat = (fromLat + toLat) / 2; + midLon = (fromLon + toLon) / 2; + h3StartAddress = h3.latLngToCellAddress(fromLat, fromLon, h3Resolution); + h3MidAddress = h3.latLngToCellAddress(midLat, midLon, h3Resolution); + h3EndAddress = h3.latLngToCellAddress(toLat, toLon, h3Resolution); + try { + gpCells = h3.gridPathCells(h3StartAddress, h3MidAddress); + for (int j = 0; j < gpCells.size(); j++) { + listh3Address.add(gpCells.get(j)); + } + gpCells.clear(); + } catch (Exception e1){ + //listh3Address = Collections.singletonList("-1"); + } + try { + gpCells = h3.gridPathCells((h3MidAddress), h3EndAddress); + for (int j = 0; j < gpCells.size(); j++) { + listh3Address.add(gpCells.get(j)); + } + gpCells.clear(); + } catch (Exception e1){ + //listh3Address = Collections.singletonList("-1"); + } + } + } + } else { + listh3Address = Collections.singletonList("-2"); + } + } catch (Exception e) { + //System.out.println(e); + listh3Address = Collections.singletonList("-1"); + // TODO Auto-generated catch block + //e.printStackTrace(); + } + return listh3Address.stream().map(H3StringAddress::of); + } + // Geography Functions + @UserFunction(name = "com.neo4jh3.centeraswkb") @Description("com.neo4jh3.centeraswkb(hexAddress) - Provides the distance in grid cells between the two indexes.") public String centeraswkb( @@ -1657,7 +1750,6 @@ public Stream gridpathcellString(@Name("fromAddress") String fr return ringList.stream().map(H3StringAddress::of); } } - /* * Return list of hex addresses for a line diff --git a/src/test/java/com/neo4jh3/Neo4jH3Test.java b/src/test/java/com/neo4jh3/Neo4jH3Test.java index 0e487e3..86cea3a 100644 --- a/src/test/java/com/neo4jh3/Neo4jH3Test.java +++ b/src/test/java/com/neo4jh3/Neo4jH3Test.java @@ -296,16 +296,25 @@ public void should_return_hex_address() throws InterruptedException { result=session.run("call com.neo4jh3.polygonToCellsString(['37.7866,-122.3805','37.7198,-122.3544','37.7076,-122.5123','37.7835,-122.5247','37.8151,-122.4798'],[],20,'latlon') yield value return value limit 1"); assertEquals("\"-2\"",result.single().get(0).toString()); + result = session.run("call com.neo4jh3.multilineash3('MULTILINESTRING((40.736691045913472 73.99311953429248), (40.73733046783797 -73.99265431029018) , (40.93733046783797 -74.00265431029018))',12) yield value return value limit 1"); + assertEquals(631243922688264703L, result.single().get(0).asLong(),0); + + result = session.run("call com.neo4jh3.multilineash3String('MULTILINESTRING((40.736691045913472 73.99311953429248), (40.73733046783797 -73.99265431029018) , (40.93733046783797 -74.00265431029018))',12) yield value return value limit 1"); + assertEquals("\"8c2a100d27549ff\"",result.single().get(0).toString()); + + result = session.run("call com.neo4jh3.multilineash3String('ZZZ((40.736691045913472 73.99311953429248), (40.73733046783797 -73.99265431029018) , (40.93733046783797 -74.00265431029018))',12) yield value return value limit 1"); + assertEquals("\"-1\"",result.single().get(0).toString()); + + result = session.run("call com.neo4jh3.multilineash3String('MULTILINESTRING((40.736691045913472 73.99311953429248), (40.73733046783797 -73.99265431029018) , (40.93733046783797 -74.00265431029018))',17) yield value return value limit 1"); + assertEquals("\"-2\"",result.single().get(0).toString()); + + result = session.run("call com.neo4jh3.multilineash3('MULTILINESTRING((40.736691045913472 73.99311953429248), (40.73733046783797 -73.99265431029018) , (40.93733046783797 -74.00265431029018))',17) yield value return value limit 1"); + assertEquals(-2L,result.single().get(0).asLong(),0); + /* Geography tests */ result = session.run("RETURN com.neo4jh3.pointash3('POINT(37.8199 -122.4783)',13) AS value"); assertEquals(635714569676958015L, result.single().get("value").asLong(),0); - result = session.run("RETURN com.neo4jh3.multilineash3('MULTILINESTRING((37.2713558667319 -121.91508032705622), (37.353926450852256 -121.86222328902491))',13) AS value"); - assertEquals(635714810904422079L, result.single().get("value").asLong(),0); - - result = session.run("RETURN com.neo4jh3.multilineash3('MULTILINESTRING((40.736691045913472 73.99311953429248), (40.73733046783797 -73.99265431029018))',13) AS value"); - assertEquals(635747522315622719L, result.single().get("value").asLong(),0); - result = session.run("RETURN com.neo4jh3.centeraswkb(599686042433355775) AS value"); assertEquals("\"00000000014042AC42F51330C7C05E7E7CF1A5AD49\"", result.single().get("value").toString());