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); } }