Class LinearComponentExtracter

  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.geom.util;
 14  
 15 import java.util.ArrayList;
 16 import java.util.Collection;
 17 import java.util.Iterator;
 18 import java.util.List;
 19  
 20 import org.locationtech.jts.geom.Geometry;
 21 import org.locationtech.jts.geom.GeometryComponentFilter;
 22 import org.locationtech.jts.geom.LineString;
 23 import org.locationtech.jts.geom.LinearRing;
 24 import org.locationtech.jts.geom.MultiLineString;
 25  
 26  
 27 /**
 28  * Extracts all the 1-dimensional ({@link LineString}) components from a {@link Geometry}.
 29  * For polygonal geometries, this will extract all the component {@link LinearRing}s.
 30  * If desired, <code>LinearRing</code>s can be forced to be returned as <code>LineString</code>s.
 31  *
 32  * @version 1.7
 33  */
 34 public class LinearComponentExtracter
 35   implements GeometryComponentFilter
 36 {
 37   /**
 38    * Extracts the linear components from a single {@link Geometry}
 39    * and adds them to the provided {@link Collection}.
 40    *
 41    * @param geoms the collection of geometries from which to extract linear components
 42    * @param lines the collection to add the extracted linear components to
 43    * @return the collection of linear components (LineStrings or LinearRings)
 44    */
 45   public static Collection getLines(Collection geoms, Collection lines)
 46   {
 47       for (Iterator i = geoms.iterator(); i.hasNext(); ) {
 48           Geometry g = (Geometry) i.next();
 49           getLines(g, lines);
 50       }
 51     return lines;
 52   }
 53  
 54   /**
 55    * Extracts the linear components from a single {@link Geometry}
 56    * and adds them to the provided {@link Collection}.
 57    *
 58    * @param geoms the Collection of geometries from which to extract linear components
 59    * @param lines the collection to add the extracted linear components to
 60    * @param forceToLineString true if LinearRings should be converted to LineStrings
 61    * @return the collection of linear components (LineStrings or LinearRings)
 62    */
 63   public static Collection getLines(Collection geoms, Collection lines, boolean forceToLineString)
 64   {
 65       for (Iterator i = geoms.iterator(); i.hasNext(); ) {
 66           Geometry g = (Geometry) i.next();
 67           getLines(g, lines, forceToLineString);
 68       }
 69     return lines;
 70   }
 71  
 72   /**
 73    * Extracts the linear components from a single {@link Geometry}
 74    * and adds them to the provided {@link Collection}.
 75    *
 76    * @param geom the geometry from which to extract linear components
 77    * @param lines the Collection to add the extracted linear components to
 78    * @return the Collection of linear components (LineStrings or LinearRings)
 79    */
 80   public static Collection getLines(Geometry geom, Collection lines)
 81   {
 82       if (geom instanceof LineString) {
 83           lines.add(geom);
 84       }
 85       else {
 86       geom.apply(new LinearComponentExtracter(lines));
 87       }
 88     return lines;
 89   }
 90  
 91   /**
 92    * Extracts the linear components from a single {@link Geometry}
 93    * and adds them to the provided {@link Collection}.
 94    *
 95    * @param geom the geometry from which to extract linear components
 96    * @param lines the Collection to add the extracted linear components to
 97    * @param forceToLineString true if LinearRings should be converted to LineStrings
 98    * @return the Collection of linear components (LineStrings or LinearRings)
 99    */
100   public static Collection getLines(Geometry geom, Collection lines, boolean forceToLineString)
101   {
102     geom.apply(new LinearComponentExtracter(lines, forceToLineString));
103     return lines;
104   }
105  
106   /**
107    * Extracts the linear components from a single geometry.
108    * If more than one geometry is to be processed, it is more
109    * efficient to create a single {@link LinearComponentExtracter} instance
110    * and pass it to multiple geometries.
111    *
112    * @param geom the geometry from which to extract linear components
113    * @return the list of linear components
114    */
115   public static List getLines(Geometry geom)
116   {
117     return getLines(geom, false);
118   }
119  
120   /**
121    * Extracts the linear components from a single geometry.
122    * If more than one geometry is to be processed, it is more
123    * efficient to create a single {@link LinearComponentExtracter} instance
124    * and pass it to multiple geometries.
125    *
126    * @param geom the geometry from which to extract linear components
127    * @param forceToLineString true if LinearRings should be converted to LineStrings
128    * @return the list of linear components
129    */
130   public static List getLines(Geometry geom, boolean forceToLineString)
131   {
132     List lines = new ArrayList();
133     geom.apply(new LinearComponentExtracter(lines, forceToLineString));
134     return lines;
135   }
136  
137   /**
138    * Extracts the linear components from a single {@link Geometry}
139    * and returns them as either a {@link LineString} or {@link MultiLineString}.
140    * 
141    * @param geom the geometry from which to extract
142    * @return a linear geometry
143    */
144   public static Geometry getGeometry(Geometry geom)
145   {
146     return geom.getFactory().buildGeometry(getLines(geom));
147   }
148  
149  
150   /**
151    * Extracts the linear components from a single {@link Geometry}
152    * and returns them as either a {@link LineString} or {@link MultiLineString}.
153    * 
154    * @param geom the geometry from which to extract
155    * @param forceToLineString true if LinearRings should be converted to LineStrings
156    * @return a linear geometry
157    */
158   public static Geometry getGeometry(Geometry geom, boolean forceToLineString)
159   {
160     return geom.getFactory().buildGeometry(getLines(geom, forceToLineString));
161   }
162  
163  
164   private Collection lines;
165   private boolean isForcedToLineString = false;
166   
167   /**
168    * Constructs a LineExtracterFilter with a list in which to store LineStrings found.
169    */
170   public LinearComponentExtracter(Collection lines)
171   {
172     this.lines = lines;
173   }
174  
175   /**
176    * Constructs a LineExtracterFilter with a list in which to store LineStrings found.
177    */
178   public LinearComponentExtracter(Collection lines, boolean isForcedToLineString)
179   {
180     this.lines = lines;
181     this.isForcedToLineString = isForcedToLineString;
182   }
183  
184   /**
185    * Indicates that LinearRing components should be 
186    * converted to pure LineStrings.
187    * 
188    * @param isForcedToLineString true if LinearRings should be converted to LineStrings
189    */
190   public void setForceToLineString(boolean isForcedToLineString)
191   {
192       this.isForcedToLineString = isForcedToLineString;
193   }
194   
195   public void filter(Geometry geom)
196   {
197       if (isForcedToLineString && geom instanceof LinearRing) {
198           LineString line = geom.getFactory().createLineString( ((LinearRing) geom).getCoordinateSequence());
199           lines.add(line);
200           return;
201       }
202       // if not being forced, and this is a linear component
203       if (geom instanceof LineString) 
204           lines.add(geom);
205       
206       // else this is not a linear component, so skip it
207   }
208  
209 }
210