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.
231 righe
8.4 KiB
231 righe
8.4 KiB
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]); |
|
} |
|
} |
|
}, |
|
|
|
});
|
|
|