mappe per georeferenziazione
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

232 righe
8.4 KiB

2 anni fa
L.LabelTextCollision = L.Canvas
.extend({
options : {
/**
* Collision detection
*/
collisionFlg : true
},
initialize : function(options) {
options = L.Util.setOptions(this, options);
},
_handleMouseHover : function(e, point) {
var id, layer;
for (id in this._drawnLayers) {
layer = this._drawnLayers[id];
if (layer.options.interactive
&& layer._containsPoint(point)) {
L.DomUtil.addClass(this._containerText,
'leaflet-interactive'); // change cursor
this._fireEvent([ layer ], e, 'mouseover');
this._hoveredLayer = layer;
}
}
if (this._hoveredLayer) {
this._fireEvent([ this._hoveredLayer ], e);
}
},
_handleMouseOut : function(e, point) {
var layer = this._hoveredLayer;
if (layer
&& (e.type === 'mouseout' || !layer
._containsPoint(point))) {
// if we're leaving the layer, fire mouseout
L.DomUtil.removeClass(this._containerText,
'leaflet-interactive');
this._fireEvent([ layer ], e, 'mouseout');
this._hoveredLayer = null;
}
},
_updateTransform : function(center, zoom) {
L.Canvas.prototype._updateTransform.call(this, center, zoom);
var scale = this._map.getZoomScale(zoom, this._zoom), position = L.DomUtil
.getPosition(this._container), viewHalf = this._map
.getSize().multiplyBy(0.5 + this.options.padding), currentCenterPoint = this._map
.project(this._center, zoom), destCenterPoint = this._map
.project(center, zoom), centerOffset = destCenterPoint
.subtract(currentCenterPoint),
topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(
viewHalf).subtract(centerOffset);
if (L.Browser.any3d) {
L.DomUtil.setTransform(this._containerText, topLeftOffset,
scale);
} else {
L.DomUtil.setPosition(this._containerText, topLeftOffset);
}
},
_initContainer : function(options) {
L.Canvas.prototype._initContainer.call(this);
this._containerText = document.createElement('canvas');
L.DomEvent.on(this._containerText, 'mousemove',
L.Util.throttle(this._onMouseMove, 32, this), this).on(
this._containerText,
'click dblclick mousedown mouseup contextmenu',
this._onClick, this).on(this._containerText,
'mouseout', this._handleMouseOut, this);
this._ctxLabel = this._containerText.getContext('2d');
L.DomUtil
.addClass(this._containerText, 'leaflet-zoom-animated');
this.getPane().appendChild(this._containerText);
},
_update : function() {
// textList
this._textList = [];
L.Renderer.prototype._update.call(this);
var b = this._bounds, container = this._containerText, size = b
.getSize(), m = L.Browser.retina ? 2 : 1;
L.DomUtil.setPosition(container, b.min);
// set canvas size (also clearing it); use double size on retina
container.width = m * size.x;
container.height = m * size.y;
container.style.width = size.x + 'px';
container.style.height = size.y + 'px';
// display text on the whole surface
container.style.zIndex = '4';
this._container.style.zIndex = '3';
if (L.Browser.retina) {
this._ctxLabel.scale(2, 2);
}
// translate so we use the same path coordinates after canvas
// element moves
this._ctxLabel.translate(-b.min.x, -b.min.y);
L.Canvas.prototype._update.call(this);
},
_updatePoly : function(layer, closed) {
L.Canvas.prototype._updatePoly.call(this, layer, closed);
this._text(this._ctxLabel, layer);
},
_updateCircle : function(layer) {
L.Canvas.prototype._updateCircle.call(this, layer);
this._text(this._ctxLabel, layer);
},
_text : function(ctx, layer) {
if (layer.options.text != undefined) {
ctx.globalAlpha = 1;
var p = layer._point;
var textPoint;
if (p == undefined) {
// polygon or polyline
if (layer._parts.length == 0
|| layer._parts[0].length == 0) {
return;
}
p = this._getCenter(layer._parts[0]);
}
// label bounds offset
var offsetX = 0;
var offsetY = 0;
/**
* TODO setting for custom font
*/
ctx.lineWidth = 4.0;
ctx.font = "16px 'Meiryo'";
// Collision detection
var textWidth = (ctx.measureText(layer.options.text).width)
+ p.x;// + offsetX;
var textHeight = p.y + offsetY + 20;
var bounds = L.bounds(
L.point(p.x + offsetX, p.y + offsetY), L.point(
textWidth, textHeight));
if (this.options.collisionFlg) {
for ( var index in this._textList) {
var pointBounds = this._textList[index];
if (pointBounds.intersects(bounds)) {
return;
}
}
}
this._textList.push(bounds);
ctx.strokeStyle = "white";
ctx.strokeText(layer.options.text, p.x + offsetX, p.y
+ offsetY);
if (layer.options.textColor == undefined) {
ctx.fillStyle = "blue";
} else {
ctx.fillStyle = layer.options.textColor;
}
ctx.fillText(layer.options.text, p.x + offsetX, p.y
+ offsetY);
}
},
_getCenter : function(points) {
var i, halfDist, segDist, dist, p1, p2, ratio, len = points.length;
if (!len) {
return null;
}
// polyline centroid algorithm; only uses the first ring if
// there are multiple
for (i = 0, halfDist = 0; i < len - 1; i++) {
halfDist += points[i].distanceTo(points[i + 1]) / 2;
}
// The line is so small in the current view that all points are
// on the same pixel.
if (halfDist === 0) {
return points[0];
}
for (i = 0, dist = 0; i < len - 1; i++) {
p1 = points[i];
p2 = points[i + 1];
segDist = p1.distanceTo(p2);
dist += segDist;
if (dist > halfDist) {
ratio = (dist - halfDist) / segDist;
var resutl = [ p2.x - ratio * (p2.x - p1.x),
p2.y - ratio * (p2.y - p1.y) ];
return L.point(resutl[0], resutl[1]);
}
}
},
});