在之前的【高德地图进阶】— 自定义地图中,有了解过如果给地图添加纹理. 但是该功能是收费的,这就劝退了不少人.
通常的业务都是将城市版块抬高,这部分之前的文章也讲述过.都是在地图上添加覆盖物
在高德的api中只有mesh有添加纹理并且可以做抬高版块的功能.但是该功能需要进行计算.对于复杂的城市版块,并不适用. 因此本章我们选择另辟蹊径
效果图:
制作地图图片
这里以河北省为例,首先你需要找到河北省地图,越高清越好.比例一定要是实际比例.
我是通过datav 截的图
截取该地图之后,找到美工老师,给该地图添加纹理,和市级交界线.并把图片制作成透明背景
注意:
图片一定要按实际比例,
图片边界和地图四个点相交,如下图
图片背景必须透明
将图片放到地图上
var imageLayer = new AMap.ImageLayer({
url: "图片地址",
bounds: new AMap.Bounds(
[113.44544, 36.037978],
[119.883334, 42.629816]
),
visible: true
});
imageLayer.setMap(map);
这里面的 bounds 是这个图片,在地图上的左下角坐标,和右上角坐标,如下图所示 ,需要自己计算,调试
步骤:
1.通过这篇【高德地图进阶】— 使用DistrictSearch 绘制城市版块,画出该省事的边界线
2.找到边界线,东西南北的四个顶点坐标, 如下图 标的数字
3.图片左下角坐标 , 是 点1 的经度 和 点2 的纬度
4.图片右上角坐标 , 是 点4 的经度 和 点3 的纬度
这样就得到了bounds 的值
这四个点的坐标,要么计算出来,要么就给地图添加点击事件.通过点击事件获取这四个点的坐标
抬高版块
到这步图片就已经正确的放置在地图上了. 这时候只需要给版块添加个wall ,把版块抬起来就可以了
可以参考这篇【高德地图进阶】— 3d城市版块之wall
全部代码
<!DOCTYPE html>
<html>
<head>
<meta
name="viewport"
content="width=device-width initial-scale=1.0 maximum-scale=1.0 user-scalable=0"
/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style>
body,
html,
#container {
margin: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
window._AMapSecurityConfig = {
securityJsCode: "xxxx",
};
</script>
<script
language="javascript"
src="https://webapi.amap.com/maps?v=1.4.15&key=cccc&plugin=AMap.DistrictSearch"
></script>
<script language="javascript">
//-----------------------------------创建map示例-----------------------------------------------------
var map = (window.map = new AMap.Map("container", {
center: [114.530399, 38.037707],
viewMode: "3D",
zoom: 7.5,
mapStyle: "amap://styles/7f17f200395774dd586158c865661f99", //设置地图的显示样式
pitch: 50,
showLabel: false,
}));
//给地图添加点击事件,用于获取坐标
map.on("click", showInfoClick);
//给地图手动画上城市名.非必须
loadMap(map);
//-----------------------------------把图片放置到地图上-----------------------------------------------------
var imageLayer = new AMap.ImageLayer({
url: "图片地址",
bounds: new AMap.Bounds(
[113.44544, 36.037978],
[119.883334, 42.629816]
),
visible: true,
//透明度
// opacity :0.8
});
imageLayer.setMap(map);
//-----------------------------------搜索省边界线用于创建wall 把图片顶起来-----------------------------------------------------
var opts = {
subdistrict: 1,
extensions: "all",
level: "city",
};
var district = new AMap.DistrictSearch(opts);
district.search("河北省", function (status, result) {
var bounds = result.districtList[0].boundaries;
//给地图绘制wall
var object3Dlayer = new AMap.Object3DLayer({ zIndex: 100 });
map.add(object3Dlayer);
var height = -80000;
var color = "#051B3D";
var wall = new AMap.Object3D.Wall({
path: bounds,
height: height,
color: color,
});
wall.transparent = true;
object3Dlayer.add(wall);
});
// 地图点击事件 通过鼠标点击 获取点击处的坐标
function showInfoClick(e) {
var text =
"您在 [ " +
e.lnglat.getLng() +
"," +
e.lnglat.getLat() +
" ] 的位置单击了地图!";
alert(text);
}
// 该方法不是必须, 因为 map中 showLabel: false,会隐藏城市名等信息 , 所以这里手动给城市添加名称
function loadMap(map) {
const markers = [
{
text: "邯郸市",
position: [114.52204, 36.591642],
},
{
text: "邢台市",
position: [114.943519, 37.334049],
},
{
text: "石家庄市",
position: [114.38895, 38.051754],
},
{
text: "衡水市",
position: [115.820133, 37.707642],
},
{
text: "沧州市",
position: [116.850438, 38.247648],
},
{
text: "廊坊市",
position: [116.566929, 39.05921],
},
{
text: "保定市",
position: [115.155485, 38.987941],
},
{
text: "张家口市",
position: [115.043847, 40.736147],
},
{
text: "承德市",
position: [117.518114, 41.24472],
},
{
text: "秦皇岛市",
position: [119.234677, 40.104363],
},
{
text: "唐山市",
position: [118.37154, 39.657324],
},
];
markers.forEach((e) => {
let marker = new AMap.Text({
map,
text: e.text,
position: e.position,
});
marker.setStyle({
background: "transparent",
color: "white",
border: "transparent",
"font-weight": "bold",
"font-style": "italic",
});
});
}
</script>
</body>
</html>
总结 按照以上的操作,就实现了城市板块 添加纹理的功能.
但是覆盖的方式也有问题.
1.无法看到图片下的地图,可以通过设置imageLayer 的透明度,或者监听地图缩放事件.根据缩放选择性的去除图片 ,显示城市道路信息等
2.可能你会觉得放的是整个图片,但是希望某个市的城市版块抬高怎么办.其实很好办,只要控制wall的绘制就可以指定城市抬高,而不只是整个省级抬高,如下图
代码里,我有加了个描边功能,这样市级抬高,也有边界线的效果.纯纯为了美观
//添加描边
for (var i = 0; i < bounds.length; i += 1) {
new AMap.Polyline({
path: bounds[i],
strokeColor: "#0dcdd1",
strokeWeight: 3,
map: map,
});
}