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 © <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方法加载要素,添加到矢量图层中进行渲染和显示。