This commit is contained in:
573
node_modules/ol/renderer/canvas/VectorLayer.js
generated
vendored
Normal file
573
node_modules/ol/renderer/canvas/VectorLayer.js
generated
vendored
Normal file
@@ -0,0 +1,573 @@
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
/**
|
||||
* @module ol/renderer/canvas/VectorLayer
|
||||
*/
|
||||
import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js';
|
||||
import CanvasLayerRenderer, { canvasPool } from './Layer.js';
|
||||
import ExecutorGroup from '../../render/canvas/ExecutorGroup.js';
|
||||
import ViewHint from '../../ViewHint.js';
|
||||
import { HIT_DETECT_RESOLUTION, createHitDetectionImageData, hitDetect, } from '../../render/canvas/hitdetect.js';
|
||||
import { apply, makeInverse, makeScale, toString as transformToString, } from '../../transform.js';
|
||||
import { buffer, containsExtent, createEmpty, getWidth, intersects as intersectsExtent, wrapX as wrapExtentX, } from '../../extent.js';
|
||||
import { createCanvasContext2D, releaseCanvas } from '../../dom.js';
|
||||
import { defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature, } from '../vector.js';
|
||||
import { equals } from '../../array.js';
|
||||
import { fromUserExtent, getTransformFromProjections, getUserProjection, toUserExtent, toUserResolution, } from '../../proj.js';
|
||||
import { getUid } from '../../util.js';
|
||||
import { wrapX as wrapCoordinateX } from '../../coordinate.js';
|
||||
/**
|
||||
* @classdesc
|
||||
* Canvas renderer for vector layers.
|
||||
* @api
|
||||
*/
|
||||
var CanvasVectorLayerRenderer = /** @class */ (function (_super) {
|
||||
__extends(CanvasVectorLayerRenderer, _super);
|
||||
/**
|
||||
* @param {import("../../layer/BaseVector.js").default} vectorLayer Vector layer.
|
||||
*/
|
||||
function CanvasVectorLayerRenderer(vectorLayer) {
|
||||
var _this = _super.call(this, vectorLayer) || this;
|
||||
/** @private */
|
||||
_this.boundHandleStyleImageChange_ = _this.handleStyleImageChange_.bind(_this);
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
_this.animatingOrInteracting_;
|
||||
/**
|
||||
* @type {ImageData}
|
||||
*/
|
||||
_this.hitDetectionImageData_ = null;
|
||||
/**
|
||||
* @type {Array<import("../../Feature.js").default>}
|
||||
*/
|
||||
_this.renderedFeatures_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
_this.renderedRevision_ = -1;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
_this.renderedResolution_ = NaN;
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../../extent.js").Extent}
|
||||
*/
|
||||
_this.renderedExtent_ = createEmpty();
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../../extent.js").Extent}
|
||||
*/
|
||||
_this.wrappedRenderedExtent_ = createEmpty();
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
_this.renderedRotation_;
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../../coordinate").Coordinate}
|
||||
*/
|
||||
_this.renderedCenter_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../../proj/Projection").default}
|
||||
*/
|
||||
_this.renderedProjection_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {function(import("../../Feature.js").default, import("../../Feature.js").default): number|null}
|
||||
*/
|
||||
_this.renderedRenderOrder_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../../render/canvas/ExecutorGroup").default}
|
||||
*/
|
||||
_this.replayGroup_ = null;
|
||||
/**
|
||||
* A new replay group had to be created by `prepareFrame()`
|
||||
* @type {boolean}
|
||||
*/
|
||||
_this.replayGroupChanged = true;
|
||||
/**
|
||||
* @type {import("../../render/canvas/ExecutorGroup").default}
|
||||
*/
|
||||
_this.declutterExecutorGroup = null;
|
||||
/**
|
||||
* Clipping to be performed by `renderFrame()`
|
||||
* @type {boolean}
|
||||
*/
|
||||
_this.clipping = true;
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
_this.compositionContext_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
_this.opacity_ = 1;
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* @param {ExecutorGroup} executorGroup Executor group.
|
||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||
* @param {import("rbush").default} [opt_declutterTree] Declutter tree.
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.renderWorlds = function (executorGroup, frameState, opt_declutterTree) {
|
||||
var extent = frameState.extent;
|
||||
var viewState = frameState.viewState;
|
||||
var center = viewState.center;
|
||||
var resolution = viewState.resolution;
|
||||
var projection = viewState.projection;
|
||||
var rotation = viewState.rotation;
|
||||
var projectionExtent = projection.getExtent();
|
||||
var vectorSource = this.getLayer().getSource();
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var viewHints = frameState.viewHints;
|
||||
var snapToPixel = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);
|
||||
var context = this.compositionContext_;
|
||||
var width = Math.round(frameState.size[0] * pixelRatio);
|
||||
var height = Math.round(frameState.size[1] * pixelRatio);
|
||||
var multiWorld = vectorSource.getWrapX() && projection.canWrapX();
|
||||
var worldWidth = multiWorld ? getWidth(projectionExtent) : null;
|
||||
var endWorld = multiWorld
|
||||
? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1
|
||||
: 1;
|
||||
var world = multiWorld
|
||||
? Math.floor((extent[0] - projectionExtent[0]) / worldWidth)
|
||||
: 0;
|
||||
do {
|
||||
var transform = this.getRenderTransform(center, resolution, rotation, pixelRatio, width, height, world * worldWidth);
|
||||
executorGroup.execute(context, 1, transform, rotation, snapToPixel, undefined, opt_declutterTree);
|
||||
} while (++world < endWorld);
|
||||
};
|
||||
CanvasVectorLayerRenderer.prototype.setupCompositionContext_ = function () {
|
||||
if (this.opacity_ !== 1) {
|
||||
var compositionContext = createCanvasContext2D(this.context.canvas.width, this.context.canvas.height, canvasPool);
|
||||
this.compositionContext_ = compositionContext;
|
||||
}
|
||||
else {
|
||||
this.compositionContext_ = this.context;
|
||||
}
|
||||
};
|
||||
CanvasVectorLayerRenderer.prototype.releaseCompositionContext_ = function () {
|
||||
if (this.opacity_ !== 1) {
|
||||
var alpha = this.context.globalAlpha;
|
||||
this.context.globalAlpha = this.opacity_;
|
||||
this.context.drawImage(this.compositionContext_.canvas, 0, 0);
|
||||
this.context.globalAlpha = alpha;
|
||||
releaseCanvas(this.compositionContext_);
|
||||
canvasPool.push(this.compositionContext_.canvas);
|
||||
this.compositionContext_ = null;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Render declutter items for this layer
|
||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.renderDeclutter = function (frameState) {
|
||||
if (this.declutterExecutorGroup) {
|
||||
this.setupCompositionContext_();
|
||||
this.renderWorlds(this.declutterExecutorGroup, frameState, frameState.declutterTree);
|
||||
this.releaseCompositionContext_();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Render the layer.
|
||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||
* @param {HTMLElement} target Target that may be used to render content to.
|
||||
* @return {HTMLElement} The rendered element.
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.renderFrame = function (frameState, target) {
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var layerState = frameState.layerStatesArray[frameState.layerIndex];
|
||||
// set forward and inverse pixel transforms
|
||||
makeScale(this.pixelTransform, 1 / pixelRatio, 1 / pixelRatio);
|
||||
makeInverse(this.inversePixelTransform, this.pixelTransform);
|
||||
var canvasTransform = transformToString(this.pixelTransform);
|
||||
this.useContainer(target, canvasTransform, this.getBackground(frameState));
|
||||
var context = this.context;
|
||||
var canvas = context.canvas;
|
||||
var replayGroup = this.replayGroup_;
|
||||
var declutterExecutorGroup = this.declutterExecutorGroup;
|
||||
if ((!replayGroup || replayGroup.isEmpty()) &&
|
||||
(!declutterExecutorGroup || declutterExecutorGroup.isEmpty())) {
|
||||
return null;
|
||||
}
|
||||
// resize and clear
|
||||
var width = Math.round(frameState.size[0] * pixelRatio);
|
||||
var height = Math.round(frameState.size[1] * pixelRatio);
|
||||
if (canvas.width != width || canvas.height != height) {
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
if (canvas.style.transform !== canvasTransform) {
|
||||
canvas.style.transform = canvasTransform;
|
||||
}
|
||||
}
|
||||
else if (!this.containerReused) {
|
||||
context.clearRect(0, 0, width, height);
|
||||
}
|
||||
this.preRender(context, frameState);
|
||||
var viewState = frameState.viewState;
|
||||
var projection = viewState.projection;
|
||||
this.opacity_ = layerState.opacity;
|
||||
this.setupCompositionContext_();
|
||||
// clipped rendering if layer extent is set
|
||||
var clipped = false;
|
||||
var render = true;
|
||||
if (layerState.extent && this.clipping) {
|
||||
var layerExtent = fromUserExtent(layerState.extent, projection);
|
||||
render = intersectsExtent(layerExtent, frameState.extent);
|
||||
clipped = render && !containsExtent(layerExtent, frameState.extent);
|
||||
if (clipped) {
|
||||
this.clipUnrotated(this.compositionContext_, frameState, layerExtent);
|
||||
}
|
||||
}
|
||||
if (render) {
|
||||
this.renderWorlds(replayGroup, frameState);
|
||||
}
|
||||
if (clipped) {
|
||||
this.compositionContext_.restore();
|
||||
}
|
||||
this.releaseCompositionContext_();
|
||||
this.postRender(context, frameState);
|
||||
if (this.renderedRotation_ !== viewState.rotation) {
|
||||
this.renderedRotation_ = viewState.rotation;
|
||||
this.hitDetectionImageData_ = null;
|
||||
}
|
||||
return this.container;
|
||||
};
|
||||
/**
|
||||
* Asynchronous layer level hit detection.
|
||||
* @param {import("../../pixel.js").Pixel} pixel Pixel.
|
||||
* @return {Promise<Array<import("../../Feature").default>>} Promise that resolves with an array of features.
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.getFeatures = function (pixel) {
|
||||
return new Promise(
|
||||
/**
|
||||
* @param {function(Array<import("../../Feature").default|import("../../render/Feature").default>): void} resolve Resolver function.
|
||||
* @this {CanvasVectorLayerRenderer}
|
||||
*/
|
||||
function (resolve) {
|
||||
if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) {
|
||||
var size = [this.context.canvas.width, this.context.canvas.height];
|
||||
apply(this.pixelTransform, size);
|
||||
var center = this.renderedCenter_;
|
||||
var resolution = this.renderedResolution_;
|
||||
var rotation = this.renderedRotation_;
|
||||
var projection = this.renderedProjection_;
|
||||
var extent = this.wrappedRenderedExtent_;
|
||||
var layer = this.getLayer();
|
||||
var transforms = [];
|
||||
var width = size[0] * HIT_DETECT_RESOLUTION;
|
||||
var height = size[1] * HIT_DETECT_RESOLUTION;
|
||||
transforms.push(this.getRenderTransform(center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, 0).slice());
|
||||
var source = layer.getSource();
|
||||
var projectionExtent = projection.getExtent();
|
||||
if (source.getWrapX() &&
|
||||
projection.canWrapX() &&
|
||||
!containsExtent(projectionExtent, extent)) {
|
||||
var startX = extent[0];
|
||||
var worldWidth = getWidth(projectionExtent);
|
||||
var world = 0;
|
||||
var offsetX = void 0;
|
||||
while (startX < projectionExtent[0]) {
|
||||
--world;
|
||||
offsetX = worldWidth * world;
|
||||
transforms.push(this.getRenderTransform(center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, offsetX).slice());
|
||||
startX += worldWidth;
|
||||
}
|
||||
world = 0;
|
||||
startX = extent[2];
|
||||
while (startX > projectionExtent[2]) {
|
||||
++world;
|
||||
offsetX = worldWidth * world;
|
||||
transforms.push(this.getRenderTransform(center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, offsetX).slice());
|
||||
startX -= worldWidth;
|
||||
}
|
||||
}
|
||||
this.hitDetectionImageData_ = createHitDetectionImageData(size, transforms, this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation);
|
||||
}
|
||||
resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));
|
||||
}.bind(this));
|
||||
};
|
||||
/**
|
||||
* @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.
|
||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||
* @param {number} hitTolerance Hit tolerance in pixels.
|
||||
* @param {import("../vector.js").FeatureCallback<T>} callback Feature callback.
|
||||
* @param {Array<import("../Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.
|
||||
* @return {T|undefined} Callback result.
|
||||
* @template T
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {
|
||||
var _this = this;
|
||||
if (!this.replayGroup_) {
|
||||
return undefined;
|
||||
}
|
||||
var resolution = frameState.viewState.resolution;
|
||||
var rotation = frameState.viewState.rotation;
|
||||
var layer = this.getLayer();
|
||||
/** @type {!Object<string, import("../Map.js").HitMatch<T>|true>} */
|
||||
var features = {};
|
||||
/**
|
||||
* @param {import("../../Feature.js").FeatureLike} feature Feature.
|
||||
* @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.
|
||||
* @param {number} distanceSq The squared distance to the click position
|
||||
* @return {T|undefined} Callback result.
|
||||
*/
|
||||
var featureCallback = function (feature, geometry, distanceSq) {
|
||||
var key = getUid(feature);
|
||||
var match = features[key];
|
||||
if (!match) {
|
||||
if (distanceSq === 0) {
|
||||
features[key] = true;
|
||||
return callback(feature, layer, geometry);
|
||||
}
|
||||
matches.push((features[key] = {
|
||||
feature: feature,
|
||||
layer: layer,
|
||||
geometry: geometry,
|
||||
distanceSq: distanceSq,
|
||||
callback: callback,
|
||||
}));
|
||||
}
|
||||
else if (match !== true && distanceSq < match.distanceSq) {
|
||||
if (distanceSq === 0) {
|
||||
features[key] = true;
|
||||
matches.splice(matches.lastIndexOf(match), 1);
|
||||
return callback(feature, layer, geometry);
|
||||
}
|
||||
match.geometry = geometry;
|
||||
match.distanceSq = distanceSq;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
var result;
|
||||
var executorGroups = [this.replayGroup_];
|
||||
if (this.declutterExecutorGroup) {
|
||||
executorGroups.push(this.declutterExecutorGroup);
|
||||
}
|
||||
executorGroups.some(function (executorGroup) {
|
||||
return (result = executorGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, featureCallback, executorGroup === _this.declutterExecutorGroup &&
|
||||
frameState.declutterTree
|
||||
? frameState.declutterTree.all().map(function (item) { return item.value; })
|
||||
: null));
|
||||
});
|
||||
return result;
|
||||
};
|
||||
/**
|
||||
* Perform action necessary to get the layer rendered after new fonts have loaded
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.handleFontsChanged = function () {
|
||||
var layer = this.getLayer();
|
||||
if (layer.getVisible() && this.replayGroup_) {
|
||||
layer.changed();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Handle changes in image style state.
|
||||
* @param {import("../../events/Event.js").default} event Image style change event.
|
||||
* @private
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.handleStyleImageChange_ = function (event) {
|
||||
this.renderIfReadyAndVisible();
|
||||
};
|
||||
/**
|
||||
* Determine whether render should be called.
|
||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||
* @return {boolean} Layer is ready to be rendered.
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.prepareFrame = function (frameState) {
|
||||
var vectorLayer = this.getLayer();
|
||||
var vectorSource = vectorLayer.getSource();
|
||||
if (!vectorSource) {
|
||||
return false;
|
||||
}
|
||||
var animating = frameState.viewHints[ViewHint.ANIMATING];
|
||||
var interacting = frameState.viewHints[ViewHint.INTERACTING];
|
||||
var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
|
||||
var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
|
||||
if ((this.ready && !updateWhileAnimating && animating) ||
|
||||
(!updateWhileInteracting && interacting)) {
|
||||
this.animatingOrInteracting_ = true;
|
||||
return true;
|
||||
}
|
||||
this.animatingOrInteracting_ = false;
|
||||
var frameStateExtent = frameState.extent;
|
||||
var viewState = frameState.viewState;
|
||||
var projection = viewState.projection;
|
||||
var resolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var vectorLayerRevision = vectorLayer.getRevision();
|
||||
var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
|
||||
var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
|
||||
if (vectorLayerRenderOrder === undefined) {
|
||||
vectorLayerRenderOrder = defaultRenderOrder;
|
||||
}
|
||||
var center = viewState.center.slice();
|
||||
var extent = buffer(frameStateExtent, vectorLayerRenderBuffer * resolution);
|
||||
var renderedExtent = extent.slice();
|
||||
var loadExtents = [extent.slice()];
|
||||
var projectionExtent = projection.getExtent();
|
||||
if (vectorSource.getWrapX() &&
|
||||
projection.canWrapX() &&
|
||||
!containsExtent(projectionExtent, frameState.extent)) {
|
||||
// For the replay group, we need an extent that intersects the real world
|
||||
// (-180° to +180°). To support geometries in a coordinate range from -540°
|
||||
// to +540°, we add at least 1 world width on each side of the projection
|
||||
// extent. If the viewport is wider than the world, we need to add half of
|
||||
// the viewport width to make sure we cover the whole viewport.
|
||||
var worldWidth = getWidth(projectionExtent);
|
||||
var gutter = Math.max(getWidth(extent) / 2, worldWidth);
|
||||
extent[0] = projectionExtent[0] - gutter;
|
||||
extent[2] = projectionExtent[2] + gutter;
|
||||
wrapCoordinateX(center, projection);
|
||||
var loadExtent = wrapExtentX(loadExtents[0], projection);
|
||||
// If the extent crosses the date line, we load data for both edges of the worlds
|
||||
if (loadExtent[0] < projectionExtent[0] &&
|
||||
loadExtent[2] < projectionExtent[2]) {
|
||||
loadExtents.push([
|
||||
loadExtent[0] + worldWidth,
|
||||
loadExtent[1],
|
||||
loadExtent[2] + worldWidth,
|
||||
loadExtent[3],
|
||||
]);
|
||||
}
|
||||
else if (loadExtent[0] > projectionExtent[0] &&
|
||||
loadExtent[2] > projectionExtent[2]) {
|
||||
loadExtents.push([
|
||||
loadExtent[0] - worldWidth,
|
||||
loadExtent[1],
|
||||
loadExtent[2] - worldWidth,
|
||||
loadExtent[3],
|
||||
]);
|
||||
}
|
||||
}
|
||||
if (this.ready &&
|
||||
this.renderedResolution_ == resolution &&
|
||||
this.renderedRevision_ == vectorLayerRevision &&
|
||||
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
|
||||
containsExtent(this.wrappedRenderedExtent_, extent)) {
|
||||
if (!equals(this.renderedExtent_, renderedExtent)) {
|
||||
this.hitDetectionImageData_ = null;
|
||||
this.renderedExtent_ = renderedExtent;
|
||||
}
|
||||
this.renderedCenter_ = center;
|
||||
this.replayGroupChanged = false;
|
||||
return true;
|
||||
}
|
||||
this.replayGroup_ = null;
|
||||
var replayGroup = new CanvasBuilderGroup(getRenderTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);
|
||||
var declutterBuilderGroup;
|
||||
if (this.getLayer().getDeclutter()) {
|
||||
declutterBuilderGroup = new CanvasBuilderGroup(getRenderTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);
|
||||
}
|
||||
var userProjection = getUserProjection();
|
||||
var userTransform;
|
||||
if (userProjection) {
|
||||
for (var i = 0, ii = loadExtents.length; i < ii; ++i) {
|
||||
var extent_1 = loadExtents[i];
|
||||
var userExtent_1 = toUserExtent(extent_1, projection);
|
||||
vectorSource.loadFeatures(userExtent_1, toUserResolution(resolution, projection), userProjection);
|
||||
}
|
||||
userTransform = getTransformFromProjections(userProjection, projection);
|
||||
}
|
||||
else {
|
||||
for (var i = 0, ii = loadExtents.length; i < ii; ++i) {
|
||||
vectorSource.loadFeatures(loadExtents[i], resolution, projection);
|
||||
}
|
||||
}
|
||||
var squaredTolerance = getSquaredRenderTolerance(resolution, pixelRatio);
|
||||
var ready = true;
|
||||
var render =
|
||||
/**
|
||||
* @param {import("../../Feature.js").default} feature Feature.
|
||||
* @this {CanvasVectorLayerRenderer}
|
||||
*/
|
||||
function (feature) {
|
||||
var styles;
|
||||
var styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction();
|
||||
if (styleFunction) {
|
||||
styles = styleFunction(feature, resolution);
|
||||
}
|
||||
if (styles) {
|
||||
var dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup, userTransform, declutterBuilderGroup);
|
||||
ready = ready && !dirty;
|
||||
}
|
||||
}.bind(this);
|
||||
var userExtent = toUserExtent(extent, projection);
|
||||
/** @type {Array<import("../../Feature.js").default>} */
|
||||
var features = vectorSource.getFeaturesInExtent(userExtent);
|
||||
if (vectorLayerRenderOrder) {
|
||||
features.sort(vectorLayerRenderOrder);
|
||||
}
|
||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||
render(features[i]);
|
||||
}
|
||||
this.renderedFeatures_ = features;
|
||||
this.ready = ready;
|
||||
var replayGroupInstructions = replayGroup.finish();
|
||||
var executorGroup = new ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), replayGroupInstructions, vectorLayer.getRenderBuffer());
|
||||
if (declutterBuilderGroup) {
|
||||
this.declutterExecutorGroup = new ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), declutterBuilderGroup.finish(), vectorLayer.getRenderBuffer());
|
||||
}
|
||||
this.renderedResolution_ = resolution;
|
||||
this.renderedRevision_ = vectorLayerRevision;
|
||||
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
||||
this.renderedExtent_ = renderedExtent;
|
||||
this.wrappedRenderedExtent_ = extent;
|
||||
this.renderedCenter_ = center;
|
||||
this.renderedProjection_ = projection;
|
||||
this.replayGroup_ = executorGroup;
|
||||
this.hitDetectionImageData_ = null;
|
||||
this.replayGroupChanged = true;
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* @param {import("../../Feature.js").default} feature Feature.
|
||||
* @param {number} squaredTolerance Squared render tolerance.
|
||||
* @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.
|
||||
* @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Builder group.
|
||||
* @param {import("../../proj.js").TransformFunction} [opt_transform] Transform from user to view projection.
|
||||
* @param {import("../../render/canvas/BuilderGroup.js").default} [opt_declutterBuilderGroup] Builder for decluttering.
|
||||
* @return {boolean} `true` if an image is loading.
|
||||
*/
|
||||
CanvasVectorLayerRenderer.prototype.renderFeature = function (feature, squaredTolerance, styles, builderGroup, opt_transform, opt_declutterBuilderGroup) {
|
||||
if (!styles) {
|
||||
return false;
|
||||
}
|
||||
var loading = false;
|
||||
if (Array.isArray(styles)) {
|
||||
for (var i = 0, ii = styles.length; i < ii; ++i) {
|
||||
loading =
|
||||
renderFeature(builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup) || loading;
|
||||
}
|
||||
}
|
||||
else {
|
||||
loading = renderFeature(builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup);
|
||||
}
|
||||
return loading;
|
||||
};
|
||||
return CanvasVectorLayerRenderer;
|
||||
}(CanvasLayerRenderer));
|
||||
export default CanvasVectorLayerRenderer;
|
||||
//# sourceMappingURL=VectorLayer.js.map
|
||||
Reference in New Issue
Block a user