// Input argument: the center of the projection public GnomonicProjection(Dictionary <String, double> parameters) : base(parameters) { _center = SpatialUtil.SphericalRadToCartesian(InputLatitude("latitude1", 90), InputLongitude("longitude1", 360)); // This projection is designed for numerical computations rather than cartography. // The choice of coordinate basis for the tangent plane - which affects the // orientation of the projection in the xy plane - is optimized for accuracy rather // than good looks. The first basis vector is obtained by dropping the smallest coordinate, // switching the other two, and flipping the sign of one of them. The second one is // obtained by cross product. double[] center = { _center.X, _center.Y, _center.Z }; var vector = new double[3]; var k = GetMinEntry(center); var j = (k + 2) % 3; var i = (j + 2) % 3; vector[i] = -center[j]; vector[j] = center[i]; vector[k] = 0; _xAxis = new Vector3(vector[0], vector[1], vector[2]).Unitize(); _yAxis = _center.CrossProduct(_xAxis); }
protected internal override void Project(double latitude, double longitude, out double x, out double y) { var vector = SpatialUtil.SphericalRadToCartesian(latitude, longitude); var r = vector * _center; if (r < _tolerance) { throw new ArgumentOutOfRangeException(nameof(latitude), "Input point is too far away from the center of projection."); } vector = vector / r; x = vector * _xAxis; y = vector * _yAxis; }