zoukankan      html  css  js  c++  java
  • 利用DotSpatial发布WMS, WFS服务

    我们遇到的几个给政府部门做的GIS系统,一般都只要面子,只要好看,领导高兴得不得了,点点这里点点那里,哟,这按钮一点还会转,领导开心得跟朵花似的。。。要是搞个各种分析什么的全堆上来,他就嫌烦了。。。这不说是由于使用的功能比较简单,花钱买个ArcGIS太浪费了,要用个开源系统做一个,一来给客户节省开销,二来我们自己也能赚一点。然后就在挑开源GIS,主要到现在也就会写点C#的代码,Grass, QGis, GeoTools, GeoServer什么的就都没考虑,就在DotSpatial和SharpMap里选了DotSpatial。我们的要求不高,只要能完成常用的地图加载查询什么的就好了。首先写的WMS。

    WMS

    WMS服务必须实现的有 GetCapabilites, GetMap,可选的功能是GetFeatureInfo。(说明一下,在ArcGIS发布的WMS服务里,还有GetStyles功能,但是在OGC的1.3.0版本的WMS说明文档里没有提到GetStyles,也就是说GetStyles并不是OGC标准功能)这里分条介绍一下:

      1. GetCapabilites

        其功能是获取WMS服务的功能列表,也就是描述一下我发布的这个WMS能实现哪几个功能。

        GetCapabilites请求有不同的版本,常见的是1.1.1和1.3.0的,这里我写的是1.3.0版本的,下面只针对1.3.0写一下必备的参数:       

                                 

        是否必需

        描述

        REQUEST=GetCapabilities

        必需

              

        SERVICE=WMS

        必需

        大写的WMS

        VERSION=1.3.0

        可选

        这里我写的只支持1.3.0的,所以不设置的话就默认返回1.3.0的格式了

        FORMAT=MINE_type

        可选

        返回类型,我这里只返回text/tml格式

        UPDATESEQUENCE=string

        可选

        Sequence number or string for cache control,我这里忽略了


             
        例:http://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer?version=1.3.0&request=GetMap&CRS=CRS:84&bbox=-178.217598,18.924782,-66.969271,71.406235&width=760&height=360&layers=0&styles=default&format=image/png

        在添加了一个一般处理程序wms.ashx之后,首先从HttpContext里获取各种参数,利用DotSpatial.Control.Map新建一个Map对象,接下来就是根据下面的返回格式进行解析拼凑了:

        xml太长了,直接附地址:http://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer?version=1.3.0&request=GetCapabilities&service=WMS

        大体代码如下:
        string wmsNamespaceURI = "http://www.opengis.net/wms";
        XmlDocument doc = new XmlDocument();
        XmlNode rootNode = doc.CreateNode(capabilities.CreateNode(XmlNodeType.Element, "WMS_Capabilities", wmsNamespaceURI);
        rootNode.Attributes.Append(doc.CreateAttribute(...));
        ...
        doc.AppendChild(rootNode);
        
        context.Response.Clear();
        context.Response.ContentType = "text/xml";
        XmlWriter writer = XmlWriter.Create(context.Response.OutputStream);
        capabilities.WriteTo(writer);
        writer.Close();
        context.Response.End();
      2. GetMap

        GetMap方法主要是根据请求和地图来获取图片。

        这里依旧根据1.3.0版本简单介绍一下请求参数:

        是否必需

        描述

        REQUEST=GetMap

        必需

        VERSION=1.3.0

        必需

        LAYERS=layer_list

        必需

        用逗号分隔多个图层,请求全部置为空

        STYLES=style_list

        必需

        用逗号分隔多个图层,与LAYERS排序相同

        CRS=namespace:identifier

        必需

        CRS=EPSG:2436

        BBOX=minx,miny,maxx,maxy

        必需

        要请求的图上坐标范围

        WIDTH=output_width

        必需

        请求返回的图像的宽度

        HEIGHT=output_height

        必需

        FORMAT=output_format

        必需

        返回图像格式 image/png

        TRANSPARENT=TRUE|FALSE

        可选

        地图是否透明 true

        BGCOLOR=color_value

        可选

        背景颜色 White

        EXCEPTIONS=exception_format

        可选

        抛出异常默认为xml格式

        与GetCapabilities一样,也是取到参数之后,用参数初始化一个DotSpatial.Control.Map对象,把Map.Size设置成WIDTH和HEIGHT大小,这样导出的地图就正好符合输出尺寸了,设置好LAYERS和STYLES,缩放到BBOX,然后利用Map提供的SnapShot()方法获得图像并插入到Response中。后边代码:

        var img = map.SnapShot();
        
        ImageEncodeInfo info;
        
        ImageCodecInfo [] infos = ImageCodecInfo.GetImageEncoders();
         for (int i = 0; i < infos.Length; i++)
        {
            if (infos[i].MimeType == pMimeType)
            {
                info = infos[i];
                break;
            }
        }
        
        byte[] buffer;
         using (var ms = new MemoryStream())
        {
               img.Save(ms,  info, null);
               img.Dispose();
               buffer = ms.ToArray();
        }
        context.Response.Clear();
        context.Response.ContentType = pMimeType;
        context.Response.OutputStream.Write(buffer, 0, buffer.Length);
        context.Response.End();
      3. GetFeatureInfo

        根据请求参数获取要素。

        还是1.3.0版本的参数设置:

        是否必需

        描述信息

        REQUEST=GetFeatureInfo

        必需

        VERSION=1.3.0

        必需

        #regionGetMap的设置地图部分

        LAYERS=layer_list

        必需

        用逗号分隔多个图层,请求全部置为空

        STYLES=style_list

        必需

        用逗号分隔多个图层,与LAYERS排序相同

        CRS=namespace:identifier

        必需

        如 CRS=EPSG:2436

        BBOX=minx,miny,maxx,maxy

        必需

        地图的当前范围

        WIDTH=output_width

        必需

        地图的当前范围

        HEIGHT=output_height

        必需

        请求返回的图像的宽度

        …其它可选参数

        #endregion

        I=pixel_column

        必需

        请求点在图片上的位置X

        J=pixel_row

        必需

        QUERY_LAYERS=layer_list

        必需

        查询的图层,逗号分隔,必须包含在LAYERS中

        INFO_FORMAT=output_format

        必需

        要素信息返回的格式Capabilities里<Request><FeatureInfo><Format>中的格式

        FEATURE_COUNT=number

        可选

        最大返回数量

        EXCEPTIONS=exception_format

        可选



        例:http://sampleserver1.arcgisonline.com/arcgis/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer?version=1.3.0&request=GetFeatureInfo&layers=0&styles=default&CRS=EPSG:4326&bbox=-125.192865,11.2289864971264,
        -66.105824,62.5056715028736&width=1044&height=906&format=text/html&I=500&J=400&query_layers=0&INFO_FORMAT=text/html


        GetFeatureInfo也与上面无异,首先设置好Map,然后通过DotSpatial.Control.IMapFeatureLayer.Select(Extent)工具选出要查找的要素,最后把要素的属性拼接出来。

        除了用Extent选择以外,还可以将得到的List<IFeature>用CQL_FILTER进行过滤。

        把Context.Response.ContentType设置成要返回的格式,Context.Response.Write(string)写入取得的字符串。

    WFS

    WFS(Web Feature Service)服务必须实现的功能有GetCapabilities 、 DescribeFeatureType 和 GetFeature,可选的功能有GetGmlObject 和 Tansaction。这里说明的版本为1.1.0

    这里都是根据索引号为OGC 04-094 Version: 1.1.0的Web Feature Service Implementation Specification 里的说明。

      1. GetCapabilities

        这是所有OWS(OGC Web Service)都必须实现的功能,功能都是返回该服务的服务能力等元数据。

        下面是1.1.0版本的参数说明

         

        是否必需

         

        REQUEST=GetCapabilities

        必需

         


        还是拼xml,和WMS的GetCapabilities差不多了。请求如:http://…..?Request=GetCapabilities

        <?xml version="1.0" encoding="UTF-8"?>
        <wfs:WFS_Capabilities xmlns:ows="http://www.opengis.net/ows" version="1.1.0" xmlns:Basemap="http://sritserver-pc/ArcGIS/services/Basemap/MapServer/WFSServer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xsi:schemaLocation="http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/base/gml.xsd http://www.opengis.net/ogc http://schemas.opengis.net/filter/1.1.0/filter.xsd http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsAll.xsd http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
            <ows:ServiceIdentification>……
            <ows:ServiceProvider>……
            <ows:OperationsMetadata>……
            <wfs:FeatureTypeList>……
            <ogc:Filter_Capabilities>……
        </wfs:WFS_Capabilities>
      2. DescribeFeatureType

        请求参数:

        <xsd:element name="DescribeFeatureType" type="wfs:DescribeFeatureTypeType"/>
        <xsd:complexType name="DescribeFeatureTypeType">
            <xsd:complexContent>
                <xsd:extension base="wfs:BaseRequestType">
                    <xsd:sequence>
                        <xsd:element name="TypeName" type="xsd:QName"minOccurs="0" maxOccurs="unbounded"/>
                    </xsd:sequence>
                    <xsd:attribute name="outputFormat"type="xsd:string" use="optional"default="text/xml; subtype=gml/3.1.1"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
         

        是否必需

         

        TypeName

        不必需

        如果不带TypeName参数则返回所有图层

        outputFormat

        不必需

        该属性用于设置返回的要素类型的描述语言,默认为text/xml; subtype=gml/3.1.1,如果设置错了不识别会自动跳过该属性



        返回格式大致如下:(http://…..?Request=DescribeFeatureType&TypeName=SQ).具体的格式可以查看OGC标准文档说明或arcgis发布的服务的返回。

        <?xml version="1.0" encoding="UTF-8"?>
        <xs:schema xmlns:Basemap="http://sritserver-pc/ArcGIS/services/Basemap/MapServer/WFSServer" xmlns:gml="http://www.opengis.net/gml" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://sritserverpc/ArcGIS/services/Basemap/MapServer/WFSServer"><xs:import schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" namespace="http://www.opengis.net/gml"/>
            <xs:element type="Basemap:SQType" name="SQ" substitutionGroup="gml:_Feature"/>
            <xs:complexType name="SQType">……
        </xs:schema>
      3. GetFeature


        常用的几个参数如下:

         

        是否必需

         

        Request=GetFeature

        必需

         

        featureID=SQ.F1026__6

         

        直接取得SQ图层里featureID(不是ObjectID)为F…__6的要素,以F开头,最后6是ObjectID,中间的几个字母不知道是怎么对应的,不过可以根据图层的各信息来编码,只要不重复就可以

        TypeName=SQ

        如果featureID未指定,则必需,多个用逗号隔开

         

        BBOX=xmin,ymin,xmax,ymax

        非必需

         

        outputFormat

        非必需

        默认值text/gml; subtype=gml/3.1.1,还有text/xml; subtype=gml/2.1.2等

        maxFeatures

        非必需

         

        featureVersion=ALL

        非必需

        对于支持版本的系统返回指定版本的要素

        resultType=Results

        非必需

        还有Hits可选值,Hits时不返回所有结果,只返回结果的一些描述,如数量、结构等

           

        其它参数…

           

        依旧是根据请求的参数 和 Map 来查找需要返回的要素,然后转换成 GML 的格式返回,这里列一下我用到的几个格式,不一定全:

        对于Shape,最顶层节点都是<Shape>

        点。
        <gml:Point> 
            <gml:pos>x y<gml:pos> 
        </gml:Point>
        线,多线
        <gml:multiCurve>
            <gml:CurveMember><!--每一段对应一个CurveMember-->
                <gml:LineString>
                    <gml:posList>x1 y1 x2 y2 x3 y3……</gml:posList>
                </gml:LineString>
            </gml:CurveMember>
            <gml:CurveMember></gml:CurveMember>
        </gml:multiCurve>
        面,多面
        <gml:MultiSurface>
            <gml:surfaceMember><!--每一部分面对应一个surfaceMember-->
                <gml:Polygon>
                    <gml:exterior><!--只有一个外环-->
                        <gml:LinearRing>
                            <gml:posList>x1 y1 x2 y2 x3 y3......</gml:posList>
                        </gml:LinearRing>
                    </gml:exterior>
                    <gml:interior><!--每一个内环对应一个interior-->
                        <gml:LinearRing>
                            <gml:posList>x1 y1 x2 y2 x3 y3......</gml:posList>
                        </gml:LinearRing>
                    </gml:interior>
                    <gml:interior>......</gml:interior>
                </gml:Polygon>
            </gml:surfaceMember>
            <gml:surfaceMember>......</gml:surfaceMember>
        <gml:MultiSurface>


    转载请注明出处

  • 相关阅读:
    Android Studio 第一次启动应该注意的事项
    synchronized 和 volatile 比较
    synchronized 和 volatile 比较
    【Light】[1214]Large Division
    【Light】[1214]Large Division
    【Light】[1116]Ekka Dokka
    【Light】[1116]Ekka Dokka
    【Light】[1078]Integer Divisibility
    【Light】[1078]Integer Divisibility
    【Light】[1008]Fibsieve`s Fantabulous Birthday
  • 原文地址:https://www.cnblogs.com/yuantf/p/3289194.html
Copyright © 2011-2022 走看看