Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
829 views
in Technique[技术] by (71.8m points)

mapbox gl js - set marker visibility from geoJson source

I'm using a geojson that contains cities in italy, where I have "data" to read; data is stored in the properties fields. I can add even more data, for example we are thinking about adding the density of people for each city, to make cities more or less relevant, to be translated in which city is shown before on the maps.

The geojson:

{
  type: "geojson",
  data: {
    type: "FeatureCollection",
    features: [
      {
        type: "Feature",
        geometry: {
          type: "Point",
          coordinates: [11.433, 46.883],
        },
        properties: {
          title: "Vipiteno",
          /* etc */
        },
      },
      {
        type: "Feature",
        geometry: {
          type: "Point",
          coordinates: [11.326, 46.46],
        },
        properties: {
          title: "Bolzano",
          /* etc */
        },
      },
    ],
  },
}

On my page I add the geojson to the map by using this function:

map.on("load", function () {
  // Add an image to use as a custom marker
  map.loadImage("img", function (error, image) {
    if (error) throw error;
    map.addImage("custom-marker", image);
    // Add a GeoJSON source with 2 points
    map.addSource("points", geoJson);

    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",
      },
    });
  });
});

So how can I control which markers are shown at first load, and then showing more more points when the user zooms in?

Right now just a few are rendered at starting zoom level, but there is no control on which, and small cities are rendered before capitals (for example).

How can I override this?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can override this by setting the zoom / adding a zoom expression for dynamic visibility changes. The below Mapbox example does something similar. By using a dynamic zoom expression the cirle layer opacity is gradually changed. You could do the same for your layer. Thereby you can control which layer is visible at which zoom with which specific opacity. Please see this example:

https://docs.mapbox.com/help/tutorials/mapbox-gl-js-expressions/#add-a-zoom-expression

(To run, exchange "YOUR ACCESS TOKEN")

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <title>Minneapolis Landmarks</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v2.0.1/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v2.0.1/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 = 'YOUR ACCESS TOKEN';
    var map = new mapboxgl.Map({
      container: 'map', // container id
      style: 'mapbox://styles/mapbox/light-v10', // stylesheet location
      center: [-93.261, 44.971], // starting position [lng, lat]
      zoom: 10.5 // starting zoom
    });

    map.on('load', function() {
      map.addLayer({
        id: 'historical-places',
        type: 'circle',
        source: {
          type: 'vector',
          url: 'mapbox://your-tileset-id-here'
        },
        'source-layer': 'your-source-layer-here',
        paint: {
          'circle-radius': [
            'interpolate', ['linear'], ['zoom'],
            10, ['/', ['-', 2017, ['number', ['get', 'Constructi'], 2017]], 30],
            13, ['/', ['-', 2017, ['number', ['get', 'Constructi'], 2017]], 10],
          ],
          'circle-opacity': 0.8,
          'circle-color': 'rgb(171, 72, 33)'
        }
      });
    });
  </script>
  </body>
</html>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...