Use view projection tile grid in tile loadingstrategy

This commit is contained in:
Andreas Hocevar
2021-09-10 01:36:59 +02:00
parent c9593b0cf6
commit 50e89080a4
4 changed files with 129 additions and 5 deletions

View File

@@ -0,0 +1,16 @@
---
layout: example.html
title: WFS
shortdesc: Example of using WFS with a Tile strategy.
docs: >
This example loads new features from GeoServer WFS with a tile based loading strategy.
Calling the <code>useGeographic</code> function in the <code>'ol/proj'</code> module
makes it so the map view uses geographic coordinates (even if the view projection is
not geographic).
tags: "vector, WFS, tile, strategy, loading, server, maptiler"
cloak:
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
value: Get your own API key at https://www.maptiler.com/cloud/
experimental: true
---
<div id="map" class="map"></div>

View File

@@ -0,0 +1,60 @@
import GeoJSON from '../src/ol/format/GeoJSON.js';
import Map from '../src/ol/Map.js';
import VectorSource from '../src/ol/source/Vector.js';
import View from '../src/ol/View.js';
import XYZ from '../src/ol/source/XYZ.js';
import {Stroke, Style} from '../src/ol/style.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {createXYZ} from '../src/ol/tilegrid.js';
import {tile} from '../src/ol/loadingstrategy.js';
import {useGeographic} from '../src/ol/proj.js';
useGeographic();
const vectorSource = new VectorSource({
format: new GeoJSON(),
url: function (extent) {
return (
'https://ahocevar.com/geoserver/wfs?service=WFS&' +
'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
'outputFormat=application/json&srsname=EPSG:4326&' +
'bbox=' +
extent.join(',') +
',EPSG:4326'
);
},
strategy: tile(createXYZ({tileSize: 512})),
});
const vector = new VectorLayer({
source: vectorSource,
style: new Style({
stroke: new Stroke({
color: 'rgba(0, 0, 255, 1.0)',
width: 2,
}),
}),
});
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
const attributions =
'<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> ' +
'<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>';
const raster = new TileLayer({
source: new XYZ({
attributions: attributions,
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
maxZoom: 20,
}),
});
const map = new Map({
layers: [raster, vector],
target: document.getElementById('map'),
view: new View({
center: [-80.0298, 43.4578],
maxZoom: 19,
zoom: 12,
}),
});

View File

@@ -2,6 +2,8 @@
* @module ol/loadingstrategy
*/
import {fromUserExtent, fromUserResolution, toUserExtent} from './proj.js';
/**
* Strategy function for loading all features with a single request.
* @param {import("./extent.js").Extent} extent Extent.
@@ -28,7 +30,7 @@ export function bbox(extent, resolution) {
/**
* Creates a strategy function for loading features based on a tile grid.
* @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.
* @return {function(import("./extent.js").Extent, number): Array<import("./extent.js").Extent>} Loading strategy.
* @return {function(import("./extent.js").Extent, number, import("./proj.js").Projection): Array<import("./extent.js").Extent>} Loading strategy.
* @api
*/
export function tile(tileGrid) {
@@ -36,11 +38,17 @@ export function tile(tileGrid) {
/**
* @param {import("./extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {import("./proj.js").Projection} projection Projection.
* @return {Array<import("./extent.js").Extent>} Extents.
*/
function (extent, resolution) {
const z = tileGrid.getZForResolution(resolution);
const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
function (extent, resolution, projection) {
const z = tileGrid.getZForResolution(
fromUserResolution(resolution, projection)
);
const tileRange = tileGrid.getTileRangeForExtentAndZ(
fromUserExtent(extent, projection),
z
);
/** @type {Array<import("./extent.js").Extent>} */
const extents = [];
/** @type {import("./tilecoord.js").TileCoord} */
@@ -55,7 +63,9 @@ export function tile(tileGrid) {
tileCoord[2] <= tileRange.maxY;
++tileCoord[2]
) {
extents.push(tileGrid.getTileCoordExtent(tileCoord));
extents.push(
toUserExtent(tileGrid.getTileCoordExtent(tileCoord), projection)
);
}
}
return extents;

View File

@@ -0,0 +1,38 @@
import {approximatelyEquals} from '../../../../src/ol/extent.js';
import {
clearUserProjection,
get,
toUserExtent,
toUserResolution,
transformExtent,
useGeographic,
} from '../../../../src/ol/proj.js';
import {createXYZ} from '../../../../src/ol/tilegrid.js';
import {tile} from '../../../../src/ol/loadingstrategy.js';
describe('ol/loadingstrategy', function () {
describe('tile', function () {
afterEach(function () {
clearUserProjection();
});
it('uses a tile grid in view projection', function () {
useGeographic();
const tileGrid = createXYZ();
const strategy = tile(tileGrid);
const extent = tileGrid.getTileCoordExtent([1, 1, 1]);
const userExtent = toUserExtent(extent, get('EPSG:3857'));
const userResolution = toUserResolution(
tileGrid.getResolution(1),
get('EPSG:3857')
);
const extents = strategy(userExtent, userResolution, get('EPSG:3857'));
expect(
approximatelyEquals(
transformExtent(extents[0], 'EPSG:4326', 'EPSG:3857'),
extent,
1e-8
)
).to.be(true);
});
});
});