在使用 typescript 或者javascript 前端接入腾讯地图的时候,看了官方文档可能会有一点疑问(如果没搞过的话),实际上很简单,下面以 typescript 为例,介绍一下怎么用的
话不多说,先上一张多点地图图
地图
以地图为例,首先获取地图的使用对象,由于地图是js代码,因此类型问题,涉及到的都标记any即可
//声明该对象方便使用,也可以不声明,直接resolve返回
var TMap: any
//获取代码地图对象,这样就获取到了
//实际也可以在html中直接导入,个人感觉按需导入更好一些
export const TMapGL = (key: string): Promise<any> => {
return new Promise(function(resolve, reject) {
//加载一段脚本
var script = document.createElement('script')
script.type = 'text/javascript'
//引入脚本连接src,需要拼接key,可以先试用案例的key
//由于为get请求,实际可以网页打开查看返回的代码,可以看到,其在 window 上挂载了 TMap 对象
//而这个TMap对象就是官方案例用到的参数
script.src = 'https://map.qq.com/api/gljs?v=1.exp&key=' + key
script.onerror = (err) => reject(err)
script.onload = (e) => {
//加载脚本完毕之后,TMap就被挂载到window上了,注意由于js挂载上面的,ts会报错
//因此需要强转才能调用,费则会报错
TMap = (window as any).TMap
resolve(e)
}
document.head.appendChild(script)
})
}
下面简单介绍一下地图使用,以及生成多个点测试一下海量点(腾讯不支持海量点,因此上万就很卡了,这里也就几千,太多建议高德,另外腾讯有点聚合功能支持,可以根据需要更改)
ps:腾讯地图创建到节点时不会检查是否存在,因此需要额外注意(严格模式下由于方法会执行两遍,会出现两个地图,测试功能时,只能操作里面的地图,因此测试功能时出现误差,取消严格模式即可,即去掉React.StrictMode)
const initMap = () => {
//定义地图中心点坐标
TMapGL(mapkey).then(() => {
console.log('TMap', TMap)
let center = new TMap.LatLng(39.160001, 117.156150)
let myOptions = {
zoom: 18,
center
};
let dom = document.getElementById('my-map')
//创建地图,绑定dom
let map = new TMap.Map(dom, myOptions);
//Map实例创建后,通过on方法绑定点击事件
map.on("click", onClickMap)
//同时也可以监听缩放相关,通过getZoom方法获取当前缩放指数,以控制 label的显示隐藏
//可以通过提前生成 label 的方式,在不同缩放等级时控制 label 显隐即可
map.on('zoom', onMapZoom);
myMap.current = map
//创建并初始化MultiMarker
mapLayer.current = new TMap.MultiMarker({
map: map, //指定地图容器
//样式自定义
styles: {
//创建一个styleId为"myStyle"的样式(styles的子属性名即为styleId)
"marker": new TMap.MarkerStyle({
"width": 25, // 点标记样式宽度(像素)
"height": 25, // 点标记样式高度(像素)
"src": `${process.env.PUBLIC_URL}/logo192.png`, //图片路径,不设置会使用腾讯地图默认的红标
//焦点在图片中的像素位置,一般大头针类似形式的图片以针尖位置做为焦点,圆形点以圆心位置为焦点
"anchor": { x: 16, y: 32 }
})
},
//点标记数据数组
geometries: [{//第1个点标记,默认
"id": "0",
"styleId": 'marker',
"position": center,
"properties": {
"title": "defaultMarker"
}
}]
});
//可以给marker添加点击事件,注意此事件不会阻止向下继续冒泡
mapLayer.current.on("click", function(e: any) {
console.log('onClickMarker', e)
})
//当移入时 geometry.properties 里面会有我们的 item 信息,否则没有
//可以通过该属性控制 label 显示隐藏
mapMarkersLayer.current.on("hover", onMarkersHover)
mapLabelsLayer.current = new TMap.MultiLabel({
id: 'label-layer',
map: map, //设置折线图层显示到哪个地图实例中
//文字标记样式
styles: {
'label': new TMap.LabelStyle({
'color': '#1b90ff', //颜色属性
'size': 14, //文字大小属性
'offset': { x: 0, y: -38 }, //文字偏移属性单位为像素
'angle': 0, //文字旋转属性
'alignment': 'center', //文字水平对齐属性
'verticalAlignment': 'middle' //文字垂直对齐属性
})
},
//文字标记数据
geometries: []
});
}).catch(err => {
console.log('err', err)
})
}
const onMapZoom = (e: any) => {
//地图缩放更新后,我们个根据zoom是否显示 marker、label
myMap.current.getZoom()
}
//地图点击事件回调
const onClickMap = (e: any) => {
console.log('click', e)
addMorePoints(e)
}
//生成多个点,以测量大量数据
const addMorePoints = (e: any) => {
let lat = e.latLng.getLat();
let lng = e.latLng.getLng();
console.log("您点击的的坐标是:"+ lat + "," + lng);
let markers: any[] = []
for(let i = 1; i < 1000; i++) {
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat + Math.random(), lng + Math.random()), //点标记坐标位置
})
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat - Math.random(), lng - Math.random()), //点标记坐标位置
})
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat + Math.random(), lng - Math.random()), //点标记坐标位置
})
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat - Math.random(), lng + Math.random()), //点标记坐标位置
})
}
console.log('markers', markers)
// mapLayer.current.add(markers)
mapLayer.current.setGeometries(markers)
}
//注意id,map所在canvas会嵌入进去
return (
<div id="my-map" style={{width: '100vw', height: '100vh'}}></div>
);
定位
定位功能也与地图类似,只不过不需要 key 罢了,一般都是通过网络定位
var qq: any
export const TLocationGL = (): Promise<any> => {
return new Promise(function(resolve, reject) {
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = 'https://mapapi.qq.com/web/mapComponents/geoLocation/v/geolocation.min.js'
script.onerror = (err) => reject(err)
script.onload = (e) => {
//加载完成之后赋值,可以根据需要更名
qq = (window as any).qq
resolve(e)
}
document.head.appendChild(script)
})
}
//简易使用定位组件
const initLocation = () => {
TLocationGL().then(res => {
console.log('qq', (window as any).qq)
var geolocation = new qq.maps.Geolocation(mapkey, "web-map-demo");
//单次相对精准定位方法,三个参数,分别是成功回调,失败回调,参数设置,后面两个参数可以不填写
//第三个参数: {timeout: number, failTipFlag: boolean}
//分别表示超时时间,默认10s(自己更新时参数为ms),失败后是否提示打开定位,
geolocation.getLocation((position: any) => {
console.log('position', position)
myMap.current.setCenter(new TMap.LatLng(position.lat, position.lng))
})
//连续监听定位回调方法
geolocation.watchPosition(getPosition);
geolocation.clearWatch() //使用后退出页面,需要主动清除监听
}).catch(err => {
console.log('err', err)
})
}
搜索
如果要用到搜索服务,其为附加服务,默认没有导入,那么需要在导入地图的src中需要额外加入参数 &libraries=service
const TMapGL = (key: string): Promise<any> => {
if (TMap) return Promise.resolve()
return new Promise(function(resolve, reject) {
var script = document.createElement('script')
script.type = 'text/javascript'
//如果需要用到一些附加服务信息,需要添加 &libraries=service
script.src = 'https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=' + key
script.onerror = (err) => reject(err)
script.onload = (e) => {
TMap = (window as any).TMap
resolve(e)
}
document.head.appendChild(script)
})
}
使用方便,这里面就以地点搜索服务的 searchRegion为例
const searchByText = (keyword: string, cityName: string = '天津') => {
//初始化service附加服务的 Search 搜索类,这里需要调用 Search 的构造方法
let search = new TMap.service.Search({pageSize: 20})
//调用Search中的 searchRegion 搜索函数,其他也也是类似
search.searchRegion({
keyword,
cityName,
autoExtend: true //当前范围没搜索到,自动慢慢扩张到全城市
}).then((res : any) => {
console.log('搜索结果', res)
}).catch((err: any) => {
console.log(err)
})
}
全部代码
全部代码如下所示,可以尝试一下
const mapkey = "OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77" //官方案例的key,换成自己的
var TMap: any
var qq: any
export const TMapGL = (key: string): Promise<any> => {
return new Promise(function(resolve, reject) {
var script = document.createElement('script')
script.type = 'text/javascript'
script.text = 'TMap'
script.src = 'https://map.qq.com/api/gljs?v=1.exp&key=' + key
script.onerror = (err) => reject(err)
script.onload = (e) => {
TMap = (window as any).TMap
resolve(e)
}
document.head.appendChild(script)
})
}
export const TLocationGL = (): Promise<any> => {
return new Promise(function(resolve, reject) {
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = 'https://mapapi.qq.com/web/mapComponents/geoLocation/v/geolocation.min.js'
script.onerror = (err) => reject(err)
script.onload = (e) => {
qq = (window as any).qq
resolve(e)
}
document.head.appendChild(script)
})
}
function App() {
const myMap = useRef<any>(null)
const mapLayer = useRef<any>(null)
useEffect(() => {
initMap()
initLocation()
}, [])
const initLocation = () => {
TLocationGL().then(res => {
console.log('qq', (window as any).qq)
var geolocation = new qq.maps.Geolocation(mapkey, "web-map-demo");
geolocation.watchPosition(getPosition);
}).catch(err => {
console.log('err', err)
})
}
const getPosition = (position: any) => {
console.log('position', position)
myMap.current.setCenter(new TMap.LatLng(position.lat, position.lng))
}
const initMap = () => {
//定义地图中心点坐标
TMapGL(mapkey).then(() => {
console.log('TMap', TMap)
let center = new TMap.LatLng(39.160001, 117.156150)
let myOptions = {
zoom: 18,
center
};
let dom = document.getElementById('my-map')
//创建地图,绑定dom
let map = new TMap.Map(dom, myOptions);
//Map实例创建后,通过on方法绑定点击事件
map.on("click", onClickMap)
myMap.current = map
//创建并初始化MultiMarker
mapLayer.current = new TMap.MultiMarker({
map: map, //指定地图容器
//样式自定义
styles: {
//创建一个styleId为"myStyle"的样式(styles的子属性名即为styleId)
"marker": new TMap.MarkerStyle({
"width": 25, // 点标记样式宽度(像素)
"height": 25, // 点标记样式高度(像素)
"src": `${process.env.PUBLIC_URL}/logo192.png`, //图片路径,不设置会使用腾讯地图默认的红标
//焦点在图片中的像素位置,一般大头针类似形式的图片以针尖位置做为焦点,圆形点以圆心位置为焦点
"anchor": { x: 16, y: 32 }
})
},
//点标记数据数组
geometries: [{//第1个点标记
"id": "0",
"styleId": 'marker',
"position": center,
"properties": {
"title": "defaultMarker"
}
}]
});
}).catch(err => {
console.log('err', err)
})
}
const onClickMap = (e: any) => {
console.log('click', e)
// addOnePoint(e)
addMorePoints(e)
}
const addOnePoint = (e: any) => {
let lat = e.latLng.getLat();
let lng = e.latLng.getLng();
console.log("您点击的的坐标是:"+ lat + "," + lng);
let markers = [{
"id": Math.random() * 100000 % 100000 + '', //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
// "position": new TMap.LatLng(lat + Math.random() / 100, lng + Math.random() / 100), //点标记坐标位置
"position": e.latLng, //点标记坐标位置
"properties": {
"title": "defaultMarker"
}
}]
mapLayer.current.add(markers)
}
//搜索服务
const searchByText = (keyword: string, cityName: string = '天津') => {
//初始化service附加服务的 Search 搜索类,这里需要调用 Search 的构造方法
let search = new TMap.service.Search({pageSize: 20})
//调用Search中的 searchRegion 搜索函数,其他也也是类似
search.searchRegion({
keyword,
cityName,
autoExtend: true //当前范围没搜索到,自动慢慢扩张到全城市
}).then((res : any) => {
console.log('搜索结果', res)
}).catch((err: any) => {
console.log(err)
})
}
const addMorePoints = (e: any) => {
let lat = e.latLng.getLat();
let lng = e.latLng.getLng();
console.log("您点击的的坐标是:"+ lat + "," + lng);
let markers: any[] = []
for(let i = 1; i < 1000; i++) {
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat + Math.random(), lng + Math.random()), //点标记坐标位置
})
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat - Math.random(), lng - Math.random()), //点标记坐标位置
})
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat + Math.random(), lng - Math.random()), //点标记坐标位置
})
markers.push({
"id": '' + i + '' + lat + '' + lng, //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
"styleId": 'marker', //指定样式id
"position": new TMap.LatLng(lat - Math.random(), lng + Math.random()), //点标记坐标位置
})
}
console.log('markers', markers)
// mapLayer.current.add(markers)
mapLayer.current.setGeometries(markers)
}
return (
<div id="my-map" style={{width: '100vw', height: '100vh'}}></div>
);
}