Class LinearGeometryBuilder

  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.linearref;
 14  
 15 import java.util.ArrayList;
 16 import java.util.List;
 17  
 18 import org.locationtech.jts.geom.Coordinate;
 19 import org.locationtech.jts.geom.CoordinateList;
 20 import org.locationtech.jts.geom.Geometry;
 21 import org.locationtech.jts.geom.GeometryFactory;
 22 import org.locationtech.jts.geom.LineString;
 23 import org.locationtech.jts.geom.MultiLineString;
 24  
 25 /**
 26  * Builds a linear geometry ({@link LineString} or {@link MultiLineString})
 27  * incrementally (point-by-point).
 28  *
 29  * @version 1.7
 30  */
 31 public class LinearGeometryBuilder
 32 {
 33   private GeometryFactory geomFact;
 34   private List lines = new ArrayList();
 35   private CoordinateList coordList = null;
 36  
 37   private boolean ignoreInvalidLines = false;
 38   private boolean fixInvalidLines = false;
 39  
 40   private Coordinate lastPt = null;
 41  
 42   public LinearGeometryBuilder(GeometryFactory geomFact) {
 43     this.geomFact = geomFact;
 44   }
 45  
 46   /**
 47    * Allows invalid lines to be ignored rather than causing Exceptions.
 48    * An invalid line is one which has only one unique point.
 49    *
 50    * @param ignoreInvalidLines <code>true</code> if short lines are to be ignored
 51    */
 52   public void setIgnoreInvalidLines(boolean ignoreInvalidLines)
 53   {
 54     this.ignoreInvalidLines = ignoreInvalidLines;
 55   }
 56  
 57   /**
 58    * Allows invalid lines to be ignored rather than causing Exceptions.
 59    * An invalid line is one which has only one unique point.
 60    *
 61    * @param fixInvalidLines <code>true</code> if short lines are to be ignored
 62    */
 63   public void setFixInvalidLines(boolean fixInvalidLines)
 64   {
 65     this.fixInvalidLines = fixInvalidLines;
 66   }
 67  
 68   /**
 69    * Adds a point to the current line.
 70    *
 71    * @param pt the Coordinate to add
 72    */
 73   public void add(Coordinate pt)
 74   {
 75     add(pt, true);
 76   }
 77  
 78   /**
 79    * Adds a point to the current line.
 80    *
 81    * @param pt the Coordinate to add
 82    */
 83   public void add(Coordinate pt, boolean allowRepeatedPoints)
 84   {
 85     if (coordList == null)
 86       coordList = new CoordinateList();
 87     coordList.add(pt, allowRepeatedPoints);
 88     lastPt = pt;
 89   }
 90  
 91   public Coordinate getLastCoordinate() { return lastPt; }
 92  
 93   /**
 94    * Terminate the current LineString.
 95    */
 96   public void endLine()
 97   {
 98     if (coordList == null) {
 99       return;
100     }
101     if (ignoreInvalidLines && coordList.size() < 2) {
102       coordList = null;
103       return;
104     }
105     Coordinate[] rawPts = coordList.toCoordinateArray();
106     Coordinate[] pts = rawPts;
107     if (fixInvalidLines)
108       pts = validCoordinateSequence(rawPts);
109  
110     coordList = null;
111     LineString line = null;
112     try {
113       line = geomFact.createLineString(pts);
114     }
115     catch (IllegalArgumentException ex) {
116       // exception is due to too few points in line.
117       // only propagate if not ignoring short lines
118       if (! ignoreInvalidLines)
119         throw ex;
120     }
121  
122     if (line != nulllines.add(line);
123   }
124  
125   private Coordinate[] validCoordinateSequence(Coordinate[] pts)
126   {
127     if (pts.length >= 2return pts;
128     Coordinate[] validPts = new Coordinate[] { pts[0], pts[0]};
129     return validPts;
130   }
131  
132   public Geometry getGeometry()
133   {
134     // end last line in case it was not done by user
135     endLine();
136     return geomFact.buildGeometry(lines);
137   }
138 }
139