diff --git a/MapControl/Shared/EquirectangularProjection.cs b/MapControl/Shared/EquirectangularProjection.cs index d225bcea..c7e0c955 100644 --- a/MapControl/Shared/EquirectangularProjection.cs +++ b/MapControl/Shared/EquirectangularProjection.cs @@ -23,6 +23,7 @@ namespace MapControl public EquirectangularProjection(string crsId) { CrsId = crsId; + HasLatLonBoundingBox = CrsId != "CRS:84"; IsNormalCylindrical = true; TrueScale = 1d; } diff --git a/MapControl/Shared/MapProjection.cs b/MapControl/Shared/MapProjection.cs index 140a44ae..721b6889 100644 --- a/MapControl/Shared/MapProjection.cs +++ b/MapControl/Shared/MapProjection.cs @@ -27,19 +27,25 @@ namespace MapControl public const double Wgs84MetersPerDegree = Wgs84EquatorialRadius * Math.PI / 180d; /// - /// Gets or sets the WMS 1.3.0 CRS Identifier. + /// Gets or sets the WMS 1.3.0 CRS identifier. /// - public string CrsId { get; set; } + public string CrsId { get; protected set; } + + /// + /// Indicates if a lat/lon coordinate system is used for the WMS BBOX query parameter, + /// like e.g. in an EquirectangularProjection with CrsId="EPSG:4326" (but not CrsId="CRS:84"). + /// + public bool HasLatLonBoundingBox { get; protected set; } /// /// Indicates if this is a normal cylindrical projection. /// - public bool IsNormalCylindrical { get; protected set; } = false; + public bool IsNormalCylindrical { get; protected set; } /// /// Indicates if this is a web mercator projection, i.e. compatible with MapTileLayer. /// - public bool IsWebMercator { get; protected set; } = false; + public bool IsWebMercator { get; protected set; } /// /// Gets the scale factor from geographic to cartesian coordinates, on the line of true scale of a diff --git a/MapControl/Shared/WmsImageLayer.cs b/MapControl/Shared/WmsImageLayer.cs index fad30030..33e01dbc 100644 --- a/MapControl/Shared/WmsImageLayer.cs +++ b/MapControl/Shared/WmsImageLayer.cs @@ -39,10 +39,6 @@ namespace MapControl nameof(Format), typeof(string), typeof(WmsImageLayer), new PropertyMetadata("image/png", async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync())); - public static readonly DependencyProperty CrsIdMapProperty = DependencyProperty.Register( - nameof(CrsIdMap), typeof(string), typeof(WmsImageLayer), - new PropertyMetadata(null, async (o, e) => await ((WmsImageLayer)o).CrsIdMapPropertyChanged((string)e.NewValue))); - public Uri ServiceUri { get { return (Uri)GetValue(ServiceUriProperty); } @@ -67,14 +63,6 @@ namespace MapControl set { SetValue(FormatProperty, value); } } - public string CrsIdMap - { - get { return (string)GetValue(CrsIdMapProperty); } - set { SetValue(CrsIdMapProperty, value); } - } - - private Dictionary crsIdMap; - /// /// Gets a list of all layer names returned by a GetCapabilities response. /// @@ -151,10 +139,10 @@ namespace MapControl uri += "&FORMAT=" + Format; } - var crs = GetCrsValue(); var rect = projection.BoundingBoxToRect(BoundingBox); - uri += "&" + GetBboxParameters(crs, rect); + uri += "&" + GetCrsParam(projection); + uri += "&" + GetBboxParam(projection, rect); uri += "&WIDTH=" + (int)Math.Round(projection.ViewportScale * rect.Width); uri += "&HEIGHT=" + (int)Math.Round(projection.ViewportScale * rect.Height); @@ -168,33 +156,27 @@ namespace MapControl /// Gets the effective value of the CRS query parameter. /// /// - protected virtual string GetCrsValue() + protected virtual string GetCrsParam(MapProjection projection) { - var projection = ParentMap.MapProjection; - var crsId = projection.CrsId; + var crs = "CRS=" + projection.CrsId; - if (crsIdMap != null && !crsIdMap.TryGetValue(crsId, out crsId)) + if (projection.CrsId.StartsWith("AUTO2:")) { - crsId = projection.CrsId; + crs += string.Format(CultureInfo.InvariantCulture, ",1,{0},{1}", + projection.ProjectionCenter.Longitude, projection.ProjectionCenter.Latitude); } - if (crsId.StartsWith("AUTO2:") || crsId.StartsWith("AUTO:")) - { - crsId = string.Format(CultureInfo.InvariantCulture, "{0},1,{1},{2}", - crsId, projection.ProjectionCenter.Longitude, projection.ProjectionCenter.Latitude); - } - - return crsId; + return crs; } /// - /// Gets a query substring for the projected bounding box, which contains the CRS and BBOX or equivalent parameters. + /// Gets the effective value of the BBOX (or some equivalent) query parameter. /// - protected virtual string GetBboxParameters(string crs, Rect bbox) + protected virtual string GetBboxParam(MapProjection projection, Rect bbox) { return string.Format(CultureInfo.InvariantCulture, - crs == "EPSG:4326" ? "CRS={0}&BBOX={2},{1},{4},{3}" : "CRS={0}&BBOX={1},{2},{3},{4}", - crs, bbox.X, bbox.Y, (bbox.X + bbox.Width), (bbox.Y + bbox.Height)); + projection.HasLatLonBoundingBox ? "BBOX={1},{0},{3},{2}" : "BBOX={0},{1},{2},{3}", + bbox.X, bbox.Y, (bbox.X + bbox.Width), (bbox.Y + bbox.Height)); } private string GetRequestUri(string request) @@ -219,28 +201,6 @@ namespace MapControl return uri + "REQUEST=" + request; } - private Task CrsIdMapPropertyChanged(string crsIdMapString) - { - crsIdMap = null; - - if (!string.IsNullOrEmpty(crsIdMapString)) - { - var entries = crsIdMapString.Split(new char[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries); - - if (entries.Length >= 2) - { - crsIdMap = new Dictionary(); - - for (int i = 0; i < entries.Length - 1; i += 2) - { - crsIdMap[entries[i]] = entries[i + 1]; - } - } - } - - return UpdateImageAsync(); - } - private static IEnumerable ChildElements(XmlElement element, string name) { return element.ChildNodes.OfType().Where(e => (string)e.LocalName == name); diff --git a/MapProjections/Shared/GeoApiProjection.cs b/MapProjections/Shared/GeoApiProjection.cs index 28dbaf6f..c7332df5 100644 --- a/MapProjections/Shared/GeoApiProjection.cs +++ b/MapProjections/Shared/GeoApiProjection.cs @@ -53,8 +53,6 @@ namespace MapControl.Projections ? string.Format("{0}:{1}", coordinateSystem.Authority, coordinateSystem.AuthorityCode) : null; - IsWebMercator = CrsId == "EPSG:3857" || CrsId == "EPSG:900913"; - var projection = (coordinateSystem as IProjectedCoordinateSystem)?.Projection; if (projection != null) @@ -65,16 +63,20 @@ namespace MapControl.Projections var falseNorthing = projection.GetParameter("false_northing"); var scaleFactor = projection.GetParameter("scale_factor"); + HasLatLonBoundingBox = false; IsNormalCylindrical = centralMeridian != null && centralMeridian.Value == 0d && centralParallel != null && centralParallel.Value == 0d && (falseEasting == null || falseEasting.Value == 0d) && (falseNorthing == null || falseNorthing.Value == 0d); + IsWebMercator = CrsId == "EPSG:3857" || CrsId == "EPSG:900913"; TrueScale = (scaleFactor != null ? scaleFactor.Value : 1d) * Wgs84MetersPerDegree; } else { + HasLatLonBoundingBox = true; IsNormalCylindrical = true; + IsWebMercator = false; TrueScale = 1d; } }