簡體   English   中英

Openlayers / GeoServer WFS緩存,切片或任何優化

[英]Openlayers/GeoServer WFS caching, tiles or any optimization

我正在使用OpenLayers 3.20.0開發一個Web應用程序,並將來自GeoServer的圖層鏈接到Oracle數據源。 該應用程序主要使用ImageWMS層,還使用Vector層進行交互和編輯。 問題是,繪制30000多條折線后,地圖非常慢,我想使過程更快:-)

所以我想知道什么是最好的方法。 我發現了兩種方法:

  • 更改ImageWMS層中的Vector層,並僅在選擇或編輯時加載手動所需的功能,但這要求我在代碼中進行一定程度的修改
  • 使用VectorTile層而不是Vector層,我猜它應該像ImageWMS和圖塊系統一樣工作,以便僅根據地圖視圖加載數據(很好嗎?)

我尋找了VectorTile的樣本,但是樣本不是很多(大多數情況下是關於OpenLayers 2的),並且文檔有點差。

關於圖層聲明的最大未知數是關於VectorTile源的。 必須定義一個URL,並且我在文檔中發現必須放置{x} / {y} / {z}參數,但是該URL的確切位置和構建方式? (請參見https://openlayers.org/en/latest/apidoc/module-ol_source_VectorTile-VectorTile.html ,“ url”選項)

作為示例,我當前的Vector源具有以下URL:/geoserver/ANF/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ANF:myLayer&outputFormat=application%2Fjson

因此,要定義VectorTile源,如何定義我的URL,以及在GeoServer端做什么以正確的方式配置我的圖層? 我找到了這個資源: https : //docs.geoserver.org/latest/en/user/extensions/vectortiles/tutorial.html

我在GeoServer上唯一沒有圖像類型的矢量平鋪格式是'application / json; type = utfgrid'。 當我將“ @ pbf / {z} / {x} / {-y} .pbf”放在示例的URL末尾時,出現了錯誤,但我猜這不是正確的方法。

我們將不勝感激任何幫助,以便為我提供有關如何使用GeoServer使VectorTile圖層和源工作更加精確的方法,或者是優化我創建的地圖的另一種方法。

非常感謝。

編輯

在得到一些答案之后,我將介紹以下代碼示例:

this._view = new ol.View({
    center: [74000, 96000],
    projection: 'EPSG:2169',
    zoom: 13,
    maxZoom: 24,
    minZoom: 11
});

this._map = new ol.Map(
    {
        view: this._view,
        controls: [
            new ol.control.Zoom(),
            new ol.control.ScaleLine()
        ]                
    });

let vectorSourceURL: string = `/geoserver/ANF/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ANF:myLayer&outputFormat=application%2Fjson`;

let source = new ol.source.VectorTile({
    format: new ol.format.GeoJSON({
        defaultDataProjection: 'EPSG:2169',
        geometryName: 'GEOLOC'
    }),
    tileUrlFunction: function (tileCoord, pixelRatio, projection) {
        return vectorSourceURL + '&bbox=' + source.getTileGrid().getTileCoordExtent(tileCoord).join(',') + ',EPSG:2169';
    },
    tileGrid: ol.tilegrid.createXYZ(),
    projection: 'EPSG:2169'
});

let layer = new ol.layer.VectorTile({
    source: source,
    renderOrder: null
});

layer.set('name', 'myLayer');
layer.set('title', 'myLayer');

此代碼屬於以下錯誤:

錯誤TypeError:無法讀取ol.renderer.canvas.VectorTileLayer.drawTileImage(ol-debug.js:29886)處ol.renderer.canvas.VectorTileLayer.createReplayGroup_(ol-debug.js:29814)處為null的屬性'getUnits' ol.Map上的ol.renderer.canvas.Map.renderFrame(ol-debug.js:30302)上的ol.renderer.canvas.VectorTileLayer.ol.renderer.canvas.TileLayer.prepareFrame(ol-debug.js:26557)位於ol.Map的renderFrame_(ol-debug.js:42107)。 (ol-debug.js:41013),位於Object.onInvokeTask(core.js:3815)處的ZoneDelegate.push ../ node_modules / zone.js / dist / zone.js.ZoneDelegate.invokeTask(zone.js:421)處Zone.push ../ node_modules / zone.js / dist / zone.js.Zone.runTask上的ZoneDelegate.push ../ node_modules / zone.js / dist / zone.js.ZoneDelegate.invokeTask(zone.js:420) (zone.js:188)

看來此問題現在來自EPSG:2169。 EPSG:3857的示例效果很好(請參閱答案)。

我想念什么嗎?

非常感謝 !

加快應用程序速度的最簡單方法是切換到使用WMTS(或切片WMS)層。 這樣,您的應用程序就可以利用瀏覽器緩存來僅請求以前從未見過的切片,並且服務器也只需渲染一次,因為它們也被緩存到了磁盤中。

您幾乎可以肯定不需要所有300K功能來進行編輯,因此嘗試將WFS過濾為僅所請求區域的邊界框將有所幫助。

最后,最大的成功可能來自切換到適當的空間數據庫,例如PostGIS。

矢量圖塊不必為.pbf或使用XYZ網址。 這是經過重新設計的OpenLayers WFS示例,使用WFS url作為矢量切片的源。 當縮小以覆蓋整個加拿大時,它似乎比原始示例更具響應性。

  var vectorSource = new ol.source.VectorTile({ format: new ol.format.GeoJSON(), tileUrlFunction: function(tileCoord, pixelRatio, projection) { return 'https://ahocevar.com/geoserver/wfs?service=WFS&' + 'version=1.1.0&request=GetFeature&typename=osm:water_areas&' + 'outputFormat=application/json&srsname=EPSG:3857&' + 'bbox=' + vectorSource.getTileGrid().getTileCoordExtent(tileCoord).join(',') + ',EPSG:3857'; }, tileGrid: ol.tilegrid.createXYZ() }); var vector = new ol.layer.VectorTile({ source: vectorSource, style: new ol.style.Style({ stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 255, 1.0)', width: 2 }) }) }); var raster = new ol.layer.Tile({ source: new ol.source.OSM() }); var map = new ol.Map({ layers: [raster, vector], target: document.getElementById('map'), view: new ol.View({ center: [-8908887.277395891, 5381918.072437216], maxZoom: 19, zoom: 12 }) }); 
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/3.20.0/ol.css" type="text/css"> <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x --> <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/3.20.0/ol.js"></script> <div id="map"></div> 

將該代碼與基於proj4的投影一起使用似乎確實存在問題,但它應該使用圖塊加載功能工作

let viewProjection = ol.proj.get('EPSG:2169');

let format = new ol.format.GeoJSON({
        defaultDataProjection: viewProjection,
        featureProjection: viewProjection,
        geometryName: 'GEOLOC'
    });

let source = new ol.source.VectorTile({
    tileUrlFunction: function (tileCoord, pixelRatio, projection) {
        return vectorSourceURL + '&bbox=' + source.getTileGrid().getTileCoordExtent(tileCoord).join(',') + ',EPSG:2169';
    },
    tileLoadFunction: function (tile, url) {
        tile.setProjection(viewProjection);
        tile.setLoader(function() {
            var xhr = new XMLHttpRequest();
            xhr.onload = function() {
                tile.setFeatures(format.readFeatures(xhr.responseText));
            }
            xhr.open("GET", url, true);
            xhr.send();
        });
    },
    tileGrid: ol.tilegrid.createXYZ(),
    projection: viewProjection
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM