Files
openlayers/test/node/ol/source/ogcTileUtil.test.js
2021-09-04 11:17:41 -06:00

268 lines
10 KiB
JavaScript

import TileGrid from '../../../../src/ol/tilegrid/TileGrid.js';
import events from 'events';
import expect from '../../expect.js';
import fse from 'fs-extra';
import path from 'path';
import {fileURLToPath} from 'url';
import {
getMapTileUrlTemplate,
getTileSetInfo,
getVectorTileUrlTemplate,
} from '../../../../src/ol/source/ogcTileUtil.js';
import {overrideXHR, restoreXHR} from '../../../../src/ol/net.js';
function getDataDir() {
const modulePath = fileURLToPath(import.meta.url);
return path.join(path.dirname(modulePath), 'data');
}
let baseUrl;
class MockXHR extends events.EventEmitter {
addEventListener(type, listener) {
this.addListener(type, listener);
}
open(method, url) {
if (url.startsWith(baseUrl)) {
url = url.slice(baseUrl.length);
}
this.url = url;
}
setRequestHeader(key, value) {
// no-op
}
send() {
let url = path.resolve(getDataDir(), this.url);
if (!url.endsWith('.json')) {
url = url + '.json';
}
fse.readJSON(url).then(
(data) => {
this.status = 200;
this.responseText = JSON.stringify(data);
this.emit('load', {target: this});
},
(err) => {
console.error(err); // eslint-disable-line no-console
this.emit('error', {target: this});
}
);
}
}
describe('ol/source/ogcTileUtil.js', () => {
describe('getTileSetInfo()', () => {
beforeEach(() => {
overrideXHR(MockXHR);
});
afterEach(() => {
baseUrl = '';
restoreXHR();
});
it('fetches and parses map tile info', async () => {
baseUrl = 'https://maps.ecere.com/';
const sourceInfo = {
url: 'https://maps.ecere.com/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad',
};
const tileInfo = await getTileSetInfo(sourceInfo);
expect(tileInfo).to.be.an(Object);
expect(tileInfo.urlTemplate).to.be(
'/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.jpg'
);
expect(tileInfo.grid).to.be.a(TileGrid);
expect(tileInfo.grid.getTileSize(0)).to.eql([256, 256]);
expect(tileInfo.grid.getResolutions()).to.have.length(10);
expect(tileInfo.urlFunction).to.be.a(Function);
expect(tileInfo.urlFunction([3, 2, 1])).to.be(
'https://maps.ecere.com/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/3/1/2.jpg'
);
expect(tileInfo.urlFunction([3, -1, 0])).to.be(undefined); // below min x
expect(tileInfo.urlFunction([3, 8, 0])).to.be(undefined); // above max x
expect(tileInfo.urlFunction([3, 0, -1])).to.be(undefined); // below min y
expect(tileInfo.urlFunction([3, 0, 8])).to.be(undefined); // above max y
});
it('allows preferred media type to be configured', async () => {
baseUrl = 'https://maps.ecere.com/';
const sourceInfo = {
url: 'https://maps.ecere.com/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad',
mediaType: 'image/png',
};
const tileInfo = await getTileSetInfo(sourceInfo);
expect(tileInfo).to.be.an(Object);
expect(tileInfo.urlTemplate).to.be(
'/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.png'
);
expect(tileInfo.urlFunction).to.be.a(Function);
expect(tileInfo.urlFunction([3, 2, 1])).to.be(
'https://maps.ecere.com/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/3/1/2.png'
);
});
it('fetches and parses vector tile info', async () => {
baseUrl = 'https://maps.ecere.com/';
const sourceInfo = {
url: 'https://maps.ecere.com/ogcapi/collections/ne_10m_admin_0_countries/tiles/WebMercatorQuad',
};
const tileInfo = await getTileSetInfo(sourceInfo);
expect(tileInfo).to.be.an(Object);
expect(tileInfo.urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.json'
);
expect(tileInfo.grid).to.be.a(TileGrid);
expect(tileInfo.grid.getTileSize(0)).to.eql([256, 256]);
expect(tileInfo.grid.getResolutions()).to.have.length(8);
expect(tileInfo.urlFunction).to.be.a(Function);
expect(tileInfo.urlFunction([3, 2, 1])).to.be(
'https://maps.ecere.com/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/3/1/2.json'
);
expect(tileInfo.urlFunction([2, -1, 0])).to.be(undefined); // below min x
expect(tileInfo.urlFunction([2, 4, 0])).to.be(undefined); // above max x
expect(tileInfo.urlFunction([2, 0, -1])).to.be(undefined); // below min y
expect(tileInfo.urlFunction([2, 0, 4])).to.be(undefined); // above max y
});
it('allows preferred media type to be configured', async () => {
baseUrl = 'https://maps.ecere.com/';
const sourceInfo = {
url: 'https://maps.ecere.com/ogcapi/collections/ne_10m_admin_0_countries/tiles/WebMercatorQuad',
mediaType: 'application/vnd.mapbox-vector-tile',
};
const tileInfo = await getTileSetInfo(sourceInfo);
expect(tileInfo).to.be.an(Object);
expect(tileInfo.urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.mvt'
);
expect(tileInfo.urlFunction).to.be.a(Function);
expect(tileInfo.urlFunction([3, 2, 1])).to.be(
'https://maps.ecere.com/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/3/1/2.mvt'
);
});
it('uses supported media types if available', async () => {
baseUrl = 'https://maps.ecere.com/';
const sourceInfo = {
url: 'https://maps.ecere.com/ogcapi/collections/ne_10m_admin_0_countries/tiles/WebMercatorQuad',
supportedMediaTypes: [
'bogus-media-type',
'application/vnd.mapbox-vector-tile',
'application/geo+json', // should not be used
],
};
const tileInfo = await getTileSetInfo(sourceInfo);
expect(tileInfo).to.be.an(Object);
expect(tileInfo.urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.mvt'
);
expect(tileInfo.urlFunction).to.be.a(Function);
expect(tileInfo.urlFunction([3, 2, 1])).to.be(
'https://maps.ecere.com/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/3/1/2.mvt'
);
});
it('treats supported media types in descending order of priority', async () => {
baseUrl = 'https://maps.ecere.com/';
const sourceInfo = {
url: 'https://maps.ecere.com/ogcapi/collections/ne_10m_admin_0_countries/tiles/WebMercatorQuad',
supportedMediaTypes: [
'bogus-media-type',
'application/geo+json', // should be preferred
'application/vnd.mapbox-vector-tile',
],
};
const tileInfo = await getTileSetInfo(sourceInfo);
expect(tileInfo).to.be.an(Object);
expect(tileInfo.urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.json'
);
expect(tileInfo.urlFunction).to.be.a(Function);
expect(tileInfo.urlFunction([3, 2, 1])).to.be(
'https://maps.ecere.com/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/3/1/2.json'
);
});
});
describe('getVectorTileUrlTemplate()', () => {
let links;
before(async () => {
const url = path.join(
getDataDir(),
'ogcapi/collections/ne_10m_admin_0_countries/tiles/WebMercatorQuad.json'
);
const tileSet = await fse.readJSON(url);
links = tileSet.links;
});
it('gets the last known vector type if the preferred media type is absent', () => {
const urlTemplate = getVectorTileUrlTemplate(links);
expect(urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.json'
);
});
it('gets the preferred media type if given', () => {
const urlTemplate = getVectorTileUrlTemplate(
links,
'application/vnd.mapbox-vector-tile'
);
expect(urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.mvt'
);
});
it('uses supported media types is preferred media type is not given', () => {
const urlTemplate = getVectorTileUrlTemplate(links, undefined, [
'application/vnd.mapbox-vector-tile',
]);
expect(urlTemplate).to.be(
'/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.mvt'
);
});
it('throws if it cannot find preferred media type or a known fallback', () => {
function call() {
getVectorTileUrlTemplate([], 'application/vnd.mapbox-vector-tile');
}
expect(call).to.throwException('Could not find "item" link');
});
});
describe('getMapTileUrlTemplate()', () => {
let links;
before(async () => {
const url = path.join(
getDataDir(),
'ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad.json'
);
const tileSet = await fse.readJSON(url);
links = tileSet.links;
});
it('gets the last known image type if the preferred media type is absent', () => {
const urlTemplate = getMapTileUrlTemplate(links);
expect(urlTemplate).to.be(
'/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.jpg'
);
});
it('gets the preferred media type if given', () => {
const urlTemplate = getMapTileUrlTemplate(links, 'image/png');
expect(urlTemplate).to.be(
'/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}.png'
);
});
it('throws if it cannot find preferred media type or a known fallback', () => {
function call() {
getMapTileUrlTemplate([], 'image/png');
}
expect(call).to.throwException('Could not find "item" link');
});
});
});