Class CoordinateList

  1  
  2  
  3 /*
  4  * Copyright (c) 2016 Vivid Solutions.
  5  *
  6  * All rights reserved. This program and the accompanying materials
  7  * are made available under the terms of the Eclipse Public License 2.0
  8  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  9  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 10  * and the Eclipse Distribution License is available at
 11  *
 12  * http://www.eclipse.org/org/documents/edl-v10.php.
 13  */
 14 package org.locationtech.jts.geom;
 15  
 16 import java.util.ArrayList;
 17 import java.util.Collection;
 18 import java.util.Iterator;
 19  
 20 /**
 21  * A list of {@link Coordinate}s, which may
 22  * be set to prevent repeated coordinates from occurring in the list.
 23  *
 24  *
 25  * @version 1.7
 26  */
 27 public class CoordinateList
 28   extends ArrayList<Coordinate>
 29 {
 30   private static final long serialVersionUID = -1626110935756089896L;
 31 //With contributions from Markus Schaber [schabios@logi-track.com]
 32   //[Jon Aquino 2004-03-25]
 33   private final static Coordinate[] coordArrayType = new Coordinate[0];
 34  
 35   /**
 36    * Constructs a new list without any coordinates
 37    */
 38   public CoordinateList()
 39   {
 40   }
 41  
 42   /**
 43    * Constructs a new list from an array of Coordinates, allowing repeated points.
 44    * (I.e. this constructor produces a {@link CoordinateList} with exactly the same set of points
 45    * as the input array.)
 46    * 
 47    * @param coord the initial coordinates
 48    */
 49   public CoordinateList(Coordinate[] coord)
 50   {
 51       ensureCapacity(coord.length);
 52     add(coord, true);
 53   }
 54  
 55   /**
 56    * Constructs a new list from an array of Coordinates,
 57    * allowing caller to specify if repeated points are to be removed.
 58    *
 59    * @param coord the array of coordinates to load into the list
 60    * @param allowRepeated if <code>false</code>, repeated points are removed
 61    */
 62   public CoordinateList(Coordinate[] coord, boolean allowRepeated)
 63   {
 64       ensureCapacity(coord.length);
 65     add(coord, allowRepeated);
 66   }
 67  
 68   public boolean add(Coordinate coord) {
 69     return super.add(coord);
 70   }
 71  
 72   public Coordinate getCoordinate(int i) { return (Coordinate) get(i); }
 73  
 74  
 75   /** 
 76    * Adds a section of an array of coordinates to the list.
 77    * @param coord The coordinates
 78    * @param allowRepeated if set to false, repeated coordinates are collapsed
 79    * @param start the index to start from
 80    * @param end the index to add up to but not including
 81    * @return true (as by general collection contract)
 82    */
 83   public boolean add(Coordinate[] coord, boolean allowRepeated, int start, int end)
 84   {
 85     int inc = 1;
 86     if (start > end) inc = -1;
 87     
 88     for (int i = start; i != end; i += inc) {
 89       add(coord[i], allowRepeated);
 90     }
 91     return true;
 92   }
 93  
 94   /** 
 95    * Adds an array of coordinates to the list.
 96    * @param coord The coordinates
 97    * @param allowRepeated if set to false, repeated coordinates are collapsed
 98    * @param direction if false, the array is added in reverse order
 99    * @return true (as by general collection contract)
100    */
101   public boolean add(Coordinate[] coord, boolean allowRepeated, boolean direction)
102   {
103     if (direction) {
104       for (int i = 0; i < coord.length; i++) {
105         add(coord[i], allowRepeated);
106       }
107     }
108     else {
109       for (int i = coord.length - 1; i >= 0; i--) {
110         add(coord[i], allowRepeated);
111       }
112     }
113     return true;
114   }
115  
116  
117   /** 
118    * Adds an array of coordinates to the list.
119    * @param coord The coordinates
120    * @param allowRepeated if set to false, repeated coordinates are collapsed
121    * @return true (as by general collection contract)
122    */
123   public boolean add(Coordinate[] coord, boolean allowRepeated)
124   {
125     add(coord, allowRepeated, true);
126     return true;
127   }
128  
129   /** 
130    * Adds a coordinate to the list.
131    * @param obj The coordinate to add
132    * @param allowRepeated if set to false, repeated coordinates are collapsed
133    * @return true (as by general collection contract)
134    */
135   public boolean add(Object obj, boolean allowRepeated)
136   {
137     add((Coordinate) obj, allowRepeated);
138     return true;
139   }
140  
141   /**
142    * Adds a coordinate to the end of the list.
143    * 
144    * @param coord The coordinates
145    * @param allowRepeated if set to false, repeated coordinates are collapsed
146    */
147   public void add(Coordinate coord, boolean allowRepeated)
148   {
149     // don't add duplicate coordinates
150     if (! allowRepeated) {
151       if (size() >= 1) {
152         Coordinate last = (Coordinate) get(size() - 1);
153         if (last.equals2D(coord)) return;
154       }
155     }
156     super.add(coord);
157   }
158  
159   /**
160    * Inserts the specified coordinate at the specified position in this list.
161    * 
162    * @param i the position at which to insert
163    * @param coord the coordinate to insert
164    * @param allowRepeated if set to false, repeated coordinates are collapsed
165    */
166   public void add(int i, Coordinate coord, boolean allowRepeated)
167   {
168     // don't add duplicate coordinates
169     if (! allowRepeated) {
170       int size = size();
171       if (size > 0) {
172         if (i > 0) {
173           Coordinate prev = (Coordinate) get(i - 1);
174           if (prev.equals2D(coord)) return;
175         }
176         if (i < size) {
177           Coordinate next = (Coordinate) get(i);
178           if (next.equals2D(coord)) return;
179         }
180       }
181     }
182     super.add(i, coord);
183   }
184  
185   /** Add an array of coordinates
186    * @param coll The coordinates
187    * @param allowRepeated if set to false, repeated coordinates are collapsed
188    * @return true (as by general collection contract)
189    */
190   public boolean addAll(Collection<? extends Coordinate> coll, boolean allowRepeated)
191   {
192     boolean isChanged = false;
193     for (Iterator<? extends Coordinate> i = coll.iterator(); i.hasNext(); ) {
194       add(i.next(), allowRepeated);
195       isChanged = true;
196     }
197     return isChanged;
198   }
199  
200   /**
201    * Ensure this coordList is a ring, by adding the start point if necessary
202    */
203   public void closeRing()
204   {
205     if (size() > 0) {
206       Coordinate duplicate = get(0).copy();
207       add(duplicate, false);
208     }
209   }
210  
211   /** Returns the Coordinates in this collection.
212    *
213    * @return the coordinates
214    */
215   public Coordinate[] toCoordinateArray()
216   {
217     return (Coordinate[]) toArray(coordArrayType);
218   }
219  
220   /**
221    * Creates an array containing the coordinates in this list,
222    * oriented in the given direction (forward or reverse).
223    * 
224    * @param direction the direction value: true for forward, false for reverse
225    * @return an oriented array of coordinates
226    */
227   public Coordinate[] toCoordinateArray(boolean isForward)
228   {
229     if (isForward) {
230       return (Coordinate[]) toArray(coordArrayType);
231     }
232     // construct reversed array
233     int size = size();
234     Coordinate[] pts = new Coordinate[size];
235     for (int i = 0; i < size; i++) {
236       pts[i] = get(size - i - 1);
237     }
238     return pts;
239   }
240  
241   /**
242    * Returns a deep copy of this <tt>CoordinateList</tt> instance.
243    *
244    * @return a clone of this <tt>CoordinateList</tt> instance
245    */
246   public Object clone() {
247       CoordinateList clone = (CoordinateList) super.clone();
248       for (int i = 0; i < this.size(); i++) {      
249           clone.add(i, (Coordinate) this.get(i).clone());
250       }
251       return clone;
252   }
253 }
254