Integrate atlas manager into RegularShape
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
goog.provide('ol.style.RegularShape');
|
goog.provide('ol.style.RegularShape');
|
||||||
|
|
||||||
|
goog.require('goog.asserts');
|
||||||
goog.require('goog.dom');
|
goog.require('goog.dom');
|
||||||
goog.require('goog.dom.TagName');
|
goog.require('goog.dom.TagName');
|
||||||
goog.require('ol.color');
|
goog.require('ol.color');
|
||||||
@@ -35,8 +36,7 @@ ol.style.RegularShape = function(opt_options) {
|
|||||||
* @private
|
* @private
|
||||||
* @type {HTMLCanvasElement}
|
* @type {HTMLCanvasElement}
|
||||||
*/
|
*/
|
||||||
this.canvas_ = /** @type {HTMLCanvasElement} */
|
this.canvas_ = null;
|
||||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -87,19 +87,25 @@ ol.style.RegularShape = function(opt_options) {
|
|||||||
*/
|
*/
|
||||||
this.stroke_ = goog.isDef(options.stroke) ? options.stroke : null;
|
this.stroke_ = goog.isDef(options.stroke) ? options.stroke : null;
|
||||||
|
|
||||||
var size = this.render_();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Array.<number>}
|
* @type {Array.<number>}
|
||||||
*/
|
*/
|
||||||
this.anchor_ = [size / 2, size / 2];
|
this.anchor_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {ol.Size}
|
* @type {ol.Size}
|
||||||
*/
|
*/
|
||||||
this.size_ = [size, size];
|
this.size_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.Size}
|
||||||
|
*/
|
||||||
|
this.imageSize_ = null;
|
||||||
|
|
||||||
|
this.render_(options.atlasManager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
@@ -158,7 +164,7 @@ ol.style.RegularShape.prototype.getImage = function(pixelRatio) {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.style.RegularShape.prototype.getImageSize = function() {
|
ol.style.RegularShape.prototype.getImageSize = function() {
|
||||||
return this.size_;
|
return this.imageSize_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -225,16 +231,20 @@ ol.style.RegularShape.prototype.unlistenImageChange = goog.nullFunction;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @typedef {{strokeStyle: (string|undefined), strokeWidth: number,
|
||||||
* @return {number} Size.
|
* size: number}}
|
||||||
*/
|
*/
|
||||||
ol.style.RegularShape.prototype.render_ = function() {
|
ol.style.RegularShape.RenderOptions;
|
||||||
var canvas = this.canvas_;
|
|
||||||
var strokeStyle, strokeWidth;
|
|
||||||
|
|
||||||
if (goog.isNull(this.stroke_)) {
|
|
||||||
strokeWidth = 0;
|
/**
|
||||||
} else {
|
* @private
|
||||||
|
* @param {ol.style.AtlasManager|undefined} atlasManager
|
||||||
|
*/
|
||||||
|
ol.style.RegularShape.prototype.render_ = function(atlasManager) {
|
||||||
|
var strokeStyle, strokeWidth = 0, imageSize;
|
||||||
|
|
||||||
|
if (!goog.isNull(this.stroke_)) {
|
||||||
strokeStyle = ol.color.asString(this.stroke_.getColor());
|
strokeStyle = ol.color.asString(this.stroke_.getColor());
|
||||||
strokeWidth = this.stroke_.getWidth();
|
strokeWidth = this.stroke_.getWidth();
|
||||||
if (!goog.isDef(strokeWidth)) {
|
if (!goog.isDef(strokeWidth)) {
|
||||||
@@ -244,17 +254,70 @@ ol.style.RegularShape.prototype.render_ = function() {
|
|||||||
|
|
||||||
var size = 2 * (this.radius_ + strokeWidth) + 1;
|
var size = 2 * (this.radius_ + strokeWidth) + 1;
|
||||||
|
|
||||||
// draw the regular shape on the canvas
|
/** @type {ol.style.RegularShape.RenderOptions} */
|
||||||
|
var renderOptions = {
|
||||||
|
strokeStyle: strokeStyle,
|
||||||
|
strokeWidth: strokeWidth,
|
||||||
|
size: size
|
||||||
|
};
|
||||||
|
|
||||||
canvas.height = size;
|
if (!goog.isDef(atlasManager)) {
|
||||||
canvas.width = size;
|
// no atlas manager is used, create a new canvas
|
||||||
|
this.canvas_ = /** @type {HTMLCanvasElement} */
|
||||||
|
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||||
|
|
||||||
|
this.canvas_.height = size;
|
||||||
|
this.canvas_.width = size;
|
||||||
|
|
||||||
// canvas.width and height are rounded to the closest integer
|
// canvas.width and height are rounded to the closest integer
|
||||||
size = canvas.width;
|
size = this.canvas_.width;
|
||||||
|
imageSize = size;
|
||||||
|
|
||||||
var context = /** @type {CanvasRenderingContext2D} */
|
var context = /** @type {CanvasRenderingContext2D} */
|
||||||
(canvas.getContext('2d'));
|
(this.canvas_.getContext('2d'));
|
||||||
|
this.draw_(renderOptions, context, 0, 0);
|
||||||
|
} else {
|
||||||
|
// an atlas manager is used, add the symbol to an atlas
|
||||||
|
size = Math.round(size);
|
||||||
|
|
||||||
|
var id = this.getChecksum();
|
||||||
|
var info = atlasManager.add(
|
||||||
|
id, size, size, goog.bind(this.draw_, this, renderOptions));
|
||||||
|
goog.asserts.assert(info !== null, 'shape size is too large');
|
||||||
|
|
||||||
|
this.canvas_ = info.image;
|
||||||
|
this.origin_ = [info.offsetX, info.offsetY];
|
||||||
|
imageSize = info.image.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.anchor_ = [size / 2, size / 2];
|
||||||
|
this.size_ = [size, size];
|
||||||
|
this.imageSize_ = [imageSize, imageSize];
|
||||||
|
|
||||||
|
// deal with the hit detection canvas
|
||||||
|
if (!goog.isNull(this.fill_)) {
|
||||||
|
this.hitDetectionCanvas_ = this.canvas_;
|
||||||
|
} else {
|
||||||
|
this.createHitDetectionCanvas_(renderOptions);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {ol.style.Circle.RenderOptions} renderOptions
|
||||||
|
* @param {CanvasRenderingContext2D} context
|
||||||
|
* @param {number} x The origin for the symbol (x).
|
||||||
|
* @param {number} y The origin for the symbol (y).
|
||||||
|
*/
|
||||||
|
ol.style.RegularShape.prototype.draw_ = function(renderOptions, context, x, y) {
|
||||||
var i, angle0, radiusC;
|
var i, angle0, radiusC;
|
||||||
|
// reset transform
|
||||||
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
|
||||||
|
// then move to (x, y)
|
||||||
|
context.translate(x, y);
|
||||||
|
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
if (this.radius2_ !== this.radius_) {
|
if (this.radius2_ !== this.radius_) {
|
||||||
this.points_ = 2 * this.points_;
|
this.points_ = 2 * this.points_;
|
||||||
@@ -262,8 +325,8 @@ ol.style.RegularShape.prototype.render_ = function() {
|
|||||||
for (i = 0; i <= this.points_; i++) {
|
for (i = 0; i <= this.points_; i++) {
|
||||||
angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_;
|
angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_;
|
||||||
radiusC = i % 2 === 0 ? this.radius_ : this.radius2_;
|
radiusC = i % 2 === 0 ? this.radius_ : this.radius2_;
|
||||||
context.lineTo(size / 2 + radiusC * Math.cos(angle0),
|
context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0),
|
||||||
size / 2 + radiusC * Math.sin(angle0));
|
renderOptions.size / 2 + radiusC * Math.sin(angle0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!goog.isNull(this.fill_)) {
|
if (!goog.isNull(this.fill_)) {
|
||||||
@@ -271,46 +334,48 @@ ol.style.RegularShape.prototype.render_ = function() {
|
|||||||
context.fill();
|
context.fill();
|
||||||
}
|
}
|
||||||
if (!goog.isNull(this.stroke_)) {
|
if (!goog.isNull(this.stroke_)) {
|
||||||
context.strokeStyle = strokeStyle;
|
context.strokeStyle = renderOptions.strokeStyle;
|
||||||
context.lineWidth = strokeWidth;
|
context.lineWidth = renderOptions.strokeWidth;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}
|
}
|
||||||
|
context.closePath();
|
||||||
|
};
|
||||||
|
|
||||||
// deal with the hit detection canvas
|
|
||||||
|
|
||||||
if (!goog.isNull(this.fill_)) {
|
/**
|
||||||
this.hitDetectionCanvas_ = canvas;
|
* @private
|
||||||
} else {
|
* @param {ol.style.RegularShape.RenderOptions} renderOptions
|
||||||
|
*/
|
||||||
|
ol.style.RegularShape.prototype.createHitDetectionCanvas_ =
|
||||||
|
function(renderOptions) {
|
||||||
this.hitDetectionCanvas_ = /** @type {HTMLCanvasElement} */
|
this.hitDetectionCanvas_ = /** @type {HTMLCanvasElement} */
|
||||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||||
canvas = this.hitDetectionCanvas_;
|
var canvas = this.hitDetectionCanvas_;
|
||||||
|
|
||||||
canvas.height = size;
|
canvas.height = renderOptions.size;
|
||||||
canvas.width = size;
|
canvas.width = renderOptions.size;
|
||||||
|
|
||||||
context = /** @type {CanvasRenderingContext2D} */
|
var context = /** @type {CanvasRenderingContext2D} */
|
||||||
(canvas.getContext('2d'));
|
(canvas.getContext('2d'));
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
if (this.radius2_ !== this.radius_) {
|
if (this.radius2_ !== this.radius_) {
|
||||||
this.points_ = 2 * this.points_;
|
this.points_ = 2 * this.points_;
|
||||||
}
|
}
|
||||||
|
var i, radiusC, angle0;
|
||||||
for (i = 0; i <= this.points_; i++) {
|
for (i = 0; i <= this.points_; i++) {
|
||||||
angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_;
|
angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_;
|
||||||
radiusC = i % 2 === 0 ? this.radius_ : this.radius2_;
|
radiusC = i % 2 === 0 ? this.radius_ : this.radius2_;
|
||||||
context.lineTo(size / 2 + radiusC * Math.cos(angle0),
|
context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0),
|
||||||
size / 2 + radiusC * Math.sin(angle0));
|
renderOptions.size / 2 + radiusC * Math.sin(angle0));
|
||||||
}
|
}
|
||||||
|
|
||||||
context.fillStyle = ol.render.canvas.defaultFillStyle;
|
context.fillStyle = ol.render.canvas.defaultFillStyle;
|
||||||
context.fill();
|
context.fill();
|
||||||
if (!goog.isNull(this.stroke_)) {
|
if (!goog.isNull(this.stroke_)) {
|
||||||
context.strokeStyle = strokeStyle;
|
context.strokeStyle = renderOptions.strokeStyle;
|
||||||
context.lineWidth = strokeWidth;
|
context.lineWidth = renderOptions.strokeWidth;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,33 @@ goog.provide('ol.test.style.RegularShape');
|
|||||||
|
|
||||||
describe('ol.style.RegularShape', function() {
|
describe('ol.style.RegularShape', function() {
|
||||||
|
|
||||||
|
describe('#constructor', function() {
|
||||||
|
|
||||||
|
it('creates a canvas if no atlas is used', function() {
|
||||||
|
var style = new ol.style.RegularShape({radius: 10});
|
||||||
|
expect(style.getImage()).to.be.an(HTMLCanvasElement);
|
||||||
|
expect(style.getSize()).to.eql([21, 21]);
|
||||||
|
expect(style.getImageSize()).to.eql([21, 21]);
|
||||||
|
expect(style.getOrigin()).to.eql([0, 0]);
|
||||||
|
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||||
|
expect(style.getImage()).to.not.be(style.getHitDetectionImage());
|
||||||
|
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds itself to an atlas manager', function() {
|
||||||
|
var atlasManager = new ol.style.AtlasManager({size: 512});
|
||||||
|
var style = new ol.style.RegularShape(
|
||||||
|
{radius: 10, atlasManager: atlasManager});
|
||||||
|
expect(style.getImage()).to.be.an(HTMLCanvasElement);
|
||||||
|
expect(style.getSize()).to.eql([21, 21]);
|
||||||
|
expect(style.getImageSize()).to.eql([512, 512]);
|
||||||
|
expect(style.getOrigin()).to.eql([1, 1]);
|
||||||
|
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||||
|
expect(style.getImage()).to.not.be(style.getHitDetectionImage());
|
||||||
|
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('#getChecksum', function() {
|
describe('#getChecksum', function() {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user