vue调用天地图网页api
lz百度用得好好的,都做完了,突然间说要换成天地图,时间还那么赶,就很无语,稍微记录一下吧,可能以后用得到。
1.引入js
注册账号,申请密钥(网页和web服务要分别申请),然后在vue项目的index.html中添加js引用
<script src="http://api.tianditu.gov.cn/api?v=4.0&tk=您的密钥" type="text/javascript"></script>
2.渲染地图
如果只是渲染一下地图标下点这么舒服,随随便便搞搞就好了
<div class="map-canvas" id="map-canvas" style="width:100%;height:1050px"></div>
// js代码
let map = new T.Map("map-canvas");
map.centerAndZoom(new T.LngLat(113.27, 23.13), 10); // 设置中心点和比例
this.map = map;
var ctrl = new T.Control.MapType();
// 添加地图种类控件
map.addControl(ctrl);
// 设置主题颜色,好像一共就3种颜色
map.setStyle('black')
//创建标注对象
var marker = new T.Marker(new T.LngLat(经度, 纬度));
//向地图上添加标注
map.addOverLay(marker);
然而哪有这么简单,淦。
- 首先,默认的标注太丑了,也不能说丑,就是不好看,领导说要换,多种类型多个图标 (= =)。
- 然后要解析地址,标点,选中一类,则显示一类,选中多个,则混合显示(。。。这让我要怎么清楚覆盖物 ),标注要添加点击事件。
- 行政区域根据数据显示色差,就像首页的专题图层这个,太为难我个后端了:
3.复杂功能实现
- 地址解析:
我在网页api的文档找了好久,都没有找到,后面才发现,在web服务有,所以我在后台每条记录保存的方法中调用了以下代码,太简单了,不解释:
public static Map<String,Object> testApp(String place) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient client = HttpClients.createDefault();
String queryStr = "http://api.tianditu.gov.cn/geocoder?ds=%7B'keyWord':'"+place+"'密钥";
HttpGet httpGet = new HttpGet(queryStr);
CloseableHttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
String info = EntityUtils.toString(entity, "UTF-8");
Map<String,Object> map = JSON.parseObject(info);
System.out.println(map);
Map<String,Object> map2 = (Map<String, Object>) map.get("location");
response.close();
return map2;
}
- 标点:
拿到坐标,就能标点了,自定义图标的话,根据数据的分类判断,使用对应的图片
var icon = new T.Icon({
iconUrl: require("@/assets/images/图片.png"),
iconSize: new T.Point(20, 20), // 大小调整
type:'类型1',
iconAnchor: new T.Point(20, 30)
});
var pdefinedOverlay = new T.Marker(new T.LngLat(element.positionY, element.positionX), {icon: icon,'title':''});
pdefinedOverlay.addEventListener("click", markerClick);// 点击事件的方法
map.addOverLay(pdefinedOverlay);
这里我加入了一个type属性,文档是没有的,之所以加入这个属性是为了清除覆盖物的时候做区分,因为map.clearOverLays() 并不适用。都是marker,只能用removeOverLay()移除单个的,没办法只能这么做了,虽然很奇怪
let markers = this.map.getOverlays();
markers.forEach(element => {
if(element.options.icon.options.type == "类型"){
_that.map.removeOverLay(element)
});
其实加在第一个options也行,算了懒得改。
- 行政区域:
这个就挺恶心的,现在的网页api找不到行政区边界的坐标json了,就很难受,只能用datav了(存在小偏差)。然后看了开源库的d3.js渲染地图,有了大概的思路 - 首先,点进demo页面,右键查看源代码,整个复制到新建的html中,修改密钥,然后就看到了demo效果,这时候:
- 改中心点,把datav获取的json替换原来的,如果在项目中出现跨域问题就用后台中转。
- 原来的代码是fill填充色随机的,fill-opacity是固定的(本人有点水,看了几个的d3介绍和源码)才知道怎么改,但是我不说,自己看。
效果图: - 我随便改的例子源代码,太为难我后端小菜鸡了:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<title>天地图-地图API-范例-加载geojson数据</title>
<link href="../../../../images/favicon.ico" type="image/x-icon" rel="Shortcut Icon"/>
<style type="text/css">
html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0
}
.tdt-interactive:hover{
background-color:yellow;
border:1px soild #000
}
#map-canvas {
height: 100%;
fill: #000000;
}
</style>
</head>
<body>
<div id="map-canvas"></div>
<script src=" http://api.tianditu.gov.cn/api?v=4.0&tk=密钥" type="text/javascript"></script>
<script src="http://cdn.bootcss.com/d3/3.5.17/d3.js " charset="utf-8"></script>
<script src="http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.js"></script>
<script>
var countries = [];
var countriesOverlay = new T.D3Overlay(init,redraw);
//var countriesOverlay1 = new T.D3Overlay(init1,redraw1);
var map = new T.Map("map-canvas");
map.centerAndZoom(new T.LngLat(113.27, 23.13), 9)
d3.json("https://geo.datav.aliyun.com/areas_v3/bound/440100_full.json", function (data) {
countries = data.features;
map.addOverLay(countriesOverlay)
countriesOverlay.bringToFront();
//bringToFront()
// map.addOverLay(countriesOverlay1)
// countriesOverlay.bringToBack();
});
function init(sel, transform) {
console.log(countries)
var upd = sel.selectAll('path.geojson').data(countries);
upd.enter()
.append('path')
.attr("class", "geojson")
.attr('stroke', 'white')
.attr('fill','red')
.attr('fill-opacity', '0.4')
const equalBy = obj => obj.properties.name;
for(var i= 1;i<12;i++){
let arr1 = [];
arr1.push( countries[i-1])
const circle = sel.selectAll("path.geojson").data(arr1, equalBy) // UPDATE
.attr('fill-opacity', '0.'+i)
.attr('title',arr1[0].properties.name).
attr("class", "geojson tdt-interactive")
.on("click", data=> { console.log('clicked'); });
}
}
function ccccc() { console.log('clicked'); }
function redraw(sel, transform) {
sel.selectAll('path.geojson').each(
function (d, i) {
d3.select(this).attr('d', transform.pathFromGeojson)
}
)
}
/* function init1(sel, transform) {
debugger;
var upd = sel.selectAll('path.geojson1').data(countries);
upd.enter()
.append('path')
.attr("class", "geojson1")
.attr('stroke', 'black')
.attr('fill', function (d, i) {
return d3.hsl(Math.random() * 360, 0.9, 0.5)
})
.attr('fill-opacity', '0.5')
}
function redraw1(sel, transform) {
sel.selectAll('path.geojson1').each(
function (d, i) {
d3.select(this).attr('d', transform.pathFromGeojson)
}
)
}*/
</script>
</body>
</html>