/* **-------------------------------------------------------------- ** Function name: Etrs2Rdnap ** Description: convert ETRS89 coordinates to RD and NAP coordinates ** ** Parameter Type In/Out Req/Opt Default ** phi double in req none ** lambda double in req none ** h double in req none ** xRd double out - none ** yRd double out - none ** nap double out - none ** ** Additional explanation of the meaning of parameters ** phi, lambda, h input ETRS89 coordinates ** xRd, yRd, nap output RD and NAP coordinates ** ** Return value: (besides the standard return values) ** none **-------------------------------------------------------------- */ /// <summary> /// Converts ETRS89 (EPSG:4258) coordinates to RD_New (EPSG:28992) coordinates (including a vertical NAP coordinate). /// </summary> /// <param name="etrs">a <seealso cref="Geographic" /> object containing ETRS89 coordinates.</param> /// <returns>a <seealso cref="Cartesian" /> object containing RD coordinates.</returns> public static Cartesian Etrs2Rdnap(Geographic etrs) { var rd = Etrs2Rd(etrs); var betterH = Etrs2Nap(etrs); if (betterH.HasValue) { return(rd.WithZ(betterH.Value)); } return(rd); }
/* **-------------------------------------------------------------- ** Function name: Etrs2Nap ** Description: convert ellipsoidal ETRS89 height to NAP height ** ** Parameter Type In/Out Req/Opt Default ** phi double in req none ** lambda double in req none ** h double in req none ** nap double out - none ** ** Additional explanation of the meaning of parameters ** phi, lambda, h input ETRS89 coordinates ** nap output NAP height ** ** Return value: (besides the standard return values) none ** on error (outside geoid grid) nap is not computed here ** instead in Etrs2RdNap nap=hBessel **-------------------------------------------------------------- */ /// <summary> /// Converts AN ellipsoidal ETRS89 (EPSG:28992) height to an NAP (EPSG:4258) height. /// </summary> /// <param name="etrs">a <seealso cref="Geographic" /> object containing ETRS89 coordinates.</param> /// <returns>a nullable double containing the NAP height (if all went well).</returns> public static double?Etrs2Nap(Geographic etrs) { /* **-------------------------------------------------------------- ** Explanation of the meaning of variables: ** n geoid height ** on error (outside geoid grid) nap is not computed ** instead in etrs2rdnap nap=hBessel **-------------------------------------------------------------- */ var n = GrdFile.GridFileGeoid.InterpolateGrid(etrs.Lambda, etrs.Phi); if (n.HasValue) { return(etrs.H - n.Value + 0.0088); } return(null); }
/* **-------------------------------------------------------------- ** Function name: RdProjection ** Description: stereographic double projection ** ** Parameter Type In/Out Req/Opt Default ** phi double cartesian req none ** lambda double cartesian req none ** xRd double out - none ** yRd double out - none ** ** Additional explanation of the meaning of parameters ** phi input Bessel latitude cartesian degrees ** lambda input Bessel longitude cartesian degrees ** xRd, yRd output RD coordinates ** ** Return value: (besides the standard return values) ** none **-------------------------------------------------------------- */ /// <summary> /// Projects Geographic coordinates (EPSG:4258) to RD_New coordinates(EPSG:28992). /// </summary> /// <param name="geographic">The geographic coordinates container.</param> /// <returns>Cartesian object containing the converted coordinates.</returns> internal static Cartesian RdProjection(Geographic geographic) { /* **-------------------------------------------------------------- ** Source: G. Bakker, J.C. de Munck and G.L. Strang van Hees, "Radio Positioning at Sea". Delft University of Technology, 1995. ** G. Strang van Hees, "Globale en lokale geodetische systemen". Delft: Nederlandse Commissie voor Geodesie (NCG), 1997. **-------------------------------------------------------------- */ /* **-------------------------------------------------------------- ** Explanation of the meaning of constants: ** f flattening of the ellipsoid ** ee first eccentricity squared (e squared cartesian some notations) ** e first eccentricity ** eea second eccentricity squared (e' squared cartesian some notations) ** ** phiAmersfoortSphere latitude of projection base point Amersfoort on sphere cartesian degrees ** lambdaAmersfoortSphere longitude of projection base point Amersfoort on sphere cartesian degrees ** ** r1 first (North South) principal radius of curvature cartesian Amersfoort (M cartesian some notations) ** r2 second (East West) principal radius of curvature cartesian Amersfoort (N cartesian some notations) ** rSphere radius of sphere ** ** n constant of Gaussian projection n = 1.000475... ** qAmersfoort isometric latitude of Amersfoort on ellipsiod ** wAmersfoort isometric latitude of Amersfoort on sphere ** m constant of Gaussian projection m = 0.003773... (also named cartesian cartesian some notations) **-------------------------------------------------------------- */ var f = 1 / InvFBessel; var ee = f * (2 - f); var e = Math.Sqrt(ee); var eea = ee / (1.0 - ee); var phiAmersfoortSphere = DegAtan(DegTan(PhiAmersfoortBessel) / Math.Sqrt(1 + eea * Math.Pow(DegCos(PhiAmersfoortBessel), 2))); var lambdaAmersfoortSphere = LambdaAmersfoortBessel; var r1 = ABessel * (1 - ee) / Math.Pow(Math.Sqrt(1 - ee * Math.Pow(DegSin(PhiAmersfoortBessel), 2)), 3); var r2 = ABessel / Math.Sqrt(1.0 - ee * Math.Pow(DegSin(PhiAmersfoortBessel), 2)); var rSphere = Math.Sqrt(r1 * r2); var n = Math.Sqrt(1 + eea * Math.Pow(DegCos(PhiAmersfoortBessel), 4)); var qAmersfoort = Atanh(DegSin(PhiAmersfoortBessel)) - e * Atanh(e * DegSin(PhiAmersfoortBessel)); var wAmersfoort = Math.Log(DegTan(45 + 0.5 * phiAmersfoortSphere)); var m = wAmersfoort - n * qAmersfoort; /* **-------------------------------------------------------------- ** Explanation of the meaning of variables: ** q isometric latitude on ellipsoid ** w isometric latitude on sphere ** phiSphere latitude on sphere cartesian degrees ** deltaLambdaSphere difference cartesian longitude on sphere with Amersfoort cartesian degrees ** psi distance angle from Amersfoort on sphere ** alpha azimuth from Amersfoort ** r distance from Amersfoort cartesian projection plane **-------------------------------------------------------------- */ var q = Atanh(DegSin(geographic.Phi)) - e * Atanh(e * DegSin(geographic.Phi)); var w = n * q + m; var phiSphere = 2 * DegAtan(Math.Exp(w)) - 90; var deltaLambdaSphere = n * (geographic.Lambda - lambdaAmersfoortSphere); var sinHalfPsiSquared = Math.Pow(DegSin(0.5 * (phiSphere - phiAmersfoortSphere)), 2) + Math.Pow(DegSin(0.5 * deltaLambdaSphere), 2) * DegCos(phiSphere) * DegCos(phiAmersfoortSphere); var sinHalfPsi = Math.Sqrt(sinHalfPsiSquared); var cosHalfPsi = Math.Sqrt(1 - sinHalfPsiSquared); var tanHalfPsi = sinHalfPsi / cosHalfPsi; var sinPsi = 2 * sinHalfPsi * cosHalfPsi; var cosPsi = 1 - 2 * sinHalfPsiSquared; var sinAlpha = DegSin(deltaLambdaSphere) * (DegCos(phiSphere) / sinPsi); var cosAlpha = (DegSin(phiSphere) - DegSin(phiAmersfoortSphere) * cosPsi) / (DegCos(phiAmersfoortSphere) * sinPsi); var r = 2 * ScaleRd * rSphere * tanHalfPsi; var xRd = r * sinAlpha + XAmersfoortRd; var yRd = r * cosAlpha + YAmersfoortRd; return(new Cartesian(xRd, yRd)); }