高德地图实现点击特定省份高亮某条高速公路并且标出该条高速公路上的服务区

高德地图实现点击特定省份高亮某条高速公路并且标出该条高速公路上的服务区

需求背景:在高德地图上实现点击高亮安徽省境内的任一条高速公路且需要展示出沿途的服务区

效果图:

在这里插入图片描述

准备

1. 成为高德地图开发者并创建 key

先注册成为高德开放平台开发者,并申请 web 平台(JS API)的 key 和安全密钥(这一步不多做叙述,详细看高德官网)

提示:2021年12月02日以后申请的 key 需要配合你的安全密钥一起使用。

2. 引入高德地图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
    <script type="text/javascript">
      window._AMapSecurityConfig = {
        securityJsCode: "您的高德安全密钥",
      };
    </script>
    <script src="https://webapi.amap.com/maps?v=2.0&key=7c6bc75bf40b761c056521cc4434f6cd&plugin=AMap.GeoJSON,AMap.Geocoder,AMap.PlaceSearch"></script>
    <script src="https://webapi.amap.com/loca?v=2.0.0&key=您的高德key"></script>
    <style>
      html,
      body,
      #map {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }

      .amap-logo {
        display: none !important;
      }

      .amap-copyright {
        display: none !important;
      }

      .custom-input-card {
        width: 18rem;
      }

      .custom-input-card .btn:last-child {
        margin-left: 1rem;
      }

      .content-window-card {
        position: relative;
        width: 23rem;
        padding: 0.75rem 0 0 1.25rem;
        box-shadow: none;
        bottom: 0;
        left: 0;
      }

      .content-window-card p {
        height: 2rem;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      let map = new AMap.Map("map", {
        zoom: 8,
        center: [117.227267, 31.420567],
        mapStyle: "amap://styles/8694fc8103d0cbe15eb70b8308cd4171",
        viewMode: "3D",
        pitch: 50,
        fitView: true,
        labelzIndex: 111,
      });

      var distProvince = new AMap.DistrictLayer.Province({
        zIndex: 10, //设置图层层级
        zooms: [2, 15], //设置图层显示范围
        adcode: "340000", //设置行政区 adcode
        depth: 0, //设置数据显示层级,0:显示国家面,1:显示省级,当国家为中国时设置depth为2的可以显示市一级
      });

      // 设置行政区图层样式
      distProvince.setStyles({
        "stroke-width": 2, //描边线宽
        "province-stroke": "#ff714d", //描边颜色
        fill: "rgba(0,0,0,0.3)",
      });

      map.add(distProvince);
    </script>
  </body>
</html>

image.png

3. 利用overpass-turbo获取安徽省境内高速、服务区的geojson

打开overpass-turbo网站,输入查询语句(由于数据有点大,我把高速公路和服务区的查询分两次查询和导出)

image.png

3.1 查询高速公路数据

输入查询语句

[out:json];
area["name"="安徽省"]->.a;
(
  way["highway"="motorway"](area.a);
  way["highway"="motorway_link"](area.a);
);
out body;
>;
out skel qt;
3.2 查询服务区数据

输入查询语句

[out:json];
area["ISO3166-2"="CN-AH"]->.a;
(
  way(area.a)[highway=services];
);
(._;>;);
out body;

什么?你不会写这个语句!没关系,有万能的chatgpt,就像这样,拷贝下来粘贴到overpass-turbo语句输入框然后执行

image.png

至此我们已经得到高速公路(highway.geojson)和高速服务区(services.geojson)两个geojson文件了,可以愉快的写代码了

image.png

实现

1. 给高德地图添加点击事件

map.on('click', function (ev) {})

2. 利用高德逆向地理编码能力获取点击位置道路信息

map.on('click', function (ev) {
    let geocoder = new AMap.Geocoder({
        city: '340000', //设为安徽,默认:“全国”
        radius: 1000, //范围,默认:500
    })
    geocoder.getAddress([ev.lnglat.lng, ev.lnglat.lat], function (status, res) {
        if (status === 'complete' && res.regeocode) {
            console.log('道路信息:', res.regeocode.formattedAddress);
            if (res.regeocode.formattedAddress.includes('高速')) {
              // 过滤高速编号
              const regex = /[A-Z]\d+(?=[\u4e00-\u9fa5]+高速)/ // 匹配一个大写字母后跟一个或多个数字,但要求其后必须紧跟着中文字符和"高速"字符
              const result = res.regeocode.formattedAddress.match(regex)

              // 匹配高速名称
              const highwayRegex = /([\u4e00-\u9fa5]+)(高速)/
              const match = res.regeocode.formattedAddress.match(highwayRegex)
              const highwayName = match[1] + match[2]
              console.log('匹配到的高速名称:', highwayName)
            }
        }
    })
})

3. 加载高速公路geojson并匹配上面获取到的高速编号

// 加载高速geojson
fetch('./highway.geojson').then((response) => {
  return response.json()
}).then((geoJSON) => {
  // 匹配高速编号并且是LineString的要素后添加到相应的数组
  const desiredHighways = []
  for (let i = 0; i < geoJSON.features.length; i++) {
    if (geoJSON.features[i].properties.ref) {
      let wayRefs = geoJSON.features[i].properties.ref.split(';')
      for (let j = 0; j < wayRefs.length; j++) {
        if (wayRefs[j] == result[0] && geoJSON.features[i].geometry.type == 'LineString') {
          // console.log(wayRefs[j]);
          desiredHighways.push(geoJSON.features[i])
        }
      }
    }
  }

4. 添加高亮线

// 添加高亮线
for (let i = 0; i < desiredHighways.length; i++) {
    //创建 Polyline 实例
    let polyline = new AMap.Polyline({
      path: desiredHighways[i].geometry.coordinates,
      isOutline: false,
      outlineColor: '#ffeeff',
      borderWeight: 2,
      strokeColor: '#1677ff',
      strokeOpacity: 1,
      strokeWeight: 3,
      // 折线样式还支持 'dashed'
      strokeStyle: 'solid',
      // strokeStyle是dashed时有效
      // strokeDasharray: [10, 5],
      zIndex: 49,
      lineJoin: 'round',
      lineCap: 'round',
    })
    map.add(polyline)
}

至此实现了点击高亮某一条高速公路

image.png

5. 加载服务区geojson,匹配上面获取到的高速公路名称后向地图上添加服务区图形

// 加载高速服务区
fetch('./services.geojson').then((response) => {
  return response.json()
}).then((geoJSON) => {
  let geojson = new AMap.GeoJSON({
    geoJSON: geoJSON,
    getPolygon: function (json, lnglats) {
      if (json.properties.extraData.formattedAddress.includes(highwayName)) {
        let polygon = new AMap.Polygon({
          path: lnglats,
          strokeColor: '#ffd666',
          strokeWeight: 6,
          strokeOpacity: 0.4,
          fillOpacity: 0.4,
          fillColor: '#95de64',
          zIndex: 50,
          extData: json.properties,
        })
        polygon.on('click', function (e) {
          console.log('click', this.getExtData())
          polygonClick(e, this.getExtData())
        })
        return polygon
      } else {
        return []
      }
    },
    // getPolygon: function () {
    //   return [];
    // },
    getMarker: function (geojson, lnglats) {
      return []
    },
  })
  // 添加geojson图层
  map.add(geojson)
})

image.png

image.png

注意

1. 坐标转换

由于overpass-turbo上面导出的geojson坐标是坐标是WGS84,而高德是GCJ02,所以需要坐标系转换

2. 处理服务区geojson

直接导出的geojson服务区信息没有那么全,所以我使用了高德批量逆向地理编码逐个查询了geojson中的服务区详细信息,然后再将原本的geojson和从高德api获取的数据进行合并处理

完整代码

demo完整源码已经上传到github有需要的可以自取

https://github.com/jinfei-lab/amap-highway-picker

  • 33
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
首先,使用高德地图 API 获取地图,并添加 marker。点击 marker 后,获取该地点的经纬度,然后调用 echarts 的 geo 组件,绘制迁徙图。 以下是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>高德地图+echarts迁徙图</title> <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=你的高德地图APIkey"></script> <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0/echarts.min.js"></script> <style> #map { width: 100%; height: 500px; } </style> </head> <body> <div id="map"></div> <script type="text/javascript"> // 初始化地图 var map = new AMap.Map('map', { center: [116.397428, 39.90923], zoom: 10 }); // 添加 marker,并绑定点击事件 var marker = new AMap.Marker({ position: [116.397428, 39.90923], map: map, title: '北京市', clickable: true }); marker.on('click', function() { // 获取经纬度 var lnglat = marker.getPosition(); // 绘制迁徙图 var myChart = echarts.init(document.getElementById('map')); myChart.setOption({ geo: { map: 'china' }, series: [{ type: 'lines', coordinateSystem: 'geo', polyline: { // 迁徙线的坐标点 coords: [ [lnglat.lng, lnglat.lat], [120.15, 30.28] ] } }] }); }); </script> </body> </html> ``` 上面的示例代码中,我们使用了 AMap.Marker 类来添加 marker,并通过 marker.on('click') 绑定了点击事件。在点击事件中,我们获取了 marker 的经纬度,然后调用 echarts 绘制迁徙图。 当然,以上只是一个简单的示例,实际应用中还需要根据需求进行一些调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值