Add SEO metadata and security headers
This commit is contained in:
@@ -0,0 +1,629 @@
|
||||
# 路径规划 (Routing)
|
||||
|
||||
高德地图提供了驾车、步行、骑行和公交等多种路径规划服务。
|
||||
|
||||
## 1. 驾车路线规划 (Driving)
|
||||
|
||||
支持策略配置(如躲避拥堵、不走高速等)和多点路径规划。
|
||||
|
||||
```javascript
|
||||
// 构造路线规划类
|
||||
const driving = new AMap.Driving({
|
||||
map: map, // 绑定地图,自动绘制路线
|
||||
panel: 'panel-id', // 结果列表的容器 ID (可选)
|
||||
policy: AMap.DrivingPolicy.LEAST_TIME, // 策略:最快
|
||||
});
|
||||
|
||||
// 根据经纬度规划
|
||||
// 参数:起点,终点,(可选)途经点,回调
|
||||
driving.search(
|
||||
[116.379028, 39.865042], // 起点
|
||||
[116.427281, 39.903719], // 终点
|
||||
function(status, result) {
|
||||
if (status === 'complete') {
|
||||
console.log('绘制驾车路线完成');
|
||||
} else {
|
||||
console.error('获取驾车数据失败:' + result);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 根据关键字规划
|
||||
driving.search([
|
||||
{keyword: '北京站', city: '北京'},
|
||||
{keyword: '北京大学', city: '北京'}
|
||||
], function(status, result) {
|
||||
// ...
|
||||
});
|
||||
// 根据关键字规划
|
||||
driving.search([
|
||||
{keyword: '北京站', city: '北京'},
|
||||
{keyword: '北京大学', city: '北京'}
|
||||
], function(status, result) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
## 完整示例
|
||||
|
||||
```javascript
|
||||
const map = new AMap.Map('container', {
|
||||
zoom: 12,
|
||||
center: [116.397, 39.909]
|
||||
});
|
||||
|
||||
const driving = new AMap.Driving({
|
||||
policy: AMap.DrivingPolicy.LEAST_TIME,
|
||||
showTraffic: true
|
||||
});
|
||||
|
||||
function planDriving(start, end) {
|
||||
// 清除之前的路线
|
||||
driving.clear();
|
||||
|
||||
driving.search(start, end, function(status, result) {
|
||||
if (status === 'complete') {
|
||||
const route = result.routes[0];
|
||||
|
||||
// 提取路径点
|
||||
const path = [];
|
||||
route.steps.forEach(step => {
|
||||
path.push(...step.path);
|
||||
});
|
||||
|
||||
// 绘制路线
|
||||
const polyline = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#1890ff',
|
||||
strokeWeight: 6,
|
||||
strokeOpacity: 0.9,
|
||||
lineJoin: 'round',
|
||||
lineCap: 'round'
|
||||
});
|
||||
map.add(polyline);
|
||||
|
||||
// 显示信息
|
||||
showRouteInfo(route);
|
||||
|
||||
// 调整视野
|
||||
map.setFitView();
|
||||
} else {
|
||||
alert('驾车规划失败:' + result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showRouteInfo(route) {
|
||||
const distance = (route.distance / 1000).toFixed(1) + ' 公里';
|
||||
const time = formatTime(route.time);
|
||||
const tolls = route.tolls ? route.tolls + ' 元' : '无';
|
||||
|
||||
console.log(`距离: ${distance}, 时间: ${time}, 过路费: ${tolls}`);
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const minutes = Math.round((seconds % 3600) / 60);
|
||||
if (hours > 0) {
|
||||
return `${hours} 小时 ${minutes} 分钟`;
|
||||
}
|
||||
return `${minutes} 分钟`;
|
||||
}
|
||||
|
||||
// 使用
|
||||
planDriving([116.379028, 39.865042], [116.427281, 39.903719]);
|
||||
```
|
||||
|
||||
## 自定义路线样式
|
||||
|
||||
```javascript
|
||||
driving.search(start, end, function(status, result) {
|
||||
if (status === 'complete') {
|
||||
const route = result.routes[0];
|
||||
const path = [];
|
||||
|
||||
route.steps.forEach(step => {
|
||||
path.push(...step.path);
|
||||
});
|
||||
|
||||
// 底层阴影
|
||||
const shadowLine = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#0d47a1',
|
||||
strokeWeight: 10,
|
||||
strokeOpacity: 0.5
|
||||
});
|
||||
|
||||
// 主路线
|
||||
const mainLine = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#1890ff',
|
||||
strokeWeight: 6,
|
||||
strokeOpacity: 0.9
|
||||
});
|
||||
|
||||
map.add([shadowLine, mainLine]);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 清除路线
|
||||
|
||||
```javascript
|
||||
// 使用内置方法
|
||||
driving.clear();
|
||||
|
||||
// 或手动移除
|
||||
map.remove(polyline);
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **起终点格式**: 支持经纬度数组或关键字对象
|
||||
2. **途经点限制**: 最多支持 16 个途经点
|
||||
3. **路况显示**: 设置 `showTraffic: true` 显示实时路况
|
||||
4. **车牌限行**: 设置 `number` 参数可判断限行路段
|
||||
5. **自动渲染**: 设置 map 和 panel 后会自动渲染路线和结果面板
|
||||
|
||||
## 2. 其他出行方式
|
||||
|
||||
接口调用方式与 `Driving` 类似。
|
||||
|
||||
### 步行 (Walking)
|
||||
|
||||
```javascript
|
||||
const walking = new AMap.Walking({
|
||||
map: map,
|
||||
panel: 'panel'
|
||||
});
|
||||
|
||||
walking.search([116.399028, 39.845042], [116.436281, 39.880719], function(status, result) {});
|
||||
```
|
||||
## 完整示例
|
||||
|
||||
```javascript
|
||||
const map = new AMap.Map('container', {
|
||||
zoom: 14,
|
||||
center: [116.397, 39.909]
|
||||
});
|
||||
|
||||
const walking = new AMap.Walking();
|
||||
|
||||
function planWalking(start, end) {
|
||||
walking.search(start, end, function(status, result) {
|
||||
if (status === 'complete') {
|
||||
const route = result.routes[0];
|
||||
|
||||
// 提取路径点
|
||||
const path = [];
|
||||
route.steps.forEach(step => {
|
||||
path.push(...step.path);
|
||||
});
|
||||
|
||||
// 绘制路线(虚线样式)
|
||||
const polyline = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#52c41a',
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.9,
|
||||
strokeStyle: 'dashed', // 虚线
|
||||
strokeDasharray: [10, 5]
|
||||
});
|
||||
map.add(polyline);
|
||||
|
||||
// 添加起点终点标记
|
||||
addStartEndMarkers(start, end);
|
||||
|
||||
// 显示信息
|
||||
const distance = formatDistance(route.distance);
|
||||
const time = formatTime(route.time);
|
||||
console.log(`步行距离: ${distance}, 预计时间: ${time}`);
|
||||
|
||||
// 调整视野
|
||||
map.setFitView();
|
||||
} else {
|
||||
alert('步行规划失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addStartEndMarkers(start, end) {
|
||||
// 起点
|
||||
new AMap.Marker({
|
||||
map: map,
|
||||
position: start,
|
||||
content: createMarkerContent('起', '#52c41a'),
|
||||
offset: new AMap.Pixel(-16, -40)
|
||||
});
|
||||
|
||||
// 终点
|
||||
new AMap.Marker({
|
||||
map: map,
|
||||
position: end,
|
||||
content: createMarkerContent('终', '#f5222d'),
|
||||
offset: new AMap.Pixel(-16, -40)
|
||||
});
|
||||
}
|
||||
|
||||
function createMarkerContent(text, color) {
|
||||
return `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="40" viewBox="0 0 32 40">
|
||||
<path d="M16 0C7.163 0 0 7.163 0 16c0 12 16 24 16 24s16-12 16-24C32 7.163 24.837 0 16 0z" fill="${color}"/>
|
||||
<circle cx="16" cy="14" r="6" fill="#fff"/>
|
||||
<text x="16" y="18" text-anchor="middle" fill="${color}" font-size="10" font-weight="bold">${text}</text>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
function formatDistance(distance) {
|
||||
if (distance < 1000) {
|
||||
return Math.round(distance) + ' 米';
|
||||
}
|
||||
return (distance / 1000).toFixed(1) + ' 公里';
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
if (seconds < 60) {
|
||||
return Math.round(seconds) + ' 秒';
|
||||
}
|
||||
return Math.round(seconds / 60) + ' 分钟';
|
||||
}
|
||||
|
||||
// 使用
|
||||
planWalking([116.379028, 39.865042], [116.385281, 39.870719]);
|
||||
```
|
||||
|
||||
### 骑行 (Riding)
|
||||
|
||||
```javascript
|
||||
const riding = new AMap.Riding({
|
||||
map: map
|
||||
});
|
||||
|
||||
riding.search([116.399028, 39.845042], [116.436281, 39.880719]);
|
||||
```
|
||||
## 完整示例
|
||||
|
||||
```javascript
|
||||
const map = new AMap.Map('container', {
|
||||
zoom: 13,
|
||||
center: [116.397, 39.909]
|
||||
});
|
||||
|
||||
const riding = new AMap.Riding();
|
||||
|
||||
function planRiding(start, end) {
|
||||
riding.search(start, end, function(status, result) {
|
||||
if (status === 'complete') {
|
||||
const route = result.routes[0];
|
||||
|
||||
// 提取路径点
|
||||
const path = [];
|
||||
route.rides.forEach(ride => {
|
||||
path.push(...ride.path);
|
||||
});
|
||||
|
||||
// 绘制路线(橙色,表示骑行)
|
||||
const polyline = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#fa8c16',
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.9,
|
||||
lineJoin: 'round',
|
||||
lineCap: 'round'
|
||||
});
|
||||
map.add(polyline);
|
||||
|
||||
// 添加起点终点标记
|
||||
addStartEndMarkers(start, end);
|
||||
|
||||
// 显示信息
|
||||
showRouteInfo(route);
|
||||
|
||||
// 调整视野
|
||||
map.setFitView();
|
||||
} else {
|
||||
alert('骑行规划失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addStartEndMarkers(start, end) {
|
||||
// 起点
|
||||
new AMap.Marker({
|
||||
map: map,
|
||||
position: start,
|
||||
content: createBikeMarker('起', '#52c41a'),
|
||||
offset: new AMap.Pixel(-16, -40)
|
||||
});
|
||||
|
||||
// 终点
|
||||
new AMap.Marker({
|
||||
map: map,
|
||||
position: end,
|
||||
content: createBikeMarker('终', '#fa541c'),
|
||||
offset: new AMap.Pixel(-16, -40)
|
||||
});
|
||||
}
|
||||
|
||||
function createBikeMarker(text, color) {
|
||||
return `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="40" viewBox="0 0 32 40">
|
||||
<path d="M16 0C7.163 0 0 7.163 0 16c0 12 16 24 16 24s16-12 16-24C32 7.163 24.837 0 16 0z" fill="${color}"/>
|
||||
<circle cx="16" cy="14" r="6" fill="#fff"/>
|
||||
<text x="16" y="18" text-anchor="middle" fill="${color}" font-size="10" font-weight="bold">${text}</text>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
function showRouteInfo(route) {
|
||||
const distance = formatDistance(route.distance);
|
||||
const time = formatTime(route.time);
|
||||
|
||||
// 估算消耗卡路里(约 30 卡/公里)
|
||||
const calories = Math.round(route.distance / 1000 * 30);
|
||||
|
||||
console.log(`
|
||||
骑行距离: ${distance}
|
||||
预计时间: ${time}
|
||||
预计消耗: ${calories} 卡路里
|
||||
`);
|
||||
}
|
||||
|
||||
function formatDistance(distance) {
|
||||
if (distance < 1000) {
|
||||
return Math.round(distance) + ' 米';
|
||||
}
|
||||
return (distance / 1000).toFixed(1) + ' 公里';
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const minutes = Math.round((seconds % 3600) / 60);
|
||||
if (hours > 0) {
|
||||
return `${hours} 小时 ${minutes} 分钟`;
|
||||
}
|
||||
return `${minutes} 分钟`;
|
||||
}
|
||||
|
||||
// 使用
|
||||
planRiding([116.379028, 39.865042], [116.420281, 39.890719]);
|
||||
```
|
||||
|
||||
## 自定义路线样式
|
||||
|
||||
```javascript
|
||||
// 橙色渐变效果(骑行风格)
|
||||
const colors = ['#fa8c16', '#ffa940', '#ffc069'];
|
||||
|
||||
riding.search(start, end, function(status, result) {
|
||||
if (status === 'complete') {
|
||||
const route = result.routes[0];
|
||||
const path = [];
|
||||
|
||||
route.rides.forEach(ride => {
|
||||
path.push(...ride.path);
|
||||
});
|
||||
|
||||
// 底层阴影
|
||||
const shadowLine = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#d46b08',
|
||||
strokeWeight: 8,
|
||||
strokeOpacity: 0.4
|
||||
});
|
||||
|
||||
// 主路线
|
||||
const mainLine = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: '#fa8c16',
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.9,
|
||||
lineJoin: 'round',
|
||||
lineCap: 'round'
|
||||
});
|
||||
|
||||
map.add([shadowLine, mainLine]);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 电动车模式
|
||||
|
||||
```javascript
|
||||
const riding = new AMap.Riding({
|
||||
policy: 1 // 1 表示电动车
|
||||
});
|
||||
|
||||
riding.search(start, end, function(status, result) {
|
||||
// 电动车路线规划
|
||||
});
|
||||
```
|
||||
|
||||
## 清除路线
|
||||
|
||||
```javascript
|
||||
riding.clear();
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **路径特点**: 骑行路线会优先选择非机动车道、自行车道
|
||||
2. **速度估算**: 默认按照 15km/h(普通自行车)或 20km/h(电动车)估算
|
||||
3. **距离限制**: 骑行规划适合中短距离,过长距离可能无结果
|
||||
4. **颜色区分**: 建议使用橙色与驾车(蓝色)、步行(绿色)路线区分
|
||||
5. **上下坡**: 骑行路线会尽量避免陡坡路段
|
||||
|
||||
### 公交 (Transfer)
|
||||
|
||||
```javascript
|
||||
const transfer = new AMap.Transfer({
|
||||
map: map,
|
||||
city: '北京市',
|
||||
policy: AMap.TransferPolicy.LEAST_TIME // 最快捷模式
|
||||
});
|
||||
|
||||
transfer.search([116.291, 39.887], [116.436, 39.880], function(status, result) {});
|
||||
```
|
||||
## 完整示例
|
||||
|
||||
```javascript
|
||||
const map = new AMap.Map('container', {
|
||||
zoom: 12,
|
||||
center: [116.397, 39.909]
|
||||
});
|
||||
|
||||
const transfer = new AMap.Transfer({
|
||||
city: '北京市',
|
||||
policy: AMap.TransferPolicy.LEAST_TIME
|
||||
});
|
||||
|
||||
function planTransit(start, end) {
|
||||
transfer.search(start, end, function(status, result) {
|
||||
if (status === 'complete' && result.plans && result.plans.length > 0) {
|
||||
const plan = result.plans[0]; // 取第一个方案
|
||||
|
||||
// 遍历每个段落
|
||||
plan.segments.forEach((segment, index) => {
|
||||
// 乘车段
|
||||
if (segment.transit && segment.transit.path) {
|
||||
const polyline = new AMap.Polyline({
|
||||
path: segment.transit.path,
|
||||
strokeColor: '#1890ff',
|
||||
strokeWeight: 6,
|
||||
strokeOpacity: 0.9
|
||||
});
|
||||
map.add(polyline);
|
||||
|
||||
// 添加上下车站标记
|
||||
addStationMarker(segment.transit.on_station, '上');
|
||||
addStationMarker(segment.transit.off_station, '下');
|
||||
}
|
||||
|
||||
// 步行段
|
||||
if (segment.walking && segment.walking.path) {
|
||||
const polyline = new AMap.Polyline({
|
||||
path: segment.walking.path,
|
||||
strokeColor: '#52c41a',
|
||||
strokeWeight: 4,
|
||||
strokeOpacity: 0.8,
|
||||
strokeStyle: 'dashed'
|
||||
});
|
||||
map.add(polyline);
|
||||
}
|
||||
});
|
||||
|
||||
// 显示方案信息
|
||||
showPlanInfo(plan);
|
||||
|
||||
// 调整视野
|
||||
map.setFitView();
|
||||
} else {
|
||||
alert('公交规划失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addStationMarker(station, type) {
|
||||
if (!station) return;
|
||||
|
||||
new AMap.Marker({
|
||||
map: map,
|
||||
position: station.location,
|
||||
content: `<div style="
|
||||
background: ${type === '上' ? '#1890ff' : '#fa541c'};
|
||||
color: #fff;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
">${type} ${station.name}</div>`,
|
||||
offset: new AMap.Pixel(-20, -10)
|
||||
});
|
||||
}
|
||||
|
||||
function showPlanInfo(plan) {
|
||||
const distance = formatDistance(plan.distance);
|
||||
const time = formatTime(plan.time);
|
||||
const cost = plan.cost ? plan.cost + ' 元' : '未知';
|
||||
const walkDistance = formatDistance(plan.walking_distance);
|
||||
|
||||
console.log(`
|
||||
总距离: ${distance}
|
||||
预计时间: ${time}
|
||||
票价: ${cost}
|
||||
步行距离: ${walkDistance}
|
||||
`);
|
||||
|
||||
// 显示换乘详情
|
||||
plan.segments.forEach((segment, index) => {
|
||||
if (segment.transit) {
|
||||
const t = segment.transit;
|
||||
console.log(`第${index + 1}段: ${t.name} (${t.on_station.name} → ${t.off_station.name})`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function formatDistance(distance) {
|
||||
if (distance < 1000) {
|
||||
return Math.round(distance) + ' 米';
|
||||
}
|
||||
return (distance / 1000).toFixed(1) + ' 公里';
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const minutes = Math.round((seconds % 3600) / 60);
|
||||
if (hours > 0) {
|
||||
return `${hours} 小时 ${minutes} 分钟`;
|
||||
}
|
||||
return `${minutes} 分钟`;
|
||||
}
|
||||
|
||||
// 使用
|
||||
planTransit([116.379028, 39.865042], [116.527281, 39.950719]);
|
||||
```
|
||||
|
||||
## 显示多个方案
|
||||
|
||||
```javascript
|
||||
transfer.search(start, end, function(status, result) {
|
||||
if (status === 'complete' && result.plans) {
|
||||
// 显示所有方案供用户选择
|
||||
result.plans.forEach((plan, index) => {
|
||||
const info = {
|
||||
index: index + 1,
|
||||
time: formatTime(plan.time),
|
||||
cost: plan.cost + ' 元',
|
||||
transfers: plan.segments.filter(s => s.transit).length - 1 // 换乘次数
|
||||
};
|
||||
console.log(`方案${info.index}: ${info.time}, ${info.cost}, 换乘${info.transfers}次`);
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 清除路线
|
||||
|
||||
```javascript
|
||||
transfer.clear();
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **城市参数必填**: Transfer 必须指定城市参数
|
||||
2. **跨城市**: 不支持跨城市公交规划
|
||||
3. **换乘策略**: 不同策略会返回不同的方案
|
||||
4. **夜班车**: 设置 `nightflag: true` 计算夜班车路线
|
||||
5. **多方案**: 通常会返回多个方案,可供用户选择
|
||||
6. **路径绘制**: 需要分别处理乘车段和步行段
|
||||
|
||||
|
||||
## 3. 拖拽导航
|
||||
|
||||
开启 `showTraffic` 可显示实时路况,部分插件支持拖拽修改路径。
|
||||
|
||||
```javascript
|
||||
const driving = new AMap.Driving({
|
||||
map: map,
|
||||
showTraffic: true, // 显示路况
|
||||
});
|
||||
```
|
||||
Reference in New Issue
Block a user