protected double getSegmentAngle(int segmentIdx) { if (Double.isNaN(segmentAngles[segmentIdx])) { double dx = (coords.getX(segmentIdx + 1) - coords.getX(segmentIdx)); double dy = (coords.getY(segmentIdx + 1) - coords.getY(segmentIdx)); segmentAngles[segmentIdx] = Math.atan2(dy, dx); } return segmentAngles[segmentIdx]; }
@Override public void filter(CoordinateSequence seq, int i) { seq.setOrdinate(i, CoordinateSequence.X, seq.getX(i) + xShift ); }
/** @see java.awt.geom.PathIterator#currentSegment(double[]) */ public int currentSegment(double[] coords) { if (currentCoord == 0) { coords[0] = (double) coordinates.getX(0); coords[1] = (double) coordinates.getY(0); at.transform(coords, 0, coords, 0, 1); return SEG_MOVETO; } else if ((currentCoord == coordinateCount) && isClosed) { return SEG_CLOSE; } else { coords[0] = coordinates.getX(currentCoord); coords[1] = coordinates.getY(currentCoord); at.transform(coords, 0, coords, 0, 1); return SEG_LINETO; } } }
/** * Returns the current segment direction as an angle expressed in radians * * @return */ public double getLabelOrientation() { double dx = (coords.getX(segment + 1) - coords.getX(segment)); double dy = (coords.getY(segment + 1) - coords.getY(segment)); double slope = dy / dx; double angle = Math.atan(slope); // make sure we turn PI/2 into -PI/2, we don't want some labels looking straight up // and some others straight down, when almost vertical they should all be oriented // on the same side if (Math.abs(angle - Math.PI / 2) < ONE_DEGREE) { angle = -Math.PI / 2 + Math.abs(angle - Math.PI / 2); } return angle; }
private void writeCoordinateSequence(StringBuilder sb, CoordinateSequence cs) { sb.append("("); for (int i = 0; i < cs.size(); i++) { sb.append(cs.getX(i) + " " + cs.getY(i)); if (i < cs.size() - 1) { sb.append(", "); } } sb.append(")"); }
/** * Generates the WKT for a <tt>LINESTRING</tt> specified by a {@link CoordinateSequence}. * * @param seq the sequence to write * @return the WKT string */ public static String toLineString(CoordinateSequence seq) { StringBuffer buf = new StringBuffer(); buf.append("LINESTRING "); if (seq.size() == 0) buf.append(" EMPTY"); else { buf.append("("); for (int i = 0; i < seq.size(); i++) { if (i > 0) buf.append(", "); buf.append(seq.getX(i) + " " + seq.getY(i)); } buf.append(")"); } return buf.toString(); }
private void writeRing(StringBuilder sb, LineString component) { if (component instanceof SingleCurvedGeometry<?>) { SingleCurvedGeometry<?> curved = (SingleCurvedGeometry<?>) component; sb.append(curved.toCurvedText()); } else { sb.append("("); CoordinateSequence cs = component.getCoordinateSequence(); for (int i = 0; i < cs.size(); i++) { sb.append(cs.getX(i) + " " + cs.getY(i)); if (i < cs.size() - 1) { sb.append(", "); } } sb.append(")"); } }
public Object evaluate(Object feature) { LineString ls; try { // attempt to get value and perform conversion ls = (LineString) getExpression(0).evaluate(feature, LineString.class); } catch (Exception e) { // probably a type error throw new IllegalArgumentException( "Filter Function problem for function startAngle argument #0 - expected type Geometry"); } if (ls == null || ls.getNumPoints() == 1) { return null; } CoordinateSequence cs = ls.getCoordinateSequence(); double dx = (cs.getX(1) - cs.getX(0)); double dy = (cs.getY(1) - cs.getY(0)); return -Math.toDegrees(Math.atan2(dy, dx)); } }
public String toCurvedText() { StringBuilder sb = new StringBuilder("MULTICURVE("); int numGeometries = getNumGeometries(); for (int k = 0; k < numGeometries; k++) { LineString component = (LineString) getGeometryN(k); if (component instanceof SingleCurvedGeometry<?>) { SingleCurvedGeometry<?> curved = (SingleCurvedGeometry<?>) component; sb.append(curved.toCurvedText()); } else { sb.append("("); CoordinateSequence cs = component.getCoordinateSequence(); for (int i = 0; i < cs.size(); i++) { sb.append(cs.getX(i) + " " + cs.getY(i)); if (i < cs.size() - 1) { sb.append(", "); } } sb.append(")"); } if (k < numGeometries - 1) { sb.append(", "); } } sb.append(")"); return sb.toString(); }
public CircularString(CoordinateSequence points, GeometryFactory factory, double tolerance) { super(FAKE_STRING_2D, factory); this.tolerance = tolerance; if (points.getDimension() != 2) { throw new IllegalArgumentException( "Circular strings are restricted to 2 dimensions " + "at the moment. Contributions to get ND support welcomed!"); } int pointCount = points.size(); controlPoints = new double[pointCount * 2]; for (int i = 0; i < pointCount; i++) { controlPoints[i * 2] = points.getX(i); controlPoints[i * 2 + 1] = points.getY(i); } init(controlPoints, tolerance); }
void coordinates(CoordinateSequence coordinates, char cs, char ts, StringBuffer sb) { sb.setLength(0); int n = coordinates.size(); int dim = CoordinateSequences.coordinateDimension(coordinates); for (int i = 0; i < n; i++) { coordFormatter.format(coordinates.getX(i), sb).append(cs); coordFormatter.format(coordinates.getY(i), sb); if (dim > 2) { int totalDimensions = encodeMeasures ? dim : dim - coordinates.getMeasures(); // encoding the remaining ordinates, typically Z and M values for (int j = 2; j < totalDimensions; j++) { sb.append(cs); coordFormatter.format(coordinates.getOrdinate(i, j), sb); } } sb.append(ts); } sb.setLength(sb.length() - 1); }
public Object evaluate(Object feature) { LineString ls; try { // attempt to get value and perform conversion ls = (LineString) getExpression(0).evaluate(feature, LineString.class); } catch (Exception e) { // probably a type error throw new IllegalArgumentException( "Filter Function problem for function endPoint argument #0 - expected type Geometry"); } if (ls == null || ls.getNumPoints() == 1) { return null; } CoordinateSequence cs = ls.getCoordinateSequence(); double dx = (cs.getX(cs.size() - 1) - cs.getX(cs.size() - 2)); double dy = (cs.getY(cs.size() - 1) - cs.getY(cs.size() - 2)); return -Math.toDegrees(Math.atan2(dy, dx)); } }
private void applyZValues( CoordinateSequence cs, int idx, CoordinateSequence csOrig, int origIdx) { if (!cs.hasZ()) return; double lx1 = cs.getOrdinate(idx, 0); double ly1 = cs.getOrdinate(idx, 1); double lz1; double ox1 = csOrig.getX(origIdx); double oy1 = csOrig.getY(origIdx); double oz1 = csOrig.getZ(origIdx); double ox2 = csOrig.getX(origIdx + 1); double oy2 = csOrig.getY(origIdx + 1); double oz2 = csOrig.getZ(origIdx + 1); if (lx1 == ox1 && ly1 == oy1) { lz1 = oz1; } else { double d1 = distance(ox1, oy1, lx1, ly1); double d = distance(ox1, oy1, ox2, oy2); lz1 = oz1 + (oz2 - oz1) * (d1 / d); } cs.setOrdinate(idx, 2, lz1); }
List<?> toList(CoordinateSequence cs) { BasicDBList l = new BasicDBList(); for (int i = 0; i < cs.size(); i++) { BasicDBList m = new BasicDBList(); m.add(cs.getX(i)); m.add(cs.getY(i)); l.add(m); } return l; }
@Override public void filter(CoordinateSequence seq, int i) { double x = seq.getX(i); double y = seq.getY(i); //Note: we don't simply call ctx.normX & normY because // those methods use the precisionModel, but WKTReader already // used the precisionModel. It's be nice to turn that off somehow but alas. if (ctx.isGeo() && ctx.isNormWrapLongitude()) { double xNorm = DistanceUtils.normLonDEG(x); if (Double.compare(x, xNorm) != 0) {//handles NaN changed = true; seq.setOrdinate(i, CoordinateSequence.X, xNorm); } // double yNorm = DistanceUtils.normLatDEG(y); // if (y != yNorm) { // changed = true; // seq.setOrdinate(i,CoordinateSequence.Y,yNorm); // } } ctx.verifyX(x); ctx.verifyY(y); }
private void writeCoordinate(CoordinateSequence seq, int index, OutStream os) throws IOException { ByteOrderValues.putDouble(seq.getX(index), buf, byteOrder); os.write(buf, 8); ByteOrderValues.putDouble(seq.getY(index), buf, byteOrder); os.write(buf, 8); // only write 3rd dim if caller has requested it for this writer if (outputDimension >= 3) { // if 3rd dim is requested, only access and write it if the CS provides is double ordVal = Coordinate.NULL_ORDINATE; if (seq.getDimension() >= 3) ordVal = seq.getOrdinate(index, 2); ByteOrderValues.putDouble(ordVal, buf, byteOrder); os.write(buf, 8); } }
protected CoordinateSequence getLinearizedCoordinateSequence(final double tolerance) { // collect all the points of all components final GrowableOrdinateArray gar = new GrowableOrdinateArray(); for (LineString component : components) { // the last point of the previous element is the first point of the next one, // remove the duplication if (gar.size() > 0) { gar.setSize(gar.size() - 2); } // linearize with tolerance the circular strings, take the linear ones as is if (component instanceof SingleCurvedGeometry<?>) { SingleCurvedGeometry<?> curved = (SingleCurvedGeometry<?>) component; CoordinateSequence cs = curved.getLinearizedCoordinateSequence(tolerance); gar.addAll(cs); } else { CoordinateSequence cs = component.getCoordinateSequence(); for (int i = 0; i < cs.size(); i++) { gar.add(cs.getX(i), cs.getY(i)); } } } CoordinateSequence cs = gar.toCoordinateSequence(getFactory()); return cs; }
/** Checks that the measures of XYZM geometries are not transformed. */ @Test public void testXyzmGeometriesMeasuresArePreserved() throws Exception { // build a XYM geometry and reproject it Geometry geometry = new WKTReader().read("LINESTRINGZM(170 -40 10 2, 190 40 15 7)"); MathTransform transform = CRS.findMathTransform(WGS84, MERCATOR, true); Geometry transformed = JTS.transform(geometry, transform); // check that coordinates where transformed but measures preserved assertThat(transformed, instanceOf(LineString.class)); LineString line = (LineString) transformed; assertThat(line.getCoordinateSequence().getDimension(), is(4)); assertThat(line.getCoordinateSequence().getMeasures(), is(1)); // check the first coordinate assertThat(line.getCoordinateSequence().getX(0), closeTo(1.8924313434856504E7, EPS)); assertThat(line.getCoordinateSequence().getY(0), closeTo(-4838471.398061137, EPS)); assertThat(line.getCoordinateSequence().getZ(0), is(10.0)); assertThat(line.getCoordinateSequence().getM(0), is(2.0)); // check the second coordinate assertThat(line.getCoordinateSequence().getX(1), closeTo(2.115070325072198E7, EPS)); assertThat(line.getCoordinateSequence().getY(1), closeTo(4838471.398061137, EPS)); assertThat(line.getCoordinateSequence().getZ(1), is(15.0)); assertThat(line.getCoordinateSequence().getM(1), is(7.0)); }
/** Checks that the measures of XYM geometries are not transformed. */ @Test public void testXymGeometriesMeasuresArePreserved() throws Exception { // build a XYM geometry and reproject it Geometry geometry = new WKTReader().read("LINESTRINGM(170 -40 2, 190 40 7)"); MathTransform transform = CRS.findMathTransform(WGS84, MERCATOR, true); Geometry transformed = JTS.transform(geometry, transform); // check that coordinates where transformed but measures preserved assertThat(transformed, instanceOf(LineString.class)); LineString line = (LineString) transformed; assertThat(line.getCoordinateSequence().getDimension(), is(3)); assertThat(line.getCoordinateSequence().getMeasures(), is(1)); // check the first coordinate assertThat(line.getCoordinateSequence().getX(0), closeTo(1.8924313434856504E7, EPS)); assertThat(line.getCoordinateSequence().getY(0), closeTo(-4838471.398061137, EPS)); assertThat(line.getCoordinateSequence().getZ(0), is(Double.NaN)); assertThat(line.getCoordinateSequence().getM(0), is(2.0)); // check the second coordinate assertThat(line.getCoordinateSequence().getX(1), closeTo(2.115070325072198E7, EPS)); assertThat(line.getCoordinateSequence().getY(1), closeTo(4838471.398061137, EPS)); assertThat(line.getCoordinateSequence().getZ(1), is(Double.NaN)); assertThat(line.getCoordinateSequence().getM(1), is(7.0)); }