Skip to content

Commit ee085ea

Browse files
committed
PackedCoordinateSequence separated arrays variant
1 parent 1ce7a94 commit ee085ea

3 files changed

Lines changed: 213 additions & 4 deletions

File tree

modules/core/src/main/java/org/locationtech/jts/geom/impl/PackedCoordinateSequence.java

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,186 @@ public Envelope expandEnvelope(Envelope env)
420420
}
421421
}
422422

423+
public static class Double2 extends PackedCoordinateSequence {
424+
private static final long serialVersionUID = 5777450686367912720L;
425+
426+
double[] xy;
427+
double[] z;
428+
double[] m;
429+
430+
/**
431+
* Builds a new packed coordinate sequence
432+
*
433+
* @param coords an array of <c>double</c> values that contains the ordinate values of the sequence
434+
* @param dimension the total number of ordinates that make up a {@link Coordinate} in this sequence.
435+
* @param measures the number of measure-ordinates each {@link Coordinate} in this sequence has.
436+
*/
437+
public Double2(double[] xy, double[] z, double[] m) {
438+
super(z != null ? 3 : 2, m != null ? 1 : 0);
439+
this.xy = xy;
440+
this.z = z;
441+
this.m = m;
442+
}
443+
444+
/**
445+
* Builds a new packed coordinate sequence out of a coordinate array
446+
*
447+
* @param coordinates an array of {@link Coordinate}s
448+
* @param dimension the total number of ordinates that make up a {@link Coordinate} in this sequence.
449+
*/
450+
public Double2(Coordinate[] coordinates, int dimension) {
451+
this( coordinates, dimension, Math.max(0,dimension-3));
452+
}
453+
/**
454+
* Builds a new packed coordinate sequence out of a coordinate array
455+
*
456+
* @param coordinates an array of {@link Coordinate}s
457+
* @param dimension the total number of ordinates that make up a {@link Coordinate} in this sequence.
458+
* @param measures the number of measure-ordinates each {@link Coordinate} in this sequence has.
459+
*/
460+
public Double2(Coordinate[] coordinates, int dimension, int measures) {
461+
super(dimension,measures);
462+
if (coordinates == null)
463+
coordinates = new Coordinate[0];
464+
465+
xy = new double[coordinates.length];
466+
for (int i = 0; i < coordinates.length; i++) {
467+
int offset = i * 2;
468+
xy[offset] = coordinates[i].x;
469+
xy[offset + 1] = coordinates[i].y;
470+
if (dimension == 3)
471+
z[i] = coordinates[i].getOrdinate(2);
472+
if (measures == 1)
473+
m[i] = coordinates[i].getOrdinate(3);
474+
}
475+
}
476+
/**
477+
* Builds a new packed coordinate sequence out of a coordinate array
478+
*
479+
* @param coordinates an array of {@link Coordinate}s
480+
*/
481+
public Double2(Coordinate[] coordinates) {
482+
this(coordinates, 3, 0);
483+
}
484+
485+
/**
486+
* Builds a new empty packed coordinate sequence of a given size and dimension
487+
*
488+
* @param size the number of coordinates in this sequence
489+
* @param dimension the total number of ordinates that make up a {@link Coordinate} in this sequence.
490+
* @param measures the number of measure-ordinates each {@link Coordinate} in this sequence has.
491+
*/
492+
public Double2(int size, int dimension, int measures) {
493+
super(dimension,measures);
494+
xy = new double[size * 2];
495+
if (dimension == 3)
496+
z = new double[size];
497+
if (measures == 1)
498+
m = new double[size];
499+
}
500+
501+
/**
502+
* @see PackedCoordinateSequence#getCoordinate(int)
503+
*/
504+
public Coordinate getCoordinateInternal(int i) {
505+
double x = xy[i * dimension];
506+
double y = xy[i * dimension + 1];
507+
if( dimension == 2 && measures == 0 ) {
508+
return new CoordinateXY(x,y);
509+
}
510+
else if (dimension == 3 && measures == 0) {
511+
double z = this.z[i];
512+
return new Coordinate(x,y,z);
513+
}
514+
else if (dimension == 3 && measures == 1) {
515+
double m = this.m[i];
516+
return new CoordinateXYM(x,y,m);
517+
}
518+
else if (dimension == 4) {
519+
double z = this.z[i];
520+
double m = this.m[i];
521+
return new CoordinateXYZM(x,y,z,m);
522+
}
523+
return new Coordinate(x, y);
524+
}
525+
526+
/**
527+
* Gets the underlying array containing the coordinate values.
528+
*
529+
* @return the array of coordinate values
530+
*/
531+
public double[] getRawXYCoordinates()
532+
{
533+
return xy;
534+
}
535+
536+
/**
537+
* @see CoordinateSequence#size()
538+
*/
539+
public int size() {
540+
return xy.length / 2;
541+
}
542+
543+
/**
544+
* @see java.lang.Object#clone()
545+
* @see PackedCoordinateSequence#clone()
546+
* @deprecated
547+
*/
548+
public Object clone() {
549+
return copy();
550+
}
551+
552+
/**
553+
* @see PackedCoordinateSequence#size()
554+
*/
555+
public Double2 copy() {
556+
double[] cloneXy = Arrays.copyOf(xy, xy.length);
557+
double[] cloneZ = z != null ? Arrays.copyOf(z, z.length) : null;
558+
double[] cloneM = m != null ? Arrays.copyOf(m, m.length) : null;
559+
return new Double2(cloneXy, cloneZ, cloneM);
560+
}
561+
562+
/**
563+
* @see PackedCoordinateSequence#getOrdinate(int, int)
564+
* Beware, for performance reasons the ordinate index is not checked, if
565+
* it's over dimensions you may not get an exception but a meaningless
566+
* value.
567+
*/
568+
public double getOrdinate(int index, int ordinate) {
569+
if (ordinate <= 1)
570+
return xy[index * 2 + ordinate];
571+
if (ordinate == 2)
572+
return z[index];
573+
if (ordinate == 3)
574+
return m[index];
575+
throw new RuntimeException("Ordinate must be <= 3");
576+
}
577+
578+
/**
579+
* @see PackedCoordinateSequence#setOrdinate(int, int, double)
580+
*/
581+
public void setOrdinate(int index, int ordinate, double value) {
582+
coordRef = null;
583+
if (ordinate <= 1)
584+
xy[index * 2 + ordinate] = value;
585+
if (ordinate == 2)
586+
z[index] = value;
587+
if (ordinate == 3)
588+
m[index] = value;
589+
}
590+
591+
/**
592+
* @see CoordinateSequence#expandEnvelope(Envelope)
593+
*/
594+
public Envelope expandEnvelope(Envelope env)
595+
{
596+
for (int i = 0; i < xy.length; i += 2 ) {
597+
env.expandToInclude(xy[i], xy[i + 1]);
598+
}
599+
return env;
600+
}
601+
}
602+
423603
/**
424604
* Packed coordinate sequence implementation based on floats
425605
*/

modules/core/src/main/java/org/locationtech/jts/geom/impl/PackedCoordinateSequenceFactory.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public class PackedCoordinateSequenceFactory implements
3939
*/
4040
public static final int FLOAT = 1;
4141

42+
/**
43+
* Type code for dim/measure separated arrays of type <code>double</code>.
44+
*/
45+
public static final int DOUBLE2 = 1;
46+
4247
/**
4348
* A factory using array type {@link #DOUBLE}
4449
*/
@@ -51,6 +56,12 @@ public class PackedCoordinateSequenceFactory implements
5156
public static final PackedCoordinateSequenceFactory FLOAT_FACTORY =
5257
new PackedCoordinateSequenceFactory(FLOAT);
5358

59+
/**
60+
* A factory using array type {@link #DOUBLE2}
61+
*/
62+
public static final PackedCoordinateSequenceFactory DOUBLE2_FACTORY =
63+
new PackedCoordinateSequenceFactory(DOUBLE2);
64+
5465
private static final int DEFAULT_MEASURES = 0;
5566

5667
private static final int DEFAULT_DIMENSION = 3;
@@ -100,8 +111,10 @@ public CoordinateSequence create(Coordinate[] coordinates) {
100111
}
101112
if (type == DOUBLE) {
102113
return new PackedCoordinateSequence.Double(coordinates, dimension, measures);
103-
} else {
114+
} else if (type == FLOAT) {
104115
return new PackedCoordinateSequence.Float(coordinates, dimension, measures);
116+
} else {
117+
return new PackedCoordinateSequence.Double2(coordinates, dimension, measures);
105118
}
106119
}
107120

@@ -113,8 +126,10 @@ public CoordinateSequence create(CoordinateSequence coordSeq) {
113126
int measures = coordSeq.getMeasures();
114127
if (type == DOUBLE) {
115128
return new PackedCoordinateSequence.Double(coordSeq.toCoordinateArray(), dimension, measures);
116-
} else {
129+
} else if (type == FLOAT) {
117130
return new PackedCoordinateSequence.Float(coordSeq.toCoordinateArray(), dimension, measures);
131+
} else {
132+
return new PackedCoordinateSequence.Double2(coordSeq.toCoordinateArray(), dimension, measures);
118133
}
119134
}
120135

@@ -148,6 +163,11 @@ public CoordinateSequence create(double[] packedCoordinates, int dimension, int
148163
return new PackedCoordinateSequence.Float(packedCoordinates, dimension, measures);
149164
}
150165
}
166+
167+
public CoordinateSequence create(double[] xy, double[] z, double[] m) {
168+
return new PackedCoordinateSequence.Double2(xy, z, m);
169+
}
170+
151171
/**
152172
* Creates a packed coordinate sequence of type {@link #FLOAT}
153173
* from the provided array.
@@ -184,9 +204,12 @@ public CoordinateSequence create(int size, int dimension) {
184204
if (type == DOUBLE) {
185205
return new PackedCoordinateSequence.Double(
186206
size, dimension, Math.max(DEFAULT_MEASURES, dimension-3));
187-
} else {
207+
} else if (type == FLOAT) {
188208
return new PackedCoordinateSequence.Float(
189209
size, dimension, Math.max(DEFAULT_MEASURES, dimension-3));
210+
} else {
211+
return new PackedCoordinateSequence.Double2(
212+
size, dimension, Math.max(DEFAULT_MEASURES, dimension-3));
190213
}
191214
}
192215

@@ -196,8 +219,10 @@ public CoordinateSequence create(int size, int dimension) {
196219
public CoordinateSequence create(int size, int dimension, int measures) {
197220
if (type == DOUBLE) {
198221
return new PackedCoordinateSequence.Double(size, dimension, measures);
199-
} else {
222+
} else if (type == FLOAT) {
200223
return new PackedCoordinateSequence.Float(size, dimension, measures);
224+
} else {
225+
return new PackedCoordinateSequence.Double2(size, dimension, measures);
201226
}
202227
}
203228
}

modules/core/src/test/java/org/locationtech/jts/geom/impl/PackedCoordinateSequenceTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public void testDouble() {
5151
public void testFloat() {
5252
checkAll( PackedCoordinateSequenceFactory.FLOAT_FACTORY) ;
5353
}
54+
55+
public void testDouble2() {
56+
checkAll( PackedCoordinateSequenceFactory.DOUBLE2_FACTORY) ;
57+
}
5458

5559
public void checkAll(CoordinateSequenceFactory factory)
5660
{

0 commit comments

Comments
 (0)