示例#1
0
        public static ProjectionInfo CreateProjection(ICrsProjected crsProjected)
        {
            if (crsProjected == null) throw new ArgumentNullException("crsProjected");
            Contract.Ensures(Contract.Result<ProjectionInfo>() != null);

            var result = ProjectionInfo.FromProj4String(String.Empty);

            result.Name = crsProjected.Name;

            if (crsProjected.Authority != null) {
                int epsgCode;
                if (crsProjected.Authority.Name == "EPSG" && Int32.TryParse(crsProjected.Authority.Code, out epsgCode))
                    result.EpsgCode = epsgCode;

                result.Authority = crsProjected.Authority.Name;
            }

            var geographicBase = (crsProjected.BaseCrs as ICrsGeodetic) ?? (crsProjected as ICrsGeodetic);
            if (geographicBase != null)
                result.GeographicInfo = Proj4CrsGeographic.CreateGeographic(geographicBase);

            var projectionInfo = crsProjected.Projection as IParameterizedCoordinateOperationInfo;

            if (projectionInfo == null)
                return result;

            var projectionMethod = projectionInfo.Method;
            if(projectionMethod == null)
                throw new InvalidOperationException("No projection method.");

            var proj4Name = ToProj4MethodName(projectionMethod.Name);

            IUnit geographicUnit = geographicBase == null ? null : geographicBase.Unit;
            IUnit projectionUnit = crsProjected.Unit;
            if (projectionUnit != null)
                result.Unit = Proj4LinearUnit.ConvertToProj4(projectionUnit);
            switch (proj4Name) {
                case "stere":
                    ApplyParametersStere(result, projectionInfo.Parameters);
                    break;
                default:
                    ApplyParametersDefault(result, projectionInfo.Parameters);
                    break;
            }

            if (result.Zone.HasValue && proj4Name == "tmerc")
                proj4Name = "utm";

            if (!TransformManager.Transforms.Exists(x => x.Proj4Name == proj4Name)) {
                if (GeodeticOperationNameRegex.IsMatch(proj4Name)) {
                    proj4Name = "longlat";
                }
                else {
                    throw new InvalidOperationException();
                }
            }

            switch (proj4Name) {
                case "omerc": {

                    var offsetXParam = new FalseEastingParameterSelector();
                    var offsetYParam = new FalseNorthingParameterSelector();
                    var xAtOriginParam = new EastingAtCenterParameterSelector();
                    var yAtOriginParam = new NorthingAtCenterParameterSelector();
                    var paramLookup = new NamedParameterLookup(projectionInfo.Parameters);
                    paramLookup.Assign(offsetXParam, offsetYParam, xAtOriginParam, yAtOriginParam);

                    if (offsetXParam.IsSelected || offsetYParam.IsSelected)
                        result.Transform = TransformManager.GetProjection("Hotine_Oblique_Mercator_Azimuth_Center");
                    else if(xAtOriginParam.IsSelected || yAtOriginParam.IsSelected)
                        result.Transform = TransformManager.GetProjection("Hotine_Oblique_Mercator_Azimuth_Natural_Origin");
                    else
                        result.Transform = TransformManager.GetProj4(proj4Name);

                    break;
                }
                default:
                    result.Transform = TransformManager.GetProj4(proj4Name);
                    break;
            }

            var finalResult = ProjectionInfo.FromProj4String(result.ToProj4String()); // TODO: fix this hack
            /*finalResult.CentralMeridian = result.CentralMeridian;
            finalResult.LongitudeOfCenter = result.LongitudeOfCenter;
            finalResult.LatitudeOfOrigin = result.LatitudeOfOrigin;
            finalResult.StandardParallel1 = result.StandardParallel1;
            finalResult.StandardParallel2 = result.StandardParallel2;
            finalResult.FalseEasting = result.FalseEasting;
            finalResult.FalseNorthing = result.FalseNorthing;
            finalResult.ScaleFactor = result.ScaleFactor;
            finalResult.alpha = result.alpha;
            finalResult.IsSouth = result.IsSouth;
            finalResult.Zone = result.Zone;
            finalResult.Unit = result.Unit;
            if (result.GeographicInfo == null) { // NOTE: this is all so terrible
                finalResult.GeographicInfo = null;
            }
            else {
                if (finalResult.GeographicInfo == null) {
                    finalResult.GeographicInfo = result.GeographicInfo;
                }
                else {
                    finalResult.GeographicInfo.Datum.Spheroid = result.GeographicInfo.Datum.Spheroid;
                }
            }*/
            return finalResult;
        }
        private SpheroidProjectionBase CreateHotineObliqueMercator(ProjectionCompilationParams opData)
        {
            Contract.Requires(opData != null);

            var latParam = new MultiParameterSelector(
                new LatitudeOfCenterParameterSelector(),
                new LatitudeOfNaturalOriginParameterSelector());
            var lonParam = new MultiParameterSelector(
                new LongitudeOfCenterParameterSelector(),
                new LongitudeOfNaturalOriginParameterSelector());

            var scaleFactorParam = new ScaleFactorParameterSelector();
            var azimuthParam = new KeywordNamedParameterSelector("AZIMUTH");
            var angleSkewParam = new KeywordNamedParameterSelector("ANGLE", "SKEW");

            var offsetXParam = new FalseEastingParameterSelector();
            var offsetYParam = new FalseNorthingParameterSelector();
            var xAtOriginParam = new EastingAtCenterParameterSelector();
            var yAtOriginParam = new NorthingAtCenterParameterSelector();

            opData.ParameterLookup.Assign(latParam, lonParam, offsetXParam, offsetYParam, xAtOriginParam, yAtOriginParam, scaleFactorParam, azimuthParam, angleSkewParam);

            var spheroid = opData.StepParams.ConvertRelatedOutputSpheroidUnit(opData.StepParams.RelatedOutputCrsUnit);
            if (null == spheroid)
                return null;

            double lat, lon;
            if(!latParam.IsSelected || !latParam.TryGetValueAsDouble(OgcAngularUnit.DefaultRadians, out lat))
                lat = 0;
            if(!lonParam.IsSelected || !lonParam.TryGetValueAsDouble(OgcAngularUnit.DefaultRadians, out lon))
                lon = 0;
            var origin = new GeographicCoordinate(lat, lon);

            double scaleFactor;
            if (!scaleFactorParam.IsSelected || !TryGetDouble(scaleFactorParam.Selection, ScaleUnitUnity.Value, out scaleFactor))
                scaleFactor = 1.0;

            double azimuth;
            if (!azimuthParam.IsSelected || !TryGetDouble(azimuthParam.Selection, OgcAngularUnit.DefaultRadians, out azimuth))
                azimuth = 0;

            double angleSkew;
            if (!angleSkewParam.IsSelected || !TryGetDouble(angleSkewParam.Selection, OgcAngularUnit.DefaultRadians, out angleSkew))
                angleSkew = 0;

            var outputUnit = opData.StepParams.RelatedOutputCrsUnit;
            double x,y;
            if(xAtOriginParam.IsSelected || yAtOriginParam.IsSelected){
                if (!xAtOriginParam.IsSelected || !xAtOriginParam.TryGetValueAsDouble(outputUnit, out x))
                    x = 0;
                if (!yAtOriginParam.IsSelected || !yAtOriginParam.TryGetValueAsDouble(outputUnit, out y))
                    y = 0;
                return new HotineObliqueMercator.VariantB(new GeographicCoordinate(lat, lon), azimuth, angleSkew, scaleFactor, new Vector2(x,y), spheroid);
            }
            else {
                if (!offsetXParam.IsSelected || !offsetXParam.TryGetValueAsDouble(outputUnit, out x))
                    x = 0;
                if (!offsetYParam.IsSelected || !offsetYParam.TryGetValueAsDouble(outputUnit, out y))
                    y = 0;
                return new HotineObliqueMercator.VariantA(new GeographicCoordinate(lat, lon), azimuth, angleSkew, scaleFactor, new Vector2(x,y), spheroid);
            }
        }