<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<title>Title</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
<script type="text/javascript" src="https://blog-static.cnblogs.com/files/simuhunluo/debugout.js"></script>
</head>
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: '*********************',
}
</script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key= *******************">
</script>
<style>
* {
margin: 0;
padding: 0;
}
body,
html,
#container {
width: 100%;
height: 100%;
}
#as {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
}
div>ul>li {
float: left;
/*使用组合选择器定位到第一级ul下一级的li,使其左浮动*/
}
li {
list-style: none;
/*所有的项目都取消标记*/
}
li>ul {
display: none;
/*使用组合选择器定位到li下一级的ul,使其隐藏*/
}
li:hover ul {
/*使用伪类选择器设置悬停在li上面时显示ul*/
display: block;
}
.a {
text-decoration: none;
display: block;
font-size: 15px;
padding: 5px;
text-align: center;
color: yellowgreen;
background-color: gray;
cursor: pointer;
}
.a:hover {
/*使用伪类选择器设置悬停在a上面时修改a的显示样式*/
color: papayawhip;
}
#panel {
position: fixed;
background-color: white;
max-height: 90%;
overflow-y: auto;
top: 10px;
right: 10px;
width: 280px;
}
#panel .amap-call {
background-color: #009cf9;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
#panel .amap-lib-driving {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
overflow: hidden;
}
</style>
<body>
<div id="as">
<ul>
<li>
<a id='t' class="a" onclick="tj()">添加图层</a>
</li>
<li>
<a class="a" onclick="clearMarker()">删除点标记</a>
</li>
<li>
<a class="a">路线规划方式</a>
<ul>
<li><a class="a" onclick="qtz()" style="font-size: 15px" title="先选起点,再选停靠点,最后选终点">起-停-终</a></li>
<li><a class="a" onclick="qzt()" style="font-size: 15px" title="先选择起点和终点,再选停靠点">起-终-停</a></li>
</ul>
</li>
<li>
<a class="a">路线生成</a>
<ul>
<li><a class="a" onclick="dh()" style="font-size: 15px">生成路线</a></li>
</ul>
</li>
</ul>
</div>
<div id="container"></div>
<div id="panel"></div>
<div class="input-card">
<h4>左击获取经纬度:</h4>
<div class="input-item">
<input type="text" readonly="true" id="lnglat">
</div>
</div>
</body>
</html>
<script>
// const defaultData = {
// name: '赵二丫',
// age: 18,
// descript: '婷婷玉立',
// address: '河南省郑州市',
// iphone: '1234567788',
// worker: 'front-end',
// hobby: [
// { name: '动漫' }, { name: '游戏' }
// ]
// }
//添加比例尺和罗盘插件
AMap.plugin(['AMap.Scale', 'AMap.ControlBar', 'AMap.MoveAnimation'],
function () {
map.addControl(new AMap.Scale());
map.addControl(new AMap.ControlBar());
});
//设置主视图
var map = new AMap.Map('container', {
zoom: 11,//级别
pitch: 45,
center: [116.379028, 39.865042],//中心点坐标
});
let markers = [];//用来存放点标注
let info = [];//用来保存点击标注产生的信息窗口
let geojson = new AMap.GeoJSON({
geojson: null,
});
var bugout = new debugout();
//点击地图生成点标记
map.on('click', function (e) {
//console.log(`经度:${e.lnglat.lng},纬度:${e.lnglat.lat}`)
document.getElementById("lnglat").value = e.lnglat.getLng() + ',' + e.lnglat.getLat()
let marker = new AMap.Marker({
draggable: true,
position: e.lnglat,//位置
extData: {//自定义属性
_geoJsonProperties: {
id: markers.length + 1,/*点标记的唯一识别码*/
click: 0,/*点标记的点击次数*/
},
},
});
markers.push(marker);//创建一个点就加进去
geojson.addOverlay(marker);/*将一个点标记放到geojson中转站中*/
saveData(geojson.toGeoJSON());/*将geojson中转站内的标记全部保存到标准geoJSON数据*/
//点击点标记显示打卡次数
marker.on('click', function (e) {/*点击事件*/
let i = ++marker.getExtData()._geoJsonProperties.click;/*在某标签上点击一次对应的click加一次*/
info = new AMap.InfoWindow({
anchor: 'top-center',
content: `<div>${markers.indexOf(marker) + 1}打卡了${i}次</div>`
})
info.open(map, marker.getPosition());
saveData(geojson.toGeoJSON());/*将geojson中转站内的标记全部保存到标准geoJSON数据*/
})
});
//生成轨迹动画
let opts = {
waypoints: [],
}
let start = [];
let end = [];
//路线规划方法起点-停靠点-终点
function qtz() {
geojson.eachOverlay(function (item) {
//遍历geojson得到每一个点的坐标
opts.waypoints.push(item.getPosition());
})
start = opts.waypoints.shift();//删除数组最前面的对象,且返回该对象作为起点
end = opts.waypoints.pop();//删除数组最后面的对象,且返回该对象作为终点
}
//路线规划方法起点-终点-停靠点
function qzt() {
geojson.eachOverlay(function (item) {
//遍历geojson得到每一个地图上点的坐标
opts.waypoints.push(item.getPosition());
})
start = opts.waypoints.shift();//删除数组最前面的对象,且返回该对象作为起点
end = opts.waypoints.shift();//删除目前数组最前面的对象,且返回该对象作为终点
// 这时候opts中的数组对象只剩下中间点了
}
function dh() {
//如果判断到起点为0,则没有选择路线规划方法
if (start.length == 0) {
alert("请先选择路线规划方式!!!!");
}
//调用高德路线规划插件
AMap.plugin('AMap.Driving', function () {
let drivng = new AMap.Driving({
map: map,
panel: "panel",
//驾车测策
policy: AMap.DrivingPolicy.LEAST_TIME,
})
//设置规划路线方法,参数分别为起点,终点,中途点
drivng.search(start, end, opts, function (a, b) {
if (a === 'complete') {
console.log(b.routes[0].steps)
console.log(b.routes[0].steps[0].path[0].Q);
parseRoutes(b.routes[0].steps);
} else {
log.error('获取驾车数据失败:' + b)
}
//console.log(b);
//var lineArr = [];
//console.log(b.routes[0].steps);
//设置路线的样式
//var passedPolyline = new AMap.Polyline({
// map: map,
// strokeColor: "#AF5", //线颜色
// strokeWeight: 6, //线宽
//});
})
})
}
function clearMarker() {
AMap.GeoJSON();//中转站清空,这样下次新生成的点标注就不会把之前中转站的旧数据存入JSON中
map.remove(markers);//移除所有标记
markers = [];//将数组清空
opts = [];
map.remove(info);//打卡信息框删除
localStorage.clear();/*清除所有已经保存的JSON字符串*/
}
map.add(geojson);
if (JSON.stringify(getData()) != '[]') {
//导入数据
geojson.importData(getData());
//恢复旧数据的点击事件
geojson.eachOverlay(function (item) {
item.on('click', function (e) {
let i = ++item.getExtData()._geoJsonProperties.click;/*在某标签上点击一次对应的click加一次*/
let info = new AMap.InfoWindow({
anchor: 'top-center',
content: `<div>${markers.indexOf(marker) + 1}打卡了${i}次</div>`
})
info.open(map, item.getPosition());
saveData(geojson.toGeoJSON());/*将点标签内的新属性转换到标准geoJSON数据*/
});
})
}
//在localstorage中操作数据
function getData() {
if (!localStorage.getItem('geojson')) {
localStorage.setItem('geojson', '[]');/*如果不存在数据则返回js空对象*/
}
return JSON.parse(localStorage.getItem('geojson'));
}
function saveData(data) {/*保存JSON字符串*/
localStorage.setItem('geojson', JSON.stringify(data));/*保存为JSON字符串*/
}
//引入新图层
let ss = new AMap.TileLayer.Traffic({
zIndex: 10,
autoRefresh: true,
interval: 180,
});
//添加移除图层
let f = true;
function tj() {
if (f) {
map.add(ss);
document.querySelector("#t").innerText = '移除图层';
f = false;
} else {
map.remove(ss);
document.querySelector("#t").innerText = '添加图层';
f = true;
}
}
function parseRoutes(steps) {
//var path = {
// //waypoints: [],
//}
let path={
path_:[],
}
console.log('I coming ')
steps.forEach(function (content, index) {
//console.log(index.path);
content.path.forEach(function (content1, index1) {
//console.log(content1);
path.path_.push(content1);
// var position = [content1.Q, content1.R]
// path.push(position);
})
//ints.push(step.path.Q, step.path.R);
//var arrayRoute=new Array();//all points
//console.log("route"+index+"="+route.steps);
//route.steps.forEach(function(index,step){
// console.log("step"+index+"="+step.instruction+",distance="+step.distance+",path="+step.path);
// arrayRoute=arrayRoute.concat(step.path);
//});
//console.log("all pts="+arrayRoute);
});
exportFileJSON(path, 'example.json');
// var path=JSON.stringify(path)
// const blob = new Blob([path], { type: 'text/json' }),
// e = new MouseEvent('click'),
// a = document.createElement('a');
// a.download = filename;
// a.href = window.URL.createObjectURL(blob);
// a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
// a.dispatchEvent(e);
// bugout.log(path)
// bugout.downloadLog()
//console.log(path)
}
const exportFileJSON = (data = [], filename = 'dataJSON.json') => {
data = JSON.stringify(data);
// 导出数据
const blob = new Blob([data], { type: 'text/json' }),
e = new MouseEvent('click'),
a = document.createElement('a');
a.download = filename;
a.href = window.URL.createObjectURL(blob);
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
a.dispatchEvent(e);
}
</script>
在某位大神的基础上改的,具体来源忘了,等找到贴上。使用时需要将*******替换为自己的key。
使用方法:
先清除标记点,然后刷新。刷新在地图上点击几个点,最好大于等于2个,然后点击规划方式。以起-经-终为例子,起点为刚刚在地图上点击的第一个点,终点为点击的最后一个点,经过点为刚刚点击的除去第一个和最后一个点外的所有点。最后点击生成路径。结果以example.json文件保存。
获取的坐标为高德地图下的gps坐标,和真正的gps坐标有个变换。
用C++解析:
文件名:src/read_jeson.cpp
#include <bits/stdc++.h>
#include <json/json.h>
#include <iomanip>
using namespace std;
vector<pair<double,double>> recordGpsPoint;
void read_jeson()
{
ifstream srcFile("../example.json",ios::binary);
// Json::Reader reader;
if(!srcFile.is_open())
{
cout<<"Fail to open example.json"<<endl;
return ;
}
Json::Reader reader;
Json::Value root;
if (reader.parse(srcFile, root))
{
for(int i=0;i<root["path_"].size();i++)
{
double lat=root["path_"][i]["Q"].asDouble();
double lng=root["path_"][i]["R"].asDouble();
recordGpsPoint.push_back(make_pair(lat,lng));
}
}
}
void printGpsPoints()
{
for(auto ws:recordGpsPoint)
{
cout<<setprecision(12)<<ws.first<<" "<<ws.second<<endl;
}
}
int main()
{
read_jeson();
printGpsPoints();
return 0;
}
对应的cmakelists.txt
cmake_minimum_required(VERSION 2.8.3)
project(yyf)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS "-std=c++11")
#-DEIGEN_USE_MKL_ALL")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g")
find_package(PkgConfig REQUIRED)
pkg_check_modules(JSONCPP jsoncpp)
include_directories(${JSONCPP_LIBRARIES})
add_executable(test1 src/read_json.cpp)
target_link_libraries(test1 ${JSONCPP_LIBRARIES} )
使用方法:
cd /build
make
./test