Class CommonBitsOp

  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  * common bit removal to reduce the likelihood of robustness problems.
 20  * <p>
 21  * In the current implementation no rounding is performed on the
 22  * reshifted result geometry, which means that it is possible
 23  * that the returned Geometry is invalid.
 24  * Client classes should check the validity of the returned result themselves.
 25  *
 26  * @version 1.7
 27  */
 28 public class CommonBitsOp {
 29  
 30   private boolean returnToOriginalPrecision = true;
 31   private CommonBitsRemover cbr;
 32  
 33   /**
 34    * Creates a new instance of class, which reshifts result {@link Geometry}s.
 35    */
 36   public CommonBitsOp()
 37   {
 38     this(true);
 39   }
 40  
 41   /**
 42    * Creates a new instance of class, specifying whether
 43    * the result {@link Geometry}s should be reshifted.
 44    *
 45    * @param returnToOriginalPrecision
 46    */
 47   public CommonBitsOp(boolean returnToOriginalPrecision)
 48   {
 49     this.returnToOriginalPrecision = returnToOriginalPrecision;
 50   }
 51  
 52   /**
 53    * Computes the set-theoretic intersection of two {@link Geometry}s, using enhanced precision.
 54    * @param geom0 the first Geometry
 55    * @param geom1 the second Geometry
 56    * @return the Geometry representing the set-theoretic intersection of the input Geometries.
 57    */
 58   public Geometry intersection(Geometry geom0, Geometry geom1)
 59   {
 60     Geometry[] geom = removeCommonBits(geom0, geom1);
 61     return computeResultPrecision(geom[0].intersection(geom[1]));
 62   }
 63  
 64   /**
 65    * Computes the set-theoretic union of two {@link Geometry}s, using enhanced precision.
 66    * @param geom0 the first Geometry
 67    * @param geom1 the second Geometry
 68    * @return the Geometry representing the set-theoretic union of the input Geometries.
 69    */
 70   public Geometry union(Geometry geom0, Geometry geom1)
 71   {
 72     Geometry[] geom = removeCommonBits(geom0, geom1);
 73     return computeResultPrecision(geom[0].union(geom[1]));
 74   }
 75  
 76   /**
 77    * Computes the set-theoretic difference of two {@link Geometry}s, using enhanced precision.
 78    * @param geom0 the first Geometry
 79    * @param geom1 the second Geometry, to be subtracted from the first
 80    * @return the Geometry representing the set-theoretic difference of the input Geometries.
 81    */
 82   public Geometry difference(Geometry geom0, Geometry geom1)
 83   {
 84     Geometry[] geom = removeCommonBits(geom0, geom1);
 85     return computeResultPrecision(geom[0].difference(geom[1]));
 86   }
 87  
 88   /**
 89    * Computes the set-theoretic symmetric difference of two geometries,
 90    * using enhanced precision.
 91    * @param geom0 the first Geometry
 92    * @param geom1 the second Geometry
 93    * @return the Geometry representing the set-theoretic symmetric difference of the input Geometries.
 94    */
 95   public Geometry symDifference(Geometry geom0, Geometry geom1)
 96   {
 97     Geometry[] geom = removeCommonBits(geom0, geom1);
 98     return computeResultPrecision(geom[0].symDifference(geom[1]));
 99   }
100  
101   /**
102    * Computes the buffer a geometry,
103    * using enhanced precision.
104    * @param geom0 the Geometry to buffer
105    * @param distance the buffer distance
106    * @return the Geometry representing the buffer of the input Geometry.
107    */
108   public Geometry buffer(Geometry geom0, double distance)
109   {
110     Geometry geom = removeCommonBits(geom0);
111     return computeResultPrecision(geom.buffer(distance));
112   }
113  
114   /**
115    * If required, returning the result to the original precision if required.
116    * <p>
117    * In this current implementation, no rounding is performed on the
118    * reshifted result geometry, which means that it is possible
119    * that the returned Geometry is invalid.
120    *
121    * @param result the result Geometry to modify
122    * @return the result Geometry with the required precision
123    */
124   private Geometry computeResultPrecision(Geometry result)
125   {
126     if (returnToOriginalPrecision)
127       cbr.addCommonBits(result);
128     return result;
129   }
130  
131   /**
132    * Computes a copy of the input {@link Geometry} with the calculated common bits
133    * removed from each coordinate.
134    * @param geom0 the Geometry to remove common bits from
135    * @return a copy of the input Geometry with common bits removed
136    */
137   private Geometry removeCommonBits(Geometry geom0)
138   {
139     cbr = new CommonBitsRemover();
140     cbr.add(geom0);
141     Geometry geom = cbr.removeCommonBits(geom0.copy());
142     return geom;
143   }
144  
145   /**
146    * Computes a copy of each input {@link Geometry}s with the calculated common bits
147    * removed from each coordinate.
148    * @param geom0 a Geometry to remove common bits from
149    * @param geom1 a Geometry to remove common bits from
150    * @return an array containing copies
151    * of the input Geometry's with common bits removed
152    */
153   private Geometry[] removeCommonBits(Geometry geom0, Geometry geom1)
154   {
155     cbr = new CommonBitsRemover();
156     cbr.add(geom0);
157     cbr.add(geom1);
158     Geometry geom[] = new Geometry[2];
159     geom[0] = cbr.removeCommonBits(geom0.copy());
160     geom[1] = cbr.removeCommonBits(geom1.copy());
161     return geom;
162   }
163 }
164