高德地图很强大,涉及到地图相关的功能都有,连天气预报都开放了API,真心好用。
下面列举一些用车相关的功能示例,基本跟官方示例是一致的,部分有出入。
1、初始化
安装地图插件
npm i @amap/amap-jsapi-loader --save
使用示例
import AMapLoader from '@amap/amap-jsapi-loader';
AMapLoader.load({
"key": "", // 申请好的Web端开发者Key,首次调用 load 时必填
"version": "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
"plugins": [], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((AMap)=>{
map = new AMap.Map('container');
}).catch(e => {
console.log(e);
})
初始化window参数
window._AMapSecurityConfig = {
securityJsCode: aMapSecrectKey //安全密钥 路径规划要用
}
// JSAPI 默认启用了 failIfMajorPerformanceCaveat 参数来获取 webgl 上下文,图形绘制性能比较差的环境下不开启WebGL绘制,
// 如需要可以在 地图 JSAPI 脚本引用之前设置全局变量 window.forceWebGL = true;
// 高德地图2.0以上版本要求浏览器支持webgl才能修改style
window.forceWebGL = true;
初始化地图
建议将AMap、map挂载在window上,之后都使用同一个AMap、map。
const AMap = await AMapLoader.load({
key: aMapKey, // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
viewMode: '2D'
});
const map = new AMap.Map('container', {
zoom: 16, //初始化地图级别
center: [116.397428, 39.90923],
resizeEnable: true,
mapStyle: "amap://styles/whitesmoke"
})
window.AMap = AMap
window.map = map
2、画标记点
const content =
`
<div class="map-tips-root">
` +
popLayout +
markImg +
`
</div>`;
const marker = new AMap.Marker({
content: content, // 自定义点标记覆盖物内容
position: position, // 基点位置
angle: angle,
// draggable: true, //是否可拖拽
// cursor: 'move',
});
map.add(marker);
content可以根据你的需求写html代码,也可以指定样式,如:
.map-tips-root {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform: translate3d(-50%, -50%, 0);
}
3、定位
const map = window.map;
const AMap = window.AMap;
AMap.plugin('AMap.Geolocation', function () {
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:5s
position: 'RB', //定位按钮的停靠位置
offset: [10, 20], //定位按钮与设置的停靠位置的偏移量,默认:[10, 20]
zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
});
map.addControl(geolocation);
geolocation.getCurrentPosition(function (status, result) {
if (status === 'complete') {
onComplete(result);
onMapLocation(result);
} else {
onMapLocation({});
onError(result);
}
});
});
//解析定位结果
function onComplete(data) {
console.log('当前定位信息:data', data);
// document.getElementById('status').innerHTML='定位成功'
const str: any[] = [];
str.push('定位结果:' + data.position);
str.push('定位类别:' + data.location_type);
if (data.accuracy) {
str.push('精度:' + data.accuracy + ' 米');
} //如为IP精确定位结果则没有精度信息
str.push('是否经过偏移:' + (data.isConverted ? '是' : '否'));
console.log('当前定位信息:', str);
// document.getElementById('result').innerHTML = str.join('<br>');
}
//解析定位错误信息
function onError(data) {
console.log('当前定位失败:', data);
// document.getElementById('status').innerHTML='定位失败'
// document.getElementById('result').innerHTML = '失败原因排查信息:'+data.message+'</br>浏览器返回信息:'+data.originMessage;
}
4、路径规划
//根据经纬度规划路经
AMap.plugin('AMap.Driving', function () {
const driving = new AMap.Driving({
// 驾车路线规划策略,AMap.DrivingPolicy.LEAST_TIME是最快捷模式
policy: AMap.DrivingPolicy.LEAST_TIME,
// map 指定将路线规划方案绘制到对应的AMap.Map对象上
map: map,
hideMarkers: true, //设置隐藏路径规划的起始点图标,设置为true:隐藏图标;设置false:显示图标
// panel 指定将结构化的路线详情数据显示的对应的DOM上,传入值需是DOM的ID
// panel: 'panel'
});
lastDriving.current = driving;
//todo 模拟司机在起点位置,后面修改成司机实时位置
const startLngLat = [driverLng, driverLat];
// const startLngLat = [startEndLngLat.start.lng, startEndLngLat.start.lat];
const endLngLat = [startEndLngLat.end.lng, startEndLngLat.end.lat];
driving.search(startLngLat, endLngLat, function (status, result) {
console.log('testDriving status,result', status, result);
if (status === 'complete') {
let popTips;
if (result.routes && result.routes.length > 0) {
// const dis = result.routes[0].distance || 0;
// const time = result.routes[0].time || 0;
const distance = result.routes[0].distance || 0;
const isFast = distance < 1000;
let distanceAfter = distance >= 1000 ? distance / 1000 : distance;
distanceAfter = distanceAfter.toFixed(1);
let time = result.routes[0].time || 0;
time = time / 60;
time = parseInt(time);
time = time < 1 ? 1 : time;
//todo 添加即将到达逻辑,小于一公里显示“即将到达”
if (isFast) {
if (!isEnding.current) {
isEnding.current = true;
mapUpdateState(OrderState.serviceEnding);
}
}
popTips = isFast
? {
oneTip: '即将到达',
}
: {
moreTip: {
// normal1: '距您',
highLight1: distanceAfter,
normal2: '公里',
highLight2: time,
normal3: '分钟',
},
};
}
if (driverLng && driverLat) {
//先画汽车
testMarkLayoutReal(
AMap,
map,
[driverLng, driverLat],
getMarkCar(),
null,
driverAngle,
);
//再画气泡
testMarkLayoutReal(AMap, map, [driverLng, driverLat], getMarkCarAlpha0(), popTips);
}
}
});
});
}
5、轨迹回放
const lineArr = [
[116.478935, 39.997761],
[116.478939, 39.997825],
[116.478912, 39.998549],
[116.478912, 39.998549],
[116.478998, 39.998555],
[116.478998, 39.998555],
[116.479282, 39.99856],
[116.479658, 39.998528],
[116.480151, 39.998453],
[116.480784, 39.998302],
[116.480784, 39.998302],
[116.481149, 39.998184],
[116.481573, 39.997997],
[116.481863, 39.997846],
[116.482072, 39.997718],
[116.482362, 39.997718],
[116.483633, 39.998935],
[116.48367, 39.998968],
[116.484648, 39.999861],
];
AMap.plugin('AMap.MoveAnimation', function () {
const lineArr = orderDetailInfo.drivingRoads.map((item) => {
return [item.lng, item.lat];
});
console.log('drawPay lineArr', lineArr);
const marker = new AMap.Marker({
map: map,
position: [116.478935, 39.997761],
content: getMarkCar(),
offset: new AMap.Pixel(-13, -26),
});
// 绘制轨迹
const passedPolyline = new AMap.Polyline({
map: map,
// path: lineArr,
showDir: true,
strokeColor: '#C7C7C7', //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
strokeStyle: 'solid', //线样式
});
marker.on('moving', function (e) {
passedPolyline.setPath(e.passedPath);
map.setCenter(e.target.getPosition(), true);
});
// map.setFitView();
marker.moveAlong(lineArr, {
// 每一段的时长
duration: 500, //可根据实际采集时间间隔设置
// JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
autoRotation: true,
});
}
6、拖动选址
拖动标记点获取位置(拖动选址)
marker.on('dragend', function (e)
const marker = testMarkLayoutReal(
AMap,
map,
[startEndLngLat.start.lng, startEndLngLat.start.lat],
getMarkStart(),
popTips,
);
// map.setZoomAndCenter(14, [121.457054, 31.183843]);
map.setZoomAndCenter(14, [startEndLngLat.start.lng, startEndLngLat.start.lat]);
marker.setCursor('move');
marker.setDraggable(true);
marker.on('dragend', function (e) {
//拖拽标记 更新经纬度
const lat = e.lnglat.lat;
const lng = e.lnglat.lng;
console.log('dragend ...lat,lng', lat, lng);
const lnglatXY = [lng, lat]; //地图上所标点的坐标
AMap.plugin('AMap.Geocoder', function () {
//回调函数
const geocoder = new AMap.Geocoder({});
geocoder.getAddress(lnglatXY, function (status, result) {
if (status === 'complete' && result.info === 'OK') {
//获得了有效的地址信息:
console.log('AMap.Geocoder result', result);
const formattedAddress =
(result && result.regeocode && result.regeocode.formattedAddress) || '';
let subAddress = '';
const indexOf = (formattedAddress && formattedAddress.indexOf('街道')) || 0;
if (indexOf >= 0) {
subAddress =
formattedAddress.length > indexOf + 2 &&
formattedAddress.substring(indexOf + 2, formattedAddress.length);
}
console.log('AMap.Geocoder subAddress', subAddress);
onUpdateSearch({
...onSearch,
startPoint: {
name: subAddress,
location: {
lat: lat,
lng: lng,
},
},
});
} else {
//获取地址失败
}
});
});
});
7、点击标记点响应
const marker = testMarkLayoutReal(
AMap,
map,
[startEndLngLat.end.lng, startEndLngLat.end.lat],
getMarkEnd(),
popTips,
);
map.setZoomAndCenter(14, [startEndLngLat.end.lng, startEndLngLat.end.lat]);
marker.setCursor('move');
marker.setDraggable(true);
marker.on('click', function (e) {
//点击标记 去搜索页
console.log('click ... ', e);
});
testMarkLayoutReal:
const testMarkLayoutReal = (AMap, map, position: number[], markImg, popTips: any, angle?) => {
const content = getMarkContent(markImg, popTips);
const marker = new AMap.Marker({
content: content, // 自定义点标记覆盖物内容
position: position, // 基点位置
angle: angle,
});
map.add(marker);
return marker;
};
getMarkContent:
const getMarkContent = (markImg, popTips: any) => {
// popTips = {
// oneTip: '上海平安大厦',
// rightIcon: require('../Image/map_tips_right_arrow.png'),
// moreTip: {
// normal1: '距您',
// highLight1: '1.7',
// normal2: '公里',
// highLight2: '11',
// normal3: '分钟',
// },
// };
// const markImg = require('../Image/map_location_start.png');
// const imgStr = '<img class="map-mark-start-end" src="' + markImg + '"/>';
const tipsIcon = require('../Image/map_tips_arrow.png');
const tipsIconStr = '<img class="map-tips-pop-arrow" src="' + tipsIcon + '"/>';
let popLayout = '';
if (popTips) {
const oneTip = getNormalSpan(popTips.oneTip);
let normal1 = '';
let normal2 = '';
let normal3 = '';
let highLight1 = '';
let highLight2 = '';
if (!oneTip && popTips.moreTip) {
normal1 = getNormalSpan(popTips.moreTip.normal1);
normal2 = getNormalSpan(popTips.moreTip.normal2);
normal3 = getNormalSpan(popTips.moreTip.normal3);
highLight1 = getHighLightSpan(popTips.moreTip.highLight1);
highLight2 = getHighLightSpan(popTips.moreTip.highLight2);
}
// const tipsRightArrow = require('../Image/map_tips_right_arrow.png');
const rightIcon = popTips.rightIcon
? '<img class="map-tips-pop-right-arrow" src="' + popTips.rightIcon + '"/>'
: '';
popLayout =
popTips &&
`
<div class="map-tips-pop">
<div class="map-tips-pop-row">
` +
oneTip +
normal1 +
highLight1 +
normal2 +
highLight2 +
normal3 +
rightIcon +
`
</div>
` +
tipsIconStr +
`
</div>`;
}
const content =
`
<div class="map-tips-root">
` +
popLayout +
markImg +
`
</div>`;
return content;
};
markImg:
const getMarkStart = () => {
return (
'<img class="map-mark-start-end" src="' +
require('../Image/map_location_start.png') +
'"/>\n'
);
};
markImg = getMarkStart();
暂无评论