【问题标题】:how to different markers for different data set in mapbox如何在mapbox中为不同的数据集设置不同的标记
【发布时间】:2021-03-17 16:46:59
【问题描述】:

我正在使用带有 react 的地图框 api,我从后端获得了两种数据集,一种是自行车的停车点,另一种是发生事故的地方,我想用不同的标记显示这两种数据集/mapbox中的图标,我该怎么做?

目前显示单个数据集我正在使用下面的代码。

import React, { useState, useEffect, useRef } from "react";
import { useDispatch, useSelector } from 'react-redux';
import mapboxgl from 'mapbox-gl';
import {getBikeInfo, mapDetails} from  './features/counter/getInfo/getDetails.js'
<link href="https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.css" rel="stylesheet"></link>


function App() {
  const dispatch = useDispatch();
  const [dataLoaded, setDataLoaded] = useState(false);
  const dataToDisplay = useSelector(mapDetails);
  mapboxgl.accessToken = 'pk.eyJ1IjoidmloYW5nMTYiLCJhIjoiY2ttOHowc2ZhMWN2OTJvcXJ0dGpiY21pNyJ9.hK5Wxwby89E7tKWoBoY5bg';
  const mapContainer = useRef(null);
  let styles = {
    'display' : 'none'
  }
  useEffect(() => {
   // dispatch(getBikeInfo())
    var map = new mapboxgl.Map({
      container: mapContainer.current,
      style: 'mapbox://styles/mapbox/light-v10',
      center: [-96, 37.8],
      zoom: 3
    });

    map.on('load', function () {
      // Add an image to use as a custom marker
      map.loadImage(
        'https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png',
        function (error, image) {
          if (error) throw error;
          map.addImage('custom-marker', image);
          // Add a GeoJSON source with 2 points
          map.addSource('points', {
            'type': 'geojson',
            'data': {
              'type': 'FeatureCollection',
              'features': dataToDisplay //list of all coordinates along require data 
            }
          });

          // Add a symbol layer
          map.addLayer({
            'id': 'points',
            'type': 'symbol',
            'source': 'points',
            'layout': {
              'icon-image': 'custom-marker',
              // get the title name from the source's "title" property
              'text-field': ['get', 'title'],
              'text-font': [
                'Open Sans Semibold',
                'Arial Unicode MS Bold'
              ],
              'text-offset': [0, 1.25],
              'text-anchor': 'top'
            }
          });
        }
      );
    });
    setDataLoaded(true);
  }, [dataToDisplay]);
  
  useEffect(() => {
    dispatch(getBikeInfo())
  },[])

  return (
    <div className="district-map-wrapper" style={dataLoaded ? undefined : {display: 'none'}}>
            <div id="districtDetailMap" className="map">
                <div style={{ height: "100%" }} ref={mapContainer}>

                </div>
            </div>
        </div>
   
  );
}

export default App;

以下是要填充的示例数据

type: "Feature",
          geometry: {
            type: "Point",
        coordinates: [
           -74.04281705617905,
          40.71458403535893,
         
        ]
      },
      properties: {
        title: 'some field'
      }

解决方案: 根据@tylerban 的回答,我已经像这样更新了我的代码:

map.on('load', function () {
      // Add an image to use as a custom marker
      loadDataFromPara( dataToDisplay, 'https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png', 'bikeLocation', 'bikePoints', 'bike-marker')
      loadDataFromPara( collisionInfo, marker, 'collisionLocation', 'collisionPoints', 'collision-marker')

    });
    setDataLoaded(true);
  function loadDataFromPara( data, image1, sourceName, layerName, imageMarker ){
      map.loadImage(
        image1,
        function (error, image) {
          if (error) throw error;
          map.addImage(imageMarker, image);
          // Add a GeoJSON source with 2 points
          map.addSource(sourceName, {
            'type': 'geojson',
            'data': {
              'type': 'FeatureCollection',
              'features': data
            }
          });

          // Add a symbol layer
          map.addLayer({
            'id': layerName,
            'type': 'symbol',
            'source': sourceName,
            'icon-allow-overlap': true,
            'layout': {
              'icon-image': imageMarker,
              // get the title name from the source's "title" property
              'text-field': ['get', 'title'],
              'icon-allow-overlap': true,
              'text-font': [
                'Open Sans Semibold',
                'Arial Unicode MS Bold'
              ],
              'text-offset': [0, 1.25],
              'text-anchor': 'top'
            }
          });


         
        }
      );
    }

【问题讨论】:

    标签: mapbox mapbox-gl-js mapbox-gl mapbox-marker


    【解决方案1】:

    自行车停车点和事故地点是否包含在同一个源(数据集)中,或者它们是您添加到地图中的两个不同的源和图层?

    如果自行车停放和事故包含在同一来源中,您可以使用data driven styling in Mapbox 根据数据中的字段分配图标。因此,如果您在源中有一个字段可用于确定某个点是否代表自行车停车位或事故,您可以关闭它。

    这里有一些伪代码说明了如何做到这一点。

    map.addLayer({
      id: 'points',
      type: 'symbol',
      source: 'points',
      layout: {
        'icon-image': [
          'match',
          [ 'get', 'type' ], // type corresponds to the field name you are keying off of
          [ 'bike parking' ],
          'custom-marker',
          [ 'pedestrian' ],
          'custom-marker-2',
          'custom-marker' // fallback icon
        ],
        // get the title name from the source's "title" property
        'text-field': [ 'get', 'title' ],
        'text-font': [
          'Open Sans Semibold',
          'Arial Unicode MS Bold'
        ],
        'text-offset': [ 0, 1.25 ],
        'text-anchor': 'top'
      }
    })
    

    如果自行车停放和事故包含在两个不同的来源中,您只需为每个来源添加一个图层,并在将图层添加到地图时分配一个图标。

    这是一些伪代码

    // Add a bike parking layer
    map.addLayer({
      'id': 'bike-parking',
      'type': 'symbol',
      'source': 'bike-parking-source',
      'layout': {
        'icon-image': 'custom-marker',
        // get the title name from the source's "title" property
        'text-field': ['get', 'title'],
        'text-font': [
          'Open Sans Semibold',
          'Arial Unicode MS Bold'
        ],
        'text-offset': [0, 1.25],
        'text-anchor': 'top'
      }
    });
    
    // Add an accidents layer
    map.addLayer({
      'id': 'accidents',
      'type': 'symbol',
      'source': 'accidents-source',
      'layout': {
        'icon-image': 'custom-marker-2',
        // get the title name from the source's "title" property
        'text-field': ['get', 'title'],
        'text-font': [
          'Open Sans Semibold',
          'Arial Unicode MS Bold'
        ],
        'text-offset': [0, 1.25],
        'text-anchor': 'top'
      }
    });
    

    我已经写了一些关于使用 React 和 Mapbox 的深度文章,如果你觉得它们有用,我会在下面链接到它们。我还在编写 Mapbox 开发人员手册,其中包含如何构建强大的地图驱动应用程序的细节。

    【讨论】:

    • 我有 2 个不同的数据集,从你的代码我解释我需要为不同的数据集单独的源和层?
    • 是的,是的。如果您有两个不同的数据集,您可能希望为每个数据集添加一个源,然后为每个源添加一个层,在每个层的 layout 属性下指定要使用的自定义图标。我链接到的帖子(“React 和 Mapbox GL JS 中的源和层的完整指南”)有一个向地图添加多个源和层的示例。
    • 嘿,我还有一个问题,我的地图在 UI 上被渲染了两次,如果你能帮助我,我在这里有详细的问题 stackoverflow.com/questions/66650960/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多