Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dynamically finding crs nodes from xml if matching with preferred crs. if not but has nodes then take first available node from xml. if none apply take our first preferred crs #416

Merged
merged 3 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Assets/_BuildingBlocks/OGCWebServices/Shared/BaseRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ protected string GetInnerTextForNode(XmlNode layerNode, string nodeName, bool se
}
}

protected XmlNodeList GetNodesByName(XmlNode layerNode, string nodeName)
{
var queryForNode = $"*[local-name()='{nodeName}']";
return layerNode.SelectNodes($".//{queryForNode}", namespaceManager);
}

protected XmlNodeList GetNodesByNameAndAttributes(XmlNode layerNode, string nodeName)
{
var queryForNode = $"//*[local-name()='{nodeName}' or @*='{nodeName}']";
return layerNode.SelectNodes(queryForNode, namespaceManager);
}

protected XmlNode GetSingleNodeByName(XmlNode layerNode, string nodeName, bool searchInParents = false)
{
// Base query that will attempt to find the node; but we need more ...
Expand Down
61 changes: 54 additions & 7 deletions Assets/_Functionalities/Wms/Scripts/WmsGetCapabilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Xml;
using Netherlands3D.Coordinates;
using Netherlands3D.OgcWebServices.Shared;
using Netherlands3D.Twin.ExtensionMethods;
using Netherlands3D.Twin.Utility;
using UnityEngine;

Expand All @@ -13,6 +14,7 @@ public class WmsGetCapabilities : BaseRequest, IGetCapabilities
{
public Uri GetCapabilitiesUri => Url;
public const string DefaultFallbackVersion = "1.3.0";
private CoordinateSystem[] preferredCRS = { CoordinateSystem.RD, CoordinateSystem.WGS84_LatLon, CoordinateSystem.CRS84 };

public ServiceType ServiceType => ServiceType.Wms;
protected override Dictionary<string, string> defaultNameSpaces => new()
Expand All @@ -24,6 +26,8 @@ public class WmsGetCapabilities : BaseRequest, IGetCapabilities
{ "schemaLocation", "http://www.opengis.net/wms" }
};

private Dictionary<CoordinateSystem, string> supportedCrsDictionary = new Dictionary<CoordinateSystem, string>();

public bool CapableOfBoundingBoxes => xmlDocument.SelectSingleNode("//*[local-name()='EX_GeographicBoundingBox' or local-name()='BoundingBox']", namespaceManager) != null;

public bool HasBounds //todo: this is suboptimal because it uses the GetBounds function, maybe cache the bounds
Expand Down Expand Up @@ -184,13 +188,18 @@ public List<MapFilters> GetMaps(int width, int height, bool transparent)
// Extract styles for the layer
var styles = ExtractStyles(mapNode);

// CRS/SRS may be defined in the current MapNode, but can also inherit from a parent if it is not
// specified the flag at the end of this function will check the current node and its parents
var spatialReference = GetInnerTextForNode(mapNode, mapTemplate.spatialReferenceType, true);

// TODO: Really ugly fix to deal issues around EPSG:4326. So we fixate on CRS:84 now, hoping that will
// work in all situations
spatialReference = "CRS:84";
string spatialReference = null;
var spatialReferenceType = MapFilters.SpatialReferenceTypeFromVersion(new Version(mapTemplate.version));
XmlNodeList crsNodes = GetNodesByName(mapNode, spatialReferenceType);
if (crsNodes.Count == 0)
crsNodes = GetNodesByNameAndAttributes(mapNode, spatialReferenceType);

HasSupportedCRS(crsNodes, out spatialReference);
if (string.IsNullOrEmpty(spatialReference))
{
Debug.LogError("there is no CRS/SRS defined in the xml for this layer");
continue;
}

var map = new MapFilters()
{
Expand All @@ -210,6 +219,44 @@ public List<MapFilters> GetMaps(int width, int height, bool transparent)
return maps;
}

private bool HasSupportedCRS(XmlNodeList crsNodes, out string crsToUse)
{
supportedCrsDictionary.Clear();

//parse all available crs nodes
foreach (XmlNode crsNode in crsNodes)
{
var crsText = crsNode.InnerText;
crsText = crsText == "CRS:84" ? "CRS84" : crsText;
var hasCRS = CoordinateSystems.FindCoordinateSystem(crsText, out var crs);
if (hasCRS)
{
supportedCrsDictionary.Add(crs, crsNode.InnerText);
}
}

//try to get the preferred crs out of the list of available crses
foreach (var crs in preferredCRS)
{
if (supportedCrsDictionary.ContainsKey(crs))
{
crsToUse = supportedCrsDictionary[crs];
return true;
}
}

// our preferred crses are not available, use the first supported one
if (supportedCrsDictionary.Count > 0)
{
crsToUse = supportedCrsDictionary.Values.First();
return true;
}

//none of the crsses available in the WMS are supported by us
crsToUse = null;
return false;
}

private MapFilters CreateMapTemplate(int width, int height, bool transparent)
{
var version = GetVersion();
Expand Down
Loading