Exemple #1
0
        private Cartographic3 fromCartesian(Cartesian3 cartesian3, Ellipsoid ellipsoid)
        {
            Cartesian3Service cartesian3Service = new Cartesian3Service();

            var cartesianToCartographicN = new Cartesian3();
            var cartesianToCartographicP = new Cartesian3();
            var cartesianToCartographicH = new Cartesian3();

            Cartesian3 oneOverRadii           = ellipsoid.OneOverRadii;
            Cartesian3 oneOverRadiiSquared    = ellipsoid.OneOverRadiiSquared;
            double     centerToleranceSquared = ellipsoid.CenterToleranceSquared;

            Cartesian3 p = scaleToGeodeticSurface(cartesian3, ellipsoid, cartesian3Service);

            if (p == null)
            {
                return(null);
            }

            cartesianToCartographicN = cartesian3Service.MultiplyComponents(p, oneOverRadiiSquared);
            cartesianToCartographicN = cartesian3Service.Normalize(cartesianToCartographicN);

            cartesianToCartographicH = cartesian3Service.Subtract(cartesian3, p);

            var longitude = Math.Atan2(cartesianToCartographicN.Y, cartesianToCartographicN.X);
            var latitude  = Math.Asin(cartesianToCartographicN.Z);
            var height    = Math.Sign(cartesian3Service.Dot(cartesianToCartographicH, cartesian3)) * cartesian3Service.Magnitude(cartesianToCartographicH);

            Cartographic3 result = new Cartographic3();

            result.Longitude = longitude;
            result.Latitude  = latitude;
            result.Height    = height;

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// 源坐标转目标坐标
        /// </summary>
        /// <param name="sourceCoordinate"></param>
        /// <returns></returns>
        public ICoordinate3 SourceToTarget(ICoordinate3 sourceCoordinate)
        {
            if (sourceCoordinate == null)
            {
                return(null);
            }

            Cartesian3    cartesian3    = null;
            Cartographic3 cartographic3 = null;
            Projection    projection    = null;

            // ------------------------
            // 第一步:源坐标转换为地理坐标
            // ------------------------

            switch (sourceCoordinateType)
            {
            case CoordinateType.Cartographic:
                // 如果源是地理坐标,则不需要处理
                cartographic3 = new Cartographic3(sourceCoordinate.XAxis, sourceCoordinate.YAxis, sourceCoordinate.ZAxis);
                break;

            case CoordinateType.Cartesian:
                // 如果源是笛卡尔坐标
                // 处理方法:
                // 1.高斯反算,转为地理坐标
                cartesian3 = new Cartesian3(sourceCoordinate.XAxis, sourceCoordinate.YAxis, sourceCoordinate.ZAxis);
                GaussKrugerTransformation gauss_source_1 = new GaussKrugerTransformation(sourceEllipsoid);
                cartographic3 = gauss_source_1.GaussKrugerReverse(cartesian3, sourceCenterMeridian);
                break;

            case CoordinateType.Projection:
                // 如果源是投影坐标
                // 处理方法:
                // 1.投影坐标转笛卡尔坐标
                // 2.高斯反算,转为地理坐标
                GaussKrugerTransformation gauss_source_2 = new GaussKrugerTransformation(sourceEllipsoid);
                projection    = new Projection(sourceCoordinate.XAxis, sourceCoordinate.YAxis, sourceCoordinate.ZAxis);
                cartesian3    = gauss_source_2.ProjectionToCartesian(projection);
                cartographic3 = gauss_source_2.GaussKrugerReverse(cartesian3, sourceCenterMeridian);
                break;

            default:
                break;
            }

            // ------------------------
            // 第二步:地理坐标转换为笛卡尔空间坐标
            // ------------------------
            Cartesian3Service cartesian3Service = new Cartesian3Service();

            cartesian3 = cartesian3Service.Cartographic3ToCartesian3(cartographic3, sourceEllipsoid);

            // ------------------------
            // 第三步:通过七参数模型,对笛卡尔空间坐标进行转换,转换后同样是笛卡尔空间坐标
            // ------------------------
            BursaWolfTransformation bursaWolfTransformation = new BursaWolfTransformation(sevenParams);

            cartesian3 = bursaWolfTransformation.Transform(cartesian3);

            // ------------------------
            // 第四步:笛卡尔空间坐标转换为地理坐标
            // ------------------------
            Cartographic3Service cartographic3Service = new Cartographic3Service();

            cartographic3 = cartographic3Service.Cartesian3ToCartographic3(cartesian3, targetEllipsoid);

            // ------------------------
            // 第五步:地理坐标转换为目标坐标
            // ------------------------
            ICoordinate3 result = null;

            switch (targetCoordinateType)
            {
            case CoordinateType.Cartographic:
                // 如果目标是地理坐标,则不需要处理
                result = cartographic3.Clone();
                break;

            case CoordinateType.Cartesian:
                // 如果目标是笛卡尔坐标
                // 处理方法:
                // 1.高斯正算,转为笛卡尔坐标系
                GaussKrugerTransformation gauss_target_1 = new GaussKrugerTransformation(targetEllipsoid);
                cartesian3 = gauss_target_1.GaussKrugerForward(cartographic3, targetCenterMeridian);
                result     = cartesian3.Clone();
                break;

            case CoordinateType.Projection:
                // 如果目标是投影坐标
                // 处理方法:
                // 1.高斯正算,转为笛卡尔坐标系
                // 2.笛卡尔坐标转投影坐标
                GaussKrugerTransformation gauss_target_2 = new GaussKrugerTransformation(targetEllipsoid);
                cartesian3 = gauss_target_2.GaussKrugerForward(cartographic3, targetCenterMeridian);
                projection = gauss_target_2.CartesianToProjection(cartesian3);
                result     = projection.Clone();
                break;

            default:
                break;
            }

            return(result);
        }
Exemple #3
0
        private Cartesian3 scaleToGeodeticSurface(Cartesian3 cartesian3, Ellipsoid ellipsoid, Cartesian3Service cartesian3Service)
        {
            Cartesian3 oneOverRadii           = ellipsoid.OneOverRadii;
            Cartesian3 oneOverRadiiSquared    = ellipsoid.OneOverRadiiSquared;
            double     centerToleranceSquared = ellipsoid.CenterToleranceSquared;

            var positionX = cartesian3.X;
            var positionY = cartesian3.Y;
            var positionZ = cartesian3.Z;

            var oneOverRadiiX = oneOverRadii.X;
            var oneOverRadiiY = oneOverRadii.Y;
            var oneOverRadiiZ = oneOverRadii.Z;

            var x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX;
            var y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY;
            var z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ;

            // Compute the squared ellipsoid norm.
            var squaredNorm = x2 + y2 + z2;
            var ratio       = Math.Sqrt(1.0 / squaredNorm);

            // As an initial approximation, assume that the radial intersection is the projection point.
            var intersection = cartesian3Service.MultiplyByScalar(cartesian3, ratio);

            // If the position is near the center, the iteration will not converge.
            if (squaredNorm < centerToleranceSquared)
            {
                return(double.IsInfinity(ratio) ? null : intersection);
            }

            var oneOverRadiiSquaredX = oneOverRadiiSquared.X;
            var oneOverRadiiSquaredY = oneOverRadiiSquared.Y;
            var oneOverRadiiSquaredZ = oneOverRadiiSquared.Z;

            // Use the gradient at the intersection point in place of the true unit normal.
            // The difference in magnitude will be absorbed in the multiplier.
            var gradient = new Cartesian3();

            gradient.X = intersection.X * oneOverRadiiSquaredX * 2.0;
            gradient.Y = intersection.Y * oneOverRadiiSquaredY * 2.0;
            gradient.Z = intersection.Z * oneOverRadiiSquaredZ * 2.0;

            // Compute the initial guess at the normal vector multiplier, lambda.
            var lambda     = (1.0 - ratio) * cartesian3Service.Magnitude(cartesian3) / (0.5 * cartesian3Service.Magnitude(gradient));
            var correction = 0.0;

            double func;
            double denominator;
            double xMultiplier;
            double yMultiplier;
            double zMultiplier;
            double xMultiplier2;
            double yMultiplier2;
            double zMultiplier2;
            double xMultiplier3;
            double yMultiplier3;
            double zMultiplier3;

            do
            {
                lambda -= correction;

                xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX);
                yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY);
                zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ);

                xMultiplier2 = xMultiplier * xMultiplier;
                yMultiplier2 = yMultiplier * yMultiplier;
                zMultiplier2 = zMultiplier * zMultiplier;

                xMultiplier3 = xMultiplier2 * xMultiplier;
                yMultiplier3 = yMultiplier2 * yMultiplier;
                zMultiplier3 = zMultiplier2 * zMultiplier;

                func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0;

                // "denominator" here refers to the use of this expression in the velocity and acceleration
                // computations in the sections to follow.
                denominator = x2 * xMultiplier3 * oneOverRadiiSquaredX + y2 * yMultiplier3 * oneOverRadiiSquaredY + z2 * zMultiplier3 * oneOverRadiiSquaredZ;

                var derivative = -2.0 * denominator;

                correction = func / derivative;
            } while (Math.Abs(func) > 0.000000000001);


            Cartesian3 result = new Cartesian3();

            result.X = positionX * xMultiplier;
            result.Y = positionY * yMultiplier;
            result.Z = positionZ * zMultiplier;
            return(result);
        }
Exemple #4
0
        /// <summary>
        /// 目标坐标转源坐标(批量)
        /// </summary>
        /// <param name="targetCoordinates"></param>
        /// <returns></returns>
        public List <ICoordinate3> TargetToSourceBatch(IEnumerable <ICoordinate3> targetCoordinates)
        {
            if (targetCoordinates == null || targetCoordinates.Count() == 0)
            {
                return(null);
            }
            List <ICoordinate3> result = new List <ICoordinate3>();
            // 局部变量
            Cartesian3    cartesian3    = null;
            Cartographic3 cartographic3 = null;
            Projection    projection    = null;
            // 高斯转换
            GaussKrugerTransformation gauss_source = new GaussKrugerTransformation(sourceEllipsoid);
            GaussKrugerTransformation gauss_target = new GaussKrugerTransformation(targetEllipsoid);
            // 布尔萨转换(参数反转)
            BursaWolfTransformation bursaWolfTransformation = new BursaWolfTransformation(sevenParams.Reverse());
            // 笛卡尔组表转换
            Cartesian3Service cartesian3Service = new Cartesian3Service();
            // 地理坐标转换
            Cartographic3Service cartographic3Service = new Cartographic3Service();

            // 遍历集合中的坐标
            foreach (ICoordinate3 targetCoordinate in targetCoordinates)
            {
                // ------------------------
                // 第一步:目标坐标转换为地理坐标
                // ------------------------

                switch (targetCoordinateType)
                {
                case CoordinateType.Cartographic:
                    // 如果目标是地理坐标,则不需要处理
                    cartographic3 = new Cartographic3(targetCoordinate.XAxis, targetCoordinate.YAxis, targetCoordinate.ZAxis);
                    break;

                case CoordinateType.Cartesian:
                    // 如果目标是笛卡尔坐标
                    // 处理方法:
                    // 1.高斯反算,转为地理坐标
                    cartesian3    = new Cartesian3(targetCoordinate.XAxis, targetCoordinate.YAxis, targetCoordinate.ZAxis);
                    cartographic3 = gauss_target.GaussKrugerReverse(cartesian3, targetCenterMeridian);
                    break;

                case CoordinateType.Projection:
                    // 如果目标是投影坐标
                    // 处理方法:
                    // 1.投影坐标转笛卡尔坐标
                    // 2.高斯反算,转为地理坐标
                    projection    = new Projection(targetCoordinate.XAxis, targetCoordinate.YAxis, targetCoordinate.ZAxis);
                    cartesian3    = gauss_target.ProjectionToCartesian(projection);
                    cartographic3 = gauss_target.GaussKrugerReverse(cartesian3, targetCenterMeridian);
                    break;

                default:
                    break;
                }

                // ------------------------
                // 第二步:地理坐标转换为笛卡尔空间坐标
                // ------------------------
                cartesian3 = cartesian3Service.Cartographic3ToCartesian3(cartographic3, targetEllipsoid);

                // ------------------------
                // 第三步:通过七参数模型,对笛卡尔空间坐标进行转换,转换后同样是笛卡尔空间坐标(这里需要反转参数)
                // ------------------------
                cartesian3 = bursaWolfTransformation.Transform(cartesian3);

                // ------------------------
                // 第四步:笛卡尔空间坐标转换为地理坐标
                // ------------------------
                cartographic3 = cartographic3Service.Cartesian3ToCartographic3(cartesian3, sourceEllipsoid);

                // ------------------------
                // 第五步:地理坐标转换为源坐标
                // ------------------------
                ICoordinate3 subResult = null;

                switch (sourceCoordinateType)
                {
                case CoordinateType.Cartographic:
                    // 如果源是地理坐标,则不需要处理
                    subResult = cartographic3.Clone();
                    break;

                case CoordinateType.Cartesian:
                    // 如果源是笛卡尔坐标
                    // 处理方法:
                    // 1.高斯正算,转为笛卡尔坐标系
                    GaussKrugerTransformation gauss_source_1 = new GaussKrugerTransformation(sourceEllipsoid);
                    cartesian3 = gauss_source_1.GaussKrugerForward(cartographic3, sourceCenterMeridian);
                    subResult  = cartesian3.Clone();
                    break;

                case CoordinateType.Projection:
                    // 如果源是投影坐标
                    // 处理方法:
                    // 1.高斯正算,转为笛卡尔坐标系
                    // 2.笛卡尔坐标转投影坐标
                    GaussKrugerTransformation gauss_source_2 = new GaussKrugerTransformation(sourceEllipsoid);
                    cartesian3 = gauss_source_2.GaussKrugerForward(cartographic3, sourceCenterMeridian);
                    projection = gauss_source_2.CartesianToProjection(cartesian3);
                    subResult  = projection.Clone();
                    break;

                default:
                    break;
                }

                result.Add(subResult);
            }

            return(result);
        }