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 + '\n' + response.error.details.join('\n')); } 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方法加載要素,添加到矢量圖層中進行渲染和顯示。