在实际开发过程中,发现高德和百度地图等,无法使用卫星图查看乡镇问题,遂使用政府开发的天地图。写一份实(jiao)战(xue)记录,为开源精神做一份贡献。
讲解的功能有
- 天地图入门
- 地图渲染
- 添加地图控件
- 定位用户坐标,绘制城市边界,并通过移动标点重新定位经纬度
- 添加多个点,并且点击弹出信息框
项目使用vue-cli3,vue2开发
1、在public-index.html引入天地图cdn
key申请地址
应用创建成功就能看到key
2、渲染dome
//生命周期 - 在挂载完成(可以访问DOM元素)
mounted() {
this.onLoad()
},
methods(){
onLoad(){
let that=this //将方法放在mounted,会有指向问题,定义this使用就会正常
let zoom = 12; //地图的初始化级别,及放大比例
that.map = new T.Map("mapDiv");
that.map.centerAndZoom(new T.LngLat(116.40769, 39.89945), zoom); //地图的初始化中心点,此为北京的经纬度
}
}
3、添加地图类型控件
var ctrl = new T.Control.MapType([
{
title: "地图", //地图控件上所要显示的图层名称
icon: "http://api.tianditu.gov.cn/v4.0/image/map/maptype/vector.png", //地图控件上所要显示的图层图标(默认图标大小80x80)
layer: TMAP_NORMAL_MAP //地图类型对象,即MapType。
},
{
title: "卫星混合",
icon:
"http://api.tianditu.gov.cn/v4.0/image/map/maptype/satellitepoi.png",
layer: TMAP_HYBRID_MAP
}
]);
that.map.addControl(ctrl);
我只添加了两种类型的卫星,更多类型可以查看官方文档。
值得注意的是:官方文档提供的代码格式错误,不能直接copy下来用
4、定位用户坐标,绘制城市边界,并通过移动标点重新定位经纬度
data() {
//这里存放数据
return {
cityName:"" //暂存城市名称
};
},
positionBtn() {
let that =this
// this.map.clearOverLays(); //清理地图上的覆盖物
let lc = new T.LocalCity(); //创建一个获取本地城市位置的实例
lc.location(function(e) { //利用ip进行定位
alert(e.cityName);
let marker = new T.Marker(e.lnglat); //e.lnglat,标注点的地理坐标
that.map.addOverLay(marker); //addOverLay方法,将覆盖物添加到地图中,一个覆盖物实例只能向地图中添加一次。
that.getMap(); //创建地图对象
marker.addEventListener("dragend", overlay_style); //添加事件监听函数。
marker.enableDragging(); //开启标注拖拽功能
function overlay_style(e) {
let p = e.target;
alert(
"该地区经纬度是:" + p.getLngLat().lng + "," + p.getLngLat().lat
);
}
});
},
getMap() {
let that= this
//创建对象
let administrative = new T.AdministrativeDivision(); //创建一个获取行政区划的实例
let config = {
needSubInfo: false, //是否需要下一级信息
needAll: false, //是否需要所有子节点。
needPolygon: true,//是否需要行政区划范围。
needPre: true,//是否需要上一级所有信息。
searchType: 1,//查询类型。0表示根据code查询,1表示根据名称查询。
searchWord: this.cityName//查询行政区划的名称。
};
administrative.search(config, searchResult);//方法:根据检索词发起检索,searchResult:回调参数
function searchResult(result) {
if (result.getStatus() == 100) {
let data = result.getData();
that.showMsg(data);
} else {
result.getMsg();
}
}
//具体内容详见AdministrativeDivisionResult类。
},
showMsg(data) {
for (let i = 0; i < data.length; i++) {
//解释上级行政区划
if (data[i].parents) {
let upLevel = "";
if (data[i].parents.country) {
upLevel += data[i].parents.country.name;
}
if (data[i].parents.province) {
upLevel += data[i].parents.province.name;
}
}
if (data[i].points) {
//绘制行政区划
this.polygon(data[i].points);
}
//解释下级行政区划
if (data[i].child) {
showMsg(data[i].child);
console.log(data[i].child.points);
if (data[i].child.points) {
//绘制行政区划
this.polygon(data[i].child.points);
}
}
}
},
polygon(points) {
let that=this
let pointsArr = [];
for (let i = 0; i < points.length; i++) {
let regionLngLats = [];
let regionArr = points[i].region.split(",");
for (let m = 0; m < regionArr.length; m++) {
let lnglatArr = regionArr[m].split(" ");
let lnglat = new T.LngLat(lnglatArr[0], lnglatArr[1]);
regionLngLats.push(lnglat);
pointsArr.push(lnglat);
}
//创建面对象,样式
let polygon = new T.Polygon(regionLngLats, {
color: "#fd737a",
weight: 3,
opacity: 1,
fillColor: "#FFFFFF", //填充颜色。
fillOpacity: 0.3 //填充透明度
});
//向地图上添加行政区划面
that.map.addOverLay(polygon);
}
//显示最佳比例尺
that.map.setViewport(pointsArr);
alert(
"当前地图中心点:" +
that.map.getCenter().getLng() +
"," +
that.map.getCenter().getLat()
);
},
5、添加多个点,并且点击弹出信息框
pointsBtn() {
let that=this
let data_info = [
[
116.417854,
39.921988,
"地址:北京市东城区王府井大街88号乐天银泰百货八层"
],
[116.406605, 39.921585, "地址:北京市东城区东华门大街"],
[116.412222, 39.912345, "地址:北京市东城区正义路甲5号"]
];
for (let i = 0; i < data_info.length; i++) {
let marker = new T.Marker(
new T.LngLat(data_info[i][0], data_info[i][1])
); // 创建标注
let content = data_info[i][2];
that.map.addOverLay(marker); // 将标注添加到地图中
that.addClickHandler(content, marker);
}
},
addClickHandler(content, marker) {
marker.addEventListener("click", function(e) {
that.openInfo(content, e);
});
},
openInfo(content, e) {
let point = e.lnglat;
that.marker = new T.Marker(point); // 创建标注
let markerInfoWin = new T.InfoWindow(content, {
offset: new T.Point(0, -30)
}); // 创建信息窗口对象
that.map.openInfoWindow(markerInfoWin, point); //开启信息窗口
},
使用自定义信息框,会涉及到利用三目运算符,根据数字转换成对应字符的问题,记得用()把三木运算符括起来,否则会导致前面的html无法渲染
结语
网上写天地图的文章挺少,其实只要把坑踩过了还是挺好用的。
觉得有用的小伙伴,可以请我喝杯奶茶以资鼓励。