作者:john
聊聊Vue + iClient for Leaflet实现鼠标点击的交通换乘分析,效果展示:
说明
实现该效果由以下几部分组成:
1、鼠标点击取点
2、交通换乘查询
3、乘车路线查询
1、鼠标点击取点
该功能主要是通过leaflet-draw进行描点,且每个点只能选择一次,第二选择的点会覆盖先前的点,功能实现代码如下:
async addPoint (i) {
let _this = this
await this.map.on('click', e => {
let item = [e.latlng.lng, e.latlng.lat]
_this.showPoint(parseInt(i), item)
})
},
showPoint (i, item) {
if (this.listPoint[i].marker) {
this.map.removeLayer(this.listPoint[i].marker)
}
var myIcon = L.icon({
iconUrl: require('../assets/marker-icon.png'),
iconSize: [25],
iconAnchor: [17, 40]
})
var startIcon = L.icon({
iconUrl: require('../assets/start_trans.png'),
iconSize: [25],
iconAnchor: [17, 40]
})
var endIcon = L.icon({
iconUrl: require('../assets/end_trans.png'),
iconSize: [25],
iconAnchor: [17, 40]
})
var varmarker = null
if (i === 0) {
varmarker = L.marker([item[1], item[0]], { icon: startIcon }).bindPopup(this.listPoint[i].markName)
} else if (i === 1) {
varmarker = L.marker([item[1], item[0]], { icon: endIcon }).bindPopup(this.listPoint[i].markName)
} else {
varmarker = L.marker([item[1], item[0]], { icon: myIcon }).bindPopup(this.listPoint[i].markName)
}
this.listPoint[i].point = [item[1], item[0]]
this.listPoint[i].marker = varmarker
this.listPoint[i].marker.addTo(this.map)
this.map.off('click')
},
2、交通换乘查询
交通换乘查询,显示默认交通路线,功能实现代码如下:
trafficTransferAnalystService() {
if (!this.listPoint || !this.listPoint[0].marker || !this.listPoint[1].marker) {
alert('查询前请选择出发点或者目的地')
return ;
}
this.routeFeatureGroup = L.featureGroup().addTo(this.map)
this.paths = [{"x": this.listPoint[0].point[1],"y": this.listPoint[0].point[0]},{"x": this.listPoint[1].point[1],"y": this.listPoint[1].point[0]}]
// this.paths = [26, 180];
this.routLines = []
var params = new SuperMap.TransferSolutionParameters({
solutionCount: 6,
transferTactic: "LESS_TIME",
walkingRatio: 10,
points: this.paths
});
var _this = this
L.supermap.trafficTransferAnalystService(this.baseTraffSrc)
.analysisTransferSolution(params, function (serviceResult) {
// 获取服务端返回的结果
var result = serviceResult.result;
if (result) {
_this.resRoutLine = result.solutionItems
var items = result.defaultGuide.items;
for (var itemIndex = 0, itemLen = items.length; itemIndex < itemLen; itemIndex++) {
var geometry = items[itemIndex].route;
_this.routeFeatureLayers = _this.routeFeatureGroup.addLayer(L.geoJSON(L.Util.toGeoJSON(geometry)).addTo(_this.map));
_this.isFindLine = true
_this.getRoutLinData(result.solutionItems)
}
}
});
},
3、乘车路线查询
选择不同的乘车线路,功能实现代码如下:
getLine(item) {
let lines = []
// 拼接TransferPathParameters参数transferLines
if(item) {
for(var i = 0; i < item.length; i++) {
lines.push(item[i].lineItems[0])
}
}
let _this = this
var params = new SuperMap.TransferPathParameters({
// 起始点坐标
points: this.paths,
// 当前换乘路线,包含路线ID、起止点等
transferLines: lines
});
// 向服务端发送请求并获取数据
L.supermap.trafficTransferAnalystService(this.baseTraffSrc)
.analysisTransferPath(params, function (serviceResult) {
// 获取返回的路线的详细信息
var result = serviceResult.result;
if (result) {
let items = result.items;
let allDistance = 0
let allPassStopCount = 0
let layers = []
for (var itemIndex = 0, itemLen = items.length; itemIndex < itemLen; itemIndex++) {
var geometry = items[itemIndex].route;
_this.routeFeatureLayers = L.geoJSON(L.Util.toGeoJSON(geometry))
layers.push(L.geoJSON(L.Util.toGeoJSON(geometry)))
if (items[itemIndex].distance != items[itemIndex].time) {
allPassStopCount += items[itemIndex].passStopCount
} else {
allDistance += items[itemIndex].distance
}
_this.isFindLine = true
}
allDistance = Math.round(allDistance)
_this.routLines.push({
allDistance: allDistance,
allPassStopCount: allPassStopCount,
layers: layers
})
}
});
},
到此,我们的功能已经全部实现了,线面是该Vue组件中的完整代码。
完整代码
页面部分:
<div style="height: 100%; width: 100%">
<div class="findTSPPathsProcess">
<span v-for="(item, index) in listPoint" :key="index">
<span v-if="index === 0">
起点:<button v-on:click="addPoint(index)">选择</button>
<br>
</span>
<span v-else>
终点:<button v-on:click="addPoint(index)">选择</button></span>
</span>
<button v-on:click="trafficTransferAnalystService">查询</button>
</div>
<div v-if="isFindLine" class="routerLine">
<span v-for="(item,index) in resRoutLine" :key="index">路线{{index + 1}}:
<span style="cursor: pointer" v-on:click="showRouteLine(index)" v-if="routLines[index].allPassStopCount">{{"共" + routLines[index].allPassStopCount + "站, "}}</span>
<span style="cursor: pointer" v-on:click="showRouteLine(index)" v-if="routLines[index].allDistance">{{"步行: " + routLines[index].allDistance + "米"}}</span><br>
<span style="cursor: pointer" v-for="(it, ind) in item.linesItems" :key="ind" v-on:click="showRouteLine(index)">
<span v-for="i in it.lineItems">
<span v-if="ind == 0">{{i.lineName}}</span>
<span v-else> -> {{i.lineName}}</span>
</span>
</span>
<br>
</span>
</div>
</div>
样式部分:
.findTSPPathsProcess{
z-index: 999;
position: absolute;
top: 100px;
left: 300px;
width: 150px;
border-radius: 5px;
background-color: #d3dce6;
opacity: 0.9;
padding-left: 20px;
}
.routerLine{
z-index: 999;
position: absolute;
top: 40px;
right: 80px;
width: 400px;
border-radius: 5px;
background-color: #d3dce6;
opacity: 0.9;
padding-left: 20px;
}
数据部分:
props: ['map'],
data () {
return {
listPoint: [
{
id: 0,
marker: null,
markName: '起点',
point: []
},
{
id: 1,
marker: null,
markName: '终点',
point: []
}
],
routLines: [],
paths: null,
isFindLine: false,
routeFeatureGroup: null,
routeFeatureLayers: null,
resRoutLine: null,
baseMapSource: 'http://127.0.0.1:8091/iserver/services/map-changchun/rest/maps/长春市区图',
baseTraffSrc: 'http://127.0.0.1:8091/iserver/services/traffictransferanalyst-sample/restjsr/traffictransferanalyst/Traffic-Changchun'
}
methods部分:
methods: {
async addPoint (i) {
let _this = this
await this.map.on('click', e => {
let item = [e.latlng.lng, e.latlng.lat]
_this.showPoint(parseInt(i), item)
})
},
showPoint (i, item) {
if (this.listPoint[i].marker) {
this.map.removeLayer(this.listPoint[i].marker)
}
var myIcon = L.icon({
iconUrl: require('../assets/marker-icon.png'),
iconSize: [25],
iconAnchor: [17, 40]
})
var startIcon = L.icon({
iconUrl: require('../assets/start_trans.png'),
iconSize: [25],
iconAnchor: [17, 40]
})
var endIcon = L.icon({
iconUrl: require('../assets/end_trans.png'),
iconSize: [25],
iconAnchor: [17, 40]
})
var varmarker = null
if (i === 0) {
varmarker = L.marker([item[1], item[0]], { icon: startIcon }).bindPopup(this.listPoint[i].markName)
} else if (i === 1) {
varmarker = L.marker([item[1], item[0]], { icon: endIcon }).bindPopup(this.listPoint[i].markName)
} else {
varmarker = L.marker([item[1], item[0]], { icon: myIcon }).bindPopup(this.listPoint[i].markName)
}
this.listPoint[i].point = [item[1], item[0]]
this.listPoint[i].marker = varmarker
this.listPoint[i].marker.addTo(this.map)
this.map.off('click')
},
showRouteLine(index) {
if (this.routeFeatureGroup) {
this.routeFeatureGroup.clearLayers()
}
for (var i = 0; i < this.routLines[index].layers.length; i++) {
this.routeFeatureLayers = this.routeFeatureGroup.addLayer(this.routLines[index].layers[i].addTo(this.map));
}
},
getLine(item) {
let lines = []
// 拼接TransferPathParameters参数transferLines
if(item) {
for(var i = 0; i < item.length; i++) {
lines.push(item[i].lineItems[0])
}
}
let _this = this
var params = new SuperMap.TransferPathParameters({
// 起始点坐标
points: this.paths,
// 当前换乘路线,包含路线ID、起止点等
transferLines: lines
});
// 向服务端发送请求并获取数据
L.supermap.trafficTransferAnalystService(this.baseTraffSrc)
.analysisTransferPath(params, function (serviceResult) {
// 获取返回的路线的详细信息
var result = serviceResult.result;
if (result) {
let items = result.items;
let allDistance = 0
let allPassStopCount = 0
let layers = []
for (var itemIndex = 0, itemLen = items.length; itemIndex < itemLen; itemIndex++) {
var geometry = items[itemIndex].route;
_this.routeFeatureLayers = L.geoJSON(L.Util.toGeoJSON(geometry))
layers.push(L.geoJSON(L.Util.toGeoJSON(geometry)))
if (items[itemIndex].distance != items[itemIndex].time) {
allPassStopCount += items[itemIndex].passStopCount
} else {
allDistance += items[itemIndex].distance
}
_this.isFindLine = true
}
allDistance = Math.round(allDistance)
_this.routLines.push({
allDistance: allDistance,
allPassStopCount: allPassStopCount,
layers: layers
})
}
});
},
trafficTransferAnalystService() {
if (!this.listPoint || !this.listPoint[0].marker || !this.listPoint[1].marker) {
alert('查询前请选择出发点或者目的地')
return ;
}
this.routeFeatureGroup = L.featureGroup().addTo(this.map)
this.paths = [{"x": this.listPoint[0].point[1],"y": this.listPoint[0].point[0]},{"x": this.listPoint[1].point[1],"y": this.listPoint[1].point[0]}]
// this.paths = [26, 180];
this.routLines = []
var params = new SuperMap.TransferSolutionParameters({
solutionCount: 6,
transferTactic: "LESS_TIME",
walkingRatio: 10,
points: this.paths
});
var _this = this
L.supermap.trafficTransferAnalystService(this.baseTraffSrc)
.analysisTransferSolution(params, function (serviceResult) {
// 获取服务端返回的结果
var result = serviceResult.result;
if (result) {
_this.resRoutLine = result.solutionItems
var items = result.defaultGuide.items;
for (var itemIndex = 0, itemLen = items.length; itemIndex < itemLen; itemIndex++) {
var geometry = items[itemIndex].route;
_this.routeFeatureLayers = _this.routeFeatureGroup.addLayer(L.geoJSON(L.Util.toGeoJSON(geometry)).addTo(_this.map));
_this.isFindLine = true
_this.getRoutLinData(result.solutionItems)
}
}
});
},
getRoutLinData(item) {
if (item) {
for (let i = 0; i < item.length; i++) {
this.getLine(item[i].linesItems)
}
}
}
}
L.Util.toGeoJSON(geometry)).addTo(_this.map));
_this.isFindLine = true
_this.getRoutLinData(result.solutionItems)
}
}
});
},
getRoutLinData(item) {
if (item) {
for (let i = 0; i < item.length; i++) {
this.getLine(item[i].linesItems)
}
}
}
}
有需要改进的地方,请多指正。