天地图官网:
常用地图类型:
百度地图(BMap),高德地图(AMap),天地图(TMap).
地图相关常用属性:
地图的定位,地图的缩放,地图的添加覆盖物,绘制覆盖物,覆盖物的事件监听以及轨迹回放等
tips:
1:天地图使用的是handler来绘制,
但是handler绘制完成后不会返回绘制的对象,
需要我们对正在绘制的handler进行事件监听来获取绘制的对象,
但是他们监听的事件还不一样!
类型 | 监听类型 |
---|---|
marker | mouseup(鼠标抬起) |
cirlce | drawend(绘制完成) |
polyline | draw(绘制完成) |
rectangle | draw(绘制完成) |
polygon | draw(绘制完成) |
2:一般数据库表结构设计(部分重要字段):
字段名 | 类型(mysql/oracle) | 注释 |
---|---|---|
lng | float/number | 中心点经度 |
lat | float/number | 中心点纬度 |
type | varchar(15)/varchar2(15) | 类型(marker:点,circle:圆,polyline:折线,rectangle:矩形,polygon:多边形) |
radius | float/number | 半径,默认0(只有type为circle的有) |
collection | varchar(3000)/varchar2(3000) | 点集合,折线,矩形,多边形有 多个用,分割,样例:123.11111,34.12345,111.23456,35.112341… |
使用方法:
let map = new T.Map('mapDiv'); // 初始化地图
let point = new T.LngLat(117.12345,34.123456); // 中心点
map.centerAndZoom(point,16); // 定位
let icon = new T.Icon({
// icon options
});
// MarkerTool/CircleTool/PolylineTool/PolygonTool/RectangleTool
let handler = new T.MarkerTool(map,{
icon: icon,
follow:true, // 点跟随鼠标
});
handler.open(); // 开启绘制
// mouseup/drawend/draw/draw/draw
handler.on('mouseup',function(e){
console.log(e)
// do something
handler.close(); // 结束绘制
});
根据天地图的api封装一个js来实现地图的加载以及上述功能:
思路:
1:该JS文件要实现高内聚,低耦合的复用,把常用的绘制接口和数据请求接口暴露出去
2:实现对绘制的路线进行轨迹回放等功能
var MAP = {
map:null, // 实例化的对象
container:'mapDiv', // 地图容器DOM元素
center:{
lng:'', // 经度
lat:'' // 纬度
}, // 中心点
mapTypeArr:[
{title:'地图',layer:TMAP_NORMAL_MAP,icon:'../resources/images/vector.png'},
{title:'微卫星混合',layer:TMAP_HYBRID_MAP,icon:'../resources/images/satellitepoi.png'},
], // 地图样式切换
zoom:16, // 初始化缩放程度
url:'', // 请求数据URL,
iconOpt: null, // 默认点icon配置
startIconOpt:null, // 轨迹开始点icon配置
endIconOpt:null, // 轨迹结束点icon配置
overlays:{}, // 产生的overlay
markerOpt:{}, // 点的默认样式
polylineOpt:{}, // 线的默认样式
polygonOpt:{}, // 多边形默认样式
circleOpt:{}, // 圆形默认样式
rectangleOpt:{}, // 矩形默认样式
toolBarOpt:[
{value:'clear',text:'清空地图',color:'red'},
{value:'marker',text:'标记点位'},
{value:'circle',text:'清空地图'},
{value:'polyline',text:'清空地图'},
{value:'rectangle',text:'清空地图'},
{value:'polygon',text:'清空地图'}
], //绘制工具集合
showToolBar: false, // 是否开启工具栏
activeHandler:null, // 正在使用的绘制工具
activeIndex:0, // 绘制图形的index
activeType:'', // 绘制图形的类型
carTrackOpt:{
interval:10, // 越大越慢
speed:10 // 越大越快
}, // 轨迹回放配置
carTrackObj:{}, // 轨迹回放对象,实现共同回放多个轨迹
// 初始化方法,传入config
init(config){
this.extendConfig(config);
this.map = new T.Map(this.container);
let p = new T.LngLat(this.center.lng,this.center.lat);
this.map.centerAndZoom(p,this.zoom);
let iconOpt = {
iconUrl:'images/default-point-icon.png',
iconSize: new T.Point(19.27),
iconAnchor:new T.Point(10,25)
};
this.iconOpt = new T.Icon(iconOpt); // 设置默认点图标
iconOpt.iconUrl = 'images/start-point-icon.png',
this.startIconOpt = new T.Icon(iconOpt); // 设置开始点图标
iconOpt.iconUrl = 'images/end-point-icon.png',
this.endIconOpt = new T.Icon(iconOpt); // 设置结束点图标
this.initMapType();
if(this.showToolBar) this.initToolBar();
},
// 扩展配置
extendConfig(config){
for(let i in config){
this[i] = config[i];
}
},
// 显示地图切换样式
initMapType(){
if(this.mapTypeArr.length > 1){
let control = new T.Control.MapType(this.mapTypeArr);
this.map.addControl(control);
}
},
// 显示工具栏
initToolBar(){
let textLength = 0; // 文本长度
let html = '<div class="map-tool-bar">';
for(let i=0;i<this.toolBarOpt.length;i++){
if(textLength<this.toolBarOpt[i].text.length)
textLength = this.toolBarOpt[i].text.length;
html += '<div class="map-tool-bar-item" color="'+this.toolBarOpt[i].color+'" data-type="'+this.toolBarOpt[i].value+'">'+this.toolBarOpt[i].text+'</div>';
}
html += '</div>';
$('#'+this,container).after(html);
let $dom = $('.map-tool-bar-item');
$dom.css('flex','0 0 '+100/this.this.toolBarOpt.length+'%');
if(textLength>4) $dom.css('min-width',75+(textLength-4)*10+'px');
let self = this;
// 增加工具条监听
$dom.click(function(){
if(self.activeHandler){
self.activeHandler.close;
}
if(!$(this).hasClass('active')){
$(this).siblings().removeClass('active');
$(this).addClass('active');
}
self.operateMap($(this).attr('data-type'));
})
},
// 绘制地图
operateMap(type){
this.activeType = type;
this.activeHandler && this.activeHandler.close();
switch(type){
case 'clear':
this.clearOverlays();
break;
case 'marker':
this.addMarker();
break;
case 'circle':
this.addCircle();
break;
case 'polyline':
this.addPolyline();
break;
case 'rectangle':
this.addRectangle();
break;
case 'polygon':
this.addPolygon();
break;
default:
break;
}
},
// 以addCircle为例
addCircle(){
this.activeHandler = new T.CircleTool(this.map,this.circleOpt);
this.activeHandler.open();
this.addEventListener('drawed');
},
// 添加监听事件
addEventListener(type){
let self = this;
this.activeHandler.on(type,function(e){
self.overlays[self.activeType + '-' + self.activeIndex++] = {
obj:e,
type:self.activeType
};
})
},
// 组织数据,把绘制的数据组织好
// marker:currentLnglat
// circle:currentCenter:中心点.currentRadius:半径
// polygon:currentLnglats:点集合
// polyline: currentLnglats:点集合
// rectangle:currentBounds:点集合
creatData(){
let arr = [];
for(let key in this.overlays){
let obj = {
id:this.overlays[key].id ? this.overlays[key].id : '',
type:this.overlays[key].type,
radius:0,
lng:0,
lat:0,
};
let temp = [];
swicth(obj.type){
case 'marker':
obj.lng = this.overlays[key].currentLnglat.lng;
obj.lat = this.overlays[key].currentLnglat.lat;
break;
case 'circle':
obj.lng = this.overlays[key].currentLnglat.lng;
obj.lat = this.overlays[key].currentLnglat.lat;
obj.radius = this.overlays[key].currentRadius;
break;
case 'polyline':
temp = [];
for(let i = 0;i<this.overlays[key].obj.currentLngLats.length;i++){
temp.push(this.overlays[key].obj.currentLngLats[i].lng);
temp.push(this.overlays[key].obj.currentLngLats[i].lat);
}
obj.collection = temp.join(',');
break;
case 'rectangle':
temp = [];
temp.push(this.overlays[key].obj.currentBounds.Lq.lng);
temp.push(this.overlays[key].obj.currentBounds.Lq.lat);
temp.push(this.overlays[key].obj.currentBounds.kq.lng);
temp.push(this.overlays[key].obj.currentBounds.kq.lat);
obj.collection = temp.join(',');
break;
case 'polygon':
temp = [];
for(let i = 0;i<this.overlays[key].obj.currentLngLats.length;i++){
temp.push(this.overlays[key].obj.currentLngLats[i].lng);
temp.push(this.overlays[key].obj.currentLngLats[i].lat);
}
obj.collection = temp.join(',');
break;
default:
break;
}
arr.push(obj);
}
return arr;
},
}
回显数据时 for循环遍历数据,将数据的id作为overlay的key,并且将对象中的type和obj进行赋值即可:
只写出多边形的回显数据:
setPolygon(data){
let arr = data.collection.split(',');
let temp = [];
// 每隔一个数据,new一个点,将点push到数组中
for(let i=0;i<arr.length;i++){
if(i%2===0)
temp.push(new T.LngLat(arr[i],arr[i+1]));
}
let o = new T.Polygon(temp);
this.overlays['polygon-'+this.activeIndex]={
obj:{
curremtLnglats:temp
},
type:'polygon',
id:data.id,
};
this.map.addOverLay(o);
}
轨迹回放:引入JS:
<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 src="http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/CarTrack.js"></script>
其中data格式:
http://lbs.tianditu.gov.cn/api/js4.0/opensource/data/point.js
var map = new T.Map("mapDiv");
map.centerAndZoom(new T.LngLat(116.318090, 39.920270), 13);
var _CarTrack = new T.CarTrack(map, {
interval: 5,
speed: 10,
dynamicLine: true,
polylinestyle: {color: "#2C64A7", weight: 5, opacity: 0.9},
Datas: datas.features.map(function (obj, i) {
var coordinates = obj.geometry.coordinates;
var lnlat = new T.LngLat(coordinates[0], coordinates[1]);
return lnlat;
}
)
})