From 76f44efbb6dc7bddac1c2dc8474f86373ef89654 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 14 Jun 2019 12:11:15 +0200 Subject: [PATCH 1/2] Add support for tile pixels to feature formats --- src/ol/format/Feature.js | 15 +++++++++++---- test/spec/ol/format/geojson.test.js | 24 +++++++++++++++++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/ol/format/Feature.js b/src/ol/format/Feature.js index a426546bb2..08dc0e66a9 100644 --- a/src/ol/format/Feature.js +++ b/src/ol/format/Feature.js @@ -13,8 +13,10 @@ import {get as getProjection, equivalent as equivalentProjection, transformExten * the `dataProjection` of the format is assigned (where set). If the projection * can not be derived from the data and if no `dataProjection` is set for a format, * the features will not be reprojected. - * @property {import("../extent.js").Extent} [extent] Tile extent of the tile being read. This is only used and - * required for {@link module:ol/format/MVT}. + * @property {import("../extent.js").Extent} [extent] Tile extent in map units of the tile being read. + * This is only required when reading data with tile pixels as geometry units. When configured, + * a `dataProjection` with `TILE_PIXELS` as `units` and the tile's pixel extent as `extent` needs to be + * provided. * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries * created by the format reader. If not provided, features will be returned in the * `dataProjection`. @@ -86,9 +88,14 @@ class FeatureFormat { getReadOptions(source, opt_options) { let options; if (opt_options) { + let dataProjection = opt_options.dataProjection ? + opt_options.dataProjection : this.readProjection(source); + if (opt_options.extent) { + dataProjection = getProjection(dataProjection); + dataProjection.setWorldExtent(opt_options.extent); + } options = { - dataProjection: opt_options.dataProjection ? - opt_options.dataProjection : this.readProjection(source), + dataProjection: dataProjection, featureProjection: opt_options.featureProjection }; } diff --git a/test/spec/ol/format/geojson.test.js b/test/spec/ol/format/geojson.test.js index 1ebb8faf26..879643a4df 100644 --- a/test/spec/ol/format/geojson.test.js +++ b/test/spec/ol/format/geojson.test.js @@ -8,7 +8,7 @@ import LinearRing from '../../../../src/ol/geom/LinearRing.js'; import MultiPolygon from '../../../../src/ol/geom/MultiPolygon.js'; import Point from '../../../../src/ol/geom/Point.js'; import Polygon from '../../../../src/ol/geom/Polygon.js'; -import {fromLonLat, get as getProjection, toLonLat, transform} from '../../../../src/ol/proj.js'; +import {fromLonLat, get as getProjection, toLonLat, transform, Projection} from '../../../../src/ol/proj.js'; describe('ol.format.GeoJSON', function() { @@ -260,6 +260,28 @@ describe('ol.format.GeoJSON', function() { expect(feature.getGeometry()).to.be.an(Point); }); + it('transforms tile pixel coordinates', function() { + const geojson = { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [1024, 1024] + } + }; + const format = new GeoJSON({ + dataProjection: new Projection({ + code: '', + units: 'tile-pixels', + extent: [0, 0, 4096, 4096] + }) + }); + const feature = format.readFeature(geojson, { + extent: [-180, -90, 180, 90], + featureProjection: 'EPSG:3857' + }); + expect(feature.getGeometry().getCoordinates()).to.eql([-135, 45]); + }); + }); describe('#readFeatures', function() { From 124e984a6d693a375bd31be4a691d1e220b7bd5f Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 14 Jun 2019 12:11:31 +0200 Subject: [PATCH 2/2] Fix and simplify geojson-vt example --- examples/geojson-vt.js | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/examples/geojson-vt.js b/examples/geojson-vt.js index 859fe02a3b..a61ca1fd50 100644 --- a/examples/geojson-vt.js +++ b/examples/geojson-vt.js @@ -6,7 +6,7 @@ import VectorTileSource from '../src/ol/source/VectorTile.js'; import {Tile as TileLayer, VectorTile as VectorTileLayer} from '../src/ol/layer.js'; import Projection from '../src/ol/proj/Projection.js'; - +// Converts geojson-vt data to GeoJSON const replacer = function(key, value) { if (value.geometry) { let type; @@ -46,11 +46,6 @@ const replacer = function(key, value) { } }; -const tilePixels = new Projection({ - code: 'TILE_PIXELS', - units: 'tile-pixels' -}); - const map = new Map({ layers: [ new TileLayer({ @@ -73,23 +68,22 @@ fetch(url).then(function(response) { debug: 1 }); const vectorSource = new VectorTileSource({ - format: new GeoJSON(), - tileLoadFunction: function(tile) { - const format = tile.getFormat(); - const tileCoord = tile.getTileCoord(); + format: new GeoJSON({ + // Data returned from geojson-vt is in tile pixel units + dataProjection: new Projection({ + code: 'TILE_PIXELS', + units: 'tile-pixels', + extent: [0, 0, 4096, 4096] + }) + }), + tileUrlFunction: function(tileCoord) { const data = tileIndex.getTile(tileCoord[0], tileCoord[1], tileCoord[2]); - - const features = format.readFeatures( - JSON.stringify({ - type: 'FeatureCollection', - features: data ? data.features : [] - }, replacer)); - tile.setLoader(function() { - tile.setFeatures(features); - tile.setProjection(tilePixels); - }); - }, - url: 'data:' // arbitrary url, we don't use it in the tileLoadFunction + const geojson = JSON.stringify({ + type: 'FeatureCollection', + features: data ? data.features : [] + }, replacer); + return 'data:application/json;charset=UTF-8,' + geojson; + } }); const vectorLayer = new VectorTileLayer({ source: vectorSource