Add ol.source.ImageVector
This commit is contained in:
@@ -638,6 +638,20 @@
|
||||
* @property {ol.source.State|undefined} state Source state.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.source.ImageVectorOptions
|
||||
* @property {Array.<ol.Attribution>|undefined} attributions Attributions.
|
||||
* @property {ol.Extent|undefined} extent Extent.
|
||||
* @property {string|undefined} logo Logo.
|
||||
* @property {ol.proj.ProjectionLike} projection Projection.
|
||||
* @property {number|undefined} ratio Ratio. 1 means canvases are the size
|
||||
* of the map viewport, 2 means twice the size of the map viewport, and so
|
||||
* on.
|
||||
* @property {Array.<number>|undefined} resolutions Resolutions. If specified,
|
||||
* new canvases will be created for these resolutions only.
|
||||
* @property {ol.source.Vector} source Vector source.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.source.ImageWMSOptions
|
||||
* @property {Array.<ol.Attribution>|undefined} attributions Attributions.
|
||||
|
||||
1
src/ol/source/imagevectorsource.exports
Normal file
1
src/ol/source/imagevectorsource.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.source.ImageVector
|
||||
213
src/ol/source/imagevectorsource.js
Normal file
213
src/ol/source/imagevectorsource.js
Normal file
@@ -0,0 +1,213 @@
|
||||
goog.provide('ol.source.ImageVector');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.render.canvas.ReplayGroup');
|
||||
goog.require('ol.renderer.vector');
|
||||
goog.require('ol.source.ImageCanvas');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.ImageState');
|
||||
goog.require('ol.vec.Mat4');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.ImageCanvas}
|
||||
* @param {olx.source.ImageVectorOptions} options Options.
|
||||
*/
|
||||
ol.source.ImageVector = function(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.source.Vector}
|
||||
*/
|
||||
this.source_ = options.source;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.feature.StyleFunction}
|
||||
*/
|
||||
this.styleFunction_ = options.styleFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.transform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvasElement_ = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.canvasContext_ = /** @type {CanvasRenderingContext2D} */
|
||||
(this.canvasElement_.getContext('2d'));
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Size}
|
||||
*/
|
||||
this.canvasSize_ = [0, 0];
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
canvasFunction: goog.bind(this.canvasFunctionInternal_, this),
|
||||
extent: options.extent,
|
||||
logo: options.logo,
|
||||
projection: options.projection,
|
||||
ratio: options.ratio,
|
||||
resolutions: options.resolutions,
|
||||
state: this.source_.getState()
|
||||
});
|
||||
|
||||
goog.events.listen(this.source_, goog.events.EventType.CHANGE,
|
||||
this.handleSourceChange_, undefined, this);
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.ImageVector, ol.source.ImageCanvas);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.Size} size Size.
|
||||
* @param {ol.proj.Projection} projection Projection;
|
||||
* @return {HTMLCanvasElement} Canvas element.
|
||||
* @private
|
||||
*/
|
||||
ol.source.ImageVector.prototype.canvasFunctionInternal_ =
|
||||
function(extent, resolution, pixelRatio, size, projection) {
|
||||
|
||||
var tolerance = resolution / (2 * pixelRatio);
|
||||
var replayGroup = new ol.render.canvas.ReplayGroup(
|
||||
pixelRatio, tolerance);
|
||||
|
||||
var loading = false;
|
||||
this.source_.forEachFeatureInExtent(extent,
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
*/
|
||||
function(feature) {
|
||||
loading = loading ||
|
||||
this.renderFeature_(feature, resolution, pixelRatio, replayGroup);
|
||||
}, this);
|
||||
replayGroup.finish();
|
||||
|
||||
if (loading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.canvasSize_[0] != size[0] || this.canvasSize_[1] != size[1]) {
|
||||
this.canvasElement_.width = size[0];
|
||||
this.canvasElement_.height = size[1];
|
||||
this.canvasSize_[0] = size[0];
|
||||
this.canvasSize_[1] = size[1];
|
||||
} else {
|
||||
this.canvasContext_.clearRect(0, 0, size[0], size[1]);
|
||||
}
|
||||
|
||||
var transform = this.getTransform_(ol.extent.getCenter(extent),
|
||||
resolution, pixelRatio, size);
|
||||
replayGroup.replay(this.canvasContext_, extent, transform,
|
||||
goog.functions.TRUE);
|
||||
|
||||
return this.canvasElement_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} center Center.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.Size} size Size.
|
||||
* @return {!goog.vec.Mat4.Number} Transform.
|
||||
* @private
|
||||
*/
|
||||
ol.source.ImageVector.prototype.getTransform_ =
|
||||
function(center, resolution, pixelRatio, size) {
|
||||
return ol.vec.Mat4.makeTransform2D(this.transform_,
|
||||
size[0] / 2, size[1] / 2,
|
||||
pixelRatio / resolution, -pixelRatio / resolution,
|
||||
0,
|
||||
-center[0], -center[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle changes in image style state.
|
||||
* @param {goog.events.Event} event Image style change event.
|
||||
* @private
|
||||
*/
|
||||
ol.source.ImageVector.prototype.handleImageStyleChange_ =
|
||||
function(event) {
|
||||
var imageStyle = /** @type {ol.style.Image} */ (event.target);
|
||||
if (imageStyle.getImageState() == ol.style.ImageState.LOADED) {
|
||||
this.dispatchChangeEvent();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.source.ImageVector.prototype.handleSourceChange_ = function() {
|
||||
// setState will trigger a CHANGE event, so we always rely
|
||||
// change events by calling setState.
|
||||
this.setState(this.source_.getState());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
|
||||
* @return {boolean} `true` if an image is loading.
|
||||
* @private
|
||||
*/
|
||||
ol.source.ImageVector.prototype.renderFeature_ =
|
||||
function(feature, resolution, pixelRatio, replayGroup) {
|
||||
var loading = false;
|
||||
var styles = this.styleFunction_(feature, resolution);
|
||||
if (!goog.isDefAndNotNull(styles)) {
|
||||
return false;
|
||||
}
|
||||
// simplify to a tolerance of half a device pixel
|
||||
var squaredTolerance =
|
||||
resolution * resolution / (4 * pixelRatio * pixelRatio);
|
||||
var i, ii, style, imageStyle, imageState;
|
||||
for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||
style = styles[i];
|
||||
imageStyle = style.getImage();
|
||||
if (!goog.isNull(imageStyle)) {
|
||||
if (imageStyle.getImageState() == ol.style.ImageState.IDLE) {
|
||||
goog.events.listenOnce(imageStyle, goog.events.EventType.CHANGE,
|
||||
this.handleImageStyleChange_, false, this);
|
||||
imageStyle.load();
|
||||
} else if (imageStyle.getImageState() == ol.style.ImageState.LOADED) {
|
||||
ol.renderer.vector.renderFeature(
|
||||
replayGroup, feature, style, squaredTolerance, feature);
|
||||
}
|
||||
goog.asserts.assert(
|
||||
imageStyle.getImageState() != ol.style.ImageState.IDLE);
|
||||
loading = imageStyle.getImageState() == ol.style.ImageState.LOADING;
|
||||
} else {
|
||||
ol.renderer.vector.renderFeature(
|
||||
replayGroup, feature, style, squaredTolerance, feature);
|
||||
}
|
||||
}
|
||||
return loading;
|
||||
};
|
||||
Reference in New Issue
Block a user