Index: src/Common/SharpMap/Web/Wms/Client.cs
===================================================================
diff -u -r8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9 -r5fc71a385897af92ccb092f2f969b5709afab85a
--- src/Common/SharpMap/Web/Wms/Client.cs (.../Client.cs) (revision 8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9)
+++ src/Common/SharpMap/Web/Wms/Client.cs (.../Client.cs) (revision 5fc71a385897af92ccb092f2f969b5709afab85a)
@@ -1,496 +1,534 @@
using System;
using System.Collections.ObjectModel;
+using System.Drawing;
+using System.Globalization;
+using System.IO;
+using System.Net;
using System.Text;
using System.Xml;
using GeoAPI.Geometries;
+using SharpMap.Converters.Geometries;
namespace SharpMap.Web.Wms
{
- ///
- /// Class for requesting and parsing a WMS servers capabilities
- ///
- [Serializable]
- public class Client
- {
- private XmlNamespaceManager nsmgr;
+ ///
+ /// Class for requesting and parsing a WMS servers capabilities
+ ///
+ [Serializable]
+ public class Client
+ {
+ private XmlNamespaceManager nsmgr;
- #region WMS Data structures
+ ///
+ /// Initalizes WMS server and parses the Capabilities request
+ ///
+ /// URL of wms server
+ public Client(string url)
+ : this(url, null) {}
- ///
- /// Structure for holding information about a WMS Layer
- ///
- public struct WmsServerLayer
- {
- ///
- /// Layer title
- ///
- public string Title;
- ///
- /// Unique name of this layer used for requesting layer
- ///
- public string Name;
- ///
- /// Abstract
- ///
- public string Abstract;
- ///
- /// Specifies whether this layer is queryable using GetFeatureInfo requests
- ///
- public bool Queryable;
- ///
- /// Keywords
- ///
- public string[] Keywords;
- ///
- /// List of styles supported by layer
- ///
- public WmsLayerStyle[] Style;
- ///
- /// Coordinate Reference Systems supported by layer
- ///
- public string[] CRS;
- ///
- /// Collection of child layers
- ///
- public WmsServerLayer[] ChildLayers;
- ///
- /// Latitudal/longitudal extent of this layer
- ///
- public IEnvelope LatLonBoundingBox;
- }
+ ///
+ /// Initalizes WMS server and parses the Capabilities request
+ ///
+ /// URL of wms server
+ /// Proxy to use
+ public Client(string url, WebProxy proxy)
+ {
+ StringBuilder strReq = new StringBuilder(url);
+ if (!url.Contains("?"))
+ {
+ strReq.Append("?");
+ }
+ if (!strReq.ToString().EndsWith("&") && !strReq.ToString().EndsWith("?"))
+ {
+ strReq.Append("&");
+ }
+ if (!url.ToLower().Contains("service=wms"))
+ {
+ strReq.AppendFormat("SERVICE=WMS&");
+ }
+ if (!url.ToLower().Contains("request=getcapabilities"))
+ {
+ strReq.AppendFormat("REQUEST=GetCapabilities&");
+ }
- ///
- /// Structure for storing information about a WMS Layer Style
- ///
- public struct WmsLayerStyle
- {
- ///
- /// Name
- ///
- public string Name;
- ///
- /// Title
- ///
- public string Title;
- ///
- /// Abstract
- ///
- public string Abstract;
- ///
- /// Legend
- ///
- public WmsStyleLegend LegendUrl;
- ///
- /// Style Sheet Url
- ///
- public WmsOnlineResource StyleSheetUrl;
- }
+ XmlDocument xml = GetRemoteXml(strReq.ToString(), proxy);
+ ParseCapabilities(xml);
+ }
- ///
- /// Structure for storing WMS Legend information
- ///
- public struct WmsStyleLegend
- {
- ///
- /// Online resource for legend style
- ///
- public WmsOnlineResource OnlineResource;
- ///
- /// Size of legend
- ///
- public System.Drawing.Size Size;
- }
+ ///
+ /// Downloads servicedescription from WMS service
+ ///
+ /// XmlDocument from Url. Null if Url is empty or inproper XmlDocument
+ private XmlDocument GetRemoteXml(string Url, WebProxy proxy)
+ {
+ try
+ {
+ WebRequest myRequest = WebRequest.Create(Url);
+ if (proxy != null)
+ {
+ myRequest.Proxy = proxy;
+ }
+ WebResponse myResponse = myRequest.GetResponse();
+ Stream stream = myResponse.GetResponseStream();
+ XmlTextReader r = new XmlTextReader(Url, stream);
+ XmlDocument doc = new XmlDocument();
+ doc.Load(r);
+ stream.Close();
+ nsmgr = new XmlNamespaceManager(doc.NameTable);
+ return doc;
+ }
+ catch (Exception ex)
+ {
+ throw new ApplicationException("Could now download capabilities", ex);
+ }
+ }
- ///
- /// Structure for storing info on an Online Resource
- ///
- public struct WmsOnlineResource
- {
- ///
- /// Type of online resource (Ex. request method 'Get' or 'Post')
- ///
- public string Type;
- ///
- /// URI of online resource
- ///
- public string OnlineResource;
- }
+ ///
+ /// Parses a servicedescription and stores the data in the ServiceDescription property
+ ///
+ /// XmlDocument containing a valid Service Description
+ private void ParseCapabilities(XmlDocument doc)
+ {
+ if (doc.DocumentElement.Attributes["version"] != null)
+ {
+ WmsVersion = doc.DocumentElement.Attributes["version"].Value;
+ if (WmsVersion != "1.0.0" && WmsVersion != "1.1.0" && WmsVersion != "1.1.1" && WmsVersion != "1.3.0")
+ {
+ throw new ApplicationException("WMS Version " + WmsVersion + " not supported");
+ }
- #endregion
+ nsmgr.AddNamespace(String.Empty, "http://www.opengis.net/wms");
+ if (WmsVersion == "1.3.0")
+ {
+ nsmgr.AddNamespace("sm", "http://www.opengis.net/wms");
+ }
+ else
+ {
+ nsmgr.AddNamespace("sm", "");
+ }
+ nsmgr.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
+ nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
+ }
+ else
+ {
+ throw (new ApplicationException("No service version number found!"));
+ }
- #region Properties
+ XmlNode xnService = doc.DocumentElement.SelectSingleNode("sm:Service", nsmgr);
+ XmlNode xnCapability = doc.DocumentElement.SelectSingleNode("sm:Capability", nsmgr);
+ if (xnService != null)
+ {
+ ParseServiceDescription(xnService);
+ }
+ else
+ {
+ throw (new ApplicationException("No service tag found!"));
+ }
- private Capabilities.WmsServiceDescription _ServiceDescription;
+ if (xnCapability != null)
+ {
+ ParseCapability(xnCapability);
+ }
+ else
+ {
+ throw (new ApplicationException("No capability tag found!"));
+ }
+ }
- ///
- /// Gets the service description
- ///
- public Capabilities.WmsServiceDescription ServiceDescription
- {
- get { return _ServiceDescription; }
- }
- private string _WmsVersion;
+ ///
+ /// Parses service description node
+ ///
+ ///
+ private void ParseServiceDescription(XmlNode xnlServiceDescription)
+ {
+ XmlNode node = xnlServiceDescription.SelectSingleNode("sm:Title", nsmgr);
+ _ServiceDescription.Title = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:OnlineResource/@xlink:href", nsmgr);
+ _ServiceDescription.OnlineResource = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:Abstract", nsmgr);
+ _ServiceDescription.Abstract = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:Fees", nsmgr);
+ _ServiceDescription.Fees = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:AccessConstraints", nsmgr);
+ _ServiceDescription.AccessConstraints = (node != null ? node.InnerText : null);
- ///
- /// Gets the version of the WMS server (ex. "1.3.0")
- ///
- public string WmsVersion
- {
- get { return _WmsVersion; }
- }
+ XmlNodeList xnlKeywords = xnlServiceDescription.SelectNodes("sm:KeywordList/sm:Keyword", nsmgr);
+ if (xnlKeywords != null)
+ {
+ _ServiceDescription.Keywords = new string[xnlKeywords.Count];
+ for (int i = 0; i < xnlKeywords.Count; i++)
+ {
+ ServiceDescription.Keywords[i] = xnlKeywords[i].InnerText;
+ }
+ }
+ //Contact information
+ _ServiceDescription.ContactInformation = new Capabilities.WmsContactInformation();
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:Address", nsmgr);
+ _ServiceDescription.ContactInformation.Address.Address = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:AddressType", nsmgr);
+ _ServiceDescription.ContactInformation.Address.AddressType = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:City", nsmgr);
+ _ServiceDescription.ContactInformation.Address.City = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:Country", nsmgr);
+ _ServiceDescription.ContactInformation.Address.Country = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:PostCode", nsmgr);
+ _ServiceDescription.ContactInformation.Address.PostCode = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactElectronicMailAddress", nsmgr);
+ _ServiceDescription.ContactInformation.Address.StateOrProvince = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactElectronicMailAddress", nsmgr);
+ _ServiceDescription.ContactInformation.ElectronicMailAddress = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactFacsimileTelephone", nsmgr);
+ _ServiceDescription.ContactInformation.FacsimileTelephone = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactPersonPrimary/sm:ContactOrganisation", nsmgr);
+ _ServiceDescription.ContactInformation.PersonPrimary.Organisation = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactPersonPrimary/sm:ContactPerson", nsmgr);
+ _ServiceDescription.ContactInformation.PersonPrimary.Person = (node != null ? node.InnerText : null);
+ node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactVoiceTelephone", nsmgr);
+ _ServiceDescription.ContactInformation.VoiceTelephone = (node != null ? node.InnerText : null);
+ }
- private Collection _GetMapOutputFormats;
+ ///
+ /// Parses capability node
+ ///
+ ///
+ private void ParseCapability(XmlNode xnCapability)
+ {
+ XmlNode xnRequest = xnCapability.SelectSingleNode("sm:Request", nsmgr);
+ if (xnRequest == null)
+ {
+ throw (new Exception("Request parameter not specified in Service Description"));
+ }
+ ParseRequest(xnRequest);
+ XmlNode xnLayer = xnCapability.SelectSingleNode("sm:Layer", nsmgr);
+ if (xnLayer == null)
+ {
+ throw (new Exception("No layer tag found in Service Description"));
+ }
+ Layer = ParseLayer(xnLayer);
- ///
- /// Gets a list of available image mime type formats
- ///
- public Collection GetMapOutputFormats
- {
- get { return _GetMapOutputFormats; }
- }
+ XmlNode xnException = xnCapability.SelectSingleNode("sm:Exception", nsmgr);
+ if (xnException != null)
+ {
+ ParseExceptions(xnException);
+ }
+ }
- private string[] _ExceptionFormats;
+ ///
+ /// Parses valid exceptions
+ ///
+ ///
+ private void ParseExceptions(XmlNode xnlExceptionNode)
+ {
+ XmlNodeList xnlFormats = xnlExceptionNode.SelectNodes("sm:Format", nsmgr);
+ if (xnlFormats != null)
+ {
+ ExceptionFormats = new string[xnlFormats.Count];
+ for (int i = 0; i < xnlFormats.Count; i++)
+ {
+ ExceptionFormats[i] = xnlFormats[i].InnerText;
+ }
+ }
+ }
- ///
- /// Gets a list of available exception mime type formats
- ///
- public string[] ExceptionFormats
- {
- get { return _ExceptionFormats; }
- }
+ ///
+ /// Parses request node
+ ///
+ ///
+ private void ParseRequest(XmlNode xmlRequestNode)
+ {
+ XmlNode xnGetMap = xmlRequestNode.SelectSingleNode("sm:GetMap", nsmgr);
+ ParseGetMapRequest(xnGetMap);
+ //TODO:
+ //XmlNode xnGetFeatureInfo = xmlRequestNodes.SelectSingleNode("sm:GetFeatureInfo", nsmgr);
+ //XmlNode xnCapa = xmlRequestNodes.SelectSingleNode("sm:GetCapabilities", nsmgr); <-- We don't really need this do we?
+ }
- private WmsOnlineResource[] _GetMapRequests;
+ ///
+ /// Parses GetMap request nodes
+ ///
+ ///
+ private void ParseGetMapRequest(XmlNode GetMapRequestNodes)
+ {
+ XmlNode xnlHttp = GetMapRequestNodes.SelectSingleNode("sm:DCPType/sm:HTTP", nsmgr);
+ if (xnlHttp != null && xnlHttp.HasChildNodes)
+ {
+ GetMapRequests = new WmsOnlineResource[xnlHttp.ChildNodes.Count];
+ for (int i = 0; i < xnlHttp.ChildNodes.Count; i++)
+ {
+ WmsOnlineResource wor = new WmsOnlineResource();
+ wor.Type = xnlHttp.ChildNodes[i].Name;
+ wor.OnlineResource = xnlHttp.ChildNodes[i].SelectSingleNode("sm:OnlineResource", nsmgr).Attributes["xlink:href"].InnerText;
+ GetMapRequests[i] = wor;
+ }
+ }
+ XmlNodeList xnlFormats = GetMapRequestNodes.SelectNodes("sm:Format", nsmgr);
+ //_GetMapOutputFormats = new Collection(xnlFormats.Count);
+ GetMapOutputFormats = new Collection();
+ for (int i = 0; i < xnlFormats.Count; i++)
+ {
+ GetMapOutputFormats.Add(xnlFormats[i].InnerText);
+ }
+ }
- ///
- /// Gets the available GetMap request methods and Online Resource URI
- ///
- public WmsOnlineResource[] GetMapRequests
- {
- get { return _GetMapRequests; }
- }
+ ///
+ /// Iterates through the layer nodes recursively
+ ///
+ ///
+ ///
+ private WmsServerLayer ParseLayer(XmlNode xmlLayer)
+ {
+ WmsServerLayer layer = new WmsServerLayer();
+ XmlNode node = xmlLayer.SelectSingleNode("sm:Name", nsmgr);
+ layer.Name = (node != null ? node.InnerText : null);
+ node = xmlLayer.SelectSingleNode("sm:Title", nsmgr);
+ layer.Title = (node != null ? node.InnerText : null);
+ if (string.IsNullOrEmpty(layer.Name))
+ {
+ layer.Name = layer.Title;
+ }
+ node = xmlLayer.SelectSingleNode("sm:Abstract", nsmgr);
+ layer.Abstract = (node != null ? node.InnerText : null);
+ XmlAttribute attr = xmlLayer.Attributes["queryable"];
+ layer.Queryable = (attr != null && attr.InnerText == "1");
- private WmsServerLayer _Layer;
- ///
- /// Gets the hiarchial layer structure
- ///
- public WmsServerLayer Layer
- {
- get { return _Layer; }
- }
- #endregion
+ XmlNodeList xnlKeywords = xmlLayer.SelectNodes("sm:KeywordList/sm:Keyword", nsmgr);
+ if (xnlKeywords != null)
+ {
+ layer.Keywords = new string[xnlKeywords.Count];
+ for (int i = 0; i < xnlKeywords.Count; i++)
+ {
+ layer.Keywords[i] = xnlKeywords[i].InnerText;
+ }
+ }
+ XmlNodeList xnlCrs = xmlLayer.SelectNodes("sm:CRS", nsmgr);
+ if (xnlCrs != null)
+ {
+ layer.CRS = new string[xnlCrs.Count];
+ for (int i = 0; i < xnlCrs.Count; i++)
+ {
+ layer.CRS[i] = xnlCrs[i].InnerText;
+ }
+ }
+ XmlNodeList xnlStyle = xmlLayer.SelectNodes("sm:Style", nsmgr);
+ if (xnlStyle != null)
+ {
+ layer.Style = new WmsLayerStyle[xnlStyle.Count];
+ for (int i = 0; i < xnlStyle.Count; i++)
+ {
+ node = xnlStyle[i].SelectSingleNode("sm:Name", nsmgr);
+ layer.Style[i].Name = (node != null ? node.InnerText : null);
+ node = xnlStyle[i].SelectSingleNode("sm:Title", nsmgr);
+ layer.Style[i].Title = (node != null ? node.InnerText : null);
+ node = xnlStyle[i].SelectSingleNode("sm:Abstract", nsmgr);
+ layer.Style[i].Abstract = (node != null ? node.InnerText : null);
+ node = xnlStyle[i].SelectSingleNode("sm:LegendUrl", nsmgr);
+ if (node != null)
+ {
+ layer.Style[i].LegendUrl = new WmsStyleLegend();
+ layer.Style[i].LegendUrl.Size = new Size(
+ int.Parse(node.Attributes["width"].InnerText), int.Parse(node.Attributes["height"].InnerText));
+ layer.Style[i].LegendUrl.OnlineResource.OnlineResource = node.SelectSingleNode("sm:OnlineResource", nsmgr).Attributes["xlink:href"].InnerText;
+ layer.Style[i].LegendUrl.OnlineResource.Type = node.SelectSingleNode("sm:Format", nsmgr).InnerText;
+ }
+ node = xnlStyle[i].SelectSingleNode("sm:StyleSheetURL", nsmgr);
+ if (node != null)
+ {
+ layer.Style[i].StyleSheetUrl = new WmsOnlineResource();
+ layer.Style[i].StyleSheetUrl.OnlineResource = node.SelectSingleNode("sm:OnlineResource", nsmgr).Attributes["xlink:href"].InnerText;
+ //layer.Style[i].StyleSheetUrl.OnlineResource = node.SelectSingleNode("sm:Format", nsmgr).InnerText;
+ }
+ }
+ }
+ XmlNodeList xnlLayers = xmlLayer.SelectNodes("sm:Layer", nsmgr);
+ if (xnlLayers != null)
+ {
+ layer.ChildLayers = new WmsServerLayer[xnlLayers.Count];
+ for (int i = 0; i < xnlLayers.Count; i++)
+ {
+ layer.ChildLayers[i] = ParseLayer(xnlLayers[i]);
+ }
+ }
+ node = xmlLayer.SelectSingleNode("sm:LatLonBoundingBox", nsmgr);
+ if (node == null)
+ {
+ node = xmlLayer.SelectSingleNode("sm:BoundingBox", nsmgr);
+ }
+ if (node != null)
+ {
+ double minx = 0;
+ double miny = 0;
+ double maxx = 0;
+ double maxy = 0;
+ if (!double.TryParse(node.Attributes["minx"].Value, NumberStyles.Any, Map.numberFormat_EnUS, out minx) &
+ !double.TryParse(node.Attributes["miny"].Value, NumberStyles.Any, Map.numberFormat_EnUS, out miny) &
+ !double.TryParse(node.Attributes["maxx"].Value, NumberStyles.Any, Map.numberFormat_EnUS, out maxx) &
+ !double.TryParse(node.Attributes["maxy"].Value, NumberStyles.Any, Map.numberFormat_EnUS, out maxy))
+ {
+ throw new ArgumentException("Invalid LatLonBoundingBox on layer '" + layer.Name + "'");
+ }
+ layer.LatLonBoundingBox = GeometryFactory.CreateEnvelope(minx, maxx, miny, maxy);
+ }
+ return layer;
+ }
- ///
- /// Initalizes WMS server and parses the Capabilities request
- ///
- /// URL of wms server
- public Client(string url)
- : this(url, null)
- {
- }
+ #region WMS Data structures
- ///
- /// Initalizes WMS server and parses the Capabilities request
- ///
- /// URL of wms server
- /// Proxy to use
- public Client(string url, System.Net.WebProxy proxy)
- {
- System.Text.StringBuilder strReq = new StringBuilder(url);
- if (!url.Contains("?"))
- strReq.Append("?");
- if (!strReq.ToString().EndsWith("&") && !strReq.ToString().EndsWith("?"))
- strReq.Append("&");
- if(!url.ToLower().Contains("service=wms"))
- strReq.AppendFormat("SERVICE=WMS&");
- if (!url.ToLower().Contains("request=getcapabilities"))
- strReq.AppendFormat("REQUEST=GetCapabilities&");
+ ///
+ /// Structure for holding information about a WMS Layer
+ ///
+ public struct WmsServerLayer
+ {
+ ///
+ /// Layer title
+ ///
+ public string Title;
- XmlDocument xml = GetRemoteXml(strReq.ToString(), proxy);
- ParseCapabilities(xml);
- }
+ ///
+ /// Unique name of this layer used for requesting layer
+ ///
+ public string Name;
+ ///
+ /// Abstract
+ ///
+ public string Abstract;
- ///
- /// Downloads servicedescription from WMS service
- ///
- /// XmlDocument from Url. Null if Url is empty or inproper XmlDocument
- private XmlDocument GetRemoteXml(string Url, System.Net.WebProxy proxy)
- {
- try
- {
- System.Net.WebRequest myRequest = System.Net.WebRequest.Create(Url);
- if (proxy != null) myRequest.Proxy = proxy;
- System.Net.WebResponse myResponse = myRequest.GetResponse();
- System.IO.Stream stream = myResponse.GetResponseStream();
- XmlTextReader r = new XmlTextReader(Url, stream);
- XmlDocument doc = new XmlDocument();
- doc.Load(r);
- stream.Close();
- nsmgr = new XmlNamespaceManager(doc.NameTable);
- return doc;
- }
- catch (System.Exception ex)
- {
- throw new ApplicationException("Could now download capabilities", ex);
- }
- }
+ ///
+ /// Specifies whether this layer is queryable using GetFeatureInfo requests
+ ///
+ public bool Queryable;
+ ///
+ /// Keywords
+ ///
+ public string[] Keywords;
- ///
- /// Parses a servicedescription and stores the data in the ServiceDescription property
- ///
- /// XmlDocument containing a valid Service Description
- private void ParseCapabilities(XmlDocument doc)
- {
- if (doc.DocumentElement.Attributes["version"] != null)
- {
- _WmsVersion = doc.DocumentElement.Attributes["version"].Value;
- if (_WmsVersion != "1.0.0" && _WmsVersion != "1.1.0" && _WmsVersion != "1.1.1" && _WmsVersion != "1.3.0")
- throw new ApplicationException("WMS Version " + _WmsVersion + " not supported");
+ ///
+ /// List of styles supported by layer
+ ///
+ public WmsLayerStyle[] Style;
- nsmgr.AddNamespace(String.Empty, "http://www.opengis.net/wms");
- if (_WmsVersion == "1.3.0")
- {
- nsmgr.AddNamespace("sm", "http://www.opengis.net/wms");
- }
- else
- nsmgr.AddNamespace("sm", "");
- nsmgr.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
- nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
- }
- else
- throw (new ApplicationException("No service version number found!"));
+ ///
+ /// Coordinate Reference Systems supported by layer
+ ///
+ public string[] CRS;
- XmlNode xnService = doc.DocumentElement.SelectSingleNode("sm:Service", nsmgr);
- XmlNode xnCapability = doc.DocumentElement.SelectSingleNode("sm:Capability", nsmgr);
- if (xnService != null)
- ParseServiceDescription(xnService);
- else
- throw (new ApplicationException("No service tag found!"));
+ ///
+ /// Collection of child layers
+ ///
+ public WmsServerLayer[] ChildLayers;
+ ///
+ /// Latitudal/longitudal extent of this layer
+ ///
+ public IEnvelope LatLonBoundingBox;
+ }
+ ///
+ /// Structure for storing information about a WMS Layer Style
+ ///
+ public struct WmsLayerStyle
+ {
+ ///
+ /// Name
+ ///
+ public string Name;
- if (xnCapability != null)
- ParseCapability(xnCapability);
- else
- throw (new ApplicationException("No capability tag found!"));
- }
+ ///
+ /// Title
+ ///
+ public string Title;
- ///
- /// Parses service description node
- ///
- ///
- private void ParseServiceDescription(XmlNode xnlServiceDescription)
- {
- XmlNode node = xnlServiceDescription.SelectSingleNode("sm:Title", nsmgr);
- _ServiceDescription.Title = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:OnlineResource/@xlink:href", nsmgr);
- _ServiceDescription.OnlineResource = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:Abstract", nsmgr);
- _ServiceDescription.Abstract = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:Fees", nsmgr);
- _ServiceDescription.Fees = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:AccessConstraints", nsmgr);
- _ServiceDescription.AccessConstraints = (node != null ? node.InnerText : null);
+ ///
+ /// Abstract
+ ///
+ public string Abstract;
- XmlNodeList xnlKeywords = xnlServiceDescription.SelectNodes("sm:KeywordList/sm:Keyword", nsmgr);
- if (xnlKeywords != null)
- {
- _ServiceDescription.Keywords = new string[xnlKeywords.Count];
- for (int i = 0; i < xnlKeywords.Count; i++)
- ServiceDescription.Keywords[i] = xnlKeywords[i].InnerText;
- }
- //Contact information
- _ServiceDescription.ContactInformation = new Capabilities.WmsContactInformation();
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:Address", nsmgr);
- _ServiceDescription.ContactInformation.Address.Address = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:AddressType", nsmgr);
- _ServiceDescription.ContactInformation.Address.AddressType = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:City", nsmgr);
- _ServiceDescription.ContactInformation.Address.City = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:Country", nsmgr);
- _ServiceDescription.ContactInformation.Address.Country = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactAddress/sm:PostCode", nsmgr);
- _ServiceDescription.ContactInformation.Address.PostCode = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactElectronicMailAddress", nsmgr);
- _ServiceDescription.ContactInformation.Address.StateOrProvince = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactElectronicMailAddress", nsmgr);
- _ServiceDescription.ContactInformation.ElectronicMailAddress = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactFacsimileTelephone", nsmgr);
- _ServiceDescription.ContactInformation.FacsimileTelephone = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactPersonPrimary/sm:ContactOrganisation", nsmgr);
- _ServiceDescription.ContactInformation.PersonPrimary.Organisation = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactPersonPrimary/sm:ContactPerson", nsmgr);
- _ServiceDescription.ContactInformation.PersonPrimary.Person = (node != null ? node.InnerText : null);
- node = xnlServiceDescription.SelectSingleNode("sm:ContactInformation/sm:ContactVoiceTelephone", nsmgr);
- _ServiceDescription.ContactInformation.VoiceTelephone = (node != null ? node.InnerText : null);
- }
-
- ///
- /// Parses capability node
- ///
- ///
- private void ParseCapability(XmlNode xnCapability)
- {
- XmlNode xnRequest = xnCapability.SelectSingleNode("sm:Request", nsmgr);
- if (xnRequest == null)
- throw (new System.Exception("Request parameter not specified in Service Description"));
- ParseRequest(xnRequest);
- XmlNode xnLayer = xnCapability.SelectSingleNode("sm:Layer", nsmgr);
- if (xnLayer == null)
- throw (new System.Exception("No layer tag found in Service Description"));
- _Layer = ParseLayer(xnLayer);
-
- XmlNode xnException = xnCapability.SelectSingleNode("sm:Exception", nsmgr);
- if (xnException != null)
- ParseExceptions(xnException);
- }
+ ///
+ /// Legend
+ ///
+ public WmsStyleLegend LegendUrl;
- ///
- /// Parses valid exceptions
- ///
- ///
- private void ParseExceptions(XmlNode xnlExceptionNode)
- {
- XmlNodeList xnlFormats = xnlExceptionNode.SelectNodes("sm:Format", nsmgr);
- if (xnlFormats != null)
- {
- _ExceptionFormats = new string[xnlFormats.Count];
- for (int i = 0; i < xnlFormats.Count; i++)
- {
- _ExceptionFormats[i] = xnlFormats[i].InnerText;
- }
- }
- }
+ ///
+ /// Style Sheet Url
+ ///
+ public WmsOnlineResource StyleSheetUrl;
+ }
- ///
- /// Parses request node
- ///
- ///
- private void ParseRequest(XmlNode xmlRequestNode)
- {
- XmlNode xnGetMap = xmlRequestNode.SelectSingleNode("sm:GetMap",nsmgr);
- ParseGetMapRequest(xnGetMap);
- //TODO:
- //XmlNode xnGetFeatureInfo = xmlRequestNodes.SelectSingleNode("sm:GetFeatureInfo", nsmgr);
- //XmlNode xnCapa = xmlRequestNodes.SelectSingleNode("sm:GetCapabilities", nsmgr); <-- We don't really need this do we?
- }
+ ///
+ /// Structure for storing WMS Legend information
+ ///
+ public struct WmsStyleLegend
+ {
+ ///
+ /// Online resource for legend style
+ ///
+ public WmsOnlineResource OnlineResource;
- ///
- /// Parses GetMap request nodes
- ///
- ///
- private void ParseGetMapRequest(XmlNode GetMapRequestNodes)
- {
- XmlNode xnlHttp = GetMapRequestNodes.SelectSingleNode("sm:DCPType/sm:HTTP", nsmgr);
- if (xnlHttp != null && xnlHttp.HasChildNodes)
- {
- _GetMapRequests = new WmsOnlineResource[xnlHttp.ChildNodes.Count];
- for (int i = 0; i < xnlHttp.ChildNodes.Count; i++)
- {
+ ///
+ /// Size of legend
+ ///
+ public Size Size;
+ }
- WmsOnlineResource wor = new WmsOnlineResource();
- wor.Type = xnlHttp.ChildNodes[i].Name;
- wor.OnlineResource = xnlHttp.ChildNodes[i].SelectSingleNode("sm:OnlineResource", nsmgr).Attributes["xlink:href"].InnerText;
- _GetMapRequests[i] = wor;
- }
- }
- XmlNodeList xnlFormats = GetMapRequestNodes.SelectNodes("sm:Format", nsmgr);
- //_GetMapOutputFormats = new Collection(xnlFormats.Count);
- _GetMapOutputFormats = new Collection();
- for (int i = 0; i < xnlFormats.Count;i++ )
- _GetMapOutputFormats.Add(xnlFormats[i].InnerText);
- }
+ ///
+ /// Structure for storing info on an Online Resource
+ ///
+ public struct WmsOnlineResource
+ {
+ ///
+ /// Type of online resource (Ex. request method 'Get' or 'Post')
+ ///
+ public string Type;
- ///
- /// Iterates through the layer nodes recursively
- ///
- ///
- ///
- private WmsServerLayer ParseLayer(XmlNode xmlLayer)
- {
- WmsServerLayer layer = new WmsServerLayer();
- XmlNode node = xmlLayer.SelectSingleNode("sm:Name", nsmgr);
- layer.Name = (node != null ? node.InnerText : null);
- node = xmlLayer.SelectSingleNode("sm:Title", nsmgr);
- layer.Title = (node != null ? node.InnerText : null);
- if (string.IsNullOrEmpty(layer.Name))
- {
- layer.Name = layer.Title;
- }
- node = xmlLayer.SelectSingleNode("sm:Abstract", nsmgr);
- layer.Abstract = (node != null ? node.InnerText : null);
- XmlAttribute attr = xmlLayer.Attributes["queryable"];
- layer.Queryable = (attr != null && attr.InnerText == "1");
+ ///
+ /// URI of online resource
+ ///
+ public string OnlineResource;
+ }
+ #endregion
- XmlNodeList xnlKeywords = xmlLayer.SelectNodes("sm:KeywordList/sm:Keyword", nsmgr);
- if (xnlKeywords != null)
- {
- layer.Keywords = new string[xnlKeywords.Count];
- for (int i = 0; i < xnlKeywords.Count; i++)
- layer.Keywords[i] = xnlKeywords[i].InnerText;
- }
- XmlNodeList xnlCrs = xmlLayer.SelectNodes("sm:CRS", nsmgr);
- if (xnlCrs != null)
- {
- layer.CRS = new string[xnlCrs.Count];
- for (int i = 0; i < xnlCrs.Count; i++)
- layer.CRS[i] = xnlCrs[i].InnerText;
- }
- XmlNodeList xnlStyle = xmlLayer.SelectNodes("sm:Style", nsmgr);
- if (xnlStyle != null)
- {
- layer.Style = new WmsLayerStyle[xnlStyle.Count];
- for (int i = 0; i < xnlStyle.Count; i++)
- {
- node = xnlStyle[i].SelectSingleNode("sm:Name", nsmgr);
- layer.Style[i].Name = (node != null ? node.InnerText : null);
- node = xnlStyle[i].SelectSingleNode("sm:Title", nsmgr);
- layer.Style[i].Title = (node != null ? node.InnerText : null);
- node = xnlStyle[i].SelectSingleNode("sm:Abstract", nsmgr);
- layer.Style[i].Abstract = (node != null ? node.InnerText : null);
- node = xnlStyle[i].SelectSingleNode("sm:LegendUrl", nsmgr);
- if (node != null)
- {
- layer.Style[i].LegendUrl = new WmsStyleLegend();
- layer.Style[i].LegendUrl.Size = new System.Drawing.Size(
- int.Parse(node.Attributes["width"].InnerText), int.Parse(node.Attributes["height"].InnerText));
- layer.Style[i].LegendUrl.OnlineResource.OnlineResource = node.SelectSingleNode("sm:OnlineResource",nsmgr).Attributes["xlink:href"].InnerText;
- layer.Style[i].LegendUrl.OnlineResource.Type = node.SelectSingleNode("sm:Format", nsmgr).InnerText;
- }
- node = xnlStyle[i].SelectSingleNode("sm:StyleSheetURL", nsmgr);
- if (node != null)
- {
- layer.Style[i].StyleSheetUrl = new WmsOnlineResource();
- layer.Style[i].StyleSheetUrl.OnlineResource = node.SelectSingleNode("sm:OnlineResource", nsmgr).Attributes["xlink:href"].InnerText;
- //layer.Style[i].StyleSheetUrl.OnlineResource = node.SelectSingleNode("sm:Format", nsmgr).InnerText;
- }
- }
- }
- XmlNodeList xnlLayers = xmlLayer.SelectNodes("sm:Layer", nsmgr);
- if (xnlLayers != null)
- {
- layer.ChildLayers = new WmsServerLayer[xnlLayers.Count];
- for (int i = 0; i < xnlLayers.Count; i++)
- layer.ChildLayers[i] = ParseLayer(xnlLayers[i]);
- }
- node = xmlLayer.SelectSingleNode("sm:LatLonBoundingBox", nsmgr);
- if(node == null)
+ #region Properties
+
+ private Capabilities.WmsServiceDescription _ServiceDescription;
+
+ ///
+ /// Gets the service description
+ ///
+ public Capabilities.WmsServiceDescription ServiceDescription
+ {
+ get
{
- node = xmlLayer.SelectSingleNode("sm:BoundingBox", nsmgr);
+ return _ServiceDescription;
}
- if (node != null)
- {
- double minx = 0; double miny = 0; double maxx = 0; double maxy = 0;
- if (!double.TryParse(node.Attributes["minx"].Value, System.Globalization.NumberStyles.Any, SharpMap.Map.numberFormat_EnUS, out minx) &
- !double.TryParse(node.Attributes["miny"].Value, System.Globalization.NumberStyles.Any, SharpMap.Map.numberFormat_EnUS, out miny) &
- !double.TryParse(node.Attributes["maxx"].Value, System.Globalization.NumberStyles.Any, SharpMap.Map.numberFormat_EnUS, out maxx) &
- !double.TryParse(node.Attributes["maxy"].Value, System.Globalization.NumberStyles.Any, SharpMap.Map.numberFormat_EnUS, out maxy))
- throw new ArgumentException("Invalid LatLonBoundingBox on layer '" + layer.Name + "'");
- layer.LatLonBoundingBox = SharpMap.Converters.Geometries.GeometryFactory.CreateEnvelope(minx, maxx, miny, maxy);
- }
- return layer;
- }
- }
-}
+ }
+
+ ///
+ /// Gets the version of the WMS server (ex. "1.3.0")
+ ///
+ public string WmsVersion { get; private set; }
+
+ ///
+ /// Gets a list of available image mime type formats
+ ///
+ public Collection GetMapOutputFormats { get; private set; }
+
+ ///
+ /// Gets a list of available exception mime type formats
+ ///
+ public string[] ExceptionFormats { get; private set; }
+
+ ///
+ /// Gets the available GetMap request methods and Online Resource URI
+ ///
+ public WmsOnlineResource[] GetMapRequests { get; private set; }
+
+ ///
+ /// Gets the hiarchial layer structure
+ ///
+ public WmsServerLayer Layer { get; private set; }
+
+ #endregion
+ }
+}
\ No newline at end of file