Skip to content

Commit c78229b

Browse files
committed
最邻近搜索完成
1 parent 70baeea commit c78229b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+812
-448
lines changed

src/main/java/org/wowtools/neo4j/rtree/RtreeIntersectsSearcher.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
import org.wowtools.neo4j.rtree.util.BooleanDataNodeVisitor;
1313

1414
import java.util.ArrayDeque;
15+
import java.util.Iterator;
1516
import java.util.Map;
1617
import java.util.concurrent.locks.Lock;
1718

1819
/**
1920
* 相交关系查询器
20-
* 查询器
2121
*
2222
* @author liuyu
2323
* @date 2021/12/24
@@ -35,7 +35,7 @@ private RtreeIntersectsSearcher(long metadataNodeId, Lock readLock) {
3535
}
3636

3737
/**
38-
* 获取索引
38+
* 获取查询器
3939
*
4040
* @param tx 事务 此事务需要在外部手动关闭
4141
* @param name 索引名
@@ -64,7 +64,11 @@ public void intersects(RectNd bbox, Transaction tx, BooleanDataNodeVisitor visit
6464
readLock.lock();
6565
try {
6666
Node metadataNode = tx.getNodeById(metadataNodeId);
67-
Node node = metadataNode.getRelationships(Relationships.RTREE_METADATA_TO_ROOT).iterator().next().getEndNode();
67+
Iterator<Relationship> iterator = metadataNode.getRelationships(Relationships.RTREE_METADATA_TO_ROOT).iterator();
68+
if (!iterator.hasNext()) {
69+
return;
70+
}
71+
Node node = iterator.next().getEndNode();
6872
ArrayDeque<Node> stack = new ArrayDeque<>();
6973
stack.push(node);
7074
do {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.wowtools.neo4j.rtree;
2+
3+
import org.neo4j.graphdb.Node;
4+
import org.neo4j.graphdb.Relationship;
5+
import org.neo4j.graphdb.Transaction;
6+
import org.wowtools.neo4j.rtree.internal.RtreeLock;
7+
import org.wowtools.neo4j.rtree.internal.define.Labels;
8+
import org.wowtools.neo4j.rtree.internal.define.Relationships;
9+
import org.wowtools.neo4j.rtree.internal.nearest.DistanceResult;
10+
import org.wowtools.neo4j.rtree.util.NearestNeighbour;
11+
12+
import java.util.Iterator;
13+
import java.util.List;
14+
import java.util.concurrent.locks.Lock;
15+
16+
/**
17+
* 最邻近搜索器
18+
*
19+
* @author liuyu
20+
* @date 2021/12/27
21+
*/
22+
public class RtreeNearestSearcher {
23+
24+
private final long metadataNodeId;
25+
private final Lock readLock;
26+
27+
28+
private RtreeNearestSearcher(long metadataNodeId, Lock readLock) {
29+
this.metadataNodeId = metadataNodeId;
30+
this.readLock = readLock;
31+
}
32+
33+
34+
/**
35+
* 获取查询器
36+
*
37+
* @param tx 事务 此事务需要在外部手动关闭
38+
* @param name 索引名
39+
* @return
40+
*/
41+
public static RtreeNearestSearcher get(Transaction tx, String name) {
42+
Node metadataNode = tx.findNode(Labels.METADATA, "name", name);
43+
if (null == metadataNode) {
44+
throw new RuntimeException("索引 " + name + " 不存在");
45+
}
46+
long metadataNodeId = metadataNode.getId();
47+
Lock readLock = RtreeLock.getUseReadWriteLock(name).readLock();
48+
RtreeNearestSearcher searcher = new RtreeNearestSearcher(metadataNodeId, readLock);
49+
return searcher;
50+
}
51+
52+
53+
/**
54+
* 最邻近查询。查询距离输入点pointNd的距离最近的点
55+
*
56+
* @param nearestNeighbour 最邻近查询函数
57+
* @param tx 事务 此事务需要在外部手动关闭
58+
* @return
59+
*/
60+
public List<DistanceResult> nearest(NearestNeighbour nearestNeighbour, Transaction tx) {
61+
readLock.lock();
62+
try {
63+
Node metadataNode = tx.getNodeById(metadataNodeId);
64+
Iterator<Relationship> iterator = metadataNode.getRelationships(Relationships.RTREE_METADATA_TO_ROOT).iterator();
65+
if (!iterator.hasNext()) {
66+
return List.of();
67+
}
68+
Node root = iterator.next().getEndNode();
69+
List<DistanceResult> res = nearestNeighbour.find(root);
70+
return res;
71+
} finally {
72+
readLock.unlock();
73+
}
74+
}
75+
76+
}

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/Constant.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
* The ASF licenses this file to You under the Apache License, Version 2.0
66
* (the "License"); you may not use this file except in compliance with
77
* the License. You may obtain a copy of the License at
8-
*
9-
* http://www.apache.org/licenses/LICENSE-2.0
10-
*
8+
* <p>
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
* <p>
1111
* Unless required by applicable law or agreed to in writing, software
1212
* distributed under the License is distributed on an "AS IS" BASIS,
1313
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/RtreeNearestQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public interface NodeFilter {
2323
/**
2424
* 过滤
2525
*
26-
* @param node 节点
26+
* @param node 节点
2727
* @param geometry geometry
2828
* @return 返回false则忽略此节点
2929
*/

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/RtreeQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
import org.neo4j.graphdb.Transaction;
2626
import org.wowtools.neo4j.rtree.geometry2dold.spatial.RTreeIndex;
2727
import org.wowtools.neo4j.rtree.geometry2dold.util.BboxIntersectUtil;
28-
import org.wowtools.neo4j.rtree.geometry2dold.util.Singleton;
2928
import org.wowtools.neo4j.rtree.geometry2dold.util.GeometryBbox;
3029
import org.wowtools.neo4j.rtree.geometry2dold.util.RtreeTraverser;
30+
import org.wowtools.neo4j.rtree.geometry2dold.util.Singleton;
3131

3232
/**
3333
* 利用rtree索引进行空间查询

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/bigshape/BigShapeManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import org.wowtools.neo4j.rtree.geometry2dold.bigshape.pojo.BigShape;
1212
import org.wowtools.neo4j.rtree.geometry2dold.bigshape.pojo.Grid;
1313
import org.wowtools.neo4j.rtree.geometry2dold.bigshape.util.GridCuter;
14+
import org.wowtools.neo4j.rtree.geometry2dold.spatial.Envelope;
1415
import org.wowtools.neo4j.rtree.geometry2dold.spatial.EnvelopeDecoder;
1516
import org.wowtools.neo4j.rtree.geometry2dold.spatial.RTreeIndex;
16-
import org.wowtools.neo4j.rtree.geometry2dold.spatial.Envelope;
1717
import org.wowtools.neo4j.rtree.geometry2dold.util.GeometryBbox;
1818

1919
import java.util.HashMap;

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/bigshape/pojo/BigShape.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import org.wowtools.neo4j.rtree.geometry2dold.bigshape.BigShapeManager;
1313
import org.wowtools.neo4j.rtree.geometry2dold.spatial.RTreeIndex;
1414
import org.wowtools.neo4j.rtree.geometry2dold.util.BboxIntersectUtil;
15-
import org.wowtools.neo4j.rtree.geometry2dold.util.WkbReaderManager;
1615
import org.wowtools.neo4j.rtree.geometry2dold.util.GeometryBbox;
16+
import org.wowtools.neo4j.rtree.geometry2dold.util.WkbReaderManager;
1717

1818
import java.util.ArrayDeque;
1919
import java.util.Deque;

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/bigshape/util/GridCuter.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package org.wowtools.neo4j.rtree.geometry2dold.bigshape.util;
22

3-
import org.locationtech.jts.geom.*;
3+
import org.locationtech.jts.geom.Coordinate;
4+
import org.locationtech.jts.geom.Geometry;
5+
import org.locationtech.jts.geom.Polygon;
6+
import org.locationtech.jts.geom.TopologyException;
47
import org.wowtools.neo4j.rtree.geometry2dold.bigshape.pojo.Grid;
5-
import org.wowtools.neo4j.rtree.geometry2dold.util.Singleton;
68
import org.wowtools.neo4j.rtree.geometry2dold.util.GeometryBbox;
9+
import org.wowtools.neo4j.rtree.geometry2dold.util.Singleton;
710

811
import java.util.LinkedList;
912
import java.util.List;

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/bigshape/util/SelfIntersectingDispose.java

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
/**
1010
* 自相交多边形处理
1111
* https://stackoverflow.com/questions/31473553/is-there-a-way-to-convert-a-self-intersecting-polygon-to-a-multipolygon-in-jts
12+
*
1213
* @author liuyu
1314
* @date 2020/11/24
1415
*/
@@ -20,52 +21,52 @@ public class SelfIntersectingDispose {
2021
* @param geom
2122
* @return a geometry
2223
*/
23-
public static Geometry validate(Geometry geom){
24-
if(geom instanceof Polygon){
25-
if(geom.isValid()){
24+
public static Geometry validate(Geometry geom) {
25+
if (geom instanceof Polygon) {
26+
if (geom.isValid()) {
2627
geom.normalize(); // validate does not pick up rings in the wrong order - this will fix that
2728
return geom; // If the polygon is valid just return it
2829
}
2930
Polygonizer polygonizer = new Polygonizer();
30-
addPolygon((Polygon)geom, polygonizer);
31+
addPolygon((Polygon) geom, polygonizer);
3132
return toPolygonGeometry(polygonizer.getPolygons(), geom.getFactory());
32-
}else if(geom instanceof MultiPolygon){
33-
if(geom.isValid()){
33+
} else if (geom instanceof MultiPolygon) {
34+
if (geom.isValid()) {
3435
geom.normalize(); // validate does not pick up rings in the wrong order - this will fix that
3536
return geom; // If the multipolygon is valid just return it
3637
}
3738
Polygonizer polygonizer = new Polygonizer();
38-
for(int n = geom.getNumGeometries(); n-- > 0;){
39-
addPolygon((Polygon)geom.getGeometryN(n), polygonizer);
39+
for (int n = geom.getNumGeometries(); n-- > 0; ) {
40+
addPolygon((Polygon) geom.getGeometryN(n), polygonizer);
4041
}
4142
return toPolygonGeometry(polygonizer.getPolygons(), geom.getFactory());
42-
}else{
43+
} else {
4344
return geom; // In my case, I only care about polygon / multipolygon geometries
4445
}
4546
}
4647

4748
/**
4849
* Add all line strings from the polygon given to the polygonizer given
4950
*
50-
* @param polygon polygon from which to extract line strings
51+
* @param polygon polygon from which to extract line strings
5152
* @param polygonizer polygonizer
5253
*/
53-
private static void addPolygon(Polygon polygon, Polygonizer polygonizer){
54+
private static void addPolygon(Polygon polygon, Polygonizer polygonizer) {
5455
addLineString(polygon.getExteriorRing(), polygonizer);
55-
for(int n = polygon.getNumInteriorRing(); n-- > 0;){
56+
for (int n = polygon.getNumInteriorRing(); n-- > 0; ) {
5657
addLineString(polygon.getInteriorRingN(n), polygonizer);
5758
}
5859
}
5960

6061
/**
6162
* Add the linestring given to the polygonizer
6263
*
63-
* @param lineString line string
64+
* @param lineString line string
6465
* @param polygonizer polygonizer
6566
*/
66-
private static void addLineString(LineString lineString, Polygonizer polygonizer){
67+
private static void addLineString(LineString lineString, Polygonizer polygonizer) {
6768

68-
if(lineString instanceof LinearRing){ // LinearRings are treated differently to line strings : we need a LineString NOT a LinearRing
69+
if (lineString instanceof LinearRing) { // LinearRings are treated differently to line strings : we need a LineString NOT a LinearRing
6970
lineString = lineString.getFactory().createLineString(lineString.getCoordinateSequence());
7071
}
7172

@@ -81,11 +82,11 @@ private static void addLineString(LineString lineString, Polygonizer polygonizer
8182
* Get a geometry from a collection of polygons.
8283
*
8384
* @param polygons collection
84-
* @param factory factory to generate MultiPolygon if required
85+
* @param factory factory to generate MultiPolygon if required
8586
* @return null if there were no polygons, the polygon if there was only one, or a MultiPolygon containing all polygons otherwise
8687
*/
87-
private static Geometry toPolygonGeometry(Collection<Polygon> polygons, GeometryFactory factory){
88-
switch(polygons.size()){
88+
private static Geometry toPolygonGeometry(Collection<Polygon> polygons, GeometryFactory factory) {
89+
switch (polygons.size()) {
8990
case 0:
9091
return null; // No valid polygons!
9192
case 1:
@@ -94,7 +95,7 @@ private static Geometry toPolygonGeometry(Collection<Polygon> polygons, Geometry
9495
//polygons may still overlap! Need to sym difference them
9596
Iterator<Polygon> iter = polygons.iterator();
9697
Geometry ret = iter.next();
97-
while(iter.hasNext()){
98+
while (iter.hasNext()) {
9899
ret = ret.symDifference(iter.next());
99100
}
100101
return ret;

src/main/java/org/wowtools/neo4j/rtree/geometry2dold/spatial/EmptyMonitor.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
/**
22
* Copyright (c) 2002-2013 "Neo Technology," Network Engine for Objects in Lund
33
* AB [http://neotechnology.com]
4-
*
4+
* <p>
55
* This file is part of Neo4j Spatial.
6-
*
6+
* <p>
77
* Neo4j is free software: you can redistribute it and/or modify it under the
88
* terms of the GNU General Public License as published by the Free Software
99
* Foundation, either version 3 of the License, or (at your option) any later
1010
* version.
11-
*
11+
* <p>
1212
* This program is distributed in the hope that it will be useful, but WITHOUT
1313
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1414
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1515
* details.
16-
*
16+
* <p>
1717
* You should have received a copy of the GNU General Public License along with
1818
* this program. If not, see <http://www.gnu.org/licenses/>.
1919
*/
@@ -26,32 +26,26 @@
2626
import java.util.List;
2727
import java.util.Map;
2828

29-
public class EmptyMonitor implements TreeMonitor
30-
{
29+
public class EmptyMonitor implements TreeMonitor {
3130
@Override
32-
public void setHeight(int height)
33-
{
31+
public void setHeight(int height) {
3432
}
3533

36-
public int getHeight()
37-
{
34+
public int getHeight() {
3835
return -1;
3936
}
4037

4138
@Override
42-
public void addNbrRebuilt(RTreeIndex rtree)
43-
{
39+
public void addNbrRebuilt(RTreeIndex rtree) {
4440
}
4541

4642
@Override
47-
public int getNbrRebuilt()
48-
{
43+
public int getNbrRebuilt() {
4944
return -1;
5045
}
5146

5247
@Override
53-
public void addSplit(Node indexNode)
54-
{
48+
public void addSplit(Node indexNode) {
5549

5650
}
5751

@@ -66,8 +60,7 @@ public void afterMergeTree(Node indexNode) {
6660
}
6761

6862
@Override
69-
public int getNbrSplit()
70-
{
63+
public int getNbrSplit() {
7164
return -1;
7265
}
7366

@@ -82,8 +75,7 @@ public Map<String, Integer> getCaseCounts() {
8275
}
8376

8477
@Override
85-
public void reset()
86-
{
78+
public void reset() {
8779

8880
}
8981

0 commit comments

Comments
 (0)