C# 解析WMTS服务元数据

介绍

WMTS,切片地图Web服务(OpenGIS Web Map Tile Service)当前版本是1.0.0。WMTS标准定义了一些操作,这些操作允许用户访问切片地图。WMTS可能是OGC首个支持RESTful访问的服务标准。

WMTS提供了一种采用预定义图块方法发布数字地图服务的标准化解决方案。WMTS弥补了WMS不能提供分块地图的不足。WMTS牺牲了提供定制地图的灵活性,代之以通过提供静态数据(基础地图)来增强伸缩性,这些静态数据的范围框和比例尺被限定在各个图块内。这些固定的图块集使得对WMTS服务的实现可以使用一个仅简单返回已有文件的Web服务器即可,同时使得可以利用一些标准的诸如分布式缓存的网络机制实现伸缩性。

原理

操作

一个服务元数据(ServiceMetadata)资源(面向过程架构风格下对GetCapabilities操作的响应)(服务器方必须实现)。ServiceMetadata资源描述指定服务器实现的能力和包含的信息。在面向过程的架构风格中该操作也支持客户端与服务器间的标准版本协商。

图块资源(对面向过程架构风格下GetTile操作的响应)(服务器方必须实现)。图块资源表示一个图层的地图表达结果的一小块。

要素信息(FeatureInfo)资源(对面向过程架构风格下GetFeatureInfo操作的响应)(服务器方可选择实现)。该资源提供了图块地图中某一特定像素位置处地物要素的信息,与WMS中GetFeatureInfo操作的行为相似,以文本形式通过提供比如专题属性名称及其取值的方式返回相关信息。

内容解析

如下为iServer发布的wmts中对Layer的描述,主要包括如下内容:地图名、地图范围、缓存图片格式、比例尺集合、获取图片的url地址模板,具体可参考如下范例:

<Layer>
		<ows:Title>China</ows:Title>
		<ows:Identifier>China</ows:Identifier>
		<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::3857">
			<ows:LowerCorner>-2.0037508342789244E7 -2.003750834278914E7</ows:LowerCorner>
			<ows:UpperCorner>2.0037508342789244E7 2.0037508342789095E7</ows:UpperCorner>
		</ows:BoundingBox>
		<Style isDefault="true">
		<ows:Identifier>default</ows:Identifier>
		</Style>
		<Format>image/png</Format>
		<InfoFormat>application/xml</InfoFormat>
		<TileMatrixSetLink>
		<TileMatrixSet>Custom_China</TileMatrixSet>
		</TileMatrixSetLink>
		<ResourceURL format="image/png" resourceType="tile" template="http://localhost:8090/iserver/services/testwmts-comp/testwmts/China/default/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
		<ResourceURL format="application/xml" resourceType="FeatureInfo" template="http://localhost:8090/iserver/services/testwmts-comp/testwmts/China/default/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml"/>
	</Layer>

读取

读取的XML是带有命名空间的,读取办法如下:

XML文件:http://58.213.23.211:7002/NJDLG_10_17_WMTS/

获取返回信息时需要调用GetCapabilities:

http://58.213.23.211:7002/NJDLG_10_17_WMTS/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetCapabilities

http://219.142.81.86/igserver/ogc/kvp/TAS10R52000J49/WMTSServer?service=WMTS&request=GetCapabilities

方法一:

XNamespace ows = "http://www.opengis.net/ows/1.1";
var xDoc = XDocument.Load(@"C:\Users\Administrator\Desktop\map\map.xml");
var id = xDoc.Root.Element(ows + "ServiceIdentification").Element(ows + "Title").Value;

方法二:

XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(@"C:\Users\Administrator\Desktop\map\map.xml");
XmlNamespaceManager xmlns = new XmlNamespaceManager(xmldoc.NameTable);
xmlns.AddNamespace("a", "http://www.opengis.net/wmts/1.0");
xmlns.AddNamespace("ows", "http://www.opengis.net/ows/1.1");
xmlns.AddNamespace("gml", "http://www.opengis.net/gml");
xmlns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlns.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
XmlNodeList nodelist = xmldoc.SelectNodes("a:Capabilities/ows:ServiceIdentification", xmlns);

事例:

            string namespace_uri = xmlDocument.DocumentElement.NamespaceURI;
            var nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
            nsmgr.AddNamespace("wmts", namespace_uri);
            nsmgr.AddNamespace("ows", "http://www.opengis.net/ows/1.1");//根据xml不同的属性前缀需要添加不同的Namespace,才能读取到属性信息

            string title = "";
            string abstrac = "";
            string keywords = "";
            double west = 0;
            double east = 0;
            double south = 0;
            double north = 0;
            string srid = "";
            Dictionary<int, _tileMatrix> tileMatrixSet = new Dictionary<int, _tileMatrix>();
            int minLevel = 9999;
            int maxLevel = -9999;                

//请求服务的名称信息
                // XmlNode nodeiden = xmlDocument.SelectSingleNode("ows:ServiceIdentification");//
                XmlNode xnIdentification = xmlDocument.SelectSingleNode("wmts:Capabilities/ows:ServiceIdentification", nsmgr);
                if (xnIdentification == null) return;
                foreach (XmlNode xn1 in xnIdentification)
                {
                    if (xn1.Name == "ows:Title")
                    {
                        XmlElement xe = (XmlElement)xn1;
                        XmlNodeList xn10 = xn1.ChildNodes;
                        title = xn10.Item(0).InnerText;
                    }
                    if (xn1.Name == "ows:Abstract")
                    {
                        XmlElement xe = (XmlElement)xn1;
                        XmlNodeList xn10 = xn1.ChildNodes;
                        abstrac = xn10.Item(0).InnerText;
                    }
                    if (xn1.Name == "ows:Keywords")
                    {
                        XmlElement xe = (XmlElement)xn1;
                        //得到crs属性
                        string crs = xe.GetAttribute("crs").ToString();
                        XmlNodeList xn10 = xn1.ChildNodes;
                        keywords = xn10.Item(0).InnerText;
                    }
                }

                XmlNode node = xmlDocument.SelectSingleNode("//wmts:Layer", nsmgr);
                if (node == null) return;
                string LowerCorner, UpperCorner;
                // 得到layer节点的所有子节点
                XmlNodeList xnl = node.ChildNodes;
                foreach (XmlNode xn1 in xnl)
                {
                    if (xn1.Name == "ows:BoundingBox" || xn1.Name == "ows:WGS84BoundingBox")
                    {
                        XmlElement xe = (XmlElement)xn1;
                        //得到crs属性
                        string crs = xe.GetAttribute("crs").ToString();

                        // 得到BoundBox节点的所有子节点                   
                        XmlNodeList xn10 = xn1.ChildNodes;
                        LowerCorner = xn10.Item(0).InnerText;
                        UpperCorner = xn10.Item(1).InnerText;
                        string[] cc = LowerCorner.Split(' ');
                        west = Convert.ToDouble(cc[0]);
                        south = Convert.ToDouble(cc[1]);
                        string[] uu = UpperCorner.Split(' ');
                        east = Convert.ToDouble(uu[0]);
                        north = Convert.ToDouble(uu[1]);
                    }
                }

                XmlNodeList nodes = xmlDocument.SelectNodes("//wmts:TileMatrixSet", nsmgr);
                if (nodes.Count <= 0) return;

                foreach (XmlNode xn1 in nodes)
                {
                    if (xn1.ParentNode == null || xn1.ParentNode.Name != "Contents")
                        continue;

                    XmlNodeList xn11 = xn1.ChildNodes;
                    foreach (XmlNode xn110 in xn11)
                    {
                        if (xn110.Name == "ows:SupportedCRS")
                        {
                            srid = xn110.InnerText;
                            int len = srid.Length;
                            srid = srid.Substring(len - 4, 4);
                        }
                        if (xn110.Name == "TileMatrix")
                        {
                            XmlNodeList xn10 = xn110.ChildNodes;
                            string strlevel = xn10.Item(0).InnerText;
                            string[] temp = strlevel.Split(':');
                            int cn = temp.Count();
                            int level = 0;
                            if (cn == 1)
                                level = Convert.ToInt32(temp[0]);
                            else
                                level = Convert.ToInt32(temp[cn - 1]);

                            double ScaleDenominator = Convert.ToDouble(xn10.Item(1).InnerText);
                            string[] TopLeftCorner = xn10.Item(2).InnerText.Split(' ');
                            double top = Convert.ToDouble(TopLeftCorner[0]);
                            double left = Convert.ToDouble(TopLeftCorner[1]);
                            int TileWidth = Convert.ToInt32(xn10.Item(3).InnerText);
                            int TileHeight = Convert.ToInt32(xn10.Item(4).InnerText);
                            int cols = Convert.ToInt32(xn10.Item(5).InnerText);
                            int rows = Convert.ToInt32(xn10.Item(6).InnerText);

                            _tileMatrix ts = new _tileMatrix();
                            ts.level = level;
                            ts.cornerTop = top;
                            ts.cornerLeft = left;
                            ts.tileWidth = TileWidth;
                            ts.tileHeight = TileHeight;
                            ts.tileCols = cols;
                            ts.tileRows = rows;
                            if (!tileMatrixSet.ContainsKey(level))
                                tileMatrixSet.Add(level, ts);

                            minLevel = Math.Min(minLevel, level);
                            maxLevel = Math.Max(maxLevel, level);
                        }
                    }
                }
                xmlReader.Close();

元数据信息类:

 public class _tileMatrix
    {
        public int level { get; set; }
        public double cornerTop { get; set; }
        public double cornerLeft { get; set; }
        public int tileWidth { get; set; }
        public int tileHeight { get; set; }
        public int tileCols { get; set; }
        public int tileRows { get; set; }

    }

参考:

https://blog.csdn.net/supermapsupport/article/details/50423782

https://blog.csdn.net/linraise/article/details/50614996

https://www.cnblogs.com/mazhenyu/p/7472231.html

发布了44 篇原创文章 · 获赞 4 · 访问量 7965

猜你喜欢

转载自blog.csdn.net/fangyu723/article/details/104892870