Class EnhancedPrecisionOp

  1  
  2 /*
  3  * Copyright (c) 2016 Vivid Solutions.
  4  *
  5  * All rights reserved. This program and the accompanying materials
  6  * are made available under the terms of the Eclipse Public License 2.0
  7  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  8  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
  9  * and the Eclipse Distribution License is available at
 10  *
 11  * http://www.eclipse.org/org/documents/edl-v10.php.
 12  */
 13 package org.locationtech.jts.precision;
 14  
 15 import org.locationtech.jts.geom.Geometry;
 16  
 17 /**
 18   * Provides versions of Geometry spatial functions which use
 19   * enhanced precision techniques to reduce the likelihood of robustness problems.
 20  *
 21  * @version 1.7
 22  */
 23 public class EnhancedPrecisionOp
 24 {
 25   /**
 26    * Computes the set-theoretic intersection of two {@link Geometry}s, using enhanced precision.
 27    * @param geom0 the first Geometry
 28    * @param geom1 the second Geometry
 29    * @return the Geometry representing the set-theoretic intersection of the input Geometries.
 30    */
 31   public static Geometry intersection(Geometry geom0, Geometry geom1)
 32   {
 33     RuntimeException originalEx;
 34     try {
 35       Geometry result = geom0.intersection(geom1);
 36       return result;
 37     }
 38     catch (RuntimeException ex)
 39     {
 40       originalEx = ex;
 41     }
 42     /*
 43      * If we are here, the original op encountered a precision problem
 44      * (or some other problem).  Retry the operation with
 45      * enhanced precision to see if it succeeds
 46      */
 47     try {
 48       CommonBitsOp cbo = new CommonBitsOp(true);
 49       Geometry resultEP = cbo.intersection(geom0, geom1);
 50       // check that result is a valid geometry after the reshift to original precision
 51       if (! resultEP.isValid())
 52         throw originalEx;
 53       return resultEP;
 54     }
 55     catch (RuntimeException ex2)
 56     {
 57       throw originalEx;
 58     }
 59   }
 60   /**
 61    * Computes the set-theoretic union of two {@link Geometry}s, using enhanced precision.
 62    * @param geom0 the first Geometry
 63    * @param geom1 the second Geometry
 64    * @return the Geometry representing the set-theoretic union of the input Geometries.
 65    */
 66   public static Geometry union(Geometry geom0, Geometry geom1)
 67   {
 68     RuntimeException originalEx;
 69     try {
 70       Geometry result = geom0.union(geom1);
 71       return result;
 72     }
 73     catch (RuntimeException ex)
 74     {
 75       originalEx = ex;
 76     }
 77     /*
 78      * If we are here, the original op encountered a precision problem
 79      * (or some other problem).  Retry the operation with
 80      * enhanced precision to see if it succeeds
 81      */
 82     try {
 83       CommonBitsOp cbo = new CommonBitsOp(true);
 84       Geometry resultEP = cbo.union(geom0, geom1);
 85       // check that result is a valid geometry after the reshift to original precision
 86       if (! resultEP.isValid())
 87         throw originalEx;
 88       return resultEP;
 89     }
 90     catch (RuntimeException ex2)
 91     {
 92       throw originalEx;
 93     }
 94   }
 95   /**
 96    * Computes the set-theoretic difference of two {@link Geometry}s, using enhanced precision.
 97    * @param geom0 the first Geometry
 98    * @param geom1 the second Geometry
 99    * @return the Geometry representing the set-theoretic difference of the input Geometries.
100    */
101   public static Geometry difference(Geometry geom0, Geometry geom1)
102   {
103     RuntimeException originalEx;
104     try {
105       Geometry result = geom0.difference(geom1);
106       return result;
107     }
108     catch (RuntimeException ex)
109     {
110       originalEx = ex;
111     }
112     /*
113      * If we are here, the original op encountered a precision problem
114      * (or some other problem).  Retry the operation with
115      * enhanced precision to see if it succeeds
116      */
117     try {
118       CommonBitsOp cbo = new CommonBitsOp(true);
119       Geometry resultEP = cbo.difference(geom0, geom1);
120       // check that result is a valid geometry after the reshift to original precision
121       if (! resultEP.isValid())
122         throw originalEx;
123       return resultEP;
124     }
125     catch (RuntimeException ex2)
126     {
127       throw originalEx;
128     }
129   }
130   /**
131    * Computes the set-theoretic symmetric difference of two {@link Geometry}s, using enhanced precision.
132    * @param geom0 the first Geometry
133    * @param geom1 the second Geometry
134    * @return the Geometry representing the set-theoretic symmetric difference of the input Geometries.
135    */
136   public static Geometry symDifference(Geometry geom0, Geometry geom1)
137   {
138     RuntimeException originalEx;
139     try {
140       Geometry result = geom0.symDifference(geom1);
141       return result;
142     }
143     catch (RuntimeException ex)
144     {
145       originalEx = ex;
146     }
147     /*
148      * If we are here, the original op encountered a precision problem
149      * (or some other problem).  Retry the operation with
150      * enhanced precision to see if it succeeds
151      */
152     try {
153       CommonBitsOp cbo = new CommonBitsOp(true);
154       Geometry resultEP = cbo.symDifference(geom0, geom1);
155       // check that result is a valid geometry after the reshift to original precision
156       if (! resultEP.isValid())
157         throw originalEx;
158       return resultEP;
159     }
160     catch (RuntimeException ex2)
161     {
162       throw originalEx;
163     }
164   }
165   /**
166    * Computes the buffer of a {@link Geometry}, using enhanced precision.
167    * This method should no longer be necessary, since the buffer algorithm
168    * now is highly robust.
169    *
170    * @param geom the first Geometry
171    * @param distance the buffer distance
172    * @return the Geometry representing the buffer of the input Geometry.
173    */
174   public static Geometry buffer(Geometry geom, double distance)
175   {
176     RuntimeException originalEx;
177     try {
178       Geometry result = geom.buffer(distance);
179       return result;
180     }
181     catch (RuntimeException ex)
182     {
183       originalEx = ex;
184     }
185     /*
186      * If we are here, the original op encountered a precision problem
187      * (or some other problem).  Retry the operation with
188      * enhanced precision to see if it succeeds
189      */
190     try {
191       CommonBitsOp cbo = new CommonBitsOp(true);
192       Geometry resultEP = cbo.buffer(geom, distance);
193       // check that result is a valid geometry after the reshift to original precision
194       if (! resultEP.isValid())
195         throw originalEx;
196       return resultEP;
197     }
198     catch (RuntimeException ex2)
199     {
200       throw originalEx;
201     }
202   }
203  
204 }
205