All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.osgeo.proj4j.ProjCoordinate Maven / Gradle / Ivy

Go to download

GeoTrellis is an open source geographic data processing engine for high performance applications.

There is a newer version: 0.10.3
Show newest version
package org.osgeo.proj4j;

import java.text.DecimalFormat;


/**
 * Stores a the coordinates for a position
 * defined relative to some {@link CoordinateReferenceSystem}.
 * The coordinate is defined via X, Y, and optional Z ordinates.
 * Provides utility methods for comparing the ordinates of two positions and
 * for creating positions from Strings/storing positions as strings.
 * 

* The primary use of this class is to represent coordinate * values which are to be transformed * by a {@link CoordinateTransform}. */ public class ProjCoordinate { public static String DECIMAL_FORMAT_PATTERN = "0.0###############"; public static DecimalFormat DECIMAL_FORMAT = new DecimalFormat(DECIMAL_FORMAT_PATTERN); /** * The X ordinate for this point. *

* Note: This member variable * can be accessed directly. In the future this direct access should * be replaced with getter and setter methods. This will require * refactoring of the Proj4J code base. */ public double x; /** * The Y ordinate for this point. *

* Note: This member variable * can be accessed directly. In the future this direct access should * be replaced with getter and setter methods. This will require * refactoring of the Proj4J code base. */ public double y; /** * The Z ordinate for this point. * If this variable has the value Double.NaN * then this coordinate does not have a Z value. *

* Note: This member variable * can be accessed directly. In the future this direct access should * be replaced with getter and setter methods. This will require * refactoring of the Proj4J code base. */ public double z; /** * Creates a ProjCoordinate with default ordinate values. * */ public ProjCoordinate() { this(0.0, 0.0); } /** * Creates a ProjCoordinate using the provided double parameters. * The first double parameter is the x ordinate (or easting), * the second double parameter is the y ordinate (or northing), * and the third double parameter is the z ordinate (elevation or height). * * Valid values should be passed for all three (3) double parameters. If * you want to create a horizontal-only point without a valid Z value, use * the constructor defined in this class that only accepts two (2) double * parameters. * * @see #ProjCoordinate(double argX, double argY) */ public ProjCoordinate(double argX, double argY, double argZ) { this.x = argX; this.y = argY; this.z = argZ; } /** * Creates a ProjCoordinate using the provided double parameters. * The first double parameter is the x ordinate (or easting), * the second double parameter is the y ordinate (or northing). * This constructor is used to create a "2D" point, so the Z ordinate * is automatically set to Double.NaN. */ public ProjCoordinate(double argX, double argY) { this.x = argX; this.y = argY; this.z = Double.NaN; } /** * Create a ProjCoordinate by parsing a String in the same format as returned * by the toString method defined by this class. * * @param argToParse the string to parse */ public ProjCoordinate(String argToParse) { // Make sure the String starts with "ProjCoordinate: ". boolean startsWith = argToParse.startsWith("ProjCoordinate: "); if(startsWith == false) { IllegalArgumentException toThrow = new IllegalArgumentException ("The input string was not in the proper format."); throw toThrow; } // 15 characters should cut out "ProjCoordinate: ". String chomped = argToParse.substring(16); // Get rid of the starting and ending square brackets. String withoutFrontBracket = chomped.substring(1); // Calc the position of the last bracket. int length = withoutFrontBracket.length(); int positionOfCharBeforeLast = length - 2; String withoutBackBracket = withoutFrontBracket.substring(0, positionOfCharBeforeLast); // We should be left with just the ordinate values as strings, // separated by spaces. Split them into an array of Strings. String[] parts = withoutBackBracket.split(" "); // Get number of elements in Array. There should be two (2) elements // or three (3) elements. // If we don't have an array with two (2) or three (3) elements, // then we need to throw an exception. if(parts.length != 2) { if(parts.length != 3) { IllegalArgumentException toThrow = new IllegalArgumentException ("The input string was not in the proper format."); throw toThrow; } } // Convert strings to doubles. this.x = Double.parseDouble(parts[0]); this.y = Double.parseDouble(parts[0]); // You might not always have a Z ordinate. If you do, set it. if(parts.length == 3) { this.z = Double.parseDouble(parts[0]); } } /** * Sets the value of this coordinate to * be equal to the given coordinate's ordinates. * * @param p the coordinate to copy */ public void setValue(ProjCoordinate p) { this.x = p.x; this.y = p.y; this.z = p.z; } /** * Sets the value of this coordinate to * be equal to the given ordinates. * The Z ordinate is set to NaN. * * @param x the x ordinate * @param y the y ordinate */ public void setValue(double x, double y) { this.x = x; this.y = y; this.z = Double.NaN; } /** * Sets the value of this coordinate to * be equal to the given ordinates. * * @param x the x ordinate * @param y the y ordinate * @param z the z ordinate */ public void setValue(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public void clearZ() { z = Double.NaN; } /** * Returns a boolean indicating if the X ordinate value of the * ProjCoordinate provided as an ordinate is equal to the X ordinate * value of this ProjCoordinate. Because we are working with floating * point numbers the ordinates are considered equal if the difference * between them is less than the specified tolerance. */ public boolean areXOrdinatesEqual(ProjCoordinate argToCompare, double argTolerance) { // Subtract the x ordinate values and then see if the difference // between them is less than the specified tolerance. If the difference // is less, return true. double difference = argToCompare.x - this.x; if(difference > argTolerance) { return false; } else { return true; } } /** * Returns a boolean indicating if the Y ordinate value of the * ProjCoordinate provided as an ordinate is equal to the Y ordinate * value of this ProjCoordinate. Because we are working with floating * point numbers the ordinates are considered equal if the difference * between them is less than the specified tolerance. */ public boolean areYOrdinatesEqual(ProjCoordinate argToCompare, double argTolerance) { // Subtract the y ordinate values and then see if the difference // between them is less than the specified tolerance. If the difference // is less, return true. double difference = argToCompare.y - this.y; if(difference > argTolerance) { return false; } else { return true; } } /** * Returns a boolean indicating if the Z ordinate value of the * ProjCoordinate provided as an ordinate is equal to the Z ordinate * value of this ProjCoordinate. Because we are working with floating * point numbers the ordinates are considered equal if the difference * between them is less than the specified tolerance. * * If both Z ordinate values are Double.NaN this method will return * true. If one Z ordinate value is a valid double value and one is * Double.Nan, this method will return false. */ public boolean areZOrdinatesEqual(ProjCoordinate argToCompare, double argTolerance) { // We have to handle Double.NaN values here, because not every // ProjCoordinate will have a valid Z Value. if(Double.isNaN(z)) { if(Double.isNaN(argToCompare.z)) { // Both the z ordinate values are Double.Nan. Return true. return true; } else { // We've got one z ordinate with a valid value and one with // a Double.NaN value. Return false. return false; } } // We have a valid z ordinate value in this ProjCoordinate object. else { if(Double.isNaN(argToCompare.z)) { // We've got one z ordinate with a valid value and one with // a Double.NaN value. Return false. return false; } // If we get to this point in the method execution, we have to // z ordinates with valid values, and we need to do a regular // comparison. This is done in the remainder of the method. } // Subtract the z ordinate values and then see if the difference // between them is less than the specified tolerance. If the difference // is less, return true. double difference = argToCompare.z - this.z; if(difference > argTolerance) { return false; } else { return true; } } public boolean equals(Object other) { if (!(other instanceof ProjCoordinate)) { return false; } ProjCoordinate p = (ProjCoordinate) other; if (x != p.x) { return false; } if (y != p.y) { return false; } return true; } /** * Gets a hashcode for this coordinate. * * @return a hashcode for this coordinate */ public int hashCode() { //Algorithm from Effective Java by Joshua Bloch [Jon Aquino] int result = 17; result = 37 * result + hashCode(x); result = 37 * result + hashCode(y); return result; } /** * Computes a hash code for a double value, using the algorithm from * Joshua Bloch's book Effective Java" * * @return a hashcode for the double value */ private static int hashCode(double x) { long f = Double.doubleToLongBits(x); return (int)(f^(f>>>32)); } /** * Returns a string representing the ProjPoint in the format: * ProjCoordinate[X Y Z]. *

* Example: *

     *    ProjCoordinate[6241.11 5218.25 12.3]
     * 
*/ public String toString() { StringBuilder builder = new StringBuilder(); builder.append("ProjCoordinate["); builder.append(this.x); builder.append(" "); builder.append(this.y); builder.append(" "); builder.append(this.z); builder.append("]"); return builder.toString(); } /** * Returns a string representing the ProjPoint in the format: * [X Y] * or [X, Y, Z]. * Z is not displayed if it is NaN. *

* Example: *

     *          [6241.11, 5218.25, 12.3]
     * 
*/ public String toShortString() { StringBuilder builder = new StringBuilder(); builder.append("["); builder.append(DECIMAL_FORMAT.format(x).replace(",", ".")); builder.append(", "); builder.append(DECIMAL_FORMAT.format(y).replace(",", ".")); if (! Double.isNaN(z)) { builder.append(", "); builder.append(this.z); } builder.append("]"); return builder.toString(); } public boolean hasValidZOrdinate() { if(Double.isNaN(this.z)) { return false; } else { return true; } } /** * Indicates if this ProjCoordinate has valid X ordinate and Y ordinate * values. Values are considered invalid if they are Double.NaN or * positive/negative infinity. */ public boolean hasValidXandYOrdinates() { if(Double.isNaN(x)) { return false; } else if(Double.isInfinite(this.x) == true) { return false; } if(Double.isNaN(y)) { return false; } else if(Double.isInfinite(this.y) == true) { return false; } else { return true; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy