Merge pull request #1483 from elemoine/vector-api-anchor-units
[vector-api] Support different anchor units in ol.style.Icon
This commit is contained in:
@@ -18,9 +18,12 @@ var raster = new ol.layer.Tile({
|
||||
});
|
||||
|
||||
var styleArray = [new ol.style.Style({
|
||||
image: new ol.style.Icon({
|
||||
image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
|
||||
anchor: [0.5, 46],
|
||||
anchorXUnits: 'fraction',
|
||||
anchorYUnits: 'pixels',
|
||||
src: 'data/icon.png'
|
||||
})
|
||||
}))
|
||||
})];
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
|
||||
@@ -797,7 +797,16 @@
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.style.IconOptions
|
||||
* @property {ol.Pixel|undefined} anchor Anchor.
|
||||
* @property {Array.<number>|undefined} anchor Anchor. Default value is [0.5, 0.5]
|
||||
* (icon center).
|
||||
* @property {ol.style.IconAnchorUnits|undefined} anchorXUnits Units in which the anchor x value is specified.
|
||||
* A value of `'fraction'` indicates the x value is a fraction of the icon.
|
||||
* A value of `'pixels'` indicates the x value in pixels. Default is
|
||||
* `'fraction'`.
|
||||
* @property {ol.style.IconAnchorUnits|undefined} anchorYUnits Units in which the anchor y value is specified.
|
||||
* A value of `'fraction'` indicates the y value is a fraction of the icon.
|
||||
* A value of `'pixels'` indicates the y value in pixels. Default is
|
||||
* `'fraction'`.
|
||||
* @property {null|string|undefined} crossOrigin crossOrigin setting for image.
|
||||
* @property {number|undefined} scale Scale.
|
||||
* @property {number|undefined} rotation Rotation.
|
||||
|
||||
@@ -30,6 +30,7 @@ goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Icon');
|
||||
goog.require('ol.style.IconAnchorUnits');
|
||||
goog.require('ol.style.Image');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
@@ -43,8 +44,8 @@ ol.KML_RESPECT_VISIBILITY = false;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{x: number, xunits: (string|null),
|
||||
* y: number, yunits: (string|null)}}
|
||||
* @typedef {{x: number, xunits: (ol.style.IconAnchorUnits|undefined),
|
||||
* y: number, yunits: (ol.style.IconAnchorUnits|undefined)}}
|
||||
*/
|
||||
ol.format.KMLVec2_;
|
||||
|
||||
@@ -160,6 +161,22 @@ ol.format.KML.DEFAULT_FILL_STYLE_ = new ol.style.Fill({
|
||||
ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_ = [2, 20]; // FIXME maybe [8, 32] ?
|
||||
|
||||
|
||||
/**
|
||||
* @const {ol.style.IconAnchorUnits}
|
||||
* @private
|
||||
*/
|
||||
ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_ =
|
||||
ol.style.IconAnchorUnits.PIXELS;
|
||||
|
||||
|
||||
/**
|
||||
* @const {ol.style.IconAnchorUnits}
|
||||
* @private
|
||||
*/
|
||||
ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS_ =
|
||||
ol.style.IconAnchorUnits.PIXELS;
|
||||
|
||||
|
||||
/**
|
||||
* @const {ol.Size}
|
||||
* @private
|
||||
@@ -181,6 +198,8 @@ ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_ =
|
||||
*/
|
||||
ol.format.KML.DEFAULT_IMAGE_STYLE_ = new ol.style.Icon({
|
||||
anchor: ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_,
|
||||
anchorXUnits: ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_,
|
||||
anchorYUnits: ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS_,
|
||||
crossOrigin: 'anonymous',
|
||||
rotation: 0,
|
||||
scale: 1,
|
||||
@@ -219,6 +238,16 @@ ol.format.KML.DEFAULT_STYLE_ = new ol.style.Style({
|
||||
ol.format.KML.DEFAULT_STYLE_ARRAY_ = [ol.format.KML.DEFAULT_STYLE_];
|
||||
|
||||
|
||||
/**
|
||||
* @const {Object.<string, ol.style.IconAnchorUnits>}
|
||||
* @private
|
||||
*/
|
||||
ol.format.KML.ICON_ANCHOR_UNITS_MAP_ = {
|
||||
'fraction': ol.style.IconAnchorUnits.FRACTION,
|
||||
'pixels': ol.style.IconAnchorUnits.PIXELS
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} resolution Resolution.
|
||||
* @private
|
||||
@@ -394,11 +423,15 @@ ol.format.KML.readURI_ = function(node) {
|
||||
* @return {ol.format.KMLVec2_} Vec2.
|
||||
*/
|
||||
ol.format.KML.readVec2_ = function(node) {
|
||||
var xunits = node.getAttribute('xunits');
|
||||
var yunits = node.getAttribute('yunits');
|
||||
return {
|
||||
x: parseFloat(node.getAttribute('x')),
|
||||
xunits: node.getAttribute('xunits'),
|
||||
xunits: goog.isNull(xunits) ?
|
||||
undefined : ol.format.KML.ICON_ANCHOR_UNITS_MAP_[xunits],
|
||||
y: parseFloat(node.getAttribute('y')),
|
||||
yunits: node.getAttribute('yunits')
|
||||
yunits: goog.isNull(yunits) ?
|
||||
undefined : ol.format.KML.ICON_ANCHOR_UNITS_MAP_[yunits]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -452,15 +485,21 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) {
|
||||
} else {
|
||||
src = ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_;
|
||||
}
|
||||
var anchor;
|
||||
var anchor, anchorXUnits, anchorYUnits;
|
||||
var hotSpot = /** @type {ol.format.KMLVec2_|undefined} */
|
||||
(goog.object.get(object, 'hotSpot'));
|
||||
if (goog.isDef(hotSpot)) {
|
||||
goog.asserts.assert(hotSpot.xunits == 'pixels');
|
||||
goog.asserts.assert(hotSpot.yunits == 'pixels');
|
||||
anchor = [hotSpot.x, hotSpot.y];
|
||||
anchorXUnits = hotSpot.xunits;
|
||||
anchorYUnits = hotSpot.yunits;
|
||||
} else if (src === ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) {
|
||||
anchor = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_;
|
||||
anchorXUnits = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_;
|
||||
anchorYUnits = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS_;
|
||||
} else if (/^http:\/\/maps\.(?:google|gstatic)\.com\//.test(src)) {
|
||||
anchor = [0.5, 1];
|
||||
anchorXUnits = ol.style.IconAnchorUnits.FRACTION;
|
||||
anchorYUnits = ol.style.IconAnchorUnits.FRACTION;
|
||||
} else {
|
||||
anchor = null;
|
||||
}
|
||||
@@ -482,6 +521,8 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) {
|
||||
}
|
||||
var imageStyle = new ol.style.Icon({
|
||||
anchor: anchor,
|
||||
anchorXUnits: anchorXUnits,
|
||||
anchorYUnits: anchorYUnits,
|
||||
crossOrigin: 'anonymous', // FIXME should this be configurable?
|
||||
rotation: rotation,
|
||||
scale: scale,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// FIXME decide default value for snapToPixel
|
||||
|
||||
goog.provide('ol.style.Icon');
|
||||
goog.provide('ol.style.IconAnchorUnits');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
@@ -12,6 +13,15 @@ goog.require('ol.style.Image');
|
||||
goog.require('ol.style.ImageState');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.style.IconAnchorUnits = {
|
||||
FRACTION: 'fraction',
|
||||
PIXELS: 'pixels'
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -67,16 +77,23 @@ ol.style.Icon = function(opt_options) {
|
||||
var size = goog.isDef(options.size) ? options.size : null;
|
||||
|
||||
/**
|
||||
* @type {ol.Pixel}
|
||||
* @private
|
||||
* @type {ol.style.IconAnchorUnits}
|
||||
*/
|
||||
var anchor;
|
||||
if (goog.isDef(options.anchor)) {
|
||||
anchor = options.anchor;
|
||||
} else if (!goog.isNull(size)) {
|
||||
anchor = [size[0] / 2, size[1] / 2];
|
||||
} else {
|
||||
anchor = null;
|
||||
}
|
||||
this.anchorXUnits_ = goog.isDef(options.anchorXUnits) ?
|
||||
options.anchorXUnits : ol.style.IconAnchorUnits.FRACTION;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.style.IconAnchorUnits}
|
||||
*/
|
||||
this.anchorYUnits_ = goog.isDef(options.anchorYUnits) ?
|
||||
options.anchorYUnits : ol.style.IconAnchorUnits.FRACTION;
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
var anchor = goog.isDef(options.anchor) ? options.anchor : [0.5, 0.5];
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
@@ -139,8 +156,11 @@ ol.style.Icon.prototype.handleImageLoad_ = function() {
|
||||
if (goog.isNull(this.size)) {
|
||||
this.size = [this.image_.width, this.image_.height];
|
||||
}
|
||||
if (goog.isNull(this.anchor)) {
|
||||
this.anchor = [this.size[0] / 2, this.size[1] / 2];
|
||||
if (this.anchorXUnits_ == ol.style.IconAnchorUnits.FRACTION) {
|
||||
this.anchor[0] = this.size[0] * this.anchor[0];
|
||||
}
|
||||
if (this.anchorYUnits_ == ol.style.IconAnchorUnits.FRACTION) {
|
||||
this.anchor[1] = this.size[1] * this.anchor[1];
|
||||
}
|
||||
this.unlistenImage_();
|
||||
this.determineTainting_();
|
||||
|
||||
@@ -19,7 +19,7 @@ ol.style.ImageState = {
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{anchor: ol.Pixel,
|
||||
* @typedef {{anchor: Array.<number>,
|
||||
* imageState: ol.style.ImageState,
|
||||
* rotation: number,
|
||||
* scale: number,
|
||||
@@ -42,7 +42,7 @@ ol.style.Image = function(options) {
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.Pixel}
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.anchor = options.anchor;
|
||||
|
||||
@@ -95,7 +95,7 @@ ol.style.Image.prototype.dispatchChangeEvent = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Pixel} Anchor.
|
||||
* @return {Array.<number>} Anchor.
|
||||
*/
|
||||
ol.style.Image.prototype.getAnchor = function() {
|
||||
return this.anchor;
|
||||
|
||||
Reference in New Issue
Block a user