Class GeometryFactory

  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.io.Serializable;
 17 import java.util.Collection;
 18 import java.util.Iterator;
 19  
 20 import org.locationtech.jts.geom.impl.CoordinateArraySequenceFactory;
 21 import org.locationtech.jts.geom.util.GeometryEditor;
 22 import org.locationtech.jts.util.Assert;
 23  
 24 /**
 25  * Supplies a set of utility methods for building Geometry objects from lists
 26  * of Coordinates.
 27  * <p>
 28  * Note that the factory constructor methods do <b>not</b> change the input coordinates in any way.
 29  * In particular, they are not rounded to the supplied <tt>PrecisionModel</tt>.
 30  * It is assumed that input Coordinates meet the given precision.
 31  * <p>
 32  * Instances of this class are thread-safe.
 33  *
 34  * @version 1.7
 35  */
 36 public class GeometryFactory
 37     implements Serializable
 38 {
 39   private static final long serialVersionUID = -6820524753094095635L;
 40   private PrecisionModel precisionModel;
 41  
 42   private CoordinateSequenceFactory coordinateSequenceFactory;
 43  
 44  
 45   public static Point createPointFromInternalCoord(Coordinate coord, Geometry exemplar)
 46   {
 47     exemplar.getPrecisionModel().makePrecise(coord);
 48     return exemplar.getFactory().createPoint(coord);
 49   }
 50  
 51   /**
 52    * Constructs a GeometryFactory that generates Geometries having the given
 53    * PrecisionModel, spatial-reference ID, and CoordinateSequence implementation.
 54    */
 55   public GeometryFactory(PrecisionModel precisionModel, int SRID,
 56                          CoordinateSequenceFactory coordinateSequenceFactory) {
 57       this.precisionModel = precisionModel;
 58       this.coordinateSequenceFactory = coordinateSequenceFactory;
 59       this.SRID = SRID;
 60   }
 61  
 62   /**
 63    * Constructs a GeometryFactory that generates Geometries having the given
 64    * CoordinateSequence implementation, a double-precision floating PrecisionModel and a
 65    * spatial-reference ID of 0.
 66    */
 67   public GeometryFactory(CoordinateSequenceFactory coordinateSequenceFactory) {
 68     this(new PrecisionModel(), 0, coordinateSequenceFactory);
 69   }
 70  
 71   /**
 72    * Constructs a GeometryFactory that generates Geometries having the given
 73    * {@link PrecisionModel} and the default CoordinateSequence
 74    * implementation.
 75    *
 76    * @param precisionModel the PrecisionModel to use
 77    */
 78   public GeometryFactory(PrecisionModel precisionModel) {
 79     this(precisionModel, 0, getDefaultCoordinateSequenceFactory());
 80   }
 81  
 82   /**
 83    * Constructs a GeometryFactory that generates Geometries having the given
 84    * {@link PrecisionModel} and spatial-reference ID, and the default CoordinateSequence
 85    * implementation.
 86    *
 87    * @param precisionModel the PrecisionModel to use
 88    * @param SRID the SRID to use
 89    */
 90   public GeometryFactory(PrecisionModel precisionModel, int SRID) {
 91     this(precisionModel, SRID, getDefaultCoordinateSequenceFactory());
 92   }
 93  
 94   /**
 95    * Constructs a GeometryFactory that generates Geometries having a floating
 96    * PrecisionModel and a spatial-reference ID of 0.
 97    */
 98   public GeometryFactory() {
 99     this(new PrecisionModel(), 0);
100   }
101  
102   private static CoordinateSequenceFactory getDefaultCoordinateSequenceFactory()
103   {
104     return CoordinateArraySequenceFactory.instance();
105   }
106  
107   /**
108    *  Converts the <code>List</code> to an array.
109    *
110    *@param  points  the <code>List</code> of Points to convert
111    *@return         the <code>List</code> in array format
112    */
113   public static Point[] toPointArray(Collection points) {
114     Point[] pointArray = new Point[points.size()];
115     return (Point[]) points.toArray(pointArray);
116   }
117  
118   /**
119    *  Converts the <code>List</code> to an array.
120    *
121    *@param  geometries  the list of <code>Geometry's</code> to convert
122    *@return            the <code>List</code> in array format
123    */
124   public static Geometry[] toGeometryArray(Collection geometries) {
125     if (geometries == nullreturn null;
126     Geometry[] geometryArray = new Geometry[geometries.size()];
127     return (Geometry[]) geometries.toArray(geometryArray);
128   }
129  
130   /**
131    *  Converts the <code>List</code> to an array.
132    *
133    *@param  linearRings  the <code>List</code> of LinearRings to convert
134    *@return              the <code>List</code> in array format
135    */
136   public static LinearRing[] toLinearRingArray(Collection linearRings) {
137     LinearRing[] linearRingArray = new LinearRing[linearRings.size()];
138     return (LinearRing[]) linearRings.toArray(linearRingArray);
139   }
140  
141   /**
142    *  Converts the <code>List</code> to an array.
143    *
144    *@param  lineStrings  the <code>List</code> of LineStrings to convert
145    *@return              the <code>List</code> in array format
146    */
147   public static LineString[] toLineStringArray(Collection lineStrings) {
148     LineString[] lineStringArray = new LineString[lineStrings.size()];
149     return (LineString[]) lineStrings.toArray(lineStringArray);
150   }
151  
152   /**
153    *  Converts the <code>List</code> to an array.
154    *
155    *@param  polygons  the <code>List</code> of Polygons to convert
156    *@return           the <code>List</code> in array format
157    */
158   public static Polygon[] toPolygonArray(Collection polygons) {
159     Polygon[] polygonArray = new Polygon[polygons.size()];
160     return (Polygon[]) polygons.toArray(polygonArray);
161   }
162  
163   /**
164    *  Converts the <code>List</code> to an array.
165    *
166    *@param  multiPolygons  the <code>List</code> of MultiPolygons to convert
167    *@return                the <code>List</code> in array format
168    */
169   public static MultiPolygon[] toMultiPolygonArray(Collection multiPolygons) {
170     MultiPolygon[] multiPolygonArray = new MultiPolygon[multiPolygons.size()];
171     return (MultiPolygon[]) multiPolygons.toArray(multiPolygonArray);
172   }
173  
174   /**
175    *  Converts the <code>List</code> to an array.
176    *
177    *@param  multiLineStrings  the <code>List</code> of MultiLineStrings to convert
178    *@return                   the <code>List</code> in array format
179    */
180   public static MultiLineString[] toMultiLineStringArray(Collection multiLineStrings) {
181     MultiLineString[] multiLineStringArray = new MultiLineString[multiLineStrings.size()];
182     return (MultiLineString[]) multiLineStrings.toArray(multiLineStringArray);
183   }
184  
185   /**
186    *  Converts the <code>List</code> to an array.
187    *
188    *@param  multiPoints  the <code>List</code> of MultiPoints to convert
189    *@return              the <code>List</code> in array format
190    */
191   public static MultiPoint[] toMultiPointArray(Collection multiPoints) {
192     MultiPoint[] multiPointArray = new MultiPoint[multiPoints.size()];
193     return (MultiPoint[]) multiPoints.toArray(multiPointArray);
194   }
195  
196   /**
197    * Creates a {@link Geometry} with the same extent as the given envelope.
198    * The Geometry returned is guaranteed to be valid.  
199    * To provide this behaviour, the following cases occur:
200    * <p>
201    * If the <code>Envelope</code> is:
202    * <ul>
203    * <li>null : returns an empty {@link Point}
204    * <li>a point : returns a non-empty {@link Point}
205    * <li>a line : returns a two-point {@link LineString}
206    * <li>a rectangle : returns a {@link Polygon} whose points are (minx, miny),
207    *  (minx, maxy), (maxx, maxy), (maxx, miny), (minx, miny).
208    * </ul>
209    * 
210    *@param  envelope the <code>Envelope</code> to convert
211    *@return an empty <code>Point</code> (for null <code>Envelope</code>s), 
212    *    a <code>Point</code> (when min x = max x and min y = max y) or a
213    *      <code>Polygon</code> (in all other cases)
214    */
215   public Geometry toGeometry(Envelope envelope) 
216   {
217       // null envelope - return empty point geometry
218     if (envelope.isNull()) {
219       return createPoint();
220     }
221     
222     // point?
223     if (envelope.getMinX() == envelope.getMaxX() && envelope.getMinY() == envelope.getMaxY()) {
224       return createPoint(new Coordinate(envelope.getMinX(), envelope.getMinY()));
225     }
226     
227     // vertical or horizontal line?
228     if (envelope.getMinX() == envelope.getMaxX()
229             || envelope.getMinY() == envelope.getMaxY()) {
230         return createLineString(new Coordinate[]{
231           new Coordinate(envelope.getMinX(), envelope.getMinY()),
232           new Coordinate(envelope.getMaxX(), envelope.getMaxY())
233           });
234     }
235  
236     // create a CW ring for the polygon 
237     return createPolygon(createLinearRing(new Coordinate[]{
238         new Coordinate(envelope.getMinX(), envelope.getMinY()),
239         new Coordinate(envelope.getMinX(), envelope.getMaxY()),
240         new Coordinate(envelope.getMaxX(), envelope.getMaxY()),
241         new Coordinate(envelope.getMaxX(), envelope.getMinY()),
242         new Coordinate(envelope.getMinX(), envelope.getMinY())
243         }), null);
244   }
245  
246   /**
247    * Returns the PrecisionModel that Geometries created by this factory
248    * will be associated with.
249    * 
250    * @return the PrecisionModel for this factory
251    */
252   public PrecisionModel getPrecisionModel() {
253     return precisionModel;
254   }
255  
256   /**
257    * Constructs an empty {@link Point} geometry.
258    * 
259    * @return an empty Point
260    */
261   public Point createPoint() {
262     return createPoint(getCoordinateSequenceFactory().create(new Coordinate[]{}));
263   }
264   
265   /**
266    * Creates a Point using the given Coordinate.
267    * A null Coordinate creates an empty Geometry.
268    * 
269    * @param coordinate a Coordinate, or null
270    * @return the created Point
271    */
272   public Point createPoint(Coordinate coordinate) {
273     return createPoint(coordinate != null ? getCoordinateSequenceFactory().create(new Coordinate[]{coordinate}) : null);
274   }
275  
276   /**
277    * Creates a Point using the given CoordinateSequence; a null or empty
278    * CoordinateSequence will create an empty Point.
279    * 
280    * @param coordinates a CoordinateSequence (possibly empty), or null
281    * @return the created Point
282    */
283   public Point createPoint(CoordinateSequence coordinates) {
284       return new Point(coordinates, this);
285   }
286   
287   /**
288    * Constructs an empty {@link MultiLineString} geometry.
289    * 
290    * @return an empty MultiLineString
291    */
292   public MultiLineString createMultiLineString() {
293     return new MultiLineString(null, this);
294   }
295  
296   /**
297    * Creates a MultiLineString using the given LineStrings; a null or empty
298    * array will create an empty MultiLineString.
299    * 
300    * @param lineStrings LineStrings, each of which may be empty but not null
301    * @return the created MultiLineString
302    */
303   public MultiLineString createMultiLineString(LineString[] lineStrings) {
304       return new MultiLineString(lineStrings, this);
305   }
306   
307   /**
308    * Constructs an empty {@link GeometryCollection} geometry.
309    * 
310    * @return an empty GeometryCollection
311    */
312   public GeometryCollection createGeometryCollection() {
313     return new GeometryCollection(null, this);
314   }
315  
316   /**
317    * Creates a GeometryCollection using the given Geometries; a null or empty
318    * array will create an empty GeometryCollection.
319    * 
320    * @param geometries an array of Geometries, each of which may be empty but not null, or null
321    * @return the created GeometryCollection
322    */
323   public GeometryCollection createGeometryCollection(Geometry[] geometries) {
324       return new GeometryCollection(geometries, this);
325   }
326   
327   /**
328    * Constructs an empty {@link MultiPolygon} geometry.
329    * 
330    * @return an empty MultiPolygon
331    */
332   public MultiPolygon createMultiPolygon() {
333     return new MultiPolygon(null, this);
334   }
335  
336   /**
337    * Creates a MultiPolygon using the given Polygons; a null or empty array
338    * will create an empty Polygon. The polygons must conform to the
339    * assertions specified in the <A
340    * HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
341    * Specification for SQL</A>.
342    *
343    * @param polygons
344    *            Polygons, each of which may be empty but not null
345    * @return the created MultiPolygon
346    */
347   public MultiPolygon createMultiPolygon(Polygon[] polygons) {
348     return new MultiPolygon(polygons, this);
349   }
350   
351   /**
352    * Constructs an empty {@link LinearRing} geometry.
353    * 
354    * @return an empty LinearRing
355    */
356   public LinearRing createLinearRing() {
357     return createLinearRing(getCoordinateSequenceFactory().create(new Coordinate[]{}));
358   }
359  
360   /**
361    * Creates a {@link LinearRing} using the given {@link Coordinate}s.
362    * A null or empty array creates an empty LinearRing. 
363    * The points must form a closed and simple linestring. 
364    * @param coordinates an array without null elements, or an empty array, or null
365    * @return the created LinearRing
366    * @throws IllegalArgumentException if the ring is not closed, or has too few points
367    */
368   public LinearRing createLinearRing(Coordinate[] coordinates) {
369     return createLinearRing(coordinates != null ? getCoordinateSequenceFactory().create(coordinates) : null);
370   }
371  
372   /**
373    * Creates a {@link LinearRing} using the given {@link CoordinateSequence}. 
374    * A null or empty array creates an empty LinearRing. 
375    * The points must form a closed and simple linestring. 
376    * 
377    * @param coordinates a CoordinateSequence (possibly empty), or null
378    * @return the created LinearRing
379    * @throws IllegalArgumentException if the ring is not closed, or has too few points
380    */
381   public LinearRing createLinearRing(CoordinateSequence coordinates) {
382     return new LinearRing(coordinates, this);
383   }
384   
385   /**
386    * Constructs an empty {@link MultiPoint} geometry.
387    * 
388    * @return an empty MultiPoint
389    */
390   public MultiPoint createMultiPoint() {
391     return new MultiPoint(null, this);
392   }
393  
394   /**
395    * Creates a {@link MultiPoint} using the given {@link Point}s.
396    * A null or empty array will create an empty MultiPoint.
397    *
398    * @param point an array of Points (without null elements), or an empty array, or <code>null</code>
399    * @return a MultiPoint object
400    */
401   public MultiPoint createMultiPoint(Point[] point) {
402       return new MultiPoint(point, this);
403   }
404  
405   /**
406    * Creates a {@link MultiPoint} using the given {@link Coordinate}s.
407    * A null or empty array will create an empty MultiPoint.
408    *
409    * @param coordinates an array (without null elements), or an empty array, or <code>null</code>
410    * @return a MultiPoint object
411    * @deprecated Use {@link GeometryFactory#createMultiPointFromCoords} instead
412    */
413   public MultiPoint createMultiPoint(Coordinate[] coordinates) {
414       return createMultiPoint(coordinates != null
415                               ? getCoordinateSequenceFactory().create(coordinates)
416                               : null);
417   }
418  
419   /**
420    * Creates a {@link MultiPoint} using the given {@link Coordinate}s.
421    * A null or empty array will create an empty MultiPoint.
422    *
423    * @param coordinates an array (without null elements), or an empty array, or <code>null</code>
424    * @return a MultiPoint object
425    */
426   public MultiPoint createMultiPointFromCoords(Coordinate[] coordinates) {
427       return createMultiPoint(coordinates != null
428                               ? getCoordinateSequenceFactory().create(coordinates)
429                               : null);
430   }
431  
432   /**
433    * Creates a {@link MultiPoint} using the 
434    * points in the given {@link CoordinateSequence}.
435    * A <code>null</code> or empty CoordinateSequence creates an empty MultiPoint.
436    *
437    * @param coordinates a CoordinateSequence (possibly empty), or <code>null</code>
438    * @return a MultiPoint geometry
439    */
440   public MultiPoint createMultiPoint(CoordinateSequence coordinates) {
441     if (coordinates == null) {
442       return createMultiPoint(new Point[0]);
443     }
444     Point[] points = new Point[coordinates.size()];
445     for (int i = 0; i < coordinates.size(); i++) {
446       CoordinateSequence ptSeq = getCoordinateSequenceFactory()
447         .create(1, coordinates.getDimension(), coordinates.getMeasures());
448       CoordinateSequences.copy(coordinates, i, ptSeq, 01);
449       points[i] = createPoint(ptSeq);
450     }
451     return createMultiPoint(points);
452   }
453  
454   /**
455    * Constructs a <code>Polygon</code> with the given exterior boundary and
456    * interior boundaries.
457    *
458    * @param shell
459    *            the outer boundary of the new <code>Polygon</code>, or
460    *            <code>null</code> or an empty <code>LinearRing</code> if
461    *            the empty geometry is to be created.
462    * @param holes
463    *            the inner boundaries of the new <code>Polygon</code>, or
464    *            <code>null</code> or empty <code>LinearRing</code> s if
465    *            the empty geometry is to be created.
466    * @throws IllegalArgumentException if a ring is invalid
467    */
468   public Polygon createPolygon(LinearRing shell, LinearRing[] holes) {
469     return new Polygon(shell, holes, this);
470   }
471  
472   /**
473    * Constructs a <code>Polygon</code> with the given exterior boundary.
474    *
475    * @param shell
476    *            the outer boundary of the new <code>Polygon</code>, or
477    *            <code>null</code> or an empty <code>LinearRing</code> if
478    *            the empty geometry is to be created.
479    * @throws IllegalArgumentException if the boundary ring is invalid
480    */
481   public Polygon createPolygon(CoordinateSequence shell) {
482     return createPolygon(createLinearRing(shell));
483   }
484  
485   /**
486    * Constructs a <code>Polygon</code> with the given exterior boundary.
487    *
488    * @param shell
489    *            the outer boundary of the new <code>Polygon</code>, or
490    *            <code>null</code> or an empty <code>LinearRing</code> if
491    *            the empty geometry is to be created.
492    * @throws IllegalArgumentException if the boundary ring is invalid
493    */
494   public Polygon createPolygon(Coordinate[] shell) {
495     return createPolygon(createLinearRing(shell));
496   }
497  
498   /**
499    * Constructs a <code>Polygon</code> with the given exterior boundary.
500    *
501    * @param shell
502    *            the outer boundary of the new <code>Polygon</code>, or
503    *            <code>null</code> or an empty <code>LinearRing</code> if
504    *            the empty geometry is to be created.
505    * @throws IllegalArgumentException if the boundary ring is invalid
506    */
507   public Polygon createPolygon(LinearRing shell) {
508     return createPolygon(shell, null);
509   }
510   
511   /**
512    * Constructs an empty {@link Polygon} geometry.
513    * 
514    * @return an empty polygon
515    */
516   public Polygon createPolygon() {
517     return createPolygon(nullnull);
518   }
519  
520   /**
521    *  Build an appropriate <code>Geometry</code>, <code>MultiGeometry</code>, or
522    *  <code>GeometryCollection</code> to contain the <code>Geometry</code>s in
523    *  it.
524    * For example:<br>
525    *
526    *  <ul>
527    *    <li> If <code>geomList</code> contains a single <code>Polygon</code>,
528    *    the <code>Polygon</code> is returned.
529    *    <li> If <code>geomList</code> contains several <code>Polygon</code>s, a
530    *    <code>MultiPolygon</code> is returned.
531    *    <li> If <code>geomList</code> contains some <code>Polygon</code>s and
532    *    some <code>LineString</code>s, a <code>GeometryCollection</code> is
533    *    returned.
534    *    <li> If <code>geomList</code> is empty, an empty <code>GeometryCollection</code>
535    *    is returned
536    *  </ul>
537    *
538    * Note that this method does not "flatten" Geometries in the input, and hence if
539    * any MultiGeometries are contained in the input a GeometryCollection containing
540    * them will be returned.
541    *
542    *@param  geomList  the <code>Geometry</code>s to combine
543    *@return           a <code>Geometry</code> of the "smallest", "most
544    *      type-specific" class that can contain the elements of <code>geomList</code>
545    *      .
546    */
547   public Geometry buildGeometry(Collection geomList) {
548       
549       /**
550        * Determine some facts about the geometries in the list
551        */
552     Class geomClass = null;
553     boolean isHeterogeneous = false;
554     boolean hasGeometryCollection = false;
555     for (Iterator i = geomList.iterator(); i.hasNext(); ) {
556       Geometry geom = (Geometry) i.next();
557       Class partClass = geom.getClass();
558       if (geomClass == null) {
559         geomClass = partClass;
560       }
561       if (partClass != geomClass) {
562         isHeterogeneous = true;
563       }
564       if (geom instanceof GeometryCollection)
565         hasGeometryCollection = true;
566     }
567     
568     /**
569      * Now construct an appropriate geometry to return
570      */
571     // for the empty geometry, return an empty GeometryCollection
572     if (geomClass == null) {
573       return createGeometryCollection();
574     }
575     if (isHeterogeneous || hasGeometryCollection) {
576       return createGeometryCollection(toGeometryArray(geomList));
577     }
578     // at this point we know the collection is hetereogenous.
579     // Determine the type of the result from the first Geometry in the list
580     // this should always return a geometry, since otherwise an empty collection would have already been returned
581     Geometry geom0 = (Geometry) geomList.iterator().next();
582     boolean isCollection = geomList.size() > 1;
583     if (isCollection) {
584       if (geom0 instanceof Polygon) {
585         return createMultiPolygon(toPolygonArray(geomList));
586       }
587       else if (geom0 instanceof LineString) {
588         return createMultiLineString(toLineStringArray(geomList));
589       }
590       else if (geom0 instanceof Point) {
591         return createMultiPoint(toPointArray(geomList));
592       }
593       Assert.shouldNeverReachHere("Unhandled class: " + geom0.getClass().getName());
594     }
595     return geom0;
596   }
597   
598   /**
599    * Constructs an empty {@link LineString} geometry.
600    * 
601    * @return an empty LineString
602    */
603   public LineString createLineString() {
604     return createLineString(getCoordinateSequenceFactory().create(new Coordinate[]{}));
605   }
606  
607   /**
608    * Creates a LineString using the given Coordinates.
609    * A null or empty array creates an empty LineString. 
610    * 
611    * @param coordinates an array without null elements, or an empty array, or null
612    */
613   public LineString createLineString(Coordinate[] coordinates) {
614     return createLineString(coordinates != null ? getCoordinateSequenceFactory().create(coordinates) : null);
615   }
616   /**
617    * Creates a LineString using the given CoordinateSequence.
618    * A null or empty CoordinateSequence creates an empty LineString. 
619    * 
620    * @param coordinates a CoordinateSequence (possibly empty), or null
621    */
622   public LineString createLineString(CoordinateSequence coordinates) {
623     return new LineString(coordinates, this);
624   }
625  
626   /**
627    * Creates an empty atomic geometry of the given dimension.
628    * If passed a dimension of -1 will create an empty {@link GeometryCollection}.
629    * 
630    * @param dimension the required dimension (-1, 0, 1 or 2)
631    * @return an empty atomic geometry of given dimension
632    */
633   public Geometry createEmpty(int dimension) {
634     switch (dimension) {
635     case -1return createGeometryCollection();
636     case 0return createPoint();
637     case 1return createLineString();
638     case 2return createPolygon();
639     default:
640       throw new IllegalArgumentException("Invalid dimension: " + dimension);
641     }
642   }
643   
644   /**
645    * Creates a deep copy of the input {@link Geometry}.
646    * The {@link CoordinateSequenceFactory} defined for this factory
647    * is used to copy the {@link CoordinateSequence}s
648    * of the input geometry.
649    * <p>
650    * This is a convenient way to change the <tt>CoordinateSequence</tt>
651    * used to represent a geometry, or to change the 
652    * factory used for a geometry.
653    * <p>
654    * {@link Geometry#copy()} can also be used to make a deep copy,
655    * but it does not allow changing the CoordinateSequence type.
656    * 
657    * @return a deep copy of the input geometry, using the CoordinateSequence type of this factory
658    * 
659    * @see Geometry#copy() 
660    */
661   public Geometry createGeometry(Geometry g)
662   {
663     GeometryEditor editor = new GeometryEditor(this);
664     return editor.edit(g, new CoordSeqCloneOp(coordinateSequenceFactory));
665   }
666  
667   private static class CoordSeqCloneOp extends GeometryEditor.CoordinateSequenceOperation {
668     CoordinateSequenceFactory coordinateSequenceFactory;
669     public CoordSeqCloneOp(CoordinateSequenceFactory coordinateSequenceFactory) {
670       this.coordinateSequenceFactory = coordinateSequenceFactory;
671     }
672     public CoordinateSequence edit(CoordinateSequence coordSeq, Geometry geometry) {
673       return coordinateSequenceFactory.create(coordSeq);
674     }
675   }
676  
677   /**
678    * Gets the SRID value defined for this factory.
679    * 
680    * @return the factory SRID value
681    */
682   public int getSRID() {
683     return SRID;
684   }
685  
686   private int SRID;
687  
688   public CoordinateSequenceFactory getCoordinateSequenceFactory() {
689     return coordinateSequenceFactory;
690   }
691  
692 }
693  
694