使用OpenLayers加载ArcGIS Server矢量图层

https://www.pianshen.com/article/49481496261/

OpenLayers3数据加载的原理与方法

基于OpenLayers3加载底图数据非常方便,了解OpenLayers3的几个核心类就可以了:地图容器(ol.Map)、图层(ol.layer.Layer及其相关子类)、数据源(ol.source.Source及其相关子类)以及地图视图(ol.View)。

OpenLayers3的数据加载原理与OpenLayers2有些区别,OpenLayers3将图层(Layer)与数据源(Source)进行分离,图层是渲染地图数据的容器,数据源则是GIS数据的载体,图层要与数据源匹配设置。

关系如下图所示:

而矢量图层的构造方法如下:

同样都是矢量图层,WMS和WFS有何区别?:WMS返回的其实是图片,WFS返回的是真正的矢量数据。也就是说,WMS是矢量图层先在服务器端实时渲染完成后发送回客户端显示,WFS是在客户端渲染成图的。

针对ArcGIS数据,OpenLayers3封装了一个ArcGIS瓦片数据源,可以直接使用。同时,可以基于OpenLayers3通用的图层与数据源,加载其瓦片或矢量数据。例如,本示例以加载ArcGIS的数据为例,分别加载ArcGIS Server发布的GIS数据服务,以及ArcGIS Online提供的GIS数据服务。

实现步骤如下:

(1)新建一个html文件,引用ol3库和jquery库。

(2)创建地图容器的div层,添加选择控件,并设置其界面元素的样式。

 

代码说明:本示例分别实现了加载ArcGIS Server REST服务瓦片数据、矢量数据,以及ArcGIS Online的在线瓦片数据,通过选择控件设置加载的数据类型,默认加载第一种,即ArcGIS Server的在线瓦片数据。

(3)参照4.3节加载瓦片地图的方法,实例化地图容器对象map,将图层对象arcGISLayers添加到地图容器中,然后再通过界面中的选择控件加载选中类型的ArcGIS数据。其中,对于不同类型的数据采用如下不同的方式进行实现。

  • 加载ArcGIS Server的REST服务瓦片:ol.layer.Tile+ol.source.TileArcGISRest。
  • 加载ArcGIS Online的在线瓦片数据:ol.layer.Tile+ol.source.XYZ。
  • 加载ArcGIS Server的REST服务矢量:ol.layer.Vector+ol.source.Vector。
  //加载选中项对应的地图
  $("input[type='radio'][name='maps']").get(0).checked = true; //默认选中
  var select = document.getElementById('arcgisType');
  select.addEventListener('change', onChange); //添加地图类型选项的事件监听
  loadArcGISMap(select.value); //默认加载选中类型的地图

代码说明:基于jQuery方法实现数据类型切换功能,其关键步骤是根据选择的数据类型加载对应的数据,在此通过loadArcGISMap方法进行实现具体的数据加载。

加载ArcGIS各类型数据的关键代码如下:

function loadArcGISMap(type) { 
            //移除当前已有图层
            var cLayers = map.getLayers();
            if (cLayers != null) { 
                for (var i = 0; i < cLayers.length; i++) {
                    map.removeLayer(cLayers[i]);
                }
            }
            //加载ArcGIS MapServer地图
            if (type == "MapServer") {
                arcGISSource = new ol.source.TileArcGISRest({
                    url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' + 'Specialty/ESRI_StateCityHighway_USA/MapServer'
                });
                arcGISLayers = new ol.layer.Tile({
                    source: arcGISSource,
                    extent: [-13884991, 2870341, -7455066, 6338219]
                });
                map.addLayer(arcGISLayers); //添加瓦片地图图层   
                setMapView([-10997148, 4569099], 5);
            }
            //加载arcgisOnline地图
            else if (type == "arcgisOnline") {
                var attribution = new ol.Attribution({
                    html: 'Tiles &copy; <a href="http://services.arcgisonline.com/ArcGIS/' + 'rest/services/World_Topo_Map/MapServer">ArcGIS</a>'
                });
                arcGISLayers = new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        attributions: [attribution],
                        url: 'http://server.arcgisonline.com/ArcGIS/rest/services/' + 'World_Topo_Map/MapServer/tile/{z}/{y}/{x}'
                    })
                })
                map.addLayer(arcGISLayers); //添加地图图层   
                setMapView(ol.proj.fromLonLat([-121.1, 47.5]), 7);
            }
            //加载ArcGIS REST矢量要素服务地图
            else if (type == "RestFeatureService") {
                var serviceUrl = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/' + 'services/PDX_Pedestrian_Districts/FeatureServer/';
                var layer = '0';
                var esrijsonFormat = new ol.format.EsriJSON();//ESRI的JSON数据格式解析类
                //实例化矢量数据源对象(AJAX请求REST服务)
                var arcGISSource = new ol.source.Vector({
                    loader: function (extent, resolution, projection) {
                        var url = serviceUrl + layer + '/query/?f=json&' +
                            'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' +
                            encodeURIComponent('{"xmin":' + extent[0] + ',"ymin":' +
                                extent[1] + ',"xmax":' + extent[2] + ',"ymax":' + extent[3] +
                                ',"spatialReference":{"wkid":102100}}') +
                            '&geometryType=esriGeometryEnvelope&inSR=102100&outFields=*' +
                            '&outSR=102100';
                        $.ajax({ url: url, dataType: 'jsonp', success: function (response) {
                            if (response.error) {
                                alert(response.error.message + '
' + response.error.details.join('
'));
                            } else {
                                // 从请求结果中读取要素
                                var features = esrijsonFormat.readFeatures(response, {
                                    featureProjection: projection
                                });
                                if (features.length > 0) {
                                    arcGISSource.addFeatures(features);//将要素设置到数据源中
                                }
                            }
                        } 
                        });
                    },
                    strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
                        tileSize: 512
                    }))
                });
                arcGISLayers = new ol.layer.Vector({
                    source: arcGISSource
                });
                map.addLayer(arcGISLayers); //添加地图图层   
                setMapView(ol.proj.fromLonLat([-121.1, 47.5]), 5);
            }     
        }

代码说明:上面是加载ArcGIS各种类型数据的核心代码,不管是瓦片还是矢量,均调用相应的数据服务,因此都是基于数据url请求并加载数据。

(1)加载ArcGIS Server REST服务瓦片:使用ol.layer.Tile+ol.source.TileArcGISRest实现,TileArcGISRest的url参数是数据服务的请求地址,使用它请求ArcGIS Server发布的REST瓦片地图服务。

(2)加载ArcGIS Online地图:使用ol.layer.Tile+ol.source.XYZ实现,ol.source.XYZ的url参数是瓦片服务的请求地址。

(3)加载ArcGIS Server的REST服务矢量地图:使用ol.layer.Vector+ol.source.Vector实现,通过Vector数据源的loader参数设置加载矢量要素的函数,然后通过Ajax的方式请求矢量数据服务,再通过ol.format.EsriJSON解析数据,调用readFeatures方法解析和读取要素,最后调用矢量数据源对象的addFeatures方法加载要素,添加到矢量图层中进行渲染和显示。

原文地址:https://www.cnblogs.com/2008nmj/p/14069514.html