Skip to content

Commit

Permalink
[GEOS-8965] Simplify GeoJSON builder measures (M) encoding code (#3155)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuno Oliveira committed Oct 8, 2018
1 parent c3b2d8b commit 5359892
Showing 1 changed file with 52 additions and 55 deletions.
107 changes: 52 additions & 55 deletions src/wfs/src/main/java/org/geoserver/wfs/json/GeoJSONBuilder.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.util.logging.Logger; import java.util.logging.Logger;
import net.sf.json.JSONException; import net.sf.json.JSONException;
import net.sf.json.util.JSONBuilder; import net.sf.json.util.JSONBuilder;
import org.geotools.geometry.jts.coordinatesequence.CoordinateSequences;
import org.geotools.referencing.CRS; import org.geotools.referencing.CRS;
import org.geotools.util.Converters; import org.geotools.util.Converters;
import org.locationtech.jts.geom.CoordinateSequence; import org.locationtech.jts.geom.CoordinateSequence;
Expand Down Expand Up @@ -126,63 +125,40 @@ private JSONBuilder writeGeomCollection(GeometryCollection collection) {
return this.endArray(); return this.endArray();
} }


/**
* Helper method that encodes a {@see Point} coordinate to the JSON output. This method will
* respect the configured axis order. If activated, coordinates measures (M) will be encoded,
* otherwise measures will be ignored.
*
* @param point the point whose coordinate will be encoded
* @return the JSON builder instance, this allow chained calls
*/
private JSONBuilder writeCoordinate(Point point) throws JSONException { private JSONBuilder writeCoordinate(Point point) throws JSONException {
CoordinateSequence seq = point.getCoordinateSequence(); CoordinateSequence coordinates = point.getCoordinateSequence();
if (!seq.hasM() || !encodeMeasures) { // let's see if we need to encode measures, NaN values will not be encoded
if (seq.hasZ()) { double m = encodeMeasures ? coordinates.getM(0) : Double.NaN;
return writeCoordinate(seq.getX(0), seq.getY(0), seq.getZ(0)); return writeCoordinate(coordinates.getX(0), coordinates.getY(0), coordinates.getZ(0), m);
} else {
return writeCoordinate(seq.getX(0), seq.getY(0));
}
} else {
if (seq.hasZ()) {
return writeCoordinate(seq.getX(0), seq.getY(0), seq.getZ(0), seq.getM(0));
} else {
return writeCoordinate(seq.getX(0), seq.getY(0), 0, seq.getM(0));
}
}
} }


/** /**
* Write the coordinates of a geometry * Helper method that encodes a sequence of coordinates to the JSON output as an array. This
* method will respect the configured axis order. If activated, coordinates measures (M) will be
* encoded, otherwise measures will be ignored.
* *
* @param coords The coordinates to write * @param coordinates the coordinates sequence that will be encoded
* @return this * @return the JSON builder instance, this allow chained calls
* @throws JSONException
*/ */
private JSONBuilder writeCoordinates(CoordinateSequence coords) throws JSONException { private JSONBuilder writeCoordinates(CoordinateSequence coordinates) throws JSONException {
// start encoding the JSON array of coordinates
this.array(); this.array();

// each coordinate will be encoded has an array of ordinates
// guess the dimension of the coordinate sequence for (int i = 0; i < coordinates.size(); i++) {
int dim = CoordinateSequences.coordinateDimension(coords); // let's see if we need to encode measures, NaN values will not be encoded
// measure double m = encodeMeasures ? coordinates.getM(i) : Double.NaN;
int measures = coords.getMeasures(); // encode the coordinate ordinates to the JSON output
int dimension = coords.getDimension(); writeCoordinate(coordinates.getX(i), coordinates.getY(i), coordinates.getZ(i), m);

final int coordCount = coords.size();
for (int i = 0; i < coordCount; i++) {
// if has not measures coordinate
if (measures == 0 || !encodeMeasures) {
if (dim > 2) {
writeCoordinate(coords.getX(i), coords.getY(i), coords.getOrdinate(i, 2));
} else {
writeCoordinate(coords.getX(i), coords.getY(i));
}
} else {
// if is XYZM
if (dimension - measures > 2) {
writeCoordinate(
coords.getX(i),
coords.getY(i),
coords.getOrdinate(i, 2),
coords.getOrdinate(i, 3));
} else {
// if is XYM -> fill Z with 0
writeCoordinate(coords.getX(i), coords.getY(i), 0, coords.getOrdinate(i, 2));
}
}
} }

// we are done with the array
return this.endArray(); return this.endArray();
} }


Expand All @@ -194,23 +170,44 @@ private JSONBuilder writeCoordinate(double x, double y, double z) {
return writeCoordinate(x, y, z, Double.NaN); return writeCoordinate(x, y, z, Double.NaN);
} }


/**
* Helper method that will encode the provided coordinate values. The order the {@code X} and
* {@code Y} coordinates will be encoded will depend on the configured axis order.
*
* <p>If both provided {@code Z} or {@code M} values are {@code NaN} they will not be encoded.
* If a valid {@code M} value was provided but {@code Z} is {@code NaN}, zero (0) will be used
* for {@code Z}.
*
* @param x X ordinate
* @param y X ordinate
* @param z Z ordinate, can be {@code NaN}
* @param m M ordinate, can be {@code NaN}
* @return the JSON builder instance, this allow chained calls
*/
private JSONBuilder writeCoordinate(double x, double y, double z, double m) { private JSONBuilder writeCoordinate(double x, double y, double z, double m) {
// start encoding JSON array
this.array(); this.array();
// adjust the order of X and Y ordinates if needed
if (axisOrder == CRS.AxisOrder.NORTH_EAST) { if (axisOrder == CRS.AxisOrder.NORTH_EAST) {
// encode latitude first and then longitude
roundedValue(y); roundedValue(y);
roundedValue(x); roundedValue(x);
} else { } else {
// encode longitude first and then latitude
roundedValue(x); roundedValue(x);
roundedValue(y); roundedValue(y);
} }
// if Z value is not available but we have a measure, we set Z value to zero
z = Double.isNaN(z) && !Double.isNaN(m) ? 0 : z;
// encode Z value if available
if (!Double.isNaN(z)) { if (!Double.isNaN(z)) {
roundedValue(z); roundedValue(z);
// measure value
if (!Double.isNaN(m)) {
roundedValue(m);
}
} }

// encode M value if available
if (!Double.isNaN(m)) {
roundedValue(m);
}
// we are done with the array
return this.endArray(); return this.endArray();
} }


Expand Down

0 comments on commit 5359892

Please sign in to comment.