简体   繁体   English

在 Mapbox map 上,无论缩放级别如何,如何保持图层始终可见?

[英]On a Mapbox map, how to keep a layer always visible, no matter the zoom level?

I have tried to understand the underlying mechanisms of the data display processing at the tile level but I have not found any literature explicit enough for me to understand how it all works.我试图了解图块级别的数据显示处理的基本机制,但我没有找到任何足够明确的文献让我理解它是如何工作的。

I have a simple need though: to keep a layer of symbols always visible.不过我有一个简单的需求:让一层符号始终可见。

I have tested these attributes for a long time: 'icon-allow-overlap': true, icon-ignore-placement': true, text-allow-overlap': true, text-ignore-placement': true I also tried to play with the layers and sources orde, the visibility by zoom level, ... But I have the impression that an internal workings overload all this and take over my statements.这些属性我测试了很久: 'icon-allow-overlap': true, icon-ignore-placement': true, text-allow-overlap': true, text-ignore-placement': true 我也试过玩图层和源顺序,缩放级别的可见性,......但我的印象是内部运作超载了所有这些并接管了我的陈述。

I guess it's something to do with the data loaded by tiles... but I can't go further to understand the "problem".我想这与图块加载的数据有关......但我无法 go 进一步了解“问题”。

I'm interested in any explanation or link (or examples.) that would help me understand the workings of Mapbox in this regard.我对任何有助于我理解 Mapbox 在这方面的工作原理的解释或链接(或示例)感兴趣。

If your data is in a vector tile source, the data availability in the tiles limits your ability to control which zoom levels the symbols would be visible.如果您的数据位于矢量切片源中,切片中的数据可用性会限制您控制符号可见的缩放级别的能力。 The main reason being that when you zoom outside the zoom range the data is available within the vector tile layer, the data becomes unavailable.主要原因是当您在缩放范围之外缩放时,矢量切片图层中的数据可用,数据变得不可用。 If you control the vector tile source, you could make the data available in all zoom levels of the vector tiles, but note that this may create an issue if you have a massive number of points when zoomed all the way out.如果您控制矢量切片源,则可以使数据在矢量切片的所有缩放级别中可用,但请注意,如果在完全缩小时有大量点,这可能会产生问题。

If the data is loaded through a GeoJSON source, then you can make a symbol always appear across all zoom levels by using the four icon/text options you mentioned.如果数据是通过 GeoJSON 源加载的,那么您可以使用您提到的四个图标/文本选项使符号始终出现在所有缩放级别。

If you are using vector tiles and have no control over the tiles, you could potentially make a hack that captures the data from the vector tiles and store the data in a geojson source.如果您正在使用矢量切片并且无法控制切片,您可能会进行黑客攻击,从矢量切片中捕获数据并将数据存储在 geojson 源中。 You would load the vector tiles using a hiden layer (make things transparent or not visible so the tiles still get requested), then as the map moves, retrieve all the geometries in the viewable map area from that source.您将使用隐藏层加载矢量切片(使事物透明或不可见,以便仍然请求切片),然后随着 map 移动,从该源检索可视区域 map 中的所有几何图形。 Ideally you would have a unique identifier that you could use to keep track of geometries so you don't store/capture the same geometry more than once.理想情况下,您将拥有一个可用于跟踪几何图形的唯一标识符,这样您就不会多次存储/捕获相同的几何图形。 Note that if the geometries are captured from the vector tiles when zoomed out, the accuracy of the positions may be low since the coordinates would have been snapped to pixels at that zoom level, so you could potentially keep track of the zoom level a geometry was captured at, and if you encounter the same geometry again later when zoomed in more you could replace the geometries coordinates accordingly to improve its accuracy.请注意,如果几何图形是在缩小时从矢量图块中捕获的,则位置的准确性可能会很低,因为坐标会在该缩放级别捕捉到像素,因此您可能会跟踪几何图形的缩放级别捕获在,如果您稍后在放大更多时再次遇到相同的几何体,您可以相应地替换几何体坐标以提高其精度。 This would require a decent amount of code to get working correctly, but if you have no other option, this should be viable.这将需要相当数量的代码才能正常工作,但如果您没有其他选择,这应该是可行的。

Update更新

Going through your live sample I managed to reproduce the issue.通过您的现场样本,我设法重现了这个问题。 The console had some errors indicating that the images for the icons hadn't been loaded.控制台有一些错误表明图标的图像尚未加载。 Looking at your code you do have code to load icons but it is asynchronous and so every once and a while the icons haven't finished loading before the code for the layers is processed, thus causing these errors.查看您的代码,您确实有加载图标的代码,但它是异步的,因此每隔一段时间图标在处理图层代码之前还没有完成加载,从而导致这些错误。 To fix this you would need to wait for the icons to finish loading before creating the layer.要解决此问题,您需要在创建图层之前等待图标完成加载。 For example:例如:

import "./styles.css";
import datas from "./datas.json";
import path from "./path.json";

import chateaux_agrements from "./pins/chateaux_agrements-c.png";
import chateaux_ducaux from "./pins/chateaux_ducaux-c.png";
import chateaux_rohan from "./pins/chateaux_rohan-c.png";
import mottes_castrales from "./pins/mottes_castrales-c.png";

mapboxgl.accessToken =
  "pk.eyJ1IjoiY2xhZGppZGFuZSIsImEiOiJja2c1NDl4eGwwcHkzMnBwanZ2NTMxMWJwIn0.uKc2vVfVoSAEWp_yWug0NA";

const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/cladjidane/ckh0nxrpm03fr19lkkmp02yfz",
  center: [-2.842, 47.765],
  zoom: 8
});

const images = [
  { url: chateaux_agrements, id: "chateaux_agrements" },
  { url: chateaux_ducaux, id: "chateaux_ducaux" },
  { url: chateaux_rohan, id: "chateaux_rohan" },
  { url: mottes_castrales, id: "mottes_castrales" }
];

map.on("load", function () {
  map.addSource("game_source", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: datas.features
    }
  });

  map.addSource("path_source", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: path.features
    }
  });

  //Keep track of how many images have loaded.
  var imagesLoaded = 0;

  images.map((img) => {
    map.loadImage(img.url, (error, image) => {
      if (error) throw error;
      map.addImage(img.id, image);

      //Increment the number of images that have been loaded.
      imagesLoaded++;

      //Check to see if all images have been loaded.
      if(imagesLoaded === images.length) {
        //Run code to add the layers.
        addLayers();
      }
    });
    return true;
  });
  
  function addLayers() {
    map.addLayer({
      id: "path_line",
      source: "path_source",
      type: "line",
      layout: {
        "line-join": "round",
        "line-cap": "round"
      },
      paint: {
        "line-color": "white",
        "line-dasharray": [1, 3],
        "line-width": [
          "interpolate",
          ["linear"],
          ["zoom"],
          7.15,
          1.5,
          9.15,
          4,
          12,
          8,
          22,
          1.1
        ]
      }
    });

    map.addLayer({
      id: "game_step",
      source: "game_source",
      type: "circle",
      filter: ["==", "type", "step"],
      paint: {
        "circle-radius": 6,
        "circle-color": "rgba(255,255,255, .8)"
      }
    });

    map.addLayer({
      id: "game_castel",
      source: "game_source",
      type: "symbol",
      filter: ["all", ["==", "type", "castel"]],
      layout: {
        "text-variable-anchor": ["top", "bottom", "left", "right"],
        "text-size": 6,
        "text-offset": [0, 2.5],
        "icon-image": [
          "match",
          ["get", "castelType"],
          ["Châteaux d'agrément"],
          "chateaux_agrements",
          ["Châteaux des Rohan"],
          "chateaux_rohan",
          ["Châteaux ducaux"],
          "chateaux_ducaux",
          ["Mottes castrales"],
          "mottes_castrales",
          "mottes_castrales"
        ],
        "icon-size": 0.35,
        "icon-allow-overlap": true,
        "icon-ignore-placement": true,
        "text-allow-overlap": true,
        "text-ignore-placement": true,
        "text-field": ["get", "name"]
      },
      paint: {
        "text-color": "red",
        "text-halo-color": "#fff",
        "text-halo-width": 2
      }
    });
  }
});

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

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