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