Files
openlayers/test/spec/ol/format/mvt.test.js
Guillaume Beraudo 39fc6d7816 Avoid unnecessary transform in MVT format
When using ol.render.Feature there was a mandatory geometry transform.

With this change it is now easy to read features directly in the native tile projection.
Since there is no needed transform, there is no need either to define an extent and a world extent, for that use-case.
2020-09-10 17:13:30 +02:00

268 lines
7.7 KiB
JavaScript

import Feature from '../../../../src/ol/Feature.js';
import MVT from '../../../../src/ol/format/MVT.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 RenderFeature from '../../../../src/ol/render/Feature.js';
where('ArrayBuffer.isView').describe('ol.format.MVT', function () {
let data;
beforeEach(function (done) {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'spec/ol/data/14-8938-5680.vector.pbf');
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
data = xhr.response;
done();
};
xhr.send();
});
describe('#readFeatures', function () {
const options = {
featureProjection: 'EPSG:3857',
extent: [
1824704.739223726,
6141868.096770482,
1827150.7241288517,
6144314.081675608,
],
};
it('uses ol.render.Feature as feature class by default', function () {
const format = new MVT({layers: ['water']});
const features = format.readFeatures(data, options);
expect(features[0]).to.be.a(RenderFeature);
});
it('parses only specified layers', function () {
const format = new MVT({layers: ['water']});
const features = format.readFeatures(data, options);
expect(features.length).to.be(10);
});
it('parses geometries correctly', function () {
const format = new MVT({
featureClass: Feature,
layers: ['poi_label'],
});
let geometry;
geometry = format.readFeatures(data)[0].getGeometry();
expect(geometry.getType()).to.be('Point');
expect(geometry.getCoordinates()).to.eql([-1210, 2681]);
format.setLayers(['water']);
geometry = format.readFeatures(data)[0].getGeometry();
expect(geometry.getType()).to.be('Polygon');
expect(geometry.getCoordinates()[0].length).to.be(10);
expect(geometry.getCoordinates()[0][0]).to.eql([1007, 2302]);
format.setLayers(['barrier_line']);
geometry = format.readFeatures(data)[0].getGeometry();
expect(geometry.getType()).to.be('MultiLineString');
expect(geometry.getCoordinates()[1].length).to.be(6);
expect(geometry.getCoordinates()[1][0]).to.eql([4160, 3489]);
});
it('avoids unnecessary reprojections of the ol.render.Feature', function () {
const format = new MVT({
layers: ['poi_label'],
});
const geometry = format.readFeatures(data)[0].getGeometry();
expect(geometry.getType()).to.be('Point');
expect(geometry.getFlatCoordinates()).to.eql([-1210, 2681]);
});
it('parses id property', function () {
// ol.Feature
let format = new MVT({
featureClass: Feature,
layers: ['building'],
});
let features = format.readFeatures(data, options);
expect(features[0].getId()).to.be(2);
// ol.render.Feature
format = new MVT({
layers: ['building'],
});
features = format.readFeatures(data, options);
expect(features[0].getId()).to.be(2);
});
it('accepts custom idProperty', function () {
const format = new MVT({
featureClass: Feature,
layers: ['poi_label'],
idProperty: 'osm_id',
});
const features = format.readFeatures(data, options);
const first = features[0];
expect(first.getId()).to.be(1000000057590683);
expect(first.get('osm_id')).to.be(undefined);
});
it('accepts custom idProperty (render features)', function () {
const format = new MVT({
layers: ['poi_label'],
idProperty: 'osm_id',
});
const features = format.readFeatures(data, options);
const first = features[0];
expect(first.getId()).to.be(1000000057590683);
expect(first.get('osm_id')).to.be(undefined);
});
it('works if you provide a bogus idProperty', function () {
const format = new MVT({
layers: ['poi_label'],
idProperty: 'bogus',
});
const features = format.readFeatures(data, options);
const first = features[0];
expect(first.getId()).to.be(undefined);
});
});
});
describe('ol.format.MVT', function () {
const options = {
featureProjection: 'EPSG:3857',
extent: [
1824704.739223726,
6141868.096770482,
1827150.7241288517,
6144314.081675608,
],
};
describe('#createFeature_', function () {
it('accepts a geometryName', function () {
const format = new MVT({
featureClass: Feature,
geometryName: 'myGeom',
});
const rawFeature = {
id: 1,
properties: {
geometry: 'foo',
},
type: 1,
layer: {
name: 'layer1',
},
};
format.readRawGeometry_ = function (
{},
rawFeature,
flatCoordinates,
ends
) {
flatCoordinates.push(0, 0);
ends.push(2);
};
const feature = format.createFeature_({}, rawFeature);
const geometry = feature.getGeometry();
expect(geometry).to.be.a(Point);
expect(feature.get('myGeom')).to.equal(geometry);
expect(feature.get('geometry')).to.be('foo');
});
it('detects a Polygon', function () {
const format = new MVT({
featureClass: Feature,
});
const rawFeature = {
type: 3,
properties: {},
layer: {
name: 'layer1',
},
};
format.readRawGeometry_ = function (
{},
rawFeature,
flatCoordinates,
ends
) {
flatCoordinates.push(0, 0, 3, 0, 3, 3, 0, 3, 0, 0);
flatCoordinates.push(1, 1, 1, 2, 2, 2, 2, 1, 1, 1);
ends.push(10, 20);
};
const feature = format.createFeature_({}, rawFeature);
const geometry = feature.getGeometry();
expect(geometry).to.be.a(Polygon);
});
it('detects a MultiPolygon', function () {
const format = new MVT({
featureClass: Feature,
});
const rawFeature = {
type: 3,
properties: {},
layer: {
name: 'layer1',
},
};
format.readRawGeometry_ = function (
{},
rawFeature,
flatCoordinates,
ends
) {
flatCoordinates.push(0, 0, 1, 0, 1, 1, 0, 1, 0, 0);
flatCoordinates.push(1, 1, 2, 1, 2, 2, 1, 2, 1, 1);
ends.push(10, 20);
};
const feature = format.createFeature_({}, rawFeature);
const geometry = feature.getGeometry();
expect(geometry).to.be.a(MultiPolygon);
});
it('creates ol.render.Feature instances', function () {
const format = new MVT();
const rawFeature = {
type: 3,
properties: {
foo: 'bar',
},
layer: {
name: 'layer1',
},
};
let createdFlatCoordinates;
let createdEnds;
format.readRawGeometry_ = function (
{},
rawFeature,
flatCoordinates,
ends
) {
flatCoordinates.push(0, 0, 1, 0, 1, 1, 1, 0, 0, 0);
flatCoordinates.push(1, 1, 2, 1, 2, 2, 2, 1, 1, 1);
createdFlatCoordinates = flatCoordinates;
ends.push(10, 20);
createdEnds = ends;
};
format.dataProjection.setExtent([0, 0, 4096, 4096]);
format.dataProjection.setWorldExtent(options.extent);
const feature = format.createFeature_(
{},
rawFeature,
format.adaptOptions(options)
);
expect(feature).to.be.a(RenderFeature);
expect(feature.getType()).to.be('Polygon');
expect(feature.getFlatCoordinates()).to.equal(createdFlatCoordinates);
expect(feature.getEnds()).to.equal(createdEnds);
expect(feature.get('foo')).to.be('bar');
});
});
});