Capabilities.cs
上传用户:sex100000
上传日期:2013-11-09
资源大小:1377k
文件大小:21k
源码类别:

GIS编程

开发平台:

C#

  1. // Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
  2. //
  3. // This file is part of SharpMap.
  4. // SharpMap is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. // 
  9. // SharpMap is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU Lesser General Public License for more details.
  13. // You should have received a copy of the GNU Lesser General Public License
  14. // along with SharpMap; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Text;
  19. using System.Xml;
  20. namespace SharpMap.Web.Wms
  21. {
  22. /// <summary>
  23. /// Class for generating the WmsCapabilities Xml
  24. /// </summary>
  25. public class Capabilities
  26. {
  27. /// <summary>
  28. /// The Wms Service Description stores metadata parameters for a WMS service
  29. /// </summary>
  30. public struct WmsServiceDescription
  31. {
  32. /// <summary>
  33. /// Initializes a WmsServiceDescription object
  34. /// </summary>
  35. /// <param name="title">Mandatory Human-readable title for pick lists</param>
  36. /// <param name="onlineResource">Top-level web address of service or service provider.</param>
  37. public WmsServiceDescription(string title, string onlineResource)
  38. {
  39. Title = title;
  40. OnlineResource = onlineResource;
  41. Keywords = null;
  42. Abstract = "";
  43. ContactInformation = new WmsContactInformation();
  44. Fees = "";
  45. AccessConstraints = "";
  46. LayerLimit = 0;
  47. MaxWidth = 0;
  48. MaxHeight = 0;
  49. }
  50. /// <summary>
  51. /// Mandatory Human-readable title for pick lists
  52. /// </summary>
  53. public string Title;
  54. /// <summary>
  55. /// Optional narrative description providing additional information
  56. /// </summary>
  57. public string Abstract;
  58. /// <summary>
  59. /// Optional list of keywords or keyword phrases describing the server as a whole to help catalog searching
  60. /// </summary>
  61. public string[] Keywords;
  62. /// <summary>
  63. /// Mandatory Top-level web address of service or service provider.
  64. /// </summary>
  65. public string OnlineResource;
  66. /// <summary>
  67. /// Optional WMS contact information
  68. /// </summary>
  69. public WmsContactInformation ContactInformation;
  70. /// <summary>
  71. /// The optional element "Fees" may be omitted if it do not apply to the server. If
  72. /// the element is present, the reserved word "none" (case-insensitive) shall be used if there are no
  73. /// fees, as follows: "none".
  74. /// </summary>
  75. public string Fees;
  76. /// <summary>
  77. /// <para>The optional element "AccessConstraints" may be omitted if it do not apply to the server. If
  78. /// the element is present, the reserved word "none" (case-insensitive) shall be used if there are no
  79. /// access constraints, as follows: "none".</para>
  80. /// <para>When constraints are imposed, no precise syntax has been defined for the text content of these elements, but
  81. /// client applications may display the content for user information and action.</para>
  82. /// </summary>
  83. public string AccessConstraints;
  84. /// <summary>
  85. /// Maximum number of layers allowed (0=no restrictions)
  86. /// </summary>
  87. public uint LayerLimit;
  88. /// <summary>
  89. /// Maximum width allowed in pixels (0=no restrictions)
  90. /// </summary>
  91. public uint MaxWidth;
  92. /// <summary>
  93. /// Maximum height allowed in pixels (0=no restrictions)
  94. /// </summary>
  95. public uint MaxHeight;
  96. }
  97. /// <summary>
  98. /// Stores contact metadata about WMS service
  99. /// </summary>
  100. public struct WmsContactInformation
  101. {
  102. /// <summary>
  103. /// Primary contact person
  104. /// </summary>
  105. public ContactPerson PersonPrimary;
  106. /// <summary>
  107. /// Position of contact person
  108. /// </summary>
  109. public string Position;
  110. /// <summary>
  111. /// Address
  112. /// </summary>
  113. public ContactAddress Address;
  114. /// <summary>
  115. /// Telephone
  116. /// </summary>
  117. public string VoiceTelephone;
  118. /// <summary>
  119. /// Fax number
  120. /// </summary>
  121. public string FacsimileTelephone;
  122. /// <summary>
  123. /// Email address
  124. /// </summary>
  125. public string ElectronicMailAddress;
  126. /// <summary>
  127. /// Information about a contact person for the service.
  128. /// </summary>
  129. public struct ContactPerson
  130. {
  131. /// <summary>
  132. /// Primary contact person
  133. /// </summary>
  134. public string Person;
  135. /// <summary>
  136. /// Organisation of primary person
  137. /// </summary>
  138. public string Organisation;
  139. }
  140. /// <summary>
  141. /// Information about a contact address for the service.
  142. /// </summary>
  143. public struct ContactAddress
  144. {
  145. /// <summary>
  146. /// Type of address (usually "postal").
  147. /// </summary>
  148. public string AddressType;
  149. /// <summary>
  150. /// Contact address
  151. /// </summary>
  152. public string Address;
  153. /// <summary>
  154. /// Contact City
  155. /// </summary>
  156. public string City;
  157. /// <summary>
  158. /// State or province of contact
  159. /// </summary>
  160. public string StateOrProvince;
  161. /// <summary>
  162. /// Zipcode of contact
  163. /// </summary>
  164. public string PostCode;
  165. /// <summary>
  166. /// Country of contact address
  167. /// </summary>
  168. public string Country;
  169. }
  170. }
  171. private const string wmsNamespaceURI = "http://www.opengis.net/wms";
  172. private const string xlinkNamespaceURI = "http://www.w3.org/1999/xlink";
  173. /// <summary>
  174. /// Generates a capabilities file from a map object for use in WMS services
  175. /// </summary>
  176. /// <remarks>The capabilities document uses the v1.3.0 OpenGIS WMS specification</remarks>
  177. /// <param name="map">The map to create capabilities for</param>
  178. /// <param name="serviceDescription">Additional description of WMS</param>
  179. /// <returns>Returns XmlDocument describing capabilities</returns>
  180. public static XmlDocument GetCapabilities(SharpMap.Map map, WmsServiceDescription serviceDescription)
  181. {
  182. XmlDocument capabilities = new XmlDocument();
  183. //Set XMLSchema
  184. //capabilities.Schemas.Add(GetCapabilitiesSchema());
  185. //Instantiate an XmlNamespaceManager object.
  186. //System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(capabilities.NameTable);
  187. //xmlnsManager.AddNamespace(xlinkNamespaceURI, "urn:Books");
  188. //Insert XML tag
  189. capabilities.InsertBefore(capabilities.CreateXmlDeclaration("1.0", "UTF-8", string.Empty), capabilities.DocumentElement);
  190. capabilities.AppendChild(capabilities.CreateComment("Capabilities generated by SharpMap v. " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()));
  191. //Create root node
  192. XmlNode RootNode = capabilities.CreateNode(XmlNodeType.Element, "WMS_Capabilities", wmsNamespaceURI);
  193. RootNode.Attributes.Append(CreateAttribute("version", "1.3.0", capabilities));
  194. XmlAttribute attr = capabilities.CreateAttribute("xmlns", "xsi", "http://www.w3.org/2000/xmlns/");
  195. attr.InnerText = "http://www.w3.org/2001/XMLSchema-instance";
  196. RootNode.Attributes.Append(attr);
  197. RootNode.Attributes.Append(CreateAttribute("xmlns:xlink", xlinkNamespaceURI, capabilities));
  198. XmlAttribute attr2 = capabilities.CreateAttribute("xsi", "schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
  199. attr2.InnerText = "http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd";
  200. RootNode.Attributes.Append(attr2);
  201. //Build Service node
  202. RootNode.AppendChild(GenerateServiceNode(ref serviceDescription, capabilities));
  203. //Build Capability node
  204. RootNode.AppendChild(GenerateCapabilityNode(map, capabilities));
  205. capabilities.AppendChild(RootNode);
  206. //TODO: Validate output against schema
  207. return capabilities;
  208. }
  209. private static XmlNode GenerateServiceNode(ref WmsServiceDescription serviceDescription, XmlDocument capabilities)
  210. {
  211. //XmlNode ServiceNode = capabilities.CreateNode(XmlNodeType.Element, "Service", "");
  212. XmlElement ServiceNode = capabilities.CreateElement("Service", wmsNamespaceURI);
  213. ServiceNode.AppendChild(CreateElement("Name", "WMS", capabilities, false, wmsNamespaceURI));
  214. ServiceNode.AppendChild(CreateElement("Title", serviceDescription.Title, capabilities, false, wmsNamespaceURI)); //Add WMS Title
  215. if (!String.IsNullOrEmpty(serviceDescription.Abstract)) //Add WMS abstract
  216. ServiceNode.AppendChild(CreateElement("Abstract", serviceDescription.Abstract, capabilities, false, wmsNamespaceURI));
  217. if (serviceDescription.Keywords.Length > 0) //Add keywords
  218. {
  219. XmlElement KeywordListNode = capabilities.CreateElement("KeywordList", wmsNamespaceURI);
  220. foreach (string keyword in serviceDescription.Keywords)
  221. KeywordListNode.AppendChild(CreateElement("Keyword", keyword, capabilities, false, wmsNamespaceURI));
  222. ServiceNode.AppendChild(KeywordListNode);
  223. }
  224. //Add Online resource
  225. XmlElement OnlineResourceNode = GenerateOnlineResourceElement(capabilities, serviceDescription.OnlineResource);
  226. ServiceNode.AppendChild(OnlineResourceNode);
  227. //Add ContactInformation info
  228. XmlElement ContactInfoNode = GenerateContactInfoElement(capabilities, serviceDescription.ContactInformation);
  229. if(ContactInfoNode.HasChildNodes)
  230. ServiceNode.AppendChild(ContactInfoNode);
  231. if (serviceDescription.Fees != null && serviceDescription.Fees != string.Empty)
  232. ServiceNode.AppendChild(CreateElement("Fees", serviceDescription.Fees, capabilities, false, wmsNamespaceURI));
  233. if (serviceDescription.AccessConstraints != null && serviceDescription.AccessConstraints != string.Empty)
  234. ServiceNode.AppendChild(CreateElement("AccessConstraints", serviceDescription.AccessConstraints, capabilities, false, wmsNamespaceURI));
  235. if(serviceDescription.LayerLimit>0)
  236. ServiceNode.AppendChild(CreateElement("LayerLimit", serviceDescription.LayerLimit.ToString(), capabilities, false, wmsNamespaceURI));
  237. if (serviceDescription.MaxWidth > 0)
  238. ServiceNode.AppendChild(CreateElement("MaxWidth", serviceDescription.MaxWidth.ToString(), capabilities, false, wmsNamespaceURI));
  239. if (serviceDescription.MaxHeight > 0)
  240. ServiceNode.AppendChild(CreateElement("MaxHeight", serviceDescription.MaxHeight.ToString(), capabilities, false, wmsNamespaceURI));
  241. return ServiceNode;
  242. }
  243. private static XmlNode GenerateCapabilityNode(SharpMap.Map map, XmlDocument capabilities)
  244. {
  245. string OnlineResource = "";
  246. OnlineResource = System.Web.HttpContext.Current.Server.HtmlEncode("http://" + System.Web.HttpContext.Current.Request.Url.Host + System.Web.HttpContext.Current.Request.Url.AbsolutePath);
  247. XmlNode CapabilityNode = capabilities.CreateNode(XmlNodeType.Element, "Capability", wmsNamespaceURI);
  248. XmlNode RequestNode = capabilities.CreateNode(XmlNodeType.Element, "Request", wmsNamespaceURI);
  249. XmlNode GetCapabilitiesNode = capabilities.CreateNode(XmlNodeType.Element, "GetCapabilities", wmsNamespaceURI);
  250. //Set format of supported capabilities mime types (only text/xml supported)
  251. GetCapabilitiesNode.AppendChild(CreateElement("Format", "text/xml", capabilities, false, wmsNamespaceURI));
  252. GetCapabilitiesNode.AppendChild(GenerateDCPTypeNode(capabilities, OnlineResource));
  253. RequestNode.AppendChild(GetCapabilitiesNode);
  254. XmlNode GetMapNode = capabilities.CreateNode(XmlNodeType.Element, "GetMap", wmsNamespaceURI);
  255. //Add supported fileformats. Return the ones that GDI+ supports
  256. foreach (System.Drawing.Imaging.ImageCodecInfo encoder in System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders())
  257. GetMapNode.AppendChild(CreateElement("Format", encoder.MimeType, capabilities, false, wmsNamespaceURI));
  258. GetMapNode.AppendChild(GenerateDCPTypeNode(capabilities,OnlineResource));
  259. RequestNode.AppendChild(GetMapNode);
  260. CapabilityNode.AppendChild(RequestNode);
  261. XmlElement exceptionNode = capabilities.CreateElement("Exception",wmsNamespaceURI);
  262. exceptionNode.AppendChild(CreateElement("Format", "text/xml", capabilities, false, wmsNamespaceURI));
  263. CapabilityNode.AppendChild(exceptionNode); //Add supported exception types
  264. //Build layerlist
  265. XmlNode LayerRootNode = capabilities.CreateNode(XmlNodeType.Element, "Layer", wmsNamespaceURI);
  266. LayerRootNode.AppendChild(CreateElement("Title", "SharpMap", capabilities, false, wmsNamespaceURI));
  267. LayerRootNode.AppendChild(CreateElement("CRS", "EPSG:" + map.Layers[0].SRID.ToString(), capabilities, false, wmsNamespaceURI)); //TODO
  268. LayerRootNode.AppendChild(GenerateBoundingBoxElement(map.GetExtents(), map.Layers[0].SRID, capabilities));
  269. //This should be changed when Transformation library is complete
  270. XmlElement geoBox = capabilities.CreateElement("EX_GeographicBoundingBox", wmsNamespaceURI);
  271. geoBox.Attributes.Append(CreateAttribute("minx", "-180", capabilities));
  272. geoBox.Attributes.Append(CreateAttribute("miny", "-90", capabilities));
  273. geoBox.Attributes.Append(CreateAttribute("maxx", "180", capabilities));
  274. geoBox.Attributes.Append(CreateAttribute("maxy", "90", capabilities));
  275. LayerRootNode.AppendChild(geoBox);
  276.             foreach (SharpMap.Layers.ILayer layer in map.Layers)
  277. LayerRootNode.AppendChild(GetWmsLayerNode(layer, capabilities));
  278. CapabilityNode.AppendChild(LayerRootNode);
  279. return CapabilityNode;
  280. }
  281. private static XmlNode GenerateDCPTypeNode(XmlDocument capabilities, string OnlineResource)
  282. {
  283. XmlNode DcpType = capabilities.CreateNode(XmlNodeType.Element, "DCPType", wmsNamespaceURI);
  284. XmlNode HttpType = capabilities.CreateNode(XmlNodeType.Element, "HTTP", wmsNamespaceURI);
  285. XmlElement resource = GenerateOnlineResourceElement(capabilities, OnlineResource);
  286. XmlNode GetNode = capabilities.CreateNode(XmlNodeType.Element, "Get", wmsNamespaceURI);
  287. XmlNode PostNode = capabilities.CreateNode(XmlNodeType.Element, "Post", wmsNamespaceURI);
  288. GetNode.AppendChild(resource.Clone());
  289. PostNode.AppendChild(resource);
  290. HttpType.AppendChild(GetNode);
  291. HttpType.AppendChild(PostNode);
  292. DcpType.AppendChild(HttpType);
  293. return DcpType;
  294. }
  295. private static XmlElement GenerateOnlineResourceElement(XmlDocument capabilities, string OnlineResource)
  296. {
  297. XmlElement resource = capabilities.CreateElement("OnlineResource", wmsNamespaceURI);
  298. XmlAttribute attrType = capabilities.CreateAttribute("xlink", "type", xlinkNamespaceURI);
  299. attrType.Value = "simple";
  300. resource.Attributes.Append(attrType);
  301. XmlAttribute href = capabilities.CreateAttribute("xlink","href", xlinkNamespaceURI);
  302. href.Value = OnlineResource;
  303. resource.Attributes.Append(href);
  304. XmlAttribute xmlns = capabilities.CreateAttribute("xmlns:xlink");
  305. xmlns.Value = xlinkNamespaceURI;
  306. resource.Attributes.Append(xmlns);
  307. return resource;
  308. }
  309. private static XmlElement GenerateContactInfoElement(XmlDocument capabilities, WmsContactInformation info)
  310. {
  311. XmlElement infoNode = capabilities.CreateElement("ContactInformation", wmsNamespaceURI);
  312. //Add primary person
  313. XmlElement cpp = capabilities.CreateElement("ContactPersonPrimary", wmsNamespaceURI);
  314. if (info.PersonPrimary.Person != null && info.PersonPrimary.Person != String.Empty)
  315. cpp.AppendChild(CreateElement("ContactPerson", info.PersonPrimary.Person, capabilities, false, wmsNamespaceURI));
  316. if (info.PersonPrimary.Organisation!=null && info.PersonPrimary.Organisation!=String.Empty)
  317. cpp.AppendChild(CreateElement("ContactOrganization", info.PersonPrimary.Organisation, capabilities, false, wmsNamespaceURI));
  318. if (cpp.HasChildNodes)
  319. infoNode.AppendChild(cpp);
  320. if (info.Position != null && info.Position != string.Empty)
  321. infoNode.AppendChild(CreateElement("ContactPosition", info.Position, capabilities, false, wmsNamespaceURI));
  322. //Add address
  323. XmlElement ca = capabilities.CreateElement("ContactAddress", wmsNamespaceURI);
  324. if (info.Address.AddressType != null && info.Address.AddressType != string.Empty)
  325. ca.AppendChild(CreateElement("AddressType", info.Address.AddressType, capabilities, false, wmsNamespaceURI));
  326. if (info.Address.Address!=null && info.Address.Address != string.Empty)
  327. ca.AppendChild(CreateElement("Address", info.Address.Address, capabilities, false, wmsNamespaceURI));
  328. if (info.Address.City!=null && info.Address.City != string.Empty)
  329. ca.AppendChild(CreateElement("City", info.Address.City, capabilities, false, wmsNamespaceURI));
  330. if (info.Address.StateOrProvince!=null && info.Address.StateOrProvince != string.Empty)
  331. ca.AppendChild(CreateElement("StateOrProvince", info.Address.StateOrProvince, capabilities, false, wmsNamespaceURI));
  332. if (info.Address.PostCode !=null && info.Address.PostCode != string.Empty)
  333. ca.AppendChild(CreateElement("PostCode", info.Address.PostCode, capabilities, false, wmsNamespaceURI));
  334. if (info.Address.Country!=null && info.Address.Country != string.Empty)
  335. ca.AppendChild(CreateElement("Country", info.Address.Country, capabilities, false, wmsNamespaceURI));
  336. if (ca.HasChildNodes)
  337. infoNode.AppendChild(ca);
  338. if (info.VoiceTelephone!=null && info.VoiceTelephone != string.Empty)
  339. infoNode.AppendChild(CreateElement("ContactVoiceTelephone", info.VoiceTelephone, capabilities, false, wmsNamespaceURI));
  340. if (info.FacsimileTelephone!=null && info.FacsimileTelephone != string.Empty)
  341. infoNode.AppendChild(CreateElement("ContactFacsimileTelephone", info.FacsimileTelephone, capabilities, false, wmsNamespaceURI));
  342. if (info.ElectronicMailAddress!=null && info.ElectronicMailAddress != string.Empty)
  343. infoNode.AppendChild(CreateElement("ContactElectronicMailAddress", info.ElectronicMailAddress, capabilities, false, wmsNamespaceURI));
  344. return infoNode;
  345. }
  346. private static XmlNode GetWmsLayerNode(SharpMap.Layers.ILayer layer, XmlDocument doc)
  347. {
  348. XmlNode LayerNode = doc.CreateNode(XmlNodeType.Element, "Layer", wmsNamespaceURI);
  349. LayerNode.AppendChild(CreateElement("Name", layer.LayerName, doc, false, wmsNamespaceURI));
  350. LayerNode.AppendChild(CreateElement("Title", layer.LayerName, doc, false, wmsNamespaceURI));
  351. //If this is a grouplayer, add childlayers recursively
  352. if (layer.GetType() == typeof(SharpMap.Layers.LayerGroup))
  353. foreach (SharpMap.Layers.Layer childlayer in ((SharpMap.Layers.LayerGroup)layer).Layers)
  354. LayerNode.AppendChild(GetWmsLayerNode(childlayer, doc));
  355. LayerNode.AppendChild(GenerateBoundingBoxElement(layer.Envelope, layer.SRID, doc));
  356. return LayerNode;
  357. }
  358. private static XmlElement GenerateBoundingBoxElement(SharpMap.Geometries.BoundingBox bbox, int SRID, XmlDocument doc)
  359. {
  360. XmlElement xmlBbox = doc.CreateElement("BoundingBox", wmsNamespaceURI);
  361. xmlBbox.Attributes.Append(CreateAttribute("minx", bbox.Left.ToString(SharpMap.Map.numberFormat_EnUS), doc));
  362. xmlBbox.Attributes.Append(CreateAttribute("miny", bbox.Bottom.ToString(SharpMap.Map.numberFormat_EnUS), doc));
  363. xmlBbox.Attributes.Append(CreateAttribute("maxx", bbox.Right.ToString(SharpMap.Map.numberFormat_EnUS), doc));
  364. xmlBbox.Attributes.Append(CreateAttribute("maxy", bbox.Top.ToString(SharpMap.Map.numberFormat_EnUS), doc));
  365. xmlBbox.Attributes.Append(CreateAttribute("CRS", "EPSG:" + SRID.ToString(), doc));
  366. return xmlBbox;
  367. }
  368. private static XmlAttribute CreateAttribute(string name, string value, XmlDocument doc)
  369. {
  370. XmlAttribute attr = doc.CreateAttribute(name);
  371. attr.Value = value;
  372. return attr;
  373. }
  374. private static XmlNode CreateElement(string name, string value, XmlDocument doc, bool IsXml, string namespaceURI)
  375. {
  376. XmlNode node = doc.CreateNode(XmlNodeType.Element, name, namespaceURI);
  377. if (IsXml)
  378. node.InnerXml = value;
  379. else
  380. node.InnerText = value;
  381. return node;
  382. }
  383. internal static XmlDocument CreateXml()
  384. {
  385. XmlDocument capabilities = new XmlDocument();
  386. //Set XMLSchema
  387. capabilities.Schemas = new System.Xml.Schema.XmlSchemaSet();
  388. capabilities.Schemas.Add(GetCapabilitiesSchema());
  389. return capabilities;
  390. }
  391. private static System.Xml.Schema.XmlSchema GetCapabilitiesSchema()
  392. {
  393. //Get XML Schema
  394. System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SharpMap.Web.Wms.Schemas._1._3._0.capabilities_1_3_0.xsd");
  395. System.Xml.Schema.XmlSchema schema = System.Xml.Schema.XmlSchema.Read(stream, new System.Xml.Schema.ValidationEventHandler(ValidationError));
  396. stream.Close();
  397. return schema;
  398. }
  399. private static void ValidationError(object sender, System.Xml.Schema.ValidationEventArgs arguments)
  400. {
  401. }
  402. }
  403. }