Class SnapIfNeededOverlayOp

  1 /*
  2  * Copyright (c) 2016 Vivid Solutions.
  3  *
  4  * All rights reserved. This program and the accompanying materials
  5  * are made available under the terms of the Eclipse Public License 2.0
  6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
  8  * and the Eclipse Distribution License is available at
  9  *
 10  * http://www.eclipse.org/org/documents/edl-v10.php.
 11  */
 12  
 13 package org.locationtech.jts.operation.overlay.snap;
 14  
 15 import org.locationtech.jts.geom.Geometry;
 16 import org.locationtech.jts.geom.TopologyException;
 17 import org.locationtech.jts.operation.overlay.OverlayOp;
 18  
 19  
 20 /**
 21  * Performs an overlay operation using snapping and enhanced precision
 22  * to improve the robustness of the result.
 23  * This class only uses snapping
 24  * if an error is detected when running the standard JTS overlay code.
 25  * Errors detected include thrown exceptions 
 26  * (in particular, {@link TopologyException})
 27  * and invalid overlay computations.
 28  *     
 29  * @author Martin Davis
 30  * @version 1.7
 31  */
 32 public class SnapIfNeededOverlayOp
 33 {
 34   public static Geometry overlayOp(Geometry g0, Geometry g1, int opCode)
 35   {
 36       SnapIfNeededOverlayOp op = new SnapIfNeededOverlayOp(g0, g1);
 37       return op.getResultGeometry(opCode);
 38   }
 39  
 40   public static Geometry intersection(Geometry g0, Geometry g1)
 41   {
 42      return overlayOp(g0, g1, OverlayOp.INTERSECTION);
 43   }
 44  
 45   public static Geometry union(Geometry g0, Geometry g1)
 46   {
 47      return overlayOp(g0, g1, OverlayOp.UNION);
 48   }
 49  
 50   public static Geometry difference(Geometry g0, Geometry g1)
 51   {
 52      return overlayOp(g0, g1, OverlayOp.DIFFERENCE);
 53   }
 54  
 55   public static Geometry symDifference(Geometry g0, Geometry g1)
 56   {
 57      return overlayOp(g0, g1, OverlayOp.SYMDIFFERENCE);
 58   }
 59   
 60   private Geometry[] geom = new Geometry[2];
 61  
 62   public SnapIfNeededOverlayOp(Geometry g1, Geometry g2)
 63   {
 64     geom[0] = g1;
 65     geom[1] = g2;
 66   }
 67  
 68   public Geometry getResultGeometry(int opCode)
 69   {
 70     Geometry result = null;
 71     boolean isSuccess = false;
 72     RuntimeException savedException = null;
 73     try {
 74       // try basic operation with input geometries
 75       result = OverlayOp.overlayOp(geom[0], geom[1], opCode); 
 76       boolean isValid = true;
 77       // not needed if noding validation is used
 78 //      boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result);
 79       if (isValid)
 80           isSuccess = true;
 81     }
 82     catch (RuntimeException ex) {
 83         savedException = ex;
 84         // ignore this exception, since the operation will be rerun
 85 //        System.out.println(ex.getMessage());
 86 //        ex.printStackTrace();
 87         //System.out.println(ex.getMessage());
 88         //System.out.println("Geom 0: " + geom[0]);
 89         //System.out.println("Geom 1: " + geom[1]);
 90     }
 91     if (! isSuccess) {
 92         // this may still throw an exception
 93         // if so, throw the original exception since it has the input coordinates
 94         try {
 95             result = SnapOverlayOp.overlayOp(geom[0], geom[1], opCode);
 96         }
 97         catch (RuntimeException ex) {
 98             throw savedException;
 99         }
100     }
101     return result;
102   }
103 }
104