@@ -381,72 +381,80 @@ public byte[] write(Geometry geom)
381381 */
382382 public void write (Geometry geom , OutStream os ) throws IOException
383383 {
384+ // evaluate the ordinates actually present in the geometry
385+ EnumSet <Ordinate > actualOutputOrdinates = this .outputOrdinates ;
386+ if (!geom .isEmpty ()) {
387+ CheckOrdinatesFilter cof = new CheckOrdinatesFilter (this .outputOrdinates );
388+ geom .apply (cof );
389+ actualOutputOrdinates = cof .getOutputOrdinates ();
390+ }
391+
384392 if (geom instanceof Point )
385- writePoint ((Point ) geom , os );
393+ writePoint ((Point ) geom , actualOutputOrdinates , os );
386394 // LinearRings will be written as LineStrings
387395 else if (geom instanceof LineString )
388- writeLineString ((LineString ) geom , os );
396+ writeLineString ((LineString ) geom , actualOutputOrdinates , os );
389397 else if (geom instanceof Polygon )
390- writePolygon ((Polygon ) geom , os );
398+ writePolygon ((Polygon ) geom , actualOutputOrdinates , os );
391399 else if (geom instanceof MultiPoint )
392400 writeGeometryCollection (WKBConstants .wkbMultiPoint ,
393- (MultiPoint ) geom , os );
401+ (MultiPoint ) geom , actualOutputOrdinates , os );
394402 else if (geom instanceof MultiLineString )
395403 writeGeometryCollection (WKBConstants .wkbMultiLineString ,
396- (MultiLineString ) geom , os );
404+ (MultiLineString ) geom , actualOutputOrdinates , os );
397405 else if (geom instanceof MultiPolygon )
398406 writeGeometryCollection (WKBConstants .wkbMultiPolygon ,
399- (MultiPolygon ) geom , os );
407+ (MultiPolygon ) geom , actualOutputOrdinates , os );
400408 else if (geom instanceof GeometryCollection )
401409 writeGeometryCollection (WKBConstants .wkbGeometryCollection ,
402- (GeometryCollection ) geom , os );
410+ (GeometryCollection ) geom , actualOutputOrdinates , os );
403411 else {
404412 Assert .shouldNeverReachHere ("Unknown Geometry type" );
405413 }
406414 }
407415
408- private void writePoint (Point pt , OutStream os ) throws IOException
416+ private void writePoint (Point pt , EnumSet < Ordinate > outputOrdinates , OutStream os ) throws IOException
409417 {
410418 writeByteOrder (os );
411- writeGeometryType (WKBConstants .wkbPoint , pt , os );
419+ writeGeometryType (WKBConstants .wkbPoint , outputOrdinates , pt , os );
412420 if (pt .getCoordinateSequence ().size () == 0 ) {
413421 // write empty point as NaNs (extension to OGC standard)
414- writeNaNs (outputDimension , os );
422+ writeNaNs (outputOrdinates , os );
415423 } else {
416- writeCoordinateSequence (pt .getCoordinateSequence (), false , os );
424+ writeCoordinateSequence (pt .getCoordinateSequence (), outputOrdinates , false , os );
417425 }
418426 }
419427
420- private void writeLineString (LineString line , OutStream os )
428+ private void writeLineString (LineString line , EnumSet < Ordinate > outputOrdinates , OutStream os )
421429 throws IOException
422430 {
423431 writeByteOrder (os );
424- writeGeometryType (WKBConstants .wkbLineString , line , os );
425- writeCoordinateSequence (line .getCoordinateSequence (), true , os );
432+ writeGeometryType (WKBConstants .wkbLineString , outputOrdinates , line , os );
433+ writeCoordinateSequence (line .getCoordinateSequence (), outputOrdinates , true , os );
426434 }
427435
428- private void writePolygon (Polygon poly , OutStream os ) throws IOException
436+ private void writePolygon (Polygon poly , EnumSet < Ordinate > outputOrdinates , OutStream os ) throws IOException
429437 {
430438 writeByteOrder (os );
431- writeGeometryType (WKBConstants .wkbPolygon , poly , os );
439+ writeGeometryType (WKBConstants .wkbPolygon , outputOrdinates , poly , os );
432440 //--- write empty polygons with no rings (OCG extension)
433441 if (poly .isEmpty ()) {
434442 writeInt (0 , os );
435443 return ;
436444 }
437445 writeInt (poly .getNumInteriorRing () + 1 , os );
438- writeCoordinateSequence (poly .getExteriorRing ().getCoordinateSequence (), true , os );
446+ writeCoordinateSequence (poly .getExteriorRing ().getCoordinateSequence (), outputOrdinates , true , os );
439447 for (int i = 0 ; i < poly .getNumInteriorRing (); i ++) {
440- writeCoordinateSequence (poly .getInteriorRingN (i ).getCoordinateSequence (), true ,
448+ writeCoordinateSequence (poly .getInteriorRingN (i ).getCoordinateSequence (), outputOrdinates , true ,
441449 os );
442450 }
443451 }
444452
445- private void writeGeometryCollection (int geometryType , GeometryCollection gc ,
453+ private void writeGeometryCollection (int geometryType , GeometryCollection gc , EnumSet < Ordinate > outputOrdinates ,
446454 OutStream os ) throws IOException
447455 {
448456 writeByteOrder (os );
449- writeGeometryType (geometryType , gc , os );
457+ writeGeometryType (geometryType , outputOrdinates , gc , os );
450458 writeInt (gc .getNumGeometries (), os );
451459 boolean originalIncludeSRID = this .includeSRID ;
452460 this .includeSRID = false ;
@@ -465,7 +473,7 @@ private void writeByteOrder(OutStream os) throws IOException
465473 os .write (buf , 1 );
466474 }
467475
468- private void writeGeometryType (int geometryType , Geometry g , OutStream os )
476+ private void writeGeometryType (int geometryType , EnumSet < Ordinate > outputOrdinates , Geometry g , OutStream os )
469477 throws IOException
470478 {
471479 int ordinals = 0 ;
@@ -492,18 +500,20 @@ private void writeInt(int intValue, OutStream os) throws IOException
492500 os .write (buf , 4 );
493501 }
494502
495- private void writeCoordinateSequence (CoordinateSequence seq , boolean writeSize , OutStream os )
503+ private void writeCoordinateSequence (CoordinateSequence seq , EnumSet < Ordinate > outputOrdinates , boolean writeSize , OutStream os )
496504 throws IOException
497505 {
498506 if (writeSize )
499507 writeInt (seq .size (), os );
500508
509+ boolean hasZ = outputOrdinates .contains (Ordinate .Z );
510+ boolean hasM = outputOrdinates .contains (Ordinate .M );
501511 for (int i = 0 ; i < seq .size (); i ++) {
502- writeCoordinate (seq , i , os );
512+ writeCoordinate (seq , hasZ , hasM , i , os );
503513 }
504514 }
505515
506- private void writeCoordinate (CoordinateSequence seq , int index , OutStream os )
516+ private void writeCoordinate (CoordinateSequence seq , boolean hasZ , boolean hasM , int index , OutStream os )
507517 throws IOException
508518 {
509519 ByteOrderValues .putDouble (seq .getX (index ), buf , byteOrder );
@@ -512,25 +522,26 @@ private void writeCoordinate(CoordinateSequence seq, int index, OutStream os)
512522 os .write (buf , 8 );
513523
514524 // only write 3rd dim if caller has requested it for this writer
515- if (outputDimension >= 3 ) {
525+ if (hasZ ) {
516526 // if 3rd dim is requested, only write it if the CoordinateSequence provides it
517- double ordVal = seq .getOrdinate (index , 2 );
527+ double ordVal = seq .getZ (index );
518528 ByteOrderValues .putDouble (ordVal , buf , byteOrder );
519529 os .write (buf , 8 );
520530 }
521531 // only write 4th dim if caller has requested it for this writer
522- if (outputDimension == 4 ) {
532+ if (hasM ) {
523533 // if 4th dim is requested, only write it if the CoordinateSequence provides it
524- double ordVal = seq .getOrdinate (index , 3 );
534+ double ordVal = seq .getM (index );
525535 ByteOrderValues .putDouble (ordVal , buf , byteOrder );
526536 os .write (buf , 8 );
527537 }
528538 }
529539
530- private void writeNaNs (int numNaNs , OutStream os )
540+ private void writeNaNs (EnumSet < Ordinate > outputOrdinates , OutStream os )
531541 throws IOException
532542 {
533- for (int i = 0 ; i < numNaNs ; i ++) {
543+ int dims = outputOrdinates .size ();
544+ for (int i = 0 ; i < dims ; i ++) {
534545 ByteOrderValues .putDouble (Double .NaN , buf , byteOrder );
535546 os .write (buf , 8 );
536547 }
0 commit comments