@Test public void testDegenerate() throws ParseException { final LineString original = (LineString) new WKTReader().read(DEGENERATE_LS); final LineString simplified = (LineString) Utils.removeCollinearVertices(original); assertTrue(simplified.equalsExact(original)); }
public static LineString removeCollinearVertices(final LineString ls) { if (ls == null) { throw new NullPointerException("The provided linestring is null"); } final int N = ls.getNumPoints(); final boolean isLinearRing = ls instanceof LinearRing; List<Coordinate> retain = new ArrayList<Coordinate>(); retain.add(ls.getCoordinateN(0)); int i0 = 0, i1 = 1, i2 = 2; Coordinate firstCoord = ls.getCoordinateN(i0); Coordinate midCoord; Coordinate lastCoord; while (i2 < N) { midCoord = ls.getCoordinateN(i1); lastCoord = ls.getCoordinateN(i2); double dx1 = midCoord.x - firstCoord.x; double dy1 = midCoord.y - firstCoord.y; double dx2 = lastCoord.x - midCoord.x; double dy2 = lastCoord.y - midCoord.y; boolean redundant = false; if (CompareOp.isZero(dx1)) { if (CompareOp.isZero(dx2) && Math.signum(dy1) == Math.signum(dy2)) { redundant = true; } } else { if (!CompareOp.isZero(dx2)) { if (CompareOp.aequal(dy1 / dx1, dy2 / dx2) && Math.signum(dx1) == Math.signum(dx2)) { redundant = true; } } } if (!redundant) { retain.add(midCoord); i0 = i1; firstCoord = ls.getCoordinateN(i0); } i1++; i2++; } retain.add(ls.getCoordinateN(N - 1)); final int size = retain.size(); if (size == N) { retain.clear(); return ls; } return isLinearRing ? ls.getFactory().createLinearRing(retain.toArray(new Coordinate[size])) : ls.getFactory().createLineString(retain.toArray(new Coordinate[size])); }
Utils { public static LineString removeCollinearVertices(final LineString ls) { if (ls == null) { throw new NullPointerException("The provided linestring is null"); } final int N = ls.getNumPoints(); final boolean isLinearRing = ls instanceof LinearRing; List<Coordinate> retain = new ArrayList<Coordinate>(); retain.add(ls.getCoordinateN(0)); int i0 = 0, i1 = 1, i2 = 2; Coordinate firstCoord = ls.getCoordinateN(i0); Coordinate midCoord; Coordinate lastCoord; while (i2 < N) { midCoord = ls.getCoordinateN(i1); lastCoord = ls.getCoordinateN(i2); double dx1 = midCoord.x - firstCoord.x; double dy1 = midCoord.y - firstCoord.y; double dx2 = lastCoord.x - midCoord.x; double dy2 = lastCoord.y - midCoord.y; boolean redundant = false; if (CompareOp.isZero(dx1)) { if (CompareOp.isZero(dx2) && Math.signum(dy1) == Math.signum(dy2)) { redundant = true; } } else { if (!CompareOp.isZero(dx2)) { if (CompareOp.aequal(dy1 / dx1, dy2 / dx2) && Math.signum(dx1) == Math.signum(dx2)) { redundant = true; } } } if (!redundant) { retain.add(midCoord); i0 = i1; firstCoord = ls.getCoordinateN(i0); } i1++; i2++; } retain.add(ls.getCoordinateN(N - 1)); final int size = retain.size(); if (size == N) { retain.clear(); return ls; } return isLinearRing ? ls.getFactory().createLinearRing(retain.toArray(new Coordinate[size])) : ls.getFactory().createLineString(retain.toArray(new Coordinate[size])); } }
Utils { public static LineString removeCollinearVertices(final LineString ls) { if (ls == null) { throw new NullPointerException("The provided linestring is null"); } final int N = ls.getNumPoints(); final boolean isLinearRing = ls instanceof LinearRing; List<Coordinate> retain = new ArrayList<Coordinate>(); retain.add(ls.getCoordinateN(0)); int i0 = 0, i1 = 1, i2 = 2; Coordinate firstCoord = ls.getCoordinateN(i0); Coordinate midCoord; Coordinate lastCoord; while (i2 < N) { midCoord = ls.getCoordinateN(i1); lastCoord = ls.getCoordinateN(i2); double dx1 = midCoord.x - firstCoord.x; double dy1 = midCoord.y - firstCoord.y; double dx2 = lastCoord.x - midCoord.x; double dy2 = lastCoord.y - midCoord.y; boolean redundant = false; if (CompareOp.isZero(dx1)) { if (CompareOp.isZero(dx2) && Math.signum(dy1) == Math.signum(dy2)) { redundant = true; } } else { if (!CompareOp.isZero(dx2)) { if (CompareOp.aequal(dy1 / dx1, dy2 / dx2) && Math.signum(dx1) == Math.signum(dx2)) { redundant = true; } } } if (!redundant) { retain.add(midCoord); i0 = i1; firstCoord = ls.getCoordinateN(i0); } i1++; i2++; } retain.add(ls.getCoordinateN(N - 1)); final int size = retain.size(); if (size == N) { retain.clear(); return ls; } return isLinearRing ? ls.getFactory().createLinearRing(retain.toArray(new Coordinate[size])) : ls.getFactory().createLineString(retain.toArray(new Coordinate[size])); } private  Utils(); }
Utils { public static LineString removeCollinearVertices(final LineString ls) { if (ls == null) { throw new NullPointerException("The provided linestring is null"); } final int N = ls.getNumPoints(); final boolean isLinearRing = ls instanceof LinearRing; List<Coordinate> retain = new ArrayList<Coordinate>(); retain.add(ls.getCoordinateN(0)); int i0 = 0, i1 = 1, i2 = 2; Coordinate firstCoord = ls.getCoordinateN(i0); Coordinate midCoord; Coordinate lastCoord; while (i2 < N) { midCoord = ls.getCoordinateN(i1); lastCoord = ls.getCoordinateN(i2); double dx1 = midCoord.x - firstCoord.x; double dy1 = midCoord.y - firstCoord.y; double dx2 = lastCoord.x - midCoord.x; double dy2 = lastCoord.y - midCoord.y; boolean redundant = false; if (CompareOp.isZero(dx1)) { if (CompareOp.isZero(dx2) && Math.signum(dy1) == Math.signum(dy2)) { redundant = true; } } else { if (!CompareOp.isZero(dx2)) { if (CompareOp.aequal(dy1 / dx1, dy2 / dx2) && Math.signum(dx1) == Math.signum(dx2)) { redundant = true; } } } if (!redundant) { retain.add(midCoord); i0 = i1; firstCoord = ls.getCoordinateN(i0); } i1++; i2++; } retain.add(ls.getCoordinateN(N - 1)); final int size = retain.size(); if (size == N) { retain.clear(); return ls; } return isLinearRing ? ls.getFactory().createLinearRing(retain.toArray(new Coordinate[size])) : ls.getFactory().createLineString(retain.toArray(new Coordinate[size])); } private  Utils(); static GeometryFactory getGeometryFactory(); static GeometryFactory setPrecision(double scale); static LineString removeCollinearVertices(final LineString ls); static Polygon removeCollinearVertices(final Polygon polygon); static Geometry removeCollinearVertices(final Geometry g); }
Utils { public static LineString removeCollinearVertices(final LineString ls) { if (ls == null) { throw new NullPointerException("The provided linestring is null"); } final int N = ls.getNumPoints(); final boolean isLinearRing = ls instanceof LinearRing; List<Coordinate> retain = new ArrayList<Coordinate>(); retain.add(ls.getCoordinateN(0)); int i0 = 0, i1 = 1, i2 = 2; Coordinate firstCoord = ls.getCoordinateN(i0); Coordinate midCoord; Coordinate lastCoord; while (i2 < N) { midCoord = ls.getCoordinateN(i1); lastCoord = ls.getCoordinateN(i2); double dx1 = midCoord.x - firstCoord.x; double dy1 = midCoord.y - firstCoord.y; double dx2 = lastCoord.x - midCoord.x; double dy2 = lastCoord.y - midCoord.y; boolean redundant = false; if (CompareOp.isZero(dx1)) { if (CompareOp.isZero(dx2) && Math.signum(dy1) == Math.signum(dy2)) { redundant = true; } } else { if (!CompareOp.isZero(dx2)) { if (CompareOp.aequal(dy1 / dx1, dy2 / dx2) && Math.signum(dx1) == Math.signum(dx2)) { redundant = true; } } } if (!redundant) { retain.add(midCoord); i0 = i1; firstCoord = ls.getCoordinateN(i0); } i1++; i2++; } retain.add(ls.getCoordinateN(N - 1)); final int size = retain.size(); if (size == N) { retain.clear(); return ls; } return isLinearRing ? ls.getFactory().createLinearRing(retain.toArray(new Coordinate[size])) : ls.getFactory().createLineString(retain.toArray(new Coordinate[size])); } private  Utils(); static GeometryFactory getGeometryFactory(); static GeometryFactory setPrecision(double scale); static LineString removeCollinearVertices(final LineString ls); static Polygon removeCollinearVertices(final Polygon polygon); static Geometry removeCollinearVertices(final Geometry g);  }