1 package org.locationtech.jts.operation.overlayng;
2 
3 import org.locationtech.jts.geom.Geometry;
4 
5 public class FastOverlayFilter {
6   // superceded by overlap clipping?
7   // TODO: perhaps change this to RectangleClipping, with fast/looser semantics?
8 
9   private Geometry targetGeom;
10   private boolean isTargetRectangle;
11 
FastOverlayFilter(Geometry geom)12   public FastOverlayFilter(Geometry geom) {
13     this.targetGeom = geom;
14     isTargetRectangle = targetGeom.isRectangle();
15   }
16 
17   /**
18    * Computes the overlay operation on the input geometries,
19    * if it can be determined that the result is either
20    * empty or equal to one of the input values.
21    * Otherwise <code>null</code> is returned, indicating
22    * that a full overlay operation must be performed.
23    *
24    * @param geom
25    * @param overlayOpCode
26    * @return
27    */
overlay(Geometry geom, int overlayOpCode)28   public Geometry overlay(Geometry geom, int overlayOpCode) {
29     // for now only INTERSECTION is handled
30     if (overlayOpCode != OverlayNG.INTERSECTION)
31       return null;
32     return intersection(geom);
33   }
34 
intersection(Geometry geom)35   private Geometry intersection(Geometry geom) {
36     // handle rectangle case
37     Geometry resultForRect = intersectionRectangle(geom);
38     if (resultForRect != null)
39       return resultForRect;
40 
41     // handle general case
42     if ( ! isEnvelopeIntersects(targetGeom, geom) ) {
43       return createEmpty(geom);
44     }
45 
46     return null;
47   }
48 
createEmpty(Geometry geom)49   private Geometry createEmpty(Geometry geom) {
50     // empty result has dimension of non-rectangle input
51     return OverlayUtil.createEmptyResult(geom.getDimension(), geom.getFactory());
52   }
53 
intersectionRectangle(Geometry geom)54   private Geometry intersectionRectangle(Geometry geom) {
55     if (! isTargetRectangle)
56       return null;
57 
58     if ( isEnvelopeCovers(targetGeom, geom) ) {
59       return geom.copy();
60     }
61     if ( ! isEnvelopeIntersects(targetGeom, geom) ) {
62       return createEmpty(geom);
63     }
64     return null;
65   }
66 
isEnvelopeIntersects(Geometry a, Geometry b)67   private boolean isEnvelopeIntersects(Geometry a, Geometry b) {
68     return a.getEnvelopeInternal().intersects( b.getEnvelopeInternal() );
69   }
70 
isEnvelopeCovers(Geometry a, Geometry b)71   private boolean isEnvelopeCovers(Geometry a, Geometry b) {
72     return a.getEnvelopeInternal().covers( b.getEnvelopeInternal() );
73   }
74 }
75