Closed Kirintale closed 2 years ago
Nice catch, I think it might be something to consider for the future. I have no currently planned free time to implement this myself though.
No worries. I just did a fork and a quick fix, to convert JTS to GeoJson (but not the reverse yet).
The code is detailed below. I'll update the fork and link to it when I work out how ^_^. Please excuse the bad naming conventions it was a rush job. But here are the correction required.
package org.wololo.jts2geojson;
import com.vividsolutions.jts.algorithm.CGAlgorithms;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateArrays;
public class GeoJsonCoordinateUtilities {
/**
* Rotates if necessary JTS coordinates for conversion to a GeoJson object. This is required as GeoJson expects
* outer contours to be anti-clockwise and holes to be clockwise. JTS expects outer contours to be clockwise and
* holes to be anti-clockwise
*
* @param coordinates
* the polygon coordinates from a JTS object
* @param representsHole
* true if the coordinates represent a hole.
* @return polygon coordinates ready to be applied to GeoJson objects
*/
public static Coordinate[] correctPolygonCoordinateRotation(final Coordinate[] coordinates,
final boolean representsHole) {
if (isAntiClockwise(coordinates)) {
// If the coordiantes are anti-clockwise, but they should represent a hole. Reverse their direction.
if (representsHole) {
CoordinateArrays.reverse(coordinates);
}
} else {
// If the coordiantes are clockwise, but they should not represent a hole. Reverse their direction.
if (!representsHole) {
CoordinateArrays.reverse(coordinates);
}
}
return coordinates;
}
/**
* Checks if the co-ordinates are anti-clockwise.
*
* @param coordinates
* The co-ordinates to test.
* @return True if it is anti-clockwise.
*/
public static boolean isAntiClockwise(final Coordinate[] coordinates) {
return CGAlgorithms.isCCW(coordinates);
}
}
In GeoJsonWriter
org.wololo.geojson.Polygon convert(Polygon polygon) {
int size = polygon.getNumInteriorRing() + 1;
double[][][] rings = new double[size][][];
final Coordinate[] coordinates = polygon.getExteriorRing().getCoordinates();
rings[0] = convert(GeoJsonCoordinateUtilities.correctPolygonCoordinateRotation(coordinates, false));
for (int i = 0; i < size - 1; i++) {
final Coordinate[] holeCoordinates = polygon.getInteriorRingN(i).getCoordinates();
rings[i + 1] = convert(GeoJsonCoordinateUtilities.correctPolygonCoordinateRotation(holeCoordinates, true));
}
return new org.wololo.geojson.Polygon(rings);
}
Looks promising. Too bad there doesn't seem to be a force right hand rule or such in JTS. If you can make your fork into a reviewable PR I'll take a look when possible.
Yeah agreed.
https://github.com/Kirintale/jts2geojson
Is a link to my fork. How do I make it a reviewable PR?
One thing I should mention. On my fork I stripped back your pom file so it worked on my machine. Those changes you could likely ignore.
@Kirintale you would have to clean your repository from changes that don't belong to this problem, i.e. in a branch. And than you can easily create a pull see: https://help.github.com/articles/creating-a-pull-request/ If you are no longer interested I could maybe find some time to work on this.
Closing due to lack of activity.
Hi,
Thank you for writing this tool. I've been trying to use your tool for a polygon with a hole in it. Testing the result at (http://geojsonlint.com/).
In JTS polygons are declared such that the exterior contour will be clockwise and the holes will be anti-clockwise. GeoJson however operates on the opposite assumption that holes are anti-clockwise.
I don't think your code currently corrects for this deviation. Would an update be possible?
Thank you for any response.