Js玩玩地图
参考资料:
- https://lbs.amap.com/api/javascript-api/guide/map/lifecycle
- https://developers.google.cn/maps/documentation/javascript/examples/layer-heatmap?hl=zh-cn
- https://developers.google.cn/maps/documentation/javascript/heatmaplayer?hl=zh-cn
心得
高德的接口讲解的非常清晰, 真的没啥补充的. 但是, 我遇到了其他的问题.
读入json问题
<script type="text/javascript" src="pointgroup/forest.json"></script>
<script type="text/javascript" src="pointgroup/point.json"></script>
这么写是不行的.
function readTextFile(file, callback) {
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4 && rawFile.status == "200") {
callback(rawFile.responseText);
}
}
rawFile.send(null);
}
readTextFile("/pointgroup/forest.json", function (text) {
tree = JSON.parse(text);})
这么干是可以的, 前提是你启动了一个文件服务
最终的解决方案: 本地启动一个文件服务
npm i -g serve
然后, 直接命令行serve, 就可以启动一个文件服务了, 真方便
页面上如何写按钮问题
简单的写了absolute, 其实不值得分享, 勉强用用吧.
#floating-panel {
background-color: #fff;
border: 1px solid #999;
left: 15%;
padding: 5px;
position: absolute;
top: 10px;
z-index: 5;
}
移除标记
map.clearMap();
有时候我们希望基础图层低调一点
var maplayer = new AMap.TileLayer({
zooms: [3, 20], //可见级别
visible: true, //是否可见
opacity: 0.1, //透明度
zIndex: 0 //叠加层级
})
var map = new AMap.Map('container', {
layers: [maplayer], //当只想显示标准图层时layers属性可缺省
mapStyle: 'amap://styles/dark', //设置地图的显示样式
});
参考
- 海量点标记: https://lbs.amap.com/api/javascript-api/guide/overlays/massmarker
- 覆盖物: https://lbs.amap.com/api/javascript-api/reference/overlay#circlemarker
- 自定义地图: https://lbs.amap.com/api/javascript-api/guide/map/map-style
当我画到3000个点的时候, 效率问题出现了
高德同时描绘3000个点会很慢, 1s -> 4s -> 10s 会越来越慢.
含金量出现了, 高德的海量点展示, 能把人搞死了.
官方的最简案例是不能运行的, 别问我, 我也不知道为啥, 从比较复杂的案例删减下来是可以运行的, 代码如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>海量点</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<style>
html, body, #container {
height: 100%;
width: 100%;
}
.input-card .btn {
margin-right: 1.2rem;
width: 9rem;
}
.input-card .btn:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<div id="container" class="map" tabindex="0"></div>
<div class="input-card">
<h4>海量点效果切换</h4>
</div>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.11&key=331a358dfab40f1643316d0f8598f534"></script>
<script type="text/javascript">
var map = new AMap.Map('container', {
center: [102.342785, 35.312316]
mapStyle: 'amap://styles/dark', //设置地图的显示样式
});
var style = [{
url: 'https://a.amap.com/jsapi_demos/static/images/mass0.png',
anchor: new AMap.Pixel(6, 6),
size: new AMap.Size(11, 11)
}, {
url: 'https://a.amap.com/jsapi_demos/static/images/mass1.png',
anchor: new AMap.Pixel(4, 4),
size: new AMap.Size(7, 7)
}, {
url: 'https://a.amap.com/jsapi_demos/static/images/mass2.png',
anchor: new AMap.Pixel(3, 3),
size: new AMap.Size(5, 5)
}];
var citys = [{
"lnglat": [116.258446, 37.686622],
"name": "景县",
"style": 2
},
{
"lnglat": [116.366794, 39.915309],
"name": "西城区",
"style": 3
},
{
"lnglat": [116.486409, 39.921489],
"name": "朝阳区",
"style": 1
},
{
"lnglat": [116.286968, 39.863642],
"name": "丰台区",
"style": 2
},
{
"lnglat": [116.195445, 39.914601],
"name": "石景山区",
"style": 3
},
{
"lnglat": [116.310316, 39.956074],
"name": "海淀区",
"style": 1
},
{
"lnglat": [116.105381, 39.937183],
"name": "门头沟区",
"style": 2
},
{
"lnglat": [116.139157, 39.735535],
"name": "房山区",
"style": 3
},
{
"lnglat": [116.658603, 39.902486],
"name": "通州区",
"style": 1
}
]
var mass = new AMap.MassMarks(citys, {
opacity: 0.8,
zIndex: 111,
cursor: 'pointer',
style: style
});
mass.setMap(map);
</script>
</body>
</html>
然后你发现问题了吗?
问题就是, style只能和图片挂钩, 日哦, 如果界面要显示上百个组, 我就要弄来上百张图片. 妹哦, 坑死个人了.
在隔壁的blog: js弄图片[2018-12-08-js处理图片生成图片.md]里面我给了解决方案, 其实, canvas.toDataURL应该是一个更靠谱的方案.
1206 补记: 10天之后, 吃了一个大亏
高德不支持这种url:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwA…Q+gRaLp8pyTi7CYrA/wEdmxm1LHs5hAAAAABJRU5ErkJggg==",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwA…C6vnDVHeinT9Tsk7TOETgf8WFFMR9C6Q8AAAAAElFTkSuQmCC",
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwA…T6H1BO3/WyTpN4xCB/wPYZBrEhVxzWAAAAABJRU5ErkJggg==",
代码都写好了, 才发现不支持. 妹的.
当天被坑的另一件事.
/**
* 处理高德图层 这个必须在顶层
*
* */
const map = new AMap.Map('container', {
//layers: [maplayer], //当只想显示标准图层时layers属性可缺省
mapStyle: 'amap://styles/dark', //设置地图的显示样式
});
let mass = -1;
这个代码必须写在script的顶层.
而且高德是基于canvas做的, 所以针对canvas不要写style:
canvas{
width:200px;
height: 200px;
border: 0px;
margin: 0px;
padding: 0px;
}
#类似这种东西不要写. 写了就出各种诡异错误.
1218补充, 血淋淋的教训
看高德官方的demo, 不要看官方文档, 比如下面是文档:
let marker = new AMap.Marker({
position: new AMap.LngLat(lng, lat)
});
map.add(marker);
//这个并不能执行.
下面是demo
let marker = new AMap.Marker({
position: [lng, lat],
});
marker.setMap(map);
//这个才是能运行的.
demo是对的, 文档的代码不能运行…..
给海量点加title也要绕路
mass = new AMap.MassMarks(massdata, {
opacity: 0.8,
zIndex: 111,
cursor: 'pointer',
style: stylearray
});
log('massdata:', JSON.stringify(massdata));
let icon = new AMap.Icon({
size: new AMap.Size(0, 0), // 图标尺寸
imageOffset: new AMap.Pixel(0, -60), // 图像相对展示区域的偏移量,适于雪碧图等
imageSize: new AMap.Size(0, 0) // 根据所设置的大小拉伸或压缩图片
});
let marker = new AMap.Marker({
contnet: 'markercontent',
map: map,
icon: icon
});
mass.on('mouseover', function (e) {
marker.setPosition(e.data.lnglat);
marker.setLabel({
content: e.data.name
});
})
mass.setMap(map);
circlemaker也不支持title相关的方法和属性
也要用mouseover去写
//然后他的写法还要转化为这样:
function onmouse(e) {
marker.setPosition(e.lnglat);
marker.setLabel({
content: this
});
}
2019-1-19日后记: 总之高德的海量点接口目前还是比较坑的, 建议大家绕路.