-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
752 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* 一直覆盖在当前地图视野的Canvas对象 | ||
* | ||
* @author nikai (@胖嘟嘟的骨头, [email protected]) | ||
* | ||
* @param | ||
* { | ||
* map 地图实例对象 | ||
* } | ||
*/ | ||
|
||
function CanvasLayer(options){ | ||
this.options = options || {}; | ||
this.paneName = this.options.paneName || 'labelPane'; | ||
this.zIndex = this.options.zIndex || 0; | ||
this._map = options.map; | ||
this.show(); | ||
} | ||
|
||
CanvasLayer.prototype = new BMap.Overlay(); | ||
|
||
CanvasLayer.prototype.initialize = function(map){ | ||
this._map = map; | ||
var canvas = this.canvas = document.createElement("canvas"); | ||
canvas.style.cssText = "position:absolute;" | ||
+ "left:0;" | ||
+ "top:0;" | ||
+ "z-index:" + this.zIndex + ";"; | ||
this.adjustSize(); | ||
map.getPanes()[this.paneName].appendChild(canvas); | ||
var that = this; | ||
map.addEventListener('resize', function () { | ||
that.adjustSize(); | ||
that.draw(); | ||
}); | ||
return this.canvas; | ||
} | ||
|
||
CanvasLayer.prototype.adjustSize = function(){ | ||
var size = this._map.getSize(); | ||
var canvas = this.canvas; | ||
canvas.width = size.width; | ||
canvas.height = size.height; | ||
canvas.style.width = canvas.width + "px"; | ||
canvas.style.height = canvas.height + "px"; | ||
} | ||
|
||
CanvasLayer.prototype.draw = function(){ | ||
var map = this._map; | ||
var bounds = map.getBounds(); | ||
var sw = bounds.getSouthWest(); | ||
var ne = bounds.getNorthEast(); | ||
var pixel = map.pointToOverlayPixel(new BMap.Point(sw.lng, ne.lat)); | ||
this.canvas.style.left = pixel.x + "px"; | ||
this.canvas.style.top = pixel.y + "px"; | ||
this.dispatchEvent('draw'); | ||
this.options.update && this.options.update.call(this); | ||
} | ||
|
||
CanvasLayer.prototype.getContainer = function(){ | ||
return this.canvas; | ||
} | ||
|
||
CanvasLayer.prototype.show = function(){ | ||
if (!this.canvas) { | ||
this._map.addOverlay(this); | ||
} | ||
this.canvas.style.display = "block"; | ||
} | ||
|
||
CanvasLayer.prototype.hide = function(){ | ||
this.canvas.style.display = "none"; | ||
//this._map.removeOverlay(this); | ||
} | ||
|
||
CanvasLayer.prototype.setZIndex = function(zIndex){ | ||
this.canvas.style.zIndex = zIndex; | ||
} | ||
|
||
CanvasLayer.prototype.getZIndex = function(){ | ||
return this.zIndex; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# 地图标签云,文本标注避让 | ||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!DOCTYPE HTML> | ||
<html> | ||
<head> | ||
<title>地图可视化</title> | ||
<META http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> | ||
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script> | ||
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ"></script> | ||
<script type="text/javascript" src="CanvasLayer.js"></script> | ||
<style type="text/css"> | ||
html, body, #map{ | ||
width: 100%; | ||
height: 100%; | ||
overflow: hidden; | ||
padding: 0; | ||
margin: 0; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="map"></div> | ||
<script type="text/javascript" src="randomColor.js"></script> | ||
<script type="text/javascript" src="beijing_building.js"></script> | ||
<script type="text/javascript" src="index.js"></script> | ||
</body> | ||
</html> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
/** | ||
* @author nikai (@胖嘟嘟的骨头, [email protected]) | ||
*/ | ||
|
||
for (var i = 0, len = building.length; i < len; i++) { | ||
building[i].color = randomColor(); | ||
building[i].size = parseInt(Math.random() * 20) + 10; | ||
} | ||
|
||
building.sort(function (a, b) { | ||
return b.size - a.size; | ||
}); | ||
|
||
// 创建Map实例 | ||
var map = new BMap.Map("map"); | ||
|
||
var mercatorProjection = map.getMapType().getProjection(); | ||
|
||
map.centerAndZoom(new BMap.Point(116.405706, 39.927773), 12); // 初始化地图,设置中心点坐标和地图级别 | ||
map.enableScrollWheelZoom(); //启用滚轮放大缩小 | ||
|
||
map.setMapStyle({ | ||
styleJson: [{ | ||
featureType: 'water', | ||
elementType: 'all', | ||
stylers: { | ||
color: '#044161' | ||
} | ||
}, { | ||
featureType: 'land', | ||
elementType: 'all', | ||
stylers: { | ||
color: '#091934' | ||
} | ||
}, { | ||
featureType: 'boundary', | ||
elementType: 'geometry', | ||
stylers: { | ||
color: '#064f85' | ||
} | ||
}, { | ||
featureType: 'railway', | ||
elementType: 'all', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'highway', | ||
elementType: 'geometry', | ||
stylers: { | ||
color: '#004981' | ||
} | ||
}, { | ||
featureType: 'highway', | ||
elementType: 'geometry.fill', | ||
stylers: { | ||
color: '#005b96', | ||
lightness: 1 | ||
} | ||
}, { | ||
featureType: 'highway', | ||
elementType: 'labels', | ||
stylers: { | ||
visibility: 'on' | ||
} | ||
}, { | ||
featureType: 'arterial', | ||
elementType: 'geometry', | ||
stylers: { | ||
color: '#004981', | ||
lightness: -39 | ||
} | ||
}, { | ||
featureType: 'arterial', | ||
elementType: 'geometry.fill', | ||
stylers: { | ||
color: '#00508b' | ||
} | ||
}, { | ||
featureType: 'poi', | ||
elementType: 'all', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'green', | ||
elementType: 'all', | ||
stylers: { | ||
color: '#056197', | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'subway', | ||
elementType: 'all', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'manmade', | ||
elementType: 'all', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'local', | ||
elementType: 'all', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'arterial', | ||
elementType: 'labels', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'boundary', | ||
elementType: 'geometry.fill', | ||
stylers: { | ||
color: '#029fd4' | ||
} | ||
}, { | ||
featureType: 'building', | ||
elementType: 'all', | ||
stylers: { | ||
color: '#1a5787' | ||
} | ||
}, { | ||
featureType: 'label', | ||
elementType: 'all', | ||
stylers: { | ||
visibility: 'off' | ||
} | ||
}, { | ||
featureType: 'poi', | ||
elementType: 'labels.text.fill', | ||
stylers: { | ||
color: '#ffffff' | ||
} | ||
}, { | ||
featureType: 'poi', | ||
elementType: 'labels.text.stroke', | ||
stylers: { | ||
color: '#1e1c1c' | ||
} | ||
}] | ||
}); | ||
|
||
var canvasLayer = new CanvasLayer({ | ||
map: map, | ||
update: update | ||
}); | ||
|
||
var ctx = canvasLayer.canvas.getContext("2d"); | ||
|
||
function update() { | ||
var ctx = this.canvas.getContext("2d"); | ||
|
||
var zoom = map.getZoom(); | ||
var zoomUnit = Math.pow(2, 18 - zoom); | ||
var mcCenter = mercatorProjection.lngLatToPoint(map.getCenter()); | ||
var nwMc = new BMap.Pixel(mcCenter.x - (ctx.canvas.width / 2) * zoomUnit, mcCenter.y + (ctx.canvas.height / 2) * zoomUnit); //左上角墨卡托坐标 | ||
|
||
if (!ctx) { | ||
return; | ||
} | ||
|
||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); | ||
|
||
var temp = {}; | ||
ctx.shadowBlur = 10; | ||
ctx.shadowColor = "rgba(250, 250, 55, 0.7)"; | ||
ctx.beginPath(); | ||
|
||
ctx.textBaseline = "top"; | ||
|
||
for (var i = 0, len = building.length; i < len; i++) { | ||
var x = (building[i].x - nwMc.x) / zoomUnit; | ||
var y = (nwMc.y - building[i].y) / zoomUnit; | ||
|
||
building[i].px = x; | ||
building[i].py = y; | ||
} | ||
|
||
var rects = []; | ||
|
||
var canvasWidth = ctx.canvas.width; | ||
var canvasHeight = ctx.canvas.height; | ||
var margin = 200; // canvas扩大范围绘制,使边缘展示一致 | ||
for (var i = 0, len = building.length; i < len; i++) { | ||
var x = building[i].px; | ||
var y = building[i].py | ||
|
||
if (x < -margin || y < -margin || x > canvasWidth + margin || y > canvasHeight + margin) { | ||
continue; | ||
} | ||
|
||
ctx.font = "bold " + building[i].size + "px Arial"; | ||
var textWidth = ctx.measureText(building[i].n).width; | ||
|
||
// 根据文本宽度和高度调整x,y位置,使得绘制文本时候坐标点在文本中心点,这个计算出的是左上角坐标 | ||
var px = x - textWidth / 2; | ||
var py = y - building[i].size / 2; | ||
|
||
var rect = { | ||
sw: { | ||
x: px, | ||
y: py + building[i].size | ||
}, | ||
ne: { | ||
x: px + textWidth, | ||
y: py | ||
} | ||
} | ||
if (!hasOverlay(rects, rect)) { | ||
rects.push(rect); | ||
ctx.fillStyle = building[i].color; | ||
// ctx.fillRect(px, py, textWidth, building[i].size); | ||
ctx.fillText(building[i].n, px, py); | ||
} | ||
} | ||
} | ||
|
||
/* | ||
* 当前文字区域和已有的文字区域是否有重叠部分 | ||
*/ | ||
function hasOverlay(rects, overlay) { | ||
for (var i = 0; i < rects.length; i++) { | ||
if (isRectOverlay(rects[i], overlay)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
//判断2个矩形是否有重叠部分 | ||
function isRectOverlay(rect1, rect2) { | ||
//minx、miny 2个矩形右下角最小的x和y | ||
//maxx、maxy 2个矩形左上角最大的x和y | ||
var minx = Math.min(rect1.ne.x, rect2.ne.x); | ||
var miny = Math.min(rect1.sw.y, rect2.sw.y); | ||
var maxx = Math.max(rect1.sw.x, rect2.sw.x); | ||
var maxy = Math.max(rect1.ne.y, rect2.ne.y); | ||
if (minx > maxx && miny > maxy) { | ||
return true; | ||
} | ||
return false; | ||
} |
Oops, something went wrong.