Маска mapbox-gl карта с произвольным многоугольником

Я использую mapbox-gl и скачал векторные плитки с osm2vectortiles.org

Мне бы хотелось, чтобы карта была видна только в пределах известного многоугольника, и я не могу найти способ осуществить это.

Я могу представить несколько способов решения проблемы, и каждый путь привел меня к отсутствию ответов. Вот несколько подходов, которые я пытался исследовать:

  1. Какой-то слой маскировки карты. (Кажется, концепция не существует)
  2. Нарисуйте многоугольник и заполните его снаружи, а не внутри. (Кажется, вы можете только заполнить внутри полигонов)
  3. Нарисуйте заполненный прямоугольник вокруг внешних границ карты и вырежьте многоугольник. (Кажется, что функции MultiPolygon складываются вместо выреза)
  4. Модифицируйте mbtiles, притворяясь, что все, что находится за пределами многоугольника - это вода. ( https://github.com/mapbox/mbtiles-cutout показался многообещающим, но я не могу заставить его работать)

Как правильно подойти к этой проблеме?

1 ответ

Решение

Все упомянутые вами варианты могут работать. Вы можете вырезать исходные векторные данные так, чтобы они соответствовали области маски (как в варианте 4), или вы можете нарисовать слой маски поверх ваших данных (вариант 3).

Вот как вы можете сделать это со слоем маски:

https://jsfiddle.net/kmandov/cr2rav7v/

Добавьте вашу маску в качестве заливочного слоя:

 map.addSource('mask', {
    "type": "geojson",
    "data": polyMask(mask, bounds)
  });

  map.addLayer({
    "id": "zmask",
    "source": "mask",
    "type": "fill",
    "paint": {
      "fill-color": "white",
      'fill-opacity': 0.999
    }
  });

Вы можете создать свою маску заранее (скажем, с помощью QGis или turf) или вы можете вырезать маску прямо в браузере, используя turf:

function polyMask(mask, bounds) {
  var bboxPoly = turf.bboxPolygon(bounds);
  return turf.difference(bboxPoly, mask);
}

var bounds = [-122.5336, 37.7049, -122.3122, 37.8398]; // wsen 

var mask = turf.polygon([
  [
    [-122.43764877319336,
      37.78645343442073
    ],
    [-122.40056991577148,
      37.78930232286027
    ],
    [-122.39172935485838,
      37.76630458915842
    ],
    [-122.43550300598145,
      37.75646561597495
    ],
    [-122.45378494262697,
      37.7781096293495
    ],
    [-122.43764877319336,
      37.78645343442073
    ]
  ]
]);

Возможно, вы хотели бы предотвратить выход пользователя за пределы маски, предоставив maxBounds:

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v9',
  center: [-122.42116928100586, 37.77532815168286],
  maxBounds: bounds,
  zoom: 12
});

Обратите внимание, что, кажется, есть ошибка, и вам нужно установить fill-opacity что-то вроде 0.999

Другие вопросы по тегам