206 lines
4.9 KiB
JavaScript
206 lines
4.9 KiB
JavaScript
/**
|
|
* @license
|
|
*
|
|
* Copyright 2011 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview Map Label.
|
|
*
|
|
* @author Luke Mahe (lukem@google.com),
|
|
* Chris Broadfoot (cbro@google.com)
|
|
*/
|
|
|
|
/**
|
|
* Creates a new Map Label
|
|
* @constructor
|
|
* @extends google.maps.OverlayView
|
|
* @param {Object.<string, *>=} opt_options Optional properties to set.
|
|
*/
|
|
function MapLabel(opt_options) {
|
|
this.set('fontFamily', 'sans-serif');
|
|
this.set('fontSize', 12);
|
|
this.set('fontColor', '#000000');
|
|
this.set('strokeWeight', 0);
|
|
this.set('strokeColor', '#ffffff');
|
|
this.set('align', 'center');
|
|
this.set('zIndex', 1e3);
|
|
this.setValues(opt_options);
|
|
}
|
|
|
|
MapLabel.prototype = new google.maps.OverlayView;
|
|
|
|
window['MapLabel'] = MapLabel;
|
|
|
|
|
|
/** @inheritDoc */
|
|
MapLabel.prototype.changed = function(prop) {
|
|
switch (prop) {
|
|
case 'fontFamily':
|
|
case 'fontSize':
|
|
case 'fontColor':
|
|
case 'strokeWeight':
|
|
case 'strokeColor':
|
|
case 'align':
|
|
case 'text':
|
|
return this.drawCanvas_();
|
|
case 'maxZoom':
|
|
case 'minZoom':
|
|
case 'position':
|
|
return this.draw();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Draws the label to the canvas 2d context.
|
|
* @private
|
|
*/
|
|
MapLabel.prototype.drawCanvas_ = function() {
|
|
var canvas = this.canvas_;
|
|
if (!canvas) return;
|
|
|
|
var style = canvas.style;
|
|
style.zIndex = /** @type number */(this.get('zIndex'));
|
|
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
ctx.strokeStyle = this.get('strokeColor');
|
|
ctx.fillStyle = this.get('fontColor');
|
|
ctx.font = this.get('fontSize') + 'px ' + this.get('fontFamily');
|
|
|
|
var strokeWeight = Number(this.get('strokeWeight'));
|
|
|
|
var text = this.get('text');
|
|
if (text) {
|
|
if (strokeWeight) {
|
|
ctx.lineWidth = strokeWeight;
|
|
ctx.strokeText(text, strokeWeight, strokeWeight);
|
|
}
|
|
|
|
ctx.fillText(text, strokeWeight, strokeWeight);
|
|
|
|
var textMeasure = ctx.measureText(text);
|
|
var textWidth = textMeasure.width + strokeWeight;
|
|
style.marginLeft = this.getMarginLeft_(textWidth) + 'px';
|
|
// Bring actual text top in line with desired latitude.
|
|
// Cheaper than calculating height of text.
|
|
style.marginTop = '-0.4em';
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
MapLabel.prototype.onAdd = function() {
|
|
var canvas = this.canvas_ = document.createElement('canvas');
|
|
var style = canvas.style;
|
|
style.position = 'absolute';
|
|
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.lineJoin = 'round';
|
|
ctx.textBaseline = 'top';
|
|
|
|
this.drawCanvas_();
|
|
|
|
var panes = this.getPanes();
|
|
if (panes) {
|
|
panes.mapPane.appendChild(canvas);
|
|
}
|
|
};
|
|
MapLabel.prototype['onAdd'] = MapLabel.prototype.onAdd;
|
|
|
|
/**
|
|
* Gets the appropriate margin-left for the canvas.
|
|
* @private
|
|
* @param {number} textWidth the width of the text, in pixels.
|
|
* @return {number} the margin-left, in pixels.
|
|
*/
|
|
MapLabel.prototype.getMarginLeft_ = function(textWidth) {
|
|
switch (this.get('align')) {
|
|
case 'left':
|
|
return 0;
|
|
case 'right':
|
|
return -textWidth;
|
|
}
|
|
return textWidth / -2;
|
|
};
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
MapLabel.prototype.draw = function() {
|
|
var projection = this.getProjection();
|
|
|
|
if (!projection) {
|
|
// The map projection is not ready yet so do nothing
|
|
return;
|
|
}
|
|
|
|
if (!this.canvas_) {
|
|
// onAdd has not been called yet.
|
|
return;
|
|
}
|
|
|
|
var latLng = /** @type {google.maps.LatLng} */ (this.get('position'));
|
|
if (!latLng) {
|
|
return;
|
|
}
|
|
var pos = projection.fromLatLngToDivPixel(latLng);
|
|
|
|
var style = this.canvas_.style;
|
|
|
|
style['top'] = pos.y + 'px';
|
|
style['left'] = pos.x + 'px';
|
|
|
|
style['visibility'] = this.getVisible_();
|
|
};
|
|
MapLabel.prototype['draw'] = MapLabel.prototype.draw;
|
|
|
|
/**
|
|
* Get the visibility of the label.
|
|
* @private
|
|
* @return {string} blank string if visible, 'hidden' if invisible.
|
|
*/
|
|
MapLabel.prototype.getVisible_ = function() {
|
|
var minZoom = /** @type number */(this.get('minZoom'));
|
|
var maxZoom = /** @type number */(this.get('maxZoom'));
|
|
|
|
if (minZoom === undefined && maxZoom === undefined) {
|
|
return '';
|
|
}
|
|
|
|
var map = this.getMap();
|
|
if (!map) {
|
|
return '';
|
|
}
|
|
|
|
var mapZoom = map.getZoom();
|
|
if (mapZoom < minZoom || mapZoom > maxZoom) {
|
|
return 'hidden';
|
|
}
|
|
return '';
|
|
};
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
MapLabel.prototype.onRemove = function() {
|
|
var canvas = this.canvas_;
|
|
if (canvas && canvas.parentNode) {
|
|
canvas.parentNode.removeChild(canvas);
|
|
}
|
|
};
|
|
MapLabel.prototype['onRemove'] = MapLabel.prototype.onRemove;
|