Exemplo n.º 1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="points"></param>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <param name="startIndex"></param>
        /// <param name="numPoints"></param>
        public static void ReprojectPoints(double[] xy, double[] z, ProjectionInfo source, ProjectionInfo dest, 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, 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(!source.GeographicInfo.Datum.Matches(dest.GeographicInfo.Datum))
            {
                DatumTransform(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 +1] -= 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, startIndex, numPoints);
            }    
        }
Exemplo n.º 2
0
        private static void DatumTransform(ProjectionInfo source, ProjectionInfo dest, double[] xy, double[] z, int startIndex, int numPoints)
        {
            Spheroid wgs84 = new Spheroid(Proj4Ellipsoids.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 == DatumTypes.Unknown ||
                dDatum.DatumType == DatumTypes.Unknown) return;

            /* -------------------------------------------------------------------- */
            /*      Short cut if the datums are identical.                          */
            /* -------------------------------------------------------------------- */
            if (sDatum.Matches(dDatum)) 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 == DatumTypes.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 == DatumTypes.GridShift)
            {
                dstA = wgs84.EquatorialRadius;
                dstEs = wgs84.EccentricitySquared();
            }

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

            if( srcEs != dstEs || srcA != dstA
                || sDatum.DatumType == DatumTypes.Param3 
                || sDatum.DatumType == DatumTypes.Param7
                || dDatum.DatumType == DatumTypes.Param3 
                || dDatum.DatumType == DatumTypes.Param7)
            {
                /* -------------------------------------------------------------------- */
                /*      Convert to geocentric coordinates.                              */
                /* -------------------------------------------------------------------- */
               
                GeocentricGeodetic gc = new GeocentricGeodetic(sDatum.Spheroid);
                gc.GeodeticToGeocentric(xy, z, startIndex, numPoints);


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

                if( sDatum.DatumType == DatumTypes.Param3 || sDatum.DatumType == DatumTypes.Param7)
                {
                    
                    // pj_geocentric_to_wgs84( srcdefn, point_count, point_offset,x,y,z);
   
                }
                if( dDatum.DatumType == DatumTypes.Param3 || dDatum.DatumType == DatumTypes.Param7)
                {
                    // pj_geocentric_from_wgs84( dstdefn, point_count,point_offset,x,y,z);
                }

                /* -------------------------------------------------------------------- */
                /*      Convert back to geodetic coordinates.                           */
                /* -------------------------------------------------------------------- */
                
                gc = new GeocentricGeodetic(dDatum.Spheroid);
                gc.GeodeticToGeocentric(xy, z, startIndex, numPoints);

            }

            /* -------------------------------------------------------------------- */
            /*      Apply grid shift to destination if required.                    */
            /* -------------------------------------------------------------------- */
            if(dDatum.DatumType == DatumTypes.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);
            }

            
        }