简体   繁体   English

如何在mapbox中为不同的数据集设置不同的标记

[英]how to different markers for different data set in mapbox

I am using map box api with react, I get 2 kind of data set from backend, one with let's say bike's parking points and another is data set is places where accident happened, I want to display both data set with different markers/icons in mapbox, how should I do that?我正在使用 map 盒子 api 进行反应,我从后端获得了两种数据集,一种是自行车的停车点,另一种是数据集是发生事故的地方,我想用不同的标记/图标显示这两个数据集地图盒,我该怎么做?

currently to display single data set I am using below code.目前要显示我正在使用下面的代码的单个数据集。

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;

below is sample data to populate下面是要填充的示例数据

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

Solution: based on @tylerban's answer I have update my code like this:解决方案:根据@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'
            }
          });


         
        }
      );
    }

Are the bike parking points and accident locations contained in the same source (dataset) or are they two different sources and layers that you are adding to the map?自行车停车点和事故地点是否包含在同一源(数据集)中,或者它们是您添加到 map 的两个不同源和层?

If the bike parking and accidents are contained in the same source, you can use data driven styling in Mapbox to assign an icon based on a field in the data.如果自行车停放和事故包含在同一个源中,您可以使用Mapbox 中的数据驱动样式根据数据中的字段分配图标。 So if you have a field in the source that can be used to determine if a point represents a bike parking spot or accident you would key off of that.因此,如果您在源中有一个字段可用于确定一个点是否代表自行车停车位或事故,您将关闭它。

Here is some pseudo code that illustrates how to do this.这是一些说明如何执行此操作的伪代码。

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'
  }
})

If the bike parking and accidents are contained in two separate sources, you will just need to add a layer for each and assign an icon when adding the layer to the map.如果自行车停放和事故包含在两个不同的来源中,您只需为每个来源添加一个图层并在将图层添加到 map 时分配一个图标。

Here is some pseudo code这是一些伪代码

// 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'
  }
});

I have written a number of in depth posts on working with React and Mapbox and will link to them below in case you find them useful.我已经写了很多关于使用 React 和 Mapbox 的深度文章,如果你觉得它们有用,我会在下面链接到它们。 I am also in the process of writing a Mapbox Developer's Handbook that contains the ins and outs of how to build powerful map driven applications.我还在编写 Mapbox 开发人员手册,其中包含如何构建强大的 map 驱动应用程序的细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM