Beispiel #1
1
        private static void DatumTransform(ProjectionInfo source, ProjectionInfo dest, double[] xy, double[] z, int startIndex, int numPoints)
        {
            Spheroid wgs84 = new Spheroid(Proj4Ellipsoid.WGS_1984);
            Datum sDatum = source.GeographicInfo.Datum;
            Datum dDatum = dest.GeographicInfo.Datum;

            /* -------------------------------------------------------------------- */
            /*      We cannot do any meaningful datum transformation if either      */
            /*      the source or destination are of an unknown datum type          */
            /*      (ie. only a +ellps declaration, no +datum).  This is new        */
            /*      behavior for PROJ 4.6.0.                                        */
            /* -------------------------------------------------------------------- */
            if (sDatum.DatumType == DatumType.Unknown ||
                dDatum.DatumType == DatumType.Unknown) return;

            /* -------------------------------------------------------------------- */
            /*      Short cut if the datums are identical.                          */
            /* -------------------------------------------------------------------- */

            if (sDatum.Matches(dDatum)) return;

            // proj4 actually allows some tollerance here
            if (sDatum.DatumType == dDatum.DatumType)
            {
                if (sDatum.Spheroid.EquatorialRadius == dDatum.Spheroid.EquatorialRadius)
                {
                    if (Math.Abs(sDatum.Spheroid.EccentricitySquared() - dDatum.Spheroid.EccentricitySquared()) < 0.000000000050)
                    {
                        // The tolerence is to allow GRS80 and WGS84 to escape without being transformed at all.
                        return;
                    }
                }
            }

            double srcA = sDatum.Spheroid.EquatorialRadius;
            double srcEs = sDatum.Spheroid.EccentricitySquared();

            double dstA = dDatum.Spheroid.EquatorialRadius;
            double dstEs = dDatum.Spheroid.EccentricitySquared();

            /* -------------------------------------------------------------------- */
            /*      Create a temporary Z value if one is not provided.              */
            /* -------------------------------------------------------------------- */
            if (z == null)
            {
                z = new double[xy.Length / 2];
            }

            /* -------------------------------------------------------------------- */
            /*	If this datum requires grid shifts, then apply it to geodetic   */
            /*      coordinates.                                                    */
            /* -------------------------------------------------------------------- */
            if (sDatum.DatumType == DatumType.GridShift)
            {
                //        pj_apply_gridshift(pj_param(srcdefn->params,"snadgrids").s, 0,
                //                            point_count, point_offset, x, y, z );

                GridShift.Apply(source.GeographicInfo.Datum.NadGrids, false, xy, startIndex, numPoints);

                srcA = wgs84.EquatorialRadius;
                srcEs = wgs84.EccentricitySquared();
            }

            if (dDatum.DatumType == DatumType.GridShift)
            {
                dstA = wgs84.EquatorialRadius;
                dstEs = wgs84.EccentricitySquared();
            }

            /* ==================================================================== */
            /*      Do we need to go through geocentric coordinates?                */
            /* ==================================================================== */

            if (srcEs != dstEs || srcA != dstA
                || sDatum.DatumType == DatumType.Param3
                || sDatum.DatumType == DatumType.Param7
                || dDatum.DatumType == DatumType.Param3
                || dDatum.DatumType == DatumType.Param7)
            {
                /* -------------------------------------------------------------------- */
                /*      Convert to geocentric coordinates.                              */
                /* -------------------------------------------------------------------- */

                GeocentricGeodetic gc = new GeocentricGeodetic(sDatum.Spheroid);
                gc.GeodeticToGeocentric(xy, z, startIndex, numPoints);

                /* -------------------------------------------------------------------- */
                /*      Convert between datums.                                         */
                /* -------------------------------------------------------------------- */

                if (sDatum.DatumType == DatumType.Param3 || sDatum.DatumType == DatumType.Param7)
                {
                    PjGeocentricToWgs84(source, xy, z, startIndex, numPoints);
                }

                if (dDatum.DatumType == DatumType.Param3 || dDatum.DatumType == DatumType.Param7)
                {
                    PjGeocentricFromWgs84(dest, xy, z, startIndex, numPoints);
                }

                /* -------------------------------------------------------------------- */
                /*      Convert back to geodetic coordinates.                           */
                /* -------------------------------------------------------------------- */

                gc = new GeocentricGeodetic(dDatum.Spheroid);
                gc.GeocentricToGeodetic(xy, z, startIndex, numPoints);
            }

            /* -------------------------------------------------------------------- */
            /*      Apply grid shift to destination if required.                    */
            /* -------------------------------------------------------------------- */
            if (dDatum.DatumType == DatumType.GridShift)
            {
                //        pj_apply_gridshift(pj_param(dstdefn->params,"snadgrids").s, 1,
                //                            point_count, point_offset, x, y, z );
                GridShift.Apply(dest.GeographicInfo.Datum.NadGrids, true, xy, startIndex, numPoints);
            }
        }
Beispiel #2
0
        /// <summary>
        /// datum tranform method
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <param name="xy"></param>
        /// <param name="z"></param>
        /// <param name="startIndex"></param>
        /// <param name="numPoints"></param>
        public void Transform(ProjectionInfo source, ProjectionInfo dest, double[] xy, double[] z, int startIndex, int numPoints)
        {
            if (_aiDts.Length == 0)
            {
                return;                     // "empty" datum transform
            }
            bool bCoordsAreGeocentric = false;

            /* -------------------------------------------------------------------- */
            /*      Create a temporary Z value if one is not provided.              */
            /* -------------------------------------------------------------------- */
            if (z == null)
            {
                z = new double[xy.Length / 2];
            }

            foreach (IDatumTransformStage idts in _aiDts)
            {
                if (idts.Method == TransformMethod.GridShift)
                {
                    if (bCoordsAreGeocentric)
                    {
                        var gc = new GeocentricGeodetic(idts.FromSpheroid);
                        gc.GeocentricToGeodetic(xy, z, startIndex, numPoints);
                        bCoordsAreGeocentric = false;
                    }

                    var astrGrids = new string[1];
                    astrGrids[0] = "@" + idts.GridShiftTable;
                    GridShift.Apply(astrGrids, idts.ApplyTableInverse, xy, startIndex, numPoints);
                }
                else
                {
                    if (!bCoordsAreGeocentric)
                    {
                        var gc = new GeocentricGeodetic(idts.FromSpheroid);
                        gc.GeodeticToGeocentric(xy, z, startIndex, numPoints);
                        bCoordsAreGeocentric = true;
                    }

                    ApplyParameterizedTransform(idts, xy, z, startIndex, numPoints);
                }
            }

            /* -------------------------------------------------------------------- */
            /*      Convert back to geodetic coordinates, if needed.                */
            /* -------------------------------------------------------------------- */
            if (bCoordsAreGeocentric)
            {
                var gc = new GeocentricGeodetic(_aiDts[_aiDts.Length - 1].ToSpheroid);
                gc.GeocentricToGeodetic(xy, z, startIndex, numPoints);
            }
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="xy">The xy array should be in interleaved set of xy coordinates like [x1, y1, x2, y2, ... xn, yn]</param>
        /// <param name="z">The z array is the array of all the z values</param>
        /// <param name="source"></param>
        /// <param name="srcZtoMeter"></param>
        /// <param name="dest"></param>
        /// <param name="dstZtoMeter"></param>
        /// <param name="idt"></param>
        /// <param name="startIndex"></param>
        /// <param name="numPoints"></param>
        public static void ReprojectPoints(double[] xy, double[] z, ProjectionInfo source, double srcZtoMeter, ProjectionInfo dest, double dstZtoMeter, IDatumTransform idt, int startIndex, int numPoints)
        {
            double toMeter = source.Unit.Meters;

            // Geocentric coordinates are centered at the core of the earth.  Z is up toward the north pole.
            // The X axis goes from the center of the earth through Greenwich.
            // The Y axis passes through 90E.
            // This section converts from geocentric coordinates to geodetic ones if necessary.
            if (source.IsGeocentric)
            {
                if (z == null)
                {
                    throw new ProjectionException(45);
                }
                for (int i = startIndex; i < numPoints; i++)
                {
                    if (toMeter != 1)
                    {
                        xy[i * 2] *= toMeter;
                        xy[i * 2 + 1] *= toMeter;
                    }
                }
                GeocentricGeodetic g = new GeocentricGeodetic(source.GeographicInfo.Datum.Spheroid);
                g.GeocentricToGeodetic(xy, z, startIndex, numPoints);
            }

            // Transform source points to lam/phi if they are not already
            ConvertToLatLon(source, xy, z, srcZtoMeter, startIndex, numPoints);

            double fromGreenwich = source.GeographicInfo.Meridian.Longitude * source.GeographicInfo.Unit.Radians;
            if (fromGreenwich != 0)
            {
                for (int i = startIndex; i < numPoints; i++)
                {
                    if (xy[2 * i] != double.PositiveInfinity)
                        xy[2 * i] += fromGreenwich;
                }
            }
            // DATUM TRANSFORM IF NEEDED
            if (idt == null)
            {
                if (!source.GeographicInfo.Datum.Matches(dest.GeographicInfo.Datum))
                {
                    DatumTransform(source, dest, xy, z, startIndex, numPoints);
                }
            }
            else
            {
                idt.Transform(source, dest, xy, z, startIndex, numPoints);
            }

            // Adjust to new prime meridian if there is one in the destination cs
            fromGreenwich = dest.GeographicInfo.Meridian.Longitude * dest.GeographicInfo.Unit.Radians;
            if (fromGreenwich != 0)
            {
                for (int i = startIndex; i < numPoints; i++)
                {
                    if (xy[i * 2] != double.PositiveInfinity)
                    {
                        xy[i * 2] -= fromGreenwich;
                    }
                }
            }

            if (dest.IsGeocentric)
            {
                if (z == null)
                {
                    throw new ProjectionException(45);
                }
                GeocentricGeodetic g = new GeocentricGeodetic(dest.GeographicInfo.Datum.Spheroid);
                g.GeodeticToGeocentric(xy, z, startIndex, numPoints);
                double frmMeter = 1 / dest.Unit.Meters;
                if (frmMeter != 1)
                {
                    for (int i = startIndex; i < numPoints; i++)
                    {
                        if (xy[i * 2] != double.PositiveInfinity)
                        {
                            xy[i * 2] *= frmMeter;
                            xy[i * 2 + 1] *= frmMeter;
                        }
                    }
                }
            }
            else
            {
                ConvertToProjected(dest, xy, z, dstZtoMeter, startIndex, numPoints);
            }
        }
Beispiel #4
0
        public static void ReprojectPoints(double[] xy, double[] z, ProjectionInfo source, double srcZtoMeter, ProjectionInfo dest, double dstZtoMeter, IDatumTransform idt, int startIndex, int numPoints)
        {
            double toMeter = source.Unit.Meters;

            // Geocentric coordinates are centered at the core of the earth.  Z is up toward the north pole.
            // The X axis goes from the center of the earth through Greenwich.
            // The Y axis passes through 90E.
            // This section converts from geocentric coordinates to geodetic ones if necessary.
            if (source.IsGeocentric)
            {
                if (z == null)
                {
                    throw new ProjectionException(45);
                }
                for (int i = startIndex; i < numPoints; i++)
                {
                    if (toMeter != 1)
                    {
                        xy[i * 2]     *= toMeter;
                        xy[i * 2 + 1] *= toMeter;
                    }
                }
                GeocentricGeodetic g = new GeocentricGeodetic(source.GeographicInfo.Datum.Spheroid);
                g.GeocentricToGeodetic(xy, z, startIndex, numPoints);
            }

            // Transform source points to lam/phi if they are not already
            ConvertToLatLon(source, xy, z, srcZtoMeter, startIndex, numPoints);

            double fromGreenwich = source.GeographicInfo.Meridian.Longitude * source.GeographicInfo.Unit.Radians;

            if (fromGreenwich != 0)
            {
                for (int i = startIndex; i < numPoints; i++)
                {
                    if (xy[2 * i] != double.PositiveInfinity)
                    {
                        xy[2 * i] += fromGreenwich;
                    }
                }
            }
            // DATUM TRANSFORM IF NEEDED
            if (idt == null)
            {
                if (!source.GeographicInfo.Datum.Matches(dest.GeographicInfo.Datum))
                {
                    DatumTransform(source, dest, xy, z, startIndex, numPoints);
                }
            }
            else
            {
                idt.Transform(source, dest, xy, z, startIndex, numPoints);
            }

            // Adjust to new prime meridian if there is one in the destination cs
            fromGreenwich = dest.GeographicInfo.Meridian.Longitude * dest.GeographicInfo.Unit.Radians;
            if (fromGreenwich != 0)
            {
                for (int i = startIndex; i < numPoints; i++)
                {
                    if (xy[i * 2] != double.PositiveInfinity)
                    {
                        xy[i * 2] -= fromGreenwich;
                    }
                }
            }

            if (dest.IsGeocentric)
            {
                if (z == null)
                {
                    throw new ProjectionException(45);
                }
                GeocentricGeodetic g = new GeocentricGeodetic(dest.GeographicInfo.Datum.Spheroid);
                g.GeodeticToGeocentric(xy, z, startIndex, numPoints);
                double frmMeter = 1 / dest.Unit.Meters;
                if (frmMeter != 1)
                {
                    for (int i = startIndex; i < numPoints; i++)
                    {
                        if (xy[i * 2] != double.PositiveInfinity)
                        {
                            xy[i * 2]     *= frmMeter;
                            xy[i * 2 + 1] *= frmMeter;
                        }
                    }
                }
            }
            else
            {
                ConvertToProjected(dest, xy, z, dstZtoMeter, startIndex, numPoints);
            }
        }
Beispiel #5
0
        private static void DatumTransform(ProjectionInfo source, ProjectionInfo dest, double[] xy, double[] z, int startIndex, int numPoints)
        {
            Spheroid wgs84  = new Spheroid(Proj4Ellipsoid.WGS_1984);
            Datum    sDatum = source.GeographicInfo.Datum;
            Datum    dDatum = dest.GeographicInfo.Datum;

            /* -------------------------------------------------------------------- */
            /*      We cannot do any meaningful datum transformation if either      */
            /*      the source or destination are of an unknown datum type          */
            /*      (ie. only a +ellps declaration, no +datum).  This is new        */
            /*      behavior for PROJ 4.6.0.                                        */
            /* -------------------------------------------------------------------- */
            if (sDatum.DatumType == DatumType.Unknown ||
                dDatum.DatumType == DatumType.Unknown)
            {
                return;
            }

            /* -------------------------------------------------------------------- */
            /*      Short cut if the datums are identical.                          */
            /* -------------------------------------------------------------------- */

            if (sDatum.Matches(dDatum))
            {
                return;
            }

            // proj4 actually allows some tollerance here
            if (sDatum.DatumType == dDatum.DatumType)
            {
                if (sDatum.Spheroid.EquatorialRadius == dDatum.Spheroid.EquatorialRadius)
                {
                    if (Math.Abs(sDatum.Spheroid.EccentricitySquared() - dDatum.Spheroid.EccentricitySquared()) < 0.000000000050)
                    {
                        // The tolerence is to allow GRS80 and WGS84 to escape without being transformed at all.
                        return;
                    }
                }
            }

            double srcA  = sDatum.Spheroid.EquatorialRadius;
            double srcEs = sDatum.Spheroid.EccentricitySquared();

            double dstA  = dDatum.Spheroid.EquatorialRadius;
            double dstEs = dDatum.Spheroid.EccentricitySquared();

            /* -------------------------------------------------------------------- */
            /*      Create a temporary Z value if one is not provided.              */
            /* -------------------------------------------------------------------- */
            if (z == null)
            {
                z = new double[xy.Length / 2];
            }

            /* -------------------------------------------------------------------- */
            /*	If this datum requires grid shifts, then apply it to geodetic   */
            /*      coordinates.                                                    */
            /* -------------------------------------------------------------------- */
            if (sDatum.DatumType == DatumType.GridShift)
            {
                //        pj_apply_gridshift(pj_param(srcdefn->params,"snadgrids").s, 0,
                //                            point_count, point_offset, x, y, z );

                GridShift.Apply(source.GeographicInfo.Datum.NadGrids, false, xy, startIndex, numPoints);

                srcA  = wgs84.EquatorialRadius;
                srcEs = wgs84.EccentricitySquared();
            }

            if (dDatum.DatumType == DatumType.GridShift)
            {
                dstA  = wgs84.EquatorialRadius;
                dstEs = wgs84.EccentricitySquared();
            }

            /* ==================================================================== */
            /*      Do we need to go through geocentric coordinates?                */
            /* ==================================================================== */

            if (srcEs != dstEs || srcA != dstA ||
                sDatum.DatumType == DatumType.Param3 ||
                sDatum.DatumType == DatumType.Param7 ||
                dDatum.DatumType == DatumType.Param3 ||
                dDatum.DatumType == DatumType.Param7)
            {
                /* -------------------------------------------------------------------- */
                /*      Convert to geocentric coordinates.                              */
                /* -------------------------------------------------------------------- */

                GeocentricGeodetic gc = new GeocentricGeodetic(sDatum.Spheroid);
                gc.GeodeticToGeocentric(xy, z, startIndex, numPoints);

                /* -------------------------------------------------------------------- */
                /*      Convert between datums.                                         */
                /* -------------------------------------------------------------------- */

                if (sDatum.DatumType == DatumType.Param3 || sDatum.DatumType == DatumType.Param7)
                {
                    PjGeocentricToWgs84(source, xy, z, startIndex, numPoints);
                }

                if (dDatum.DatumType == DatumType.Param3 || dDatum.DatumType == DatumType.Param7)
                {
                    PjGeocentricFromWgs84(dest, xy, z, startIndex, numPoints);
                }

                /* -------------------------------------------------------------------- */
                /*      Convert back to geodetic coordinates.                           */
                /* -------------------------------------------------------------------- */

                gc = new GeocentricGeodetic(dDatum.Spheroid);
                gc.GeocentricToGeodetic(xy, z, startIndex, numPoints);
            }

            /* -------------------------------------------------------------------- */
            /*      Apply grid shift to destination if required.                    */
            /* -------------------------------------------------------------------- */
            if (dDatum.DatumType == DatumType.GridShift)
            {
                //        pj_apply_gridshift(pj_param(dstdefn->params,"snadgrids").s, 1,
                //                            point_count, point_offset, x, y, z );
                GridShift.Apply(dest.GeographicInfo.Datum.NadGrids, true, xy, startIndex, numPoints);
            }
        }
Beispiel #6
0
 public void GeocentricAfterDatumTest()
 {
     double[] xy = new double[2];
     xy[0] = 4257349.7546790326000000;
     xy[1] = 401477.6657818287500000;
     double[] z = new double[1];
     z[0] = 4716473.1891765557000000;
     Spheroid s = new Spheroid(Proj4Ellipsoid.WGS_1984);
     GeocentricGeodetic gc = new GeocentricGeodetic(s);
     gc.GeocentricToGeodetic(xy, z, 0, 1);
     
 }
        /// <summary>
        /// datum tranform method
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <param name="xy"></param>
        /// <param name="z"></param>
        /// <param name="startIndex"></param>
        /// <param name="numPoints"></param>
        public void Transform(ProjectionInfo source, ProjectionInfo dest, double[] xy, double[] z, int startIndex, int numPoints)
        {
            if (_aiDts.Length == 0) return; // "empty" datum transform

            bool bCoordsAreGeocentric = false;

            /* -------------------------------------------------------------------- */
            /*      Create a temporary Z value if one is not provided.              */
            /* -------------------------------------------------------------------- */
            if (z == null)
            {
                z = new double[xy.Length / 2];
            }

            foreach (IDatumTransformStage idts in _aiDts)
            {
                if (idts.Method == TransformMethod.GridShift)
                {
                    if (bCoordsAreGeocentric)
                    {
                        var gc = new GeocentricGeodetic(idts.FromSpheroid);
                        gc.GeocentricToGeodetic(xy, z, startIndex, numPoints);
                        bCoordsAreGeocentric = false;
                    }

                    var astrGrids = new string[1];
                    astrGrids[0] = "@" + idts.GridShiftTable;
                    GridShift.Apply(astrGrids, idts.ApplyTableInverse, xy, startIndex, numPoints);
                }
                else
                {
                    if (!bCoordsAreGeocentric)
                    {
                        var gc = new GeocentricGeodetic(idts.FromSpheroid);
                        gc.GeodeticToGeocentric(xy, z, startIndex, numPoints);
                        bCoordsAreGeocentric = true;
                    }

                    ApplyParameterizedTransform(idts, xy, z, startIndex, numPoints);
                }
            }

            /* -------------------------------------------------------------------- */
            /*      Convert back to geodetic coordinates, if needed.                */
            /* -------------------------------------------------------------------- */
            if (bCoordsAreGeocentric)
            {
                var gc = new GeocentricGeodetic(_aiDts[_aiDts.Length - 1].ToSpheroid);
                gc.GeocentricToGeodetic(xy, z, startIndex, numPoints);
            }
        }