Details
Description
Sanjay requested a createPosition( Position ) method for GeometryFactory ... and it took me a little while to see the utility. The preceeding technique was to treat DirectPosition as a data object and call clone().
This was in error:
- DirectPosition is not defined as a data object at this time (equals and hashcode are not defined)
- DirectPosition should not be exactly copied in the case where it is a wrapper (ie Point or List<DirectPosition backed by a double array)
Proposed changed:
/**
* Makes an exact copy of this coordinate.
* @deprecated Please use PositionFactory.createPosition( position )
*/
/*{DirectPosition}*/ Object clone();
DirectPosition is however actually used in the wild - and I need to
explain what the consequences are of using clone the way it is provided.
If you
consider DirectPosition a "data object" you would expect clone() to
give you a copy that you could proceed to manipulate on your own as
needed.
When working on List<DirectPosition> backed by a double array the
instances you get back are actually thin wrappers instead. Performing a
clone on one
of these will not give you the isolation you crave.
Having a List<DirectPosition> built over top of a double array is a very
important story from a performance stand point ... worth killing clone over.
Here is a sample (untested implementation) for discussion purposes:
public List<DirectPosition> createPositionList( final double[] array, final int start, final int end ) { return new AbstractList<DirectPosition>(){ @Override public DirectPosition get( final int index ) { return new DirectPosition(){ int position = start + ( crs.getCoordinateSystem().getDimension() * index ); public CoordinateReferenceSystem getCoordinateReferenceSystem() { return crs; } public double[] getCoordinates() { double coords[] = new double[ crs.getCoordinateSystem().getDimension() ]; System.arraycopy(array, position, coords, 0, crs.getCoordinateSystem().getDimension() ); return coords; } public int getDimension() { return crs.getCoordinateSystem().getDimension(); } public double getOrdinate( int dimension ) throws IndexOutOfBoundsException { return array[position+dimension]; } public void setOrdinate( int dimension, double value ) throws IndexOutOfBoundsException { array[position+dimension] = value; } public DirectPosition getPosition() { return this; } @Override public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { return null; // ignore? } } }; } public int size() { return end-start / crs.getCoordinateSystem().getDimension(); } }; }
I would like to confirm my understanding is correct before tormenting
GeoTools with a new SNAPSHOT.
Issue Links
| This issue is related to: | ||||
| GEO-162 | Util: Drop the Clonable interface since it's almost not used. |
|
|
|
I'm fine about removing the clone() method.