/** * Creates a projected 2D position token. * * @param x x or easting * @param y y or northing * @return a projected 2D PosToken */ public static C2D c(double x, double y) { return new C2D(x, y); }
/** * Returns the coordinate for EAST (WEST) axis direction * * @return the coordinate for EAST (WEST) axis direction */ public double getX() { return getCoordinate(0); }
/** * Adds two <code>Position</code>s. * <p/> * <p>If any of the parameters are 2D, the operation is performed in 2D.</p> * * @param p0 first operand * @param p1 second operand * @return the sum of p0 and p1. */ public static <P extends C2D> P add(P p0, P p1) { int dim = p0.getCoordinateDimension(); double[] result = new double[dim]; for (int i = 0; i < dim; i++) { result[i] = p0.getCoordinate(i) + p1.getCoordinate(i); } return (P) Positions.mkPosition(p0.getClass(), result); }
/** * Returns the dot-product of the specified <code>Position</code>s * <p/> * * @param p0 first operand * @param p1 second operand * @return the dot-product of p0 and p1. */ public static <P extends C2D> double dot(P p0, P p1) { if (p0.isEmpty() || p1.isEmpty()) return Double.NaN; return p0.getX() * p1.getX() + p0.getY() * p1.getY(); }
@Override public void visit(Point<P> point) { // Note that this is also used when visiting MultiPoints P pos = point.getPosition(); double dts = Math.hypot(pos.getX() - searchPosition.getX(), pos.getY() - searchPosition.getY()); if (dts <= distToSearchPoint) { mValue = point.getPosition().getM(); distToSearchPoint = dts; } }
/** * Hill's "perp" operator. * <p>The application of this operator on a vector <code>P</code> returns the vector perpendicular at 90 deg. * counterclockwise * from <code>P</code> in the 2D (X/Y) plane.</p> * * @param p a vector represented by a Position. * @return the vector perpendicular to p in the 2D-plane, at 90 deg. counterclockwise. */ public static <P extends C2D> P perp(P p) { if (p == null || p.isEmpty()) return p; double[] crds = p.toArray(null); double h = crds[0]; crds[0] = -crds[1]; crds[1] = h; return (P) Positions.mkPosition(p.getClass(), crds); }
private P addIfNotEqualLast(P lastPoint, P newPnt) { assert (newPnt != null); if (!newPnt.equals(lastPoint)) { currentBuilder.add(newPnt); lastPoint = newPnt; } return lastPoint; }
/** * Applies the perp dot-operation on the specified <code>Position</code>s * <p/> * <p>The perp dot operation on vectors <code>P</code>, <code>Q</code> is defined as * <code>dot(perp(P),Q)</code>.</p> * <p/> * <p>This operation will be performed in 2D only.</p> * * @param p0 first operand * @param p1 second operand * @return the Perp dot of p0 and p1. */ public static <P extends C2D> double perpDot(P p0, P p1) { if (p0 == null || p1 == null || p0.isEmpty() | p1.isEmpty()) { throw new IllegalArgumentException("Null or empty Position passed."); } return -p0.getY() * p1.getX() + p0.getX() * p1.getY(); }
/** * Returns the Morton code for the specified {@code Point}. * * @param pos an {@code Point} value. * @return the morton code for the specified {@code Point} value. * @throws IllegalArgumentException if the value of the point parameter is null, or is not contained in * the spatial extent of this instance's {@code MortonContext} */ public String ofPosition(P pos) { //check inputs checkForNull(pos); checkWithinExtent(pos); int col = getCol(pos.getX()); int row = getRow(pos.getY()); long interleaved = interleave(col, row); return pointMortonCodeAsString(interleaved); }
/** * Returns the coordinate for NORTH (SOUTH) axis direction * * @return the coordinate for NORTH (SOUTH) axis direction */ public double getY() { return getCoordinate(1); }
/** * Subtracts two <code>Position</code>s. * <p/> * <p>If any of the parameters are 2D, the operation is performed in 2D.</p> * * @param p0 first operand * @param p1 second operand * @return the Position x = p0 - p1. */ public static <P extends C2D> P substract(P p0, P p1) { int dim = p0.getCoordinateDimension(); double[] result = new double[dim]; for (int i = 0; i < dim; i++) { result[i] = p0.getCoordinate(i) - p1.getCoordinate(i); } return (P) Positions.mkPosition(p0.getClass(), result); }
/** * Returns the minimum X-coordinate of the extent * * @return the minimum X-coordinate of the extent */ public double getMinX() { return extent.lowerLeft().getCoordinate(0); } /**
/** * Returns the minimum Y-coordinate of the extent * * @return the minimum Y-coordinate of the extent */ public double getMinY() { return extent.lowerLeft().getCoordinate(1); }
/** * Returns the maximum X-coordinate of the extent. * * @return the maximum X-coordinate of the extent */ public double getMaxX() { return extent.upperRight().getCoordinate(0); }
/** * Returns the maximum Y-coordinate of the extent. * * @return the maximum Y-coordinate of the extent */ public double getMaxY() { return extent.upperRight().getCoordinate(1); }
private P interpolate(P p0, P p1, double r) { int dim = getCrs().getCoordinateDimension(); double result[] = new double[dim]; for (int i = 0; i < dim; i++) { result[i] = p0.getCoordinate(i) + r * (p1.getCoordinate(i) - p0.getCoordinate(i)); } return Positions.mkPosition(getCrs(), result); }
/** * Returns the Morton code for the specified {@code Envelope}. * * @param envelope an {@code Envelope} value. * @return the morton code for the specified {@code Envelope} value. * @throws IllegalArgumentException if the value of the envelope parameter is null, or is not contained in * the spatial extent of this instance's {@code MortonContext} */ public String ofEnvelope(Envelope<P> envelope) { checkForNull(envelope); checkWithinExtent(envelope); // recalculate the X,Y coordinates to grid-cell coordinates. These are // the row,column-indices of grid formed by the (lowest-level) leaves // of the Quadtree int colMin = getCol(envelope.lowerLeft().getCoordinate(0)); int rowMin = getRow(envelope.lowerLeft().getCoordinate(1)); int colMax = getCol(envelope.upperRight().getCoordinate(0)); int rowMax = getRow(envelope.upperRight().getCoordinate(1)); int[] cols = {colMin, colMax}; int[] rows = {rowMin, rowMax}; // interleave the binary representation of the grid-cell coordinates long[] interLeaved = {0L, 0L}; for (int i = 0; i < 2; i++) { interLeaved[i] = interleave(cols[i], rows[i]); } //return the common prefix return commonMortonCodePrefixAsString(interLeaved[0], interLeaved[1]); }
private Envelope<P> envelopeOf(String mortoncode, int index, Envelope<P> extent) { assert (extent != null); if (index >= mortoncode.length()) { return extent; } char c = mortoncode.charAt(index); double minX = extent.lowerLeft().getCoordinate(0); double minY = extent.lowerLeft().getCoordinate(1); double w = (extent.extentAlongDimension(0)) / 2.0; double h = (extent.extentAlongDimension(1)) / 2.0; CoordinateReferenceSystem<P> crs = extent.getCoordinateReferenceSystem(); switch (c) { case '0': return envelopeOf(mortoncode, ++index, new Envelope<P>(minX, minY, minX + w, minY + h, crs)); case '1': return envelopeOf(mortoncode, ++index, new Envelope<P>(minX, minY + h, minX + w, minY + 2 * h, crs)); case '2': return envelopeOf(mortoncode, ++index, new Envelope<P>(minX + w, minY, minX + 2 * w, minY + h, crs)); case '3': return envelopeOf(mortoncode, ++index, new Envelope<P>(minX + w, minY + h, minX + 2 * w, minY + 2 * h, crs)); default: //this can only be a programming error! throw new IllegalStateException("Received a mortoncode element that is not 0, 1, 2 or 3."); } }