Vue + iClient for Leaflet实现鼠标点击的交通换乘分析

作者: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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          <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)
        }
      }
    }
  }

    有需要改进的地方,请多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值