2016-03-24 2 views
0

У меня есть слой улиц geojson, которые выделяются при затушевывании.функция выделения с щелчком в mapbox gl

Моя цель - выделить отдельные улицы красным цветом с помощью события click. Одновременно можно выделять только одну улицу, и она должна оставаться подсвеченной до тех пор, пока не будет нажата другая улица.

Любая идея относительно того, что нужно добавить к следующему коду?

<!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> 

ответ

1

<!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" (удалить ложное двоеточие внутри кавычек)

1

@Lucas особенности при() должна быть Остаточным методом? Его толстая кишка бросила ошибку, но это не помогло ему выбрать сегмент дороги, по крайней мере, в 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>