public int CompareTo(ProjCoordinate other) { if (Equals(other)) { return(0); } if (!CoordinateChecker.AreXOrdinatesEqual(this, other, 0)) { return(X < other.X ? -1 : 1); } if (!CoordinateChecker.AreYOrdinatesEqual(this, other, 0)) { return(Y < other.Y ? -1 : 1); } if (CoordinateChecker.HasValidZOrdinate(this)) { if (!CoordinateChecker.HasValidZOrdinate(other)) { return(-1); } return(Z < other.Z ? -1 : 1); } if (CoordinateChecker.HasValidZOrdinate(other)) { return(Z < other.Z ? -1 : 1); } return(0); }
public bool Equals3D(ProjCoordinate other) { if (!Equals2D(other)) { return(false); } return(CoordinateChecker.AreZOrdinatesEqual(this, other, 0)); }
/** * Converts geodetic coordinates * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), * according to the current ellipsoid parameters. * * Latitude : Geodetic latitude in radians (input) * Longitude : Geodetic longitude in radians (input) * Height : Geodetic height, in meters (input) * * X : Calculated Geocentric X coordinate, in meters (output) * Y : Calculated Geocentric Y coordinate, in meters (output) * Z : Calculated Geocentric Z coordinate, in meters (output) * */ public void ConvertGeodeticToGeocentric(Coordinate p) { double longitude = p.X; double latitude = p.Y; double height = CoordinateChecker.HasValidZOrdinate(p) ? p.Z : 0; //Z value not always supplied double X; // output double Y; double Z; double Rn; /* Earth radius at location */ double Sin_Lat; /* Math.sin(Latitude) */ double Sin2_Lat; /* Square of Math.sin(Latitude) */ double Cos_Lat; /* Math.cos(Latitude) */ /* ** Don't blow up if Latitude is just a little out of the value ** range as it may just be a rounding issue. Also removed longitude ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001. */ if (latitude < -ProjectionMath.PiHalf && latitude > -1.001 * ProjectionMath.PiHalf) { latitude = -ProjectionMath.PiHalf; } else if (latitude > ProjectionMath.PiHalf && latitude < 1.001 * ProjectionMath.PiHalf) { latitude = ProjectionMath.PiHalf; } else if ((latitude < -ProjectionMath.PiHalf) || (latitude > ProjectionMath.PiHalf)) { /* Latitude out of range */ //throw new IllegalStateException(); throw new ArgumentException("Latitude is out of range: " + latitude, "p.Y"); } if (longitude > ProjectionMath.Pi) { longitude -= (2 * ProjectionMath.Pi); } Sin_Lat = Math.Sin(latitude); Cos_Lat = Math.Cos(latitude); Sin2_Lat = Sin_Lat * Sin_Lat; Rn = _a / (Math.Sqrt(1.0e0 - _e2 * Sin2_Lat)); X = (Rn + height) * Cos_Lat * Math.Cos(longitude); Y = (Rn + height) * Cos_Lat * Math.Sin(longitude); Z = ((Rn * (1 - _e2)) + height) * Sin_Lat; p.X = X; p.Y = Y; p.Z = Z; }
/// <summary> /// Returns a string representing the ProjPoint in the format: /// <tt>[X Y]</tt> or /// <tt>[X, Y, Z]</tt>. /// Z is not displayed if it is <see cref="Double.NaN"/>. /// <para/> /// Example: /// <pre>[6241.11, 5218.25, 12.3]</pre> /// </summary> public String ToShortString() { var builder = new StringBuilder(); builder.Append("["); builder.AppendFormat(DECIMAL_FORMAT, DECIMAL_FORMAT_PATTERN, X); builder.Append(", "); builder.AppendFormat(DECIMAL_FORMAT, DECIMAL_FORMAT_PATTERN, Y); if (!CoordinateChecker.HasValidZOrdinate(this)) { builder.Append(", "); builder.AppendFormat(DECIMAL_FORMAT, DECIMAL_FORMAT_PATTERN, Z); } builder.Append("]"); return(builder.ToString()); }
public bool Equals(ProjCoordinate other) { return(CoordinateChecker.AreXOrdinatesEqual(this, other, 0) && CoordinateChecker.AreYOrdinatesEqual(this, other, 0) && CoordinateChecker.AreZOrdinatesEqual(this, other, 0)); }
public void ConvertGeocentricToGeodeticIter(Coordinate p) { /* local defintions and variables */ /* end-criterium of loop, accuracy of sin(Latitude) */ const double genau = 1.0E-12; const double genau2 = (genau * genau); const int maxiter = 30; double P; /* distance between semi-minor axis and location */ double RR; /* distance between center and location */ double CT; /* sin of geocentric latitude */ double ST; /* cos of geocentric latitude */ double RX; double RK; double RN; /* Earth radius at location */ double CPHI0; /* cos of start or old geodetic latitude in iterations */ double SPHI0; /* sin of start or old geodetic latitude in iterations */ double CPHI; /* cos of searched geodetic latitude */ double SPHI; /* sin of searched geodetic latitude */ double SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ Boolean At_Pole; /* indicates location is in polar region */ int iter; /* # of continous iteration, max. 30 is always enough (s.a.) */ double X = p.X; double Y = p.Y; double Z = CoordinateChecker.HasValidZOrdinate(p) ? p.Z : 0d; //Z value not always supplied double longitude; double latitude; double height; At_Pole = false; P = Math.Sqrt(X * X + Y * Y); RR = Math.Sqrt(X * X + Y * Y + Z * Z); /* special cases for latitude and longitude */ if (P / this._a < genau) { /* special case, if P=0. (X=0., Y=0.) */ At_Pole = true; longitude = 0.0; /* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis * of ellipsoid (=center of mass), Latitude becomes PI/2 */ if (RR / this._a < genau) { latitude = ProjectionMath.PiHalf; height = -this._b; return; } } else { /* ellipsoidal (geodetic) longitude * interval: -PI < Longitude <= +PI */ longitude = Math.Atan2(Y, X); } /* -------------------------------------------------------------- * Following iterative algorithm was developped by * "Institut für Erdmessung", University of Hannover, July 1988. * Internet: www.ife.uni-hannover.de * Iterative computation of CPHI,SPHI and Height. * Iteration of CPHI and SPHI to 10**-12 radian resp. * 2*10**-7 arcsec. * -------------------------------------------------------------- */ CT = Z / RR; ST = P / RR; RX = 1.0 / Math.Sqrt(1.0 - this._e2 * (2.0 - this._e2) * ST * ST); CPHI0 = ST * (1.0 - this._e2) * RX; SPHI0 = CT * RX; iter = 0; /* loop to find sin(Latitude) resp. Latitude * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ do { iter++; RN = this._a / Math.Sqrt(1.0 - this._e2 * SPHI0 * SPHI0); /* ellipsoidal (geodetic) height */ height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - this._e2 * SPHI0 * SPHI0); RK = this._e2 * RN / (RN + height); RX = 1.0 / Math.Sqrt(1.0 - RK * (2.0 - RK) * ST * ST); CPHI = ST * (1.0 - RK) * RX; SPHI = CT * RX; SDPHI = SPHI * CPHI0 - CPHI * SPHI0; CPHI0 = CPHI; SPHI0 = SPHI; }while (SDPHI * SDPHI > genau2 && iter < maxiter); /* ellipsoidal (geodetic) latitude */ latitude = Math.Atan(SPHI / Math.Abs(CPHI)); p.X = longitude; p.Y = latitude; p.Z = height; }