44import org .locationtech .jts .geom .GeometryFactory ;
55import org .locationtech .jts .geom .Point ;
66import org .locationtech .jts .io .ParseException ;
7- import org .locationtech .jts .io .WKBReader ;
87import org .neo4j .graphdb .Direction ;
98import org .neo4j .graphdb .Node ;
109import org .neo4j .graphdb .Relationship ;
1110import org .neo4j .graphdb .Transaction ;
11+ import org .wowtools .common .utils .LruCache ;
1212import org .wowtools .neo4j .rtree .Constant ;
1313import org .wowtools .neo4j .rtree .bigshape .BigShapeManager ;
1414import org .wowtools .neo4j .rtree .spatial .RTreeIndex ;
1515import org .wowtools .neo4j .rtree .util .BboxIntersectUtil ;
1616import org .wowtools .neo4j .rtree .util .GeometryBbox ;
17+ import org .wowtools .neo4j .rtree .util .WkbReaderManager ;
1718
1819import java .util .ArrayDeque ;
1920import java .util .Deque ;
21+ import java .util .Map ;
2022
2123import static org .wowtools .neo4j .rtree .util .BboxIntersectUtil .bboxIntersect ;
2224
2830 */
2931public class BigShape {
3032 private final RTreeIndex rTreeIndex ;
33+ private final int nodeValueCacheSize ;
3134
32- public BigShape (RTreeIndex rTreeIndex ) {
35+ public BigShape (RTreeIndex rTreeIndex , int nodeValueCacheSize ) {
3336 this .rTreeIndex = rTreeIndex ;
37+ this .nodeValueCacheSize = nodeValueCacheSize ;
3438 }
3539
3640// /**
@@ -54,9 +58,9 @@ public BigShape(RTreeIndex rTreeIndex) {
5458 public boolean intersects (Transaction tx , Geometry g ) {
5559 final IntersectsJudge intersectsJudge ;
5660 if (g instanceof Point ) {
57- intersectsJudge = new PointIntersectsJudge (g );
61+ intersectsJudge = new PointIntersectsJudge (g , nodeValueCacheSize );
5862 } else {
59- intersectsJudge = new OtherIntersectsJudge (g );
63+ intersectsJudge = new OtherIntersectsJudge (g , nodeValueCacheSize );
6064 }
6165 //FIXME 这里由于找到一个相交对象即可return,所以未复用RtreeTraverser的方法,后续有相同场景的话抽取公共代码
6266 Node rtreeNode = rTreeIndex .getIndexRoot (tx );
@@ -80,8 +84,7 @@ public boolean intersects(Transaction tx, Geometry g) {
8084 //若有下级对象节点,返回结果
8185 for (Relationship relationship : rtreeNode .getRelationships (Direction .OUTGOING , Constant .Relationship .RTREE_REFERENCE )) {
8286 Node objNode = relationship .getEndNode ();
83- Object value = objNode .getProperty (BigShapeManager .keyFieldName );
84- if (intersectsJudge .judge (value )) {
87+ if (intersectsJudge .judge (objNode )) {
8588 return true ;//有一个相交即可直接返回
8689 }
8790 }
@@ -96,31 +99,42 @@ public boolean intersects(Transaction tx, Geometry g) {
9699 private static abstract class IntersectsJudge {
97100
98101 protected final Geometry geometry ;
99- protected final WKBReader wkbReader = new WKBReader ();
100102 protected final double [] geoBbox ;
103+ protected final Map <Long , Object > cache ;
101104
102- public IntersectsJudge (Geometry geometry ) {
105+ public IntersectsJudge (Geometry geometry , int cacheSize ) {
103106 this .geometry = geometry ;
104107 geoBbox = GeometryBbox .getBbox (geometry ).toDoubleArray ();
108+ cache = LruCache .buildCache (cacheSize , 32 );
105109 }
106110
107- public boolean judge (Object value ) {
111+ public boolean judge (Node node ) {
112+ Object value = cache .get (node .getId ());
113+ if (null == value ) {
114+ value = node .getProperty (BigShapeManager .keyFieldName );
115+ if (value instanceof byte []) {
116+ try {
117+ value = WkbReaderManager .get ().read ((byte []) value );
118+ } catch (ParseException e ) {
119+ throw new RuntimeException (e );
120+ }
121+ }
122+ cache .put (node .getId (), value );
123+ }
124+ return judgeValue (value );
125+ }
126+
127+ protected boolean judgeValue (Object value ) {
108128 if (value instanceof double []) {//bbox
109129 return judgeBbox ((double []) value );
110130 } else {//wkb
111- return judgeWkb (( byte [] ) value );
131+ return judgeGeometry (( Geometry ) value );
112132 }
113133 }
114134
115135 abstract boolean judgeBbox (double [] bbox );
116136
117- boolean judgeWkb (byte [] wkb ) {
118- Geometry geometry ;
119- try {
120- geometry = wkbReader .read (wkb );
121- } catch (ParseException e ) {
122- throw new RuntimeException (e );
123- }
137+ protected boolean judgeGeometry (Geometry geometry ) {
124138// double[] gb = GeometryBbox.getBbox(geometry).toDoubleArray();
125139// if(!BboxIntersectUtil.bboxIntersect(gb,geoBbox)){
126140// return false;
@@ -137,8 +151,8 @@ private static class PointIntersectsJudge extends IntersectsJudge {
137151 private final double x ;
138152 private final double y ;
139153
140- public PointIntersectsJudge (Geometry geometry ) {
141- super (geometry );
154+ public PointIntersectsJudge (Geometry geometry , int cacheSize ) {
155+ super (geometry , cacheSize );
142156 Point point = (Point ) geometry ;
143157 x = point .getX ();
144158 y = point .getY ();
@@ -157,8 +171,8 @@ boolean judgeBbox(double[] bbox) {
157171 private static class OtherIntersectsJudge extends IntersectsJudge {
158172 private final GeometryFactory geometryFactory = new GeometryFactory ();
159173
160- public OtherIntersectsJudge (Geometry geometry ) {
161- super (geometry );
174+ public OtherIntersectsJudge (Geometry geometry , int cacheSize ) {
175+ super (geometry , cacheSize );
162176 }
163177
164178 @ Override
0 commit comments