导航功能优化
parent
165ba0fec3
commit
280630586b
|
|
@ -15,6 +15,7 @@
|
|||
"@turf/turf": "^6.3.0",
|
||||
"ajv": "^8.6.2",
|
||||
"axios": "^0.21.1",
|
||||
"coordtransform": "^2.1.2",
|
||||
"core-js": "^3.6.4",
|
||||
"echarts": "^3.8.5",
|
||||
"echarts-gl": "^2.0.2",
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
"disableOther": true
|
||||
},
|
||||
"openAtStart": [
|
||||
{
|
||||
"name": "POI查询",
|
||||
"uri": "widgets/queryBaiduPOI/widget.js"
|
||||
},
|
||||
{
|
||||
"name": "右上角工具栏",
|
||||
"uri": "widgets/toolBarRight/widget.js",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -48,6 +48,11 @@
|
|||
<div class="quick-button" @click="showHistoryLabel">历史标注</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<div class="search-container">
|
||||
<search :globalmap="globalmap"></search>
|
||||
</div>
|
||||
|
||||
<!-- 地图 -->
|
||||
<Map style="width:100%;height:100vh;" :url="configUrl" :widgetUrl="widgetUrl" @onload="onMapload" />
|
||||
|
|
@ -239,7 +244,8 @@ import rightclicksetting from './widget/rightclick.vue';
|
|||
import socketDiaBox from './widget/socketdiabox.vue';
|
||||
import userpoint from './widget/userpoint.vue'
|
||||
import drag from '../../utils/draged';
|
||||
import editorbox from './widget/editorbox'
|
||||
import editorbox from './widget/editorbox';
|
||||
import search from './widget/search'
|
||||
|
||||
let BASE_URL = process.env.VUE_APP_BASE_API
|
||||
export default {
|
||||
|
|
@ -267,7 +273,8 @@ export default {
|
|||
socketDiaBox,
|
||||
taskDelivery,
|
||||
userpoint,
|
||||
editorbox
|
||||
editorbox,
|
||||
search
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
@ -727,6 +734,7 @@ export default {
|
|||
// 地图构造完成回调
|
||||
onMapload(map) {
|
||||
let _self = this;
|
||||
window.globalmap = map;
|
||||
this.globalmap = map;
|
||||
|
||||
map.on(this.mars3d.EventType.click,this.onMapClick)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,455 @@
|
|||
import axios from "axios";
|
||||
import { gcj02towgs84, wgs84togcj02 } from 'coordtransform'
|
||||
import * as turf from '@turf/turf'
|
||||
import { Url } from "../../../utils/urlFormat";
|
||||
import { getMethodCommon } from "../../../api/common";
|
||||
import { parse } from "../lib/handleGeojson";
|
||||
import { deepClone } from "../../../utils";
|
||||
const urls = new Url()
|
||||
const GD_URL = "https://restapi.amap.com/v5/direction/driving"
|
||||
const GD_KEY = "6af6a87038f44c8c793aa70331f2b7ca"
|
||||
|
||||
//路线的图层
|
||||
let pathGraphicLayers = null
|
||||
|
||||
//导航寻路
|
||||
export const getRouterFunc = (params, method = 'all') => {
|
||||
/**
|
||||
* method:
|
||||
* 当为 postgis时,仅仅使用postgis导航
|
||||
* 默认:all :高德 + postgis
|
||||
* gaode:高德
|
||||
*/
|
||||
let { startlng, startlat, endlng, endlat } = params
|
||||
|
||||
if (method == 'postgis') {
|
||||
//使用gpostgis进行导航
|
||||
return new Promise((resolve, reject) => {
|
||||
let postgisParams = {
|
||||
startlng: startlng,
|
||||
startlat: startlat,
|
||||
endlng: endlng,
|
||||
endlat: endlat,
|
||||
areaname: localStorage.getItem("areaName"),
|
||||
}
|
||||
getRouterByPostGis(postgisParams).then(geojson => {
|
||||
//postGisCoordinates:postgis返回的geojson取出坐标数组
|
||||
let postGisCoordinates = getOneLineCoordinatesFromGeometry(geojson)
|
||||
let startRouterLngLat = postGisCoordinates[0]
|
||||
let endRouterLngLat = postGisCoordinates.at(-1)
|
||||
let resObject = {
|
||||
allCoordinates: postGisCoordinates, //全部线路的合集
|
||||
postGisRoute: postGisCoordinates, // postgis线路
|
||||
gdRoute: [],
|
||||
startLngLat: [startlng, startlat], // 起点
|
||||
endLngLat: [endlng, endlat], //终点
|
||||
startRouterLngLat: startRouterLngLat, // 路线查询结果的起点
|
||||
endRouterLngLat: endRouterLngLat, //路线查询结果的终点
|
||||
}
|
||||
let simpleRoute = getMinimumRoute(resObject)
|
||||
resolve(simpleRoute)
|
||||
})
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
}
|
||||
if (method == 'all') {
|
||||
// 先用高德进行导航
|
||||
return new Promise((resolve, reject) => {
|
||||
getRouterByGD(params).then(solution => {
|
||||
// solution 为多条线路的数组,现在先用第一条线路 solution.path[0]
|
||||
let gdRoute = solution.path[0]
|
||||
let postgisParams = {
|
||||
startlng: gdRoute.endCoordinates[0],
|
||||
startlat: gdRoute.endCoordinates[1],
|
||||
endlng: endlng,
|
||||
endlat: endlat,
|
||||
areaname: localStorage.getItem("areaName"),
|
||||
}
|
||||
//使用gpostgis求出剩下的路线
|
||||
getRouterByPostGis(postgisParams).then(geojson => {
|
||||
//postGisCoordinates:postgis返回的geojson取出坐标数组
|
||||
let postGisCoordinates = getOneLineCoordinatesFromGeometry(geojson)
|
||||
// 高德返回的第一条线路的坐标数组
|
||||
let path_gd = gdRoute.path_polyline
|
||||
//合并高德和postgis的路线
|
||||
let allCoordinates = path_gd.concat(postGisCoordinates)
|
||||
//导航线路的起点和终点
|
||||
let startRouterLngLat = allCoordinates[0]
|
||||
let endRouterLngLat = allCoordinates.at(-1)
|
||||
let resObject = {
|
||||
allCoordinates: allCoordinates, //全部线路
|
||||
gdRoute: path_gd, //高德的线路
|
||||
postGisRoute: postGisCoordinates, // postgis的线路
|
||||
startLngLat: [startlng, startlat], // 起点
|
||||
endLngLat: [endlng, endlat], //终点
|
||||
startRouterLngLat: startRouterLngLat, // 路线查询结果的起点
|
||||
endRouterLngLat: endRouterLngLat, //路线查询结果的终点
|
||||
}
|
||||
let simpleRoute = getMinimumRoute(resObject)
|
||||
resolve(simpleRoute)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
let sql = `
|
||||
create table if not exists comment(
|
||||
id int(11) unsigned not null auto_increment comment "主键ID",
|
||||
pins_id int(11) not null comment "帖子ID",
|
||||
content varchar(250) not null comment "评论内容",
|
||||
create_time datatime not null comment "评论时间",
|
||||
like int(11) not null default 0 comment "点赞数量",
|
||||
state tinyint(1) not null default 1 comment "状态:1:正常;0:删除;",
|
||||
primary key(id)
|
||||
)ENGINE=innodb DEFAULT CHARSET=utf8
|
||||
`
|
||||
|
||||
if(method == 'gaode'){
|
||||
return new Promise((resolve, reject) => {
|
||||
getRouterByGD(params).then(solution => {
|
||||
// solution 为多条线路的数组,现在先用第一条线路 solution.path[0]
|
||||
let gdRoute = solution.path[0]
|
||||
let postgisParams = {
|
||||
startlng: gdRoute.endCoordinates[0],
|
||||
startlat: gdRoute.endCoordinates[1],
|
||||
endlng: endlng,
|
||||
endlat: endlat,
|
||||
areaname: localStorage.getItem("areaName"),
|
||||
}
|
||||
//使用gpostgis求出剩下的路线
|
||||
getRouterByPostGis(postgisParams).then(geojson => {
|
||||
//postGisCoordinates:postgis返回的geojson取出坐标数组
|
||||
let postGisCoordinates = getOneLineCoordinatesFromGeometry(geojson)
|
||||
// 高德返回的第一条线路的坐标数组
|
||||
let path_gd = gdRoute.path_polyline
|
||||
//合并高德和postgis的路线
|
||||
let allCoordinates = path_gd.concat(postGisCoordinates)
|
||||
//导航线路的起点和终点
|
||||
let startRouterLngLat = allCoordinates[0]
|
||||
let endRouterLngLat = allCoordinates.at(-1)
|
||||
let resObject = {
|
||||
allCoordinates: allCoordinates, //全部线路
|
||||
gdRoute: path_gd, //高德的线路
|
||||
postGisRoute: postGisCoordinates, // postgis的线路
|
||||
startLngLat: [startlng, startlat], // 起点
|
||||
endLngLat: [endlng, endlat], //终点
|
||||
startRouterLngLat: startRouterLngLat, // 路线查询结果的起点
|
||||
endRouterLngLat: endRouterLngLat, //路线查询结果的终点
|
||||
}
|
||||
let simpleRoute = getMinimumRoute(resObject)
|
||||
resolve(simpleRoute)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//高德路线导航
|
||||
export const getRouterByGD = (params) => {
|
||||
/**
|
||||
* type:Object
|
||||
*/
|
||||
let { startlng, startlat, endlng, endlat } = params
|
||||
//wgs84转火星坐标系
|
||||
var gcj02StartLngLat = wgs84togcj02(startlng, startlat);
|
||||
var gcj02EndLngLat = wgs84togcj02(endlng, endlat);
|
||||
let gd_params = {
|
||||
origin: `${gcj02StartLngLat[0]},${gcj02StartLngLat[1]}`,
|
||||
destination: `${gcj02EndLngLat[0]},${gcj02EndLngLat[1]}`,
|
||||
show_fields: 'polyline',
|
||||
key: GD_KEY
|
||||
}
|
||||
let new_url = urls.getUrl(GD_URL, gd_params)
|
||||
return new Promise((resolve, reject) => {
|
||||
axios({
|
||||
method: "get",
|
||||
url: new_url,
|
||||
}).then((res) => {
|
||||
if (res.status === 200) {
|
||||
let solution = []
|
||||
//处理数据
|
||||
res.data.route.paths.map(path => {
|
||||
let route_len = path.distance
|
||||
let path_polyline = path.steps.map(step => {
|
||||
return step.polyline
|
||||
})
|
||||
let router_path_str = [] //暂时存放 ['117.927498,35.263264']
|
||||
path_polyline.forEach(polyline => {
|
||||
let step = polyline.split(';')
|
||||
router_path_str = router_path_str.concat(step)
|
||||
});
|
||||
// 去掉重复点
|
||||
let unique_router_path_str = [...new Set(router_path_str)]
|
||||
// 坐标转数组
|
||||
let unique_router_path = unique_router_path_str.map(path_str => {
|
||||
let lng_lat_list = path_str.split(',')
|
||||
//高德坐标系转wgs84坐标系
|
||||
var wgs84Coordinate = gcj02towgs84(...lng_lat_list);
|
||||
return wgs84Coordinate
|
||||
})
|
||||
//高德导航的起点和终点
|
||||
let startCoordinates = unique_router_path[0]
|
||||
let endCoordinates = unique_router_path.at(-1)
|
||||
// 高德地图返回的结果:方案一。长度,线
|
||||
solution.push(
|
||||
{
|
||||
route_len: route_len,
|
||||
path_polyline: unique_router_path,
|
||||
startCoordinates: startCoordinates,
|
||||
endCoordinates: endCoordinates
|
||||
}
|
||||
)
|
||||
})
|
||||
let result = {
|
||||
routerCount: parseInt(res.data.count),
|
||||
path: solution
|
||||
}
|
||||
resolve(result)
|
||||
} else {
|
||||
reject(res)
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//使用postgres + postgis寻路
|
||||
export const getRouterByPostGis = (params) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
getMethodCommon("/FirePrevention/LoadRoad", params).then((res) => {
|
||||
if (res.data.length > 0) {
|
||||
console.log('res.data::: ', res.data);
|
||||
let LineString = res.data[0].route;
|
||||
if (LineString == null || LineString == "null") {
|
||||
//没有找到路线,返回空
|
||||
console.log('PostGIS未找到合适了路线')
|
||||
resolve(parse(null))
|
||||
} else {
|
||||
resolve(parse(LineString))
|
||||
}
|
||||
} else {
|
||||
console.log('PostGIS未找到合适了路线')
|
||||
resolve(parse(null))
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log('PostGIS寻路算法服务端错误')
|
||||
resolve(parse(null))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 绘制线路
|
||||
export const drawRouterFunc = (pathObject) => {
|
||||
let { allCoordinates, startLngLat, endLngLat, startRouterLngLat, endRouterLngLat, gdRoute, postGisRoute } = pathObject
|
||||
// 添加graphic
|
||||
if (pathGraphicLayers == null) {
|
||||
pathGraphicLayers = new mars3d.layer.GraphicLayer();
|
||||
window.globalmap.addLayer(pathGraphicLayers);
|
||||
|
||||
} else {
|
||||
pathGraphicLayers.clear();
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
console.log('allCoordinates.length::: ', allCoordinates.length);
|
||||
if (allCoordinates.length == 2) {
|
||||
//只绘制开头到结尾的路线的路段
|
||||
let endPathGraphic = drawPolylineDashEntity([startLngLat, endLngLat], 'YELLOW')
|
||||
pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
} else {
|
||||
// 导航数据路段
|
||||
let pathGraphic = drawLineFlowEntity(allCoordinates, 'CYAN')
|
||||
let gdPathGraphic = drawLineFlowEntity(gdRoute, 'YELLOW')
|
||||
let postgisPathGraphic = drawLineFlowEntity(postGisRoute, 'YELLOW')
|
||||
|
||||
//开始的路段
|
||||
let startPathGraphic = drawPolylineDashEntity([startLngLat, startRouterLngLat], 'YELLOW')
|
||||
|
||||
//结尾的路段
|
||||
let endPathGraphic = drawPolylineDashEntity([endRouterLngLat, endLngLat], 'YELLOW')
|
||||
|
||||
pathGraphicLayers.addGraphic(pathGraphic);
|
||||
// pathGraphicLayers.addGraphic(gdPathGraphic);
|
||||
// pathGraphicLayers.addGraphic(postgisPathGraphic);
|
||||
pathGraphicLayers.addGraphic(startPathGraphic);
|
||||
pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成虚线实体
|
||||
const drawPolylineDashEntity = (positions, cesiumColor) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: 5,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.PolylineDash,
|
||||
materialOptions: {
|
||||
color: Cesium.Color[cesiumColor],
|
||||
dashLength: 8.0,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
// 生成动态线实体
|
||||
const drawLineFlowEntity = (positions, cesiumColor) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: 5,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.LineFlow,
|
||||
materialOptions: {
|
||||
color: Cesium.Color[cesiumColor],
|
||||
image: "/img/line-colour.png",
|
||||
speed: 10,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//删除路线
|
||||
export const clearRouterFunc = () => {
|
||||
if (pathGraphicLayers == null) {
|
||||
return false
|
||||
} else {
|
||||
pathGraphicLayers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//计算最近路线
|
||||
const getMinimumRoute = (pathObject) => {
|
||||
//备份Object
|
||||
let pathObjectClone = deepClone(pathObject)
|
||||
let { allCoordinates, startLngLat, endLngLat, startRouterLngLat, endRouterLngLat, gdRoute, postGisRoute } = pathObjectClone
|
||||
// 当只有一个点时(终点),说明高德地图和postgis都未查询到线路,直接返回两点
|
||||
if (allCoordinates.length <= 1) {
|
||||
pathObjectClone.allCoordinates = [startLngLat, endLngLat]
|
||||
return pathObjectClone
|
||||
}
|
||||
//当postgis寻路时,计算两条线路的重叠之处
|
||||
if (postGisRoute.length && gdRoute.length) {
|
||||
//实例化turf标准格式
|
||||
let gdRouteLine = turf.lineString(gdRoute);
|
||||
let postGisRouteLine = turf.lineString(postGisRoute);
|
||||
//获取postgis和高德寻路的所有交点
|
||||
let intersectsGeojson = turf.lineIntersect(gdRouteLine, postGisRouteLine);
|
||||
let intersectsCoordinates = getMultPointCoordinatesFromGeoJson(intersectsGeojson)
|
||||
//如果相交点大于1,说明路线有重复部分
|
||||
if (intersectsCoordinates.length > 1) {
|
||||
let lastIntersectsCoordinates = intersectsCoordinates[0]
|
||||
let [slicedGdCoordinates, slicedPostGisCoordinates] = sliceByPoint(startRouterLngLat, gdRouteLine, endRouterLngLat, postGisRoute, lastIntersectsCoordinates)
|
||||
allCoordinates = slicedGdCoordinates.concat(slicedPostGisCoordinates)
|
||||
//处理后的结果赋值给pathObjectClone
|
||||
pathObjectClone.gdRoute = slicedGdCoordinates
|
||||
pathObjectClone.postGisRoute = slicedPostGisCoordinates
|
||||
gdRouteLine = turf.lineString(slicedGdCoordinates);
|
||||
postGisRouteLine = turf.lineString(slicedPostGisCoordinates);
|
||||
}
|
||||
// 阈值计算重复路线,去除重复线路
|
||||
let overlapping = turf.lineOverlap(gdRouteLine, postGisRouteLine, { tolerance: 0.1 });
|
||||
console.log('overlapping::: ', overlapping);
|
||||
if (overlapping.features.length) {
|
||||
let lastOverlapPoint = overlapping.features.at(-1).geometry.coordinates[0]
|
||||
let [overlapGdCoordinates, overlapPostGisCoordinates] = sliceByPoint(startRouterLngLat, gdRouteLine, endRouterLngLat, postGisRoute, lastOverlapPoint)
|
||||
allCoordinates = overlapGdCoordinates.concat(overlapPostGisCoordinates)
|
||||
}
|
||||
|
||||
}
|
||||
// 转成turf标准线格式
|
||||
let allRouteLine = turf.lineString(allCoordinates);
|
||||
// 转成turf标准点格式
|
||||
let startLngLatPoint = turf.point(startLngLat);
|
||||
let startRouterLngLatPoint = turf.point(startRouterLngLat);
|
||||
let endLngLatPoint = turf.point(endLngLat);
|
||||
let endRouterLngLatPoint = turf.point(endRouterLngLat);
|
||||
//获取终点到导航线最近的点
|
||||
let snappedGeojson = turf.nearestPointOnLine(allRouteLine, endLngLatPoint, { units: 'miles' });
|
||||
let snappedCoordinates = getOnePointCoordinatesFromGeoJson(snappedGeojson)
|
||||
// 根据最近的点截取路线,取前半部分
|
||||
let slicedGeojson = turf.lineSlice(startRouterLngLat, turf.point(snappedCoordinates), allRouteLine);
|
||||
let slicedCoordinates = getOnePointCoordinatesFromGeoJson(slicedGeojson)
|
||||
//把截取后的路线赋值给pathObjectClone
|
||||
pathObjectClone.allCoordinates = slicedCoordinates
|
||||
//计算出发地到目的地的图上距离(直线)
|
||||
let distanceStartToEnd = turf.distance(startLngLatPoint, endLngLatPoint)
|
||||
//计算出发点到出发导航路线出发点的步行距离
|
||||
let distanceStartToStartRoute = turf.distance(startLngLatPoint, startRouterLngLatPoint)
|
||||
//计算终点到出发导航路线终点的步行距离
|
||||
let distanceEndToEndRoute = turf.distance(endLngLatPoint, endRouterLngLatPoint)
|
||||
//如果出发点与目的地的实际距离小于步行的距离,直接使用出发点到目的地的距离,导航此时不适用
|
||||
if (distanceStartToEnd < (distanceStartToStartRoute + distanceEndToEndRoute)) {
|
||||
pathObjectClone.allCoordinates = [startLngLat, endLngLat]
|
||||
}
|
||||
//把终点到导航终点改为距离线路的最近的的点
|
||||
pathObjectClone.endRouterLngLat = snappedCoordinates
|
||||
return pathObjectClone
|
||||
}
|
||||
|
||||
const sliceByPoint = (line1Start, line1, line2End, line2, point) => {
|
||||
/**
|
||||
* 根据点point把line1的前半部分和line2的后半部分进行拼接
|
||||
* line1Start:line1的起始点 [lng.lat]
|
||||
* line2End:line2 的终止点 [lng,lat]
|
||||
*/
|
||||
//拷贝line2的坐标数组进行倒序排列
|
||||
let line2Copy = [...line2]
|
||||
line2Copy.reverse()
|
||||
let line2CopyReverseLineString = turf.lineString(line2Copy);
|
||||
// 根据point截取路线,line1取前半部分
|
||||
// 根据point截取路线,line2取后半部分
|
||||
//然后将两部分拼接,让line1路线从第一个交点处转向line2路段
|
||||
let slicedLine1Geojson = turf.lineSlice(line1Start, turf.point(point), line1);
|
||||
let slicedLine1Coordinates = getOnePointCoordinatesFromGeoJson(slicedLine1Geojson)
|
||||
let slicedLine2Geojson = turf.lineSlice(line2End, turf.point(point), line2CopyReverseLineString);
|
||||
let slicedLine2Coordinates = getOnePointCoordinatesFromGeoJson(slicedLine2Geojson)
|
||||
slicedLine2Coordinates.reverse()
|
||||
return [slicedLine1Coordinates, slicedLine2Coordinates]
|
||||
}
|
||||
|
||||
|
||||
// 坐标转geoJson
|
||||
const comLineStringGeoJson = (coordinates) => {
|
||||
return {
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"coordinates": coordinates,
|
||||
"type": "LineString"
|
||||
}
|
||||
}
|
||||
}
|
||||
// 从一条线的geometry中获取坐标
|
||||
const getOneLineCoordinatesFromGeometry = (geometry) => {
|
||||
let coordinates = geometry.coordinates
|
||||
console.log('geometry::: ', geometry);
|
||||
let list = []
|
||||
if (geometry.type == "MultiLineString") {
|
||||
coordinates.map(coord => {
|
||||
list = list.concat(coord)
|
||||
})
|
||||
} else if (geometry.type == 'LineString') {
|
||||
list = list.concat(geometry.coordinates)
|
||||
} else {
|
||||
list = []
|
||||
}
|
||||
return list
|
||||
|
||||
}
|
||||
//从一个点的geojson中返回坐标点
|
||||
const getOnePointCoordinatesFromGeoJson = (geojson) => {
|
||||
return geojson.geometry.coordinates
|
||||
}
|
||||
//从多个点的geojson中返回坐标点
|
||||
const getMultPointCoordinatesFromGeoJson = (geojson) => {
|
||||
console.log('geojson::: ', geojson);
|
||||
return geojson.features.map(feature => {
|
||||
return feature.geometry.coordinates
|
||||
})
|
||||
|
||||
}
|
||||
|
|
@ -29,7 +29,8 @@ import { parse } from '../lib/handleGeojson.js';
|
|||
import {transformGCJ2WGS} from '../lib/GCJ02ToWGS84.js';
|
||||
import {transformWGSGCJ2} from '../lib/WGS84ToGCJ02.js';
|
||||
import * as turf from '@turf/turf'
|
||||
import AppConfig from '../../../../public/config/app.json'
|
||||
import AppConfig from '../../../../public/config/app.json';
|
||||
import { getRouterFunc, drawRouterFunc, clearRouterFunc } from '../lib/routePath'
|
||||
export default {
|
||||
name: 'routebox',
|
||||
props:['globalmap','routeInfo'],
|
||||
|
|
@ -124,44 +125,61 @@ import AppConfig from '../../../../public/config/app.json'
|
|||
})
|
||||
this.pathPointGraphicLayer.addGraphic(graphic) // 还可以另
|
||||
},
|
||||
getRoutePath(){ // 获取路线数据
|
||||
if(this.startPoint&&this.endPoint){
|
||||
let startCoor = this.startPoint.split(",");
|
||||
let endCoor = this.endPoint.split(",");
|
||||
axios({
|
||||
method: 'get',
|
||||
url: AppConfig[localStorage.getItem('areaName')].baseUrl+'/api/FirePrevention/LoadRoad',
|
||||
params: {
|
||||
startlng: parseFloat(startCoor[0]),
|
||||
startlat: parseFloat(startCoor[1]),
|
||||
endlng: parseFloat(endCoor[0]),
|
||||
endlat: parseFloat(endCoor[1]),
|
||||
}
|
||||
}).then(data => {
|
||||
if (data.data.data.length > 0) {
|
||||
|
||||
let LineString = data.data.data[0].route;
|
||||
|
||||
if(LineString == null || LineString == "null"){
|
||||
this.getGaoDePath();
|
||||
}else{
|
||||
let _this = this;
|
||||
setTimeout(function () {
|
||||
console.log("linestring",LineString)
|
||||
_this.drawRoutePath(parse(LineString));
|
||||
// designPath(parse(LineString));
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
getRoutePath() {
|
||||
// 获取路线数据
|
||||
let startCoor = this.startPoint.split(",")
|
||||
let endCoor = this.endPoint.split(",");
|
||||
let params = {
|
||||
startlng: parseFloat(startCoor[0]),
|
||||
startlat: parseFloat(startCoor[1]),
|
||||
endlng: parseFloat(endCoor[0]),
|
||||
endlat: parseFloat(endCoor[1]),
|
||||
areaname: localStorage.getItem("areaName"),
|
||||
};
|
||||
getRouterFunc(params,).then(res => {
|
||||
drawRouterFunc(res)
|
||||
}).catch(err => {
|
||||
clearRouterFunc()
|
||||
})
|
||||
},
|
||||
// getRoutePath(){ // 获取路线数据
|
||||
// if(this.startPoint&&this.endPoint){
|
||||
// let startCoor = this.startPoint.split(",");
|
||||
// let endCoor = this.endPoint.split(",");
|
||||
// axios({
|
||||
// method: 'get',
|
||||
// url: AppConfig[localStorage.getItem('areaName')].baseUrl+'/api/FirePrevention/LoadRoad',
|
||||
// params: {
|
||||
// startlng: parseFloat(startCoor[0]),
|
||||
// startlat: parseFloat(startCoor[1]),
|
||||
// endlng: parseFloat(endCoor[0]),
|
||||
// endlat: parseFloat(endCoor[1]),
|
||||
// }
|
||||
// }).then(data => {
|
||||
// if (data.data.data.length > 0) {
|
||||
|
||||
// let LineString = data.data.data[0].route;
|
||||
|
||||
// if(LineString == null || LineString == "null"){
|
||||
// this.getGaoDePath();
|
||||
// }else{
|
||||
// let _this = this;
|
||||
// setTimeout(function () {
|
||||
// console.log("linestring",LineString)
|
||||
// _this.drawRoutePath(parse(LineString));
|
||||
// // designPath(parse(LineString));
|
||||
// }, 1000)
|
||||
// }
|
||||
|
||||
// }else{
|
||||
|
||||
// }
|
||||
// })
|
||||
|
||||
// }else{
|
||||
|
||||
// }
|
||||
// },
|
||||
getGaoDePath(){
|
||||
let startLngLatArr = this.startPoint.split(",");
|
||||
let endLngLatArr = this.endPoint.split(",");
|
||||
|
|
@ -336,6 +354,7 @@ import AppConfig from '../../../../public/config/app.json'
|
|||
_this.addContourLine(graphic.toGeoJSON({outline:true}).geometry.coordinates);
|
||||
},2000)
|
||||
},
|
||||
|
||||
addContourLine(coordinates) {
|
||||
this.contourLine = new mars3d.thing.ContourLine({
|
||||
shadingType:"slope",
|
||||
|
|
@ -408,6 +427,8 @@ import AppConfig from '../../../../public/config/app.json'
|
|||
this.contourLine.removeArea(this.contourLineAreaObj);
|
||||
}
|
||||
|
||||
clearRouterFunc();
|
||||
|
||||
this.startPoint = null;
|
||||
this.endPoint = null;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
<template>
|
||||
<div class="map-querybar">
|
||||
<input
|
||||
style="border: 0px; outline: none"
|
||||
type="search"
|
||||
class="querybar-ssk1"
|
||||
placeholder="搜索地点"
|
||||
autocomplete="off"
|
||||
v-model="parameters.keywords"
|
||||
/>
|
||||
<div class="querybar-ssk2" @click="handlerSearchPOL">
|
||||
<i class="fa fa-search fa-2x"></i>
|
||||
搜索
|
||||
</div>
|
||||
<div class="map-querybar-result" v-show="showSearchListWindow">
|
||||
<div class="search-top">
|
||||
<span></span>
|
||||
<i class="fa fa-close fa-2x" @click="hiddenSearchListWindow"></i>
|
||||
</div>
|
||||
<div
|
||||
class="search-contain"
|
||||
ref="searchContain"
|
||||
@scroll="handleScroll($event)"
|
||||
v-show="searchResultList.length"
|
||||
>
|
||||
<div
|
||||
class="map-querybar-result-i"
|
||||
v-for="(item, index) in searchResultList"
|
||||
v-bind:key="index"
|
||||
>
|
||||
<div class="i-top">
|
||||
<h3>{{ item.name }}</h3>
|
||||
<div @click="handlerFlyToPoint(item)">查看</div>
|
||||
</div>
|
||||
<div class="i-bottom">
|
||||
<span>{{ item.address }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="list-none" v-show="!hasNextPage">~~没有更多了~~</span>
|
||||
</div>
|
||||
<img
|
||||
class="none"
|
||||
v-show="!searchResultList.length"
|
||||
src="/img/none.png"
|
||||
alt=""
|
||||
/>
|
||||
<span v-show="!searchResultList.length">没有搜索到相关的地点</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const GD_POL_KEY = "ee7f561fae9249aeb971bcc661083438";
|
||||
// const GD_POL_KEY = "6346891d57dee39c07b16d9942868fbc";
|
||||
const GD_SEARCH_URL = "https://restapi.amap.com/v5/place/text?";
|
||||
import { gcj02towgs84 } from 'coordtransform'
|
||||
import axios from "axios";
|
||||
export default {
|
||||
name: "search",
|
||||
props:['globalmap'],
|
||||
data() {
|
||||
return {
|
||||
parameters: {
|
||||
key: GD_POL_KEY,
|
||||
keywords: "",
|
||||
region: "371325",
|
||||
citylimit: true,
|
||||
page_num: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
searchResultList: [],
|
||||
debounceTime: undefined,
|
||||
hasNextPage: true,
|
||||
showSearchListWindow: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 查询
|
||||
handlerSearchPOL() {
|
||||
if (!this.parameters.keywords) {
|
||||
this.$message({
|
||||
type: "warning",
|
||||
message: "请输入搜索关键词",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.parameters.page_num = 1;
|
||||
this.resetScroll("searchContain");
|
||||
this.getPOLData();
|
||||
},
|
||||
getPOLData() {
|
||||
|
||||
axios({
|
||||
method: "get",
|
||||
url: `${GD_SEARCH_URL}`,
|
||||
params: {
|
||||
...this.parameters,
|
||||
},
|
||||
}).then(
|
||||
(res) => {
|
||||
if (res.status == 200 && res.data && res.data.pois) {
|
||||
this.count = res.data.count;
|
||||
let resLength = res.data.pois.length;
|
||||
if (this.parameters.page_num == 1) {
|
||||
this.searchResultList = res.data.pois;
|
||||
this.hasNextPage = resLength >= this.parameters.page_size;
|
||||
} else {
|
||||
if (resLength) {
|
||||
this.searchResultList = this.searchResultList.concat(
|
||||
res.data.pois
|
||||
);
|
||||
this.hasNextPage = resLength >= this.parameters.page_size;
|
||||
} else {
|
||||
this.hasNextPage = false;
|
||||
}
|
||||
}
|
||||
this.showSearchListWindow = true;
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: `搜索接口错误:${res.data.info}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: "搜索接口错误",
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
//搜索滚动条回到顶部
|
||||
resetScroll(ref_contain) {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs[ref_contain]) {
|
||||
// 滚动元素跳转到顶部
|
||||
this.$refs[ref_contain].scrollTop = 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 滚动时,加载下一页数据
|
||||
handleScroll(e) {
|
||||
let _this = this;
|
||||
if (this.debounceTime) {
|
||||
clearTimeout(this.debounceTime);
|
||||
}
|
||||
this.debounceTime = setTimeout(function () {
|
||||
let el = e.target;
|
||||
if (el.scrollTop + el.clientHeight >= el.scrollHeight) {
|
||||
//控制页数
|
||||
let page = _this.parameters.page_num;
|
||||
if (_this.hasNextPage) {
|
||||
page++;
|
||||
_this.parameters.page_num = page;
|
||||
_this.getPOLData();
|
||||
}
|
||||
}
|
||||
this.debounceTime = undefined;
|
||||
}, 100);
|
||||
},
|
||||
hiddenSearchListWindow() {
|
||||
this.showSearchListWindow = false;
|
||||
this.parameters.page_num = 1
|
||||
this.parameters.keywords = ''
|
||||
this.searchResultList = []
|
||||
this.hasNextPage = true
|
||||
},
|
||||
handlerFlyToPoint(e){
|
||||
console.log(this.globalmap)
|
||||
// TODO 根据返回的坐标格式做跳转
|
||||
let lngLat = e.location.split(',').map(e=>parseFloat(e))
|
||||
var wgs84Coordinate = gcj02towgs84(...lngLat);
|
||||
this.globalmap.flyToPoint(wgs84Coordinate,{radius:400,"pitch":-90});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.map-querybar {
|
||||
top: 150px;
|
||||
left: 575px;
|
||||
position: absolute;
|
||||
flex-wrap: wrap;
|
||||
width: 340px;
|
||||
height: 47px;
|
||||
background-image: url(/img/sousuokuang.png);
|
||||
background-size: 100% 100%;
|
||||
z-index: 1;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.querybar-ssk1 {
|
||||
background-color: transparent;
|
||||
width: 230px;
|
||||
height: 47px;
|
||||
font-size: 14px;
|
||||
color: #ffffff;
|
||||
padding: 0 20px 0 20px;
|
||||
}
|
||||
|
||||
.querybar-ssk2 {
|
||||
border-color: #082b2b;
|
||||
color: #ff9811;
|
||||
width: 110px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.querybar-ssk2 .fa {
|
||||
margin-right: 10px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.map-querybar-result {
|
||||
width: 340px;
|
||||
height: 500px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px 20px 10px;
|
||||
position: absolute;
|
||||
top: 53px;
|
||||
left: 0;
|
||||
background-color: rgba(8, 43, 43, 0.7);
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.map-querybar-result .none {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: 50px auto 10px;
|
||||
}
|
||||
.map-querybar-result >span{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.map-querybar-result .search-top {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #d2d2d2;
|
||||
}
|
||||
.search-contain {
|
||||
width: 100%;
|
||||
height: 102%;
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: none; /* firefox */
|
||||
-ms-overflow-style: none; /* IE 10+ */
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
display: none; /* Chrome Safari */
|
||||
}
|
||||
.map-querybar-result-i {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.map-querybar-result-i .i-top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.map-querybar-result-i .i-top h3 {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.map-querybar-result-i .i-top div {
|
||||
width: 50px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
background-color: #ff9811;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.map-querybar-result-i .i-bottom {
|
||||
width: 100%;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dotted #d2d2d2;
|
||||
}
|
||||
|
||||
.map-querybar-result-i .i-bottom span {
|
||||
font-size: 12px;
|
||||
color: #d2d2d2;
|
||||
}
|
||||
.list-none{
|
||||
text-align: center;
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue