在地图框gl中单击高亮显示特征

highlight feature with click in mapbox gl

本文关键字:高亮 显示 特征 单击 地图 gl      更新时间:2023-09-26

我有一个geojson街道层,当鼠标悬停在上面时,这些街道会高亮显示。

我现在的目标是通过点击事件突出显示各个街道的红色。一次只能高亮显示一条街道,并且在单击另一条街道之前应保持高亮显示。

有什么想法需要添加到以下代码中吗?

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>HTML markers from geoJSON url</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.css' rel='stylesheet'/>
<style>
  body { margin:0; padding:0; }
  #map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/dark-v8',
    center: [37.625224, 55.744537,],
    zoom: 13
});
map.on('style.load', function () {
    map.addSource('streets', {
        "type": "geojson",
        "data": "https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson"
    });


    map.addLayer({
        "id": "m_streets",
        "type": "line",
        "source": "streets",
        "interactive": true,
        "layout": {},
        "paint": {
            "line-color": "#627BC1",
            "line-opacity": 0.0,
            "line-width": 2.5
        }
    });
    map.addLayer({
        "id": "route-hover",
        "type": "line",
        "source": "streets",
        "layout": {},
        "paint": {
            "line-color": "#f48024",
            "line-opacity": 0.9,
            "line-width": 2.5
        },
        "filter": ["==", "rd_name", ""]
    });
    map.addLayer({
    "id" : "street_toggle",
    "source": "streets",
    "type": "line",
    "layout": {"line-join": "round",
              "line-cap": "round"},
    "paint": {
        "line-color": "#FF0000",
        "line-opacity": 0.9,
        "line-width:": 3.5
      }
     });
    map.on('mousemove', function(e) {
        map.featuresAt(e.point, {
            radius: 5,
            layer: ["m_streets"]
        }, function (err, features) {
            if (!err && features.length) {
                map.setFilter('route-hover', ['==', 'rd_name', features[0].properties.rd_name]);
            } else {
                map.setFilter('route-hover', ['==', 'rd_name', '']);
            }
        });
    });
    map.on('click', function(e) {
        map.featuresAt(e.point, {
            radius: 5,
            layer: ["street_toggle"]
        }, function (err, features) {
            if (!err && features.length) {
                map.setFilter('street_toggle', ['==', 'rd_name', features[0].properties.rd_name]);
            } else {
                map.setFilter('street_toggle', ['==', 'rd_name', '']);
            }
        });
    });

});

   //.addTo(map);

</script>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8' />
  <title>HTML markers from geoJSON url</title>
  <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
  <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script>
  <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.css' rel='stylesheet' />
  <style>
    body {
      margin: 0;
      padding: 0;
    }
    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
</head>
<body>
  <div id='map'></div>
  <script>
    mapboxgl.accessToken = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
    var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/dark-v8',
      center: [37.625224, 55.744537, ],
      zoom: 13
    });
    map.on('style.load', function() {
      map.addSource('streets', {
        "type": "geojson",
        "data": "https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson"
      });

      map.addLayer({
        "id": "m_streets",
        "type": "line",
        "source": "streets",
        "interactive": true,
        "layout": {},
        "paint": {
          "line-color": "#627BC1",
          "line-opacity": 0.0,
          "line-width": 2.5
        }
      });
      map.addLayer({
        "id": "route-hover",
        "type": "line",
        "source": "streets",
        "layout": {},
        "paint": {
          "line-color": "#f48024",
          "line-opacity": 0.9,
          "line-width": 2.5
        },
        "filter": ["==", "rd_name", ""]
      });
      map.addLayer({
        "id": "street_toggle",
        "source": "streets",
        "type": "line",
        "layout": {
          "line-join": "round",
          "line-cap": "round"
        },
        "paint": {
          "line-color": "#FF0000",
          "line-opacity": 0.9,
          "line-width:": 3.5
        }
      });
      map.on('mousemove', function(e) {
        map.featuresAt(e.point, {
          radius: 5,
          layer: ["m_streets"]
        }, function(err, features) {
          if (!err && features.length) {
            map.setFilter('route-hover', ['==', 'rd_name', features[0].properties.rd_name]);
          } else {
            map.setFilter('route-hover', ['==', 'rd_name', '']);
          }
        });
      });
      map.on('click', function(e) {
        map.featuresAt(e.point, {
          radius: 5,
          layer: ["street_toggle"]
        }, function(err, features) {
          if (!err && features.length) {
            map.setFilter('street_toggle', ['==', 'rd_name', features[0].properties.rd_name]);
          } else {
            map.setFilter('street_toggle', ['==', 'rd_name', '']);
          }
        });
      });
    });
     //.addTo(map);
  </script>
</body>
</html>

如果您在运行代码时查看控制台输出,您应该会看到以下错误消息:

layers.street_toggle.paint.line-width:: unknown property "line-width:"

由于此错误,street_toggle层没有添加到地图中,单击交互也不起作用。

要解决此问题,请将"line-width:"键更改为"line-width"(删除引号中的伪冒号)

@Lucas features At()必须是折旧方法吗?他的冒号确实抛出了一个错误,但这对他选择路段没有帮助,至少在v0.16,对吧?我使用queryRenderedFeatures()

注意:我真的希望这个方法有一个可选的半径参数-你真的必须精确地点击直线

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset='utf-8' />
    <title>HTML markers from geoJSON url</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.16.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.16.0/mapbox-gl.css' rel='stylesheet'/>
    <style>
    body { margin:0; padding:0; }
    #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
    </head>
    <body>
    <div id='map'></div>
    <script>
    mapboxgl.accessToken = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
    var map = new mapboxgl.Map({
         container: 'map',
         style: 'mapbox://styles/mapbox/dark-v8',
         center: [37.625224, 55.744537,],
         zoom: 13
    });
    map.on('style.load', function () {
        map.addSource('streets', {
        "type": "geojson",
        "data": "https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson"
        });
    map.addLayer({
        "id": "m_streets",
        "type": "line",
        "source": "streets",
        "interactive": true,
        "layout": {},
        "paint": {
            "line-color": "red",
            // "line-opacity": 0.0,
           "line-width": 2.5
        }
    });
    map.on('click', function(e) {
        var features = map.queryRenderedFeatures(e.point, { layers: ['m_streets'] });
        if (!features.length) {
            return;
        }
        if (typeof map.getLayer('selectedRoad') !== "undefined" ){         
            map.removeLayer('selectedRoad')
            map.removeSource('selectedRoad');   
        }
        var feature = features[0];
        //I think you could add the vector tile feature to the map, but I'm more familiar with JSON
        console.log(feature.toJSON());
        map.addSource('selectedRoad', {
            "type":"geojson",
            "data": feature.toJSON()
        });
        map.addLayer({
            "id": "selectedRoad",
            "type": "line",
            "source": "selectedRoad",
            "layout": {
                "line-join": "round",
                "line-cap": "round"
            },
            "paint": {
                "line-color": "yellow",
                "line-width": 8
            }
        });
    });
    });
    </script>
    </body>
    </html>