我试图理解数据显示处理的底层机制,但我还没有找到任何明确的文献来让我理解它是如何工作的。
我有一个简单的需求:保持一层符号总是可见的。
我已经测试了这些属性很长时间:"icon-allow-overlap":没错,icon-ignore-placement":没错,text-allow-overlap":没错,text-ignore-placement":真正的我还尝试了图层和源顺序,通过缩放级别的可见性,…但我的印象是,一个内部工作超负荷了,接管了我的语句。
我猜这与tile加载的数据有关…但我无法进一步理解这个"问题"。
我对任何能帮助我理解Mapbox在这方面的工作原理的解释或链接(或示例!)都很感兴趣。
如果您的数据在矢量贴图源中,则贴图中的数据可用性限制了您控制符号可见的缩放级别的能力。主要原因是,当您在缩放范围之外进行缩放时,数据在矢量图层中可用,但数据变得不可用。如果你控制矢量贴图源,你可以让数据在矢量贴图的所有缩放级别中可用,但请注意,如果你有大量的点,当你一直放大时,这可能会产生一个问题。
如果数据是通过GeoJSON源加载的,那么您可以通过使用您提到的四个图标/文本选项使符号始终出现在所有缩放级别。
如果您正在使用矢量贴图并且无法控制这些贴图,那么您可能会从矢量贴图中捕获数据并将数据存储在geojson源中。您将使用隐藏层加载矢量贴图(使内容透明或不可见,以便仍然可以请求贴图),然后随着地图移动,从该源检索可查看地图区域中的所有几何图形。理想情况下,您可以使用唯一标识符来跟踪几何形状,这样您就不会多次存储/捕获相同的几何形状。请注意,如果几何图形是在缩小时从矢量贴图中捕获的,那么位置的精度可能会很低,因为在该缩放级别上坐标已经被捕捉到像素,因此您可能会跟踪捕获几何图形的缩放级别,如果稍后在进一步放大时再次遇到相同的几何图形,您可以相应地替换几何坐标以提高其精度。这将需要相当数量的代码才能正常工作,但如果你没有其他选择,这应该是可行的。
通过你的实时样本,我设法重现了这个问题。控制台有一些错误,表明图标的图像尚未加载。看看你的代码,你确实有加载图标的代码,但它是异步的,所以每隔一段时间,在图层代码被处理之前,图标还没有完成加载,从而导致这些错误。要解决这个问题,你需要等待图标完成加载,然后再创建图层。例如:
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
}
});
}
});