首次单击Mapbox Map后,GeoJson LineString仅加载一次

时间:2017-10-17 07:53:33

标签: javascript mapbox geojson mapbox-gl-js

我正在尝试在已加载的点和右键单击的标记点之间添加线条。我已经提到了Mapbox的例子,直到这个阶段。我第一次执行操作时只得到一行。我想要每个操作的行。操作顺序如下:

  1. 左键单击加载的点(从geojson加载的点)
  2. 右键单击地图上的任意位置。 这应该在右键单击点处创建一个标记,并将其与之前左侧的clciked点连接。
  3. 我很感激一些帮助。这是我在SO的第一篇文章。请原谅我的任何错误。提前谢谢。

    
    
    mapboxgl.accessToken = 'pk.eyJ1Ijoic3ViaGFtYmFuc3BocyIsImEiOiJjajc4czNxazEyaWE5MnFwaWllNzdwdDdkIn0.6AZVCVM-wGgh5cykoII9kA';
    var map = new mapboxgl.Map({
      container: 'map', // container id
      style: 'mapbox://styles/mapbox/streets-v9',
      center: [-80.486052, 37.830348], // starting position
      zoom: 5 // starting zoom
    });
    
    
    map.on('load', () => {
    
      map.addSource("earthquakes", {
        type: "geojson",
    
        data: "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
      });
    
      map.addLayer({
        id: "markers",
        type: "circle",
        source: "earthquakes",
        paint: {
          "circle-color": "#11b4da",
          "circle-radius": 4,
          "circle-stroke-width": 1,
          "circle-stroke-color": "#fff"
        }
      });
    });
    
    map.on('mouseenter', 'markers', () => {
      map.getCanvas().style.cursor = 'pointer'
    });
    
    map.on('mouseleave', 'markers', () => {
      map.getCanvas().style.cursor = 'crosshair'
    });
    
    let ground
    let obs
    map.on('contextmenu', (f) => {
      ground = [f.lngLat.lng, f.lngLat.lat]
      var geojson = {
        "type": "FeatureCollection",
        "features": [{
          "type": "Feature",
          "geometry": {
            "type": "Point",
            "coordinates": f.lngLat
          }
        }]
      };
      // add markers to map
      geojson.features.forEach(function(marker) {
        // create a DOM element for the marker
        var el = document.createElement('div');
        el.className = 'marker';
        el.addEventListener('click', function() {
          window.alert(f.lngLat);
        })
        new mapboxgl.Marker(el)
          .setLngLat(marker.geometry.coordinates)
          .addTo(map);
    
        map.addLayer({
          "id": "route",
          "type": "line",
          "source": {
            "type": "geojson",
            "data": {
              "type": "FeatureCollection",
              "features": [{
                "type": "Feature",
                "geometry": {
                  "type": "LineString",
                  "coordinates": [
                    ground, obs
                  ]
                }
              }, ]
            }
          },
          "layout": {
            "line-join": "round",
            "line-cap": "round"
          },
          "paint": {
            "line-color": "#888",
            "line-width": 3,
            "line-dasharray": [0.1, 1.8]
          }
    
        });
    
      });
    
    })
    
    
    map.on('click', 'markers', (e) => {
      obs = [e.lngLat.lng, e.lngLat.lat]
    });
    
    body {
      margin: 0;
      padding: 0;
    }
    
    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
    
    .marker {
      display: block;
      border: none;
      border-radius: 50%;
      cursor: pointer;
      padding: 0;
      background-color: rgba(5, 4, 244, 0.82);
      height: 10px;
      width: 10px
    }
    
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset='utf-8' />
      <title></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.40.1/mapbox-gl.js'></script>
      <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.40.1/mapbox-gl.css' rel='stylesheet' />
    
    </head>
    
    <body>
    
      <div id='map'></div>
    
    </body>
    
    </html>
    &#13;
    &#13;
    &#13;

1 个答案:

答案 0 :(得分:1)

而不是重新创建一个新的图层&amp;每当用户添加标记时,您应该创建一次行图层及其源,然后只更新基础数据:

mapboxgl.accessToken = 'pk.eyJ1Ijoic3ViaGFtYmFuc3BocyIsImEiOiJjajc4czNxazEyaWE5MnFwaWllNzdwdDdkIn0.6AZVCVM-wGgh5cykoII9kA';
var map = new mapboxgl.Map({
  container: 'map', // container id
  style: 'mapbox://styles/mapbox/streets-v9',
  center: [-80.486052, 37.830348], // starting position
  zoom: 5 // starting zoom
});


map.on('load', () => {

  map.addSource("earthquakes", {
    type: "geojson",
    data: "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
  });

  map.addLayer({
    id: "markers",
    type: "circle",
    source: "earthquakes",
    paint: {
      "circle-color": "#11b4da",
      "circle-radius": 4,
      "circle-stroke-width": 1,
      "circle-stroke-color": "#fff"
    }
  });
  
  map.addSource('line-source', {
    type: 'geojson',
    data: {
      type: 'FeatureCollection',
      features: []
    }
  });
  map.addLayer({
    type: 'line',
    source: 'line-source',
    id: 'line-layer'
  });
});

map.on('mouseenter', 'markers', () => {
  map.getCanvas().style.cursor = 'pointer'
});

map.on('mouseleave', 'markers', () => {
  map.getCanvas().style.cursor = 'crosshair'
});

let ground;
let obs;

map.on('contextmenu', (f) => {
  ground = [f.lngLat.lng, f.lngLat.lat];
  
  map.getSource('line-source').setData({
    type: 'FeatureCollection',
    features: [{
      type: 'Feature',
      geometry: {
        type: 'LineString',
        coordinates: [ground, obs]
      }
    }]
  })
});


map.on('click', 'markers', (e) => {
  obs = [e.lngLat.lng, e.lngLat.lat];
});
body {
  margin: 0;
  padding: 0;
}

#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.marker {
  display: block;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
  background-color: rgba(5, 4, 244, 0.82);
  height: 10px;
  width: 10px
}
<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8' />
  <title></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.40.1/mapbox-gl.js'></script>
  <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.40.1/mapbox-gl.css' rel='stylesheet' />

</head>

<body>

  <div id='map'></div>

</body>

</html>

我简化了你的代码片段,但你应该得到它的要点。