Merge pull request #9677 from ahocevar/featureformat-tilepixels
Add support for tile pixel projection in feature formats
This commit is contained in:
+16
-22
@@ -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 {Tile as TileLayer, VectorTile as VectorTileLayer} from '../src/ol/layer.js';
|
||||||
import Projection from '../src/ol/proj/Projection.js';
|
import Projection from '../src/ol/proj/Projection.js';
|
||||||
|
|
||||||
|
// Converts geojson-vt data to GeoJSON
|
||||||
const replacer = function(key, value) {
|
const replacer = function(key, value) {
|
||||||
if (value.geometry) {
|
if (value.geometry) {
|
||||||
let type;
|
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({
|
const map = new Map({
|
||||||
layers: [
|
layers: [
|
||||||
new TileLayer({
|
new TileLayer({
|
||||||
@@ -73,23 +68,22 @@ fetch(url).then(function(response) {
|
|||||||
debug: 1
|
debug: 1
|
||||||
});
|
});
|
||||||
const vectorSource = new VectorTileSource({
|
const vectorSource = new VectorTileSource({
|
||||||
format: new GeoJSON(),
|
format: new GeoJSON({
|
||||||
tileLoadFunction: function(tile) {
|
// Data returned from geojson-vt is in tile pixel units
|
||||||
const format = tile.getFormat();
|
dataProjection: new Projection({
|
||||||
const tileCoord = tile.getTileCoord();
|
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 data = tileIndex.getTile(tileCoord[0], tileCoord[1], tileCoord[2]);
|
||||||
|
const geojson = JSON.stringify({
|
||||||
const features = format.readFeatures(
|
type: 'FeatureCollection',
|
||||||
JSON.stringify({
|
features: data ? data.features : []
|
||||||
type: 'FeatureCollection',
|
}, replacer);
|
||||||
features: data ? data.features : []
|
return 'data:application/json;charset=UTF-8,' + geojson;
|
||||||
}, replacer));
|
}
|
||||||
tile.setLoader(function() {
|
|
||||||
tile.setFeatures(features);
|
|
||||||
tile.setProjection(tilePixels);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
url: 'data:' // arbitrary url, we don't use it in the tileLoadFunction
|
|
||||||
});
|
});
|
||||||
const vectorLayer = new VectorTileLayer({
|
const vectorLayer = new VectorTileLayer({
|
||||||
source: vectorSource
|
source: vectorSource
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import {get as getProjection, equivalent as equivalentProjection, transformExten
|
|||||||
* the `dataProjection` of the format is assigned (where set). If the projection
|
* 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,
|
* can not be derived from the data and if no `dataProjection` is set for a format,
|
||||||
* the features will not be reprojected.
|
* the features will not be reprojected.
|
||||||
* @property {import("../extent.js").Extent} [extent] Tile extent of the tile being read. This is only used and
|
* @property {import("../extent.js").Extent} [extent] Tile extent in map units of the tile being read.
|
||||||
* required for {@link module:ol/format/MVT}.
|
* 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
|
* @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
|
* created by the format reader. If not provided, features will be returned in the
|
||||||
* `dataProjection`.
|
* `dataProjection`.
|
||||||
@@ -86,9 +88,14 @@ class FeatureFormat {
|
|||||||
getReadOptions(source, opt_options) {
|
getReadOptions(source, opt_options) {
|
||||||
let options;
|
let options;
|
||||||
if (opt_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 = {
|
options = {
|
||||||
dataProjection: opt_options.dataProjection ?
|
dataProjection: dataProjection,
|
||||||
opt_options.dataProjection : this.readProjection(source),
|
|
||||||
featureProjection: opt_options.featureProjection
|
featureProjection: opt_options.featureProjection
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import LinearRing from '../../../../src/ol/geom/LinearRing.js';
|
|||||||
import MultiPolygon from '../../../../src/ol/geom/MultiPolygon.js';
|
import MultiPolygon from '../../../../src/ol/geom/MultiPolygon.js';
|
||||||
import Point from '../../../../src/ol/geom/Point.js';
|
import Point from '../../../../src/ol/geom/Point.js';
|
||||||
import Polygon from '../../../../src/ol/geom/Polygon.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() {
|
describe('ol.format.GeoJSON', function() {
|
||||||
@@ -260,6 +260,28 @@ describe('ol.format.GeoJSON', function() {
|
|||||||
expect(feature.getGeometry()).to.be.an(Point);
|
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() {
|
describe('#readFeatures', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user