UNPKG

ol-cesium

Version:

OpenLayers Cesium integration library

245 lines 19 kB
import MVT from 'ol/format/MVT.js'; import Style, {} from 'ol/style/Style.js'; import Stroke from 'ol/style/Stroke.js'; import { toContext } from 'ol/render.js'; import { get as getProjection } from 'ol/proj.js'; import { VERSION as OL_VERSION } from 'ol/util.js'; import LRUCache from 'ol/structs/LRUCache.js'; import { getForProjection as getTilegridForProjection } from 'ol/tilegrid.js'; import { createFromTemplates as createTileUrlFunctions } from 'ol/tileurlfunction.js'; import RenderFeature from 'ol/render/Feature.js'; import { createEmptyCanvas } from './core/OLImageryProvider'; const format = new MVT({ featureClass: RenderFeature }); const styles = [new Style({ stroke: new Stroke({ color: 'blue', width: 2 }) })]; export default class MVTImageryProvider { urls; emptyCanvas_ = createEmptyCanvas(); emptyCanvasPromise_ = Promise.resolve(this.emptyCanvas_); tilingScheme_ = new Cesium.WebMercatorTilingScheme; ready_ = true; rectangle_; tileRectangle_; tileWidth = 256; tileHeight = 256; maximumLevel = 20; minimumLevel_ = 0; get minimumLevel() { return this.minimumLevel_; } featureCache; tileCache; tileFunction_; styleFunction_; projection_ = getProjection('EPSG:3857'); /** * When <code>true</code>, this model is ready to render, i.e., the external binary, image, * and shader files were downloaded and the WebGL resources were created. */ get ready() { return this.ready_; } /** * Gets the rectangle, in radians, of the imagery provided by the instance. */ get rectangle() { return this.rectangle_; } /** * Gets the tiling scheme used by the provider. */ get tilingScheme() { return this.tilingScheme_; } /** * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners * are passed an instance of {@link Cesium.TileProviderError}. */ errorEvent = new Cesium.Event(); /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit * the source of the imagery. */ credit; getTileCredits(x, y, level) { return []; } /** * Gets the proxy used by this provider. */ proxy; get _ready() { return this.ready_; } /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function * returns undefined, no tiles are filtered. */ get tileDiscardPolicy() { return undefined; } // FIXME: this might be exposed /** * Gets a value indicating whether or not the images provided by this imagery provider * include an alpha channel. If this property is false, an alpha channel, if present, will * be ignored. If this property is true, any images without an alpha channel will be treated * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. */ get hasAlphaChannel() { return true; } // FIXME: this could be implemented by proxying to OL /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within * a tile. * This function is optional, so it may not exist on all ImageryProviders. * @param x - The tile X coordinate. * @param y - The tile Y coordinate. * @param level - The tile level. * @param longitude - The longitude at which to pick features. * @param latitude - The latitude at which to pick features. * @return A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. */ pickFeatures(x, y, level, longitude, latitude) { return undefined; } constructor(options) { this.urls = options.urls; this.rectangle_ = options.rectangle || this.tilingScheme.rectangle; this.credit = options.credit; this.styleFunction_ = options.styleFunction || (() => styles); this.tileRectangle_ = new Cesium.Rectangle(); // to avoid too frequent cache grooming we allow x2 capacity const cacheSize = options.cacheSize !== undefined ? options.cacheSize : 50; this.tileCache = new LRUCache(cacheSize); this.featureCache = options.featureCache || new LRUCache(cacheSize); this.minimumLevel_ = options.minimumLevel || 0; const tileGrid = getTilegridForProjection(this.projection_); this.tileFunction_ = createTileUrlFunctions(this.urls, tileGrid); } getTileFeatures(z, x, y) { const cacheKey = this.getCacheKey_(z, x, y); let promise; if (this.featureCache.containsKey(cacheKey)) { promise = this.featureCache.get(cacheKey); } if (!promise) { const url = this.getUrl_(z, x, y); promise = fetch(url) .then(r => (r.ok ? r : Promise.reject(r))) .then(r => r.arrayBuffer()) .then(buffer => this.readFeaturesFromBuffer(buffer)); this.featureCache.set(cacheKey, promise); if (this.featureCache.getCount() > 2 * this.featureCache.highWaterMark) { while (this.featureCache.canExpireCache()) { this.featureCache.pop(); } } } return promise; } readFeaturesFromBuffer(buffer) { let options; if (OL_VERSION <= '6.4.4') { // See https://github.com/openlayers/openlayers/pull/11540 options = { extent: [0, 0, 4096, 4096], dataProjection: this.projection_, featureProjection: this.projection_ }; } const features = format.readFeatures(buffer, options); const scaleFactor = this.tileWidth / 4096; features.forEach((f) => { const flatCoordinates = f.getFlatCoordinates(); let flip = false; for (let i = 0; i < flatCoordinates.length; ++i) { flatCoordinates[i] *= scaleFactor; if (flip) { // FIXME: why do we need this now? flatCoordinates[i] = this.tileWidth - flatCoordinates[i]; } if (OL_VERSION <= '6.4.4') { // LEGACY flip = !flip; } } }); return features; } getUrl_(z, x, y) { // FIXME: probably we should not pass 1 as pixelRatio const url = this.tileFunction_([z, x, y], 1, this.projection_); return url; } getCacheKey_(z, x, y) { return `${z}_${x}_${y}`; } requestImage(x, y, z, request) { if (z < this.minimumLevel_) { return this.emptyCanvasPromise_; } try { const cacheKey = this.getCacheKey_(z, x, y); let promise; if (this.tileCache.containsKey(cacheKey)) { promise = this.tileCache.get(cacheKey); } if (!promise) { promise = this.getTileFeatures(z, x, y) .then((features) => { // FIXME: here we suppose the 2D projection is in meters this.tilingScheme.tileXYToNativeRectangle(x, y, z, this.tileRectangle_); const resolution = (this.tileRectangle_.east - this.tileRectangle_.west) / this.tileWidth; return this.rasterizeFeatures(features, this.styleFunction_, resolution); }); this.tileCache.set(cacheKey, promise); if (this.tileCache.getCount() > 2 * this.tileCache.highWaterMark) { while (this.tileCache.canExpireCache()) { this.tileCache.pop(); } } } return promise; } catch (e) { console.trace(e); // FIXME: open PR on Cesium to fix incorrect typing // @ts-ignore this.errorEvent.raiseEvent('could not render pbf to tile', e); } } rasterizeFeatures(features, styleFunction, resolution) { const canvas = document.createElement('canvas'); const vectorContext = toContext(canvas.getContext('2d'), { size: [this.tileWidth, this.tileHeight] }); features.forEach((f) => { const styles = styleFunction(f, resolution); if (styles) { if (Array.isArray(styles)) { styles.forEach((style) => { vectorContext.setStyle(style); vectorContext.drawGeometry(f); }); } else { vectorContext.setStyle(styles); vectorContext.drawGeometry(f); } } }); return canvas; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTVZUSW1hZ2VyeVByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29sY3MvTVZUSW1hZ2VyeVByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sR0FBRyxNQUFNLGtCQUFrQixDQUFDO0FBQ25DLE9BQU8sS0FBSyxFQUFFLEVBQW9CLE1BQU0sbUJBQW1CLENBQUM7QUFDNUQsT0FBTyxNQUFNLE1BQU0sb0JBQW9CLENBQUM7QUFDeEMsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEVBQUMsR0FBRyxJQUFJLGFBQWEsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUNoRCxPQUFPLEVBQUMsT0FBTyxJQUFJLFVBQVUsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUNqRCxPQUFPLFFBQVEsTUFBTSx3QkFBd0IsQ0FBQztBQUM5QyxPQUFPLEVBQUMsZ0JBQWdCLElBQUksd0JBQXdCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RSxPQUFPLEVBQUMsbUJBQW1CLElBQUksc0JBQXNCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUdwRixPQUFPLGFBQWEsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQWEzRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNyQixZQUFZLEVBQUUsYUFBYTtDQUM1QixDQUFDLENBQUM7QUFFSCxNQUFNLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDO1FBQ3hCLE1BQU0sRUFBRSxJQUFJLE1BQU0sQ0FBQztZQUNqQixLQUFLLEVBQUUsTUFBTTtZQUNiLEtBQUssRUFBRSxDQUFDO1NBQ1QsQ0FBQztLQUNILENBQUMsQ0FBQyxDQUFDO0FBR0osTUFBTSxDQUFDLE9BQU8sT0FBTyxrQkFBa0I7SUFDN0IsSUFBSSxDQUFXO0lBQ2YsWUFBWSxHQUFzQixpQkFBaUIsRUFB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