mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Improved MapProjections
This commit is contained in:
parent
558dd2f98a
commit
b607268e98
|
|
@ -23,6 +23,7 @@ namespace MapControl
|
|||
public EquirectangularProjection(string crsId)
|
||||
{
|
||||
CrsId = crsId;
|
||||
HasLatLonBoundingBox = CrsId != "CRS:84";
|
||||
IsNormalCylindrical = true;
|
||||
TrueScale = 1d;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,19 +27,25 @@ namespace MapControl
|
|||
public const double Wgs84MetersPerDegree = Wgs84EquatorialRadius * Math.PI / 180d;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WMS 1.3.0 CRS Identifier.
|
||||
/// Gets or sets the WMS 1.3.0 CRS identifier.
|
||||
/// </summary>
|
||||
public string CrsId { get; set; }
|
||||
public string CrsId { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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").
|
||||
/// </summary>
|
||||
public bool HasLatLonBoundingBox { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this is a normal cylindrical projection.
|
||||
/// </summary>
|
||||
public bool IsNormalCylindrical { get; protected set; } = false;
|
||||
public bool IsNormalCylindrical { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this is a web mercator projection, i.e. compatible with MapTileLayer.
|
||||
/// </summary>
|
||||
public bool IsWebMercator { get; protected set; } = false;
|
||||
public bool IsWebMercator { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale factor from geographic to cartesian coordinates, on the line of true scale of a
|
||||
|
|
|
|||
|
|
@ -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<string, string> crsIdMap;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all layer names returned by a GetCapabilities response.
|
||||
/// </summary>
|
||||
|
|
@ -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.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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<string, string>();
|
||||
|
||||
for (int i = 0; i < entries.Length - 1; i += 2)
|
||||
{
|
||||
crsIdMap[entries[i]] = entries[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return UpdateImageAsync();
|
||||
}
|
||||
|
||||
private static IEnumerable<XmlElement> ChildElements(XmlElement element, string name)
|
||||
{
|
||||
return element.ChildNodes.OfType<XmlElement>().Where(e => (string)e.LocalName == name);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue