如何从 Mapbox GL JS 中的样式层获取特征?
How get features from a style's layer in Mapbox GL JS?
我是 JavaScript 的学习者并且在使用 Mapbox GL JS 时遇到问题:我在 Mapbox Studio 中有一个样式,其中有 one my layer — "locations"。我已将其添加为 tileset。这一层有两个 GeoJSON 点,但我无法在 GL JS 中获取它们。
我发现我应该使用方法 querySourceFeatures(sourceID, [parameters])
,但我在正确填充其参数方面遇到了问题。我写道:
var allFeatures = map.querySourceFeatures('_id-of-my-tyleset_', {
'sourceLayer': 'locations'
});
..它不起作用。
更有趣的是,稍后在代码中我将这一层与方法queryRenderedFeatures
一起使用,没关系:
map.on('click', function(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['locations']
});
if (!features.length) {
return;
}
var feature = features[0];
flyToPoint(feature);
var popup = new mapboxgl.Popup({
offset: [0, -15]
})
.setLngLat(feature.geometry.coordinates)
.setHTML('<h3>' + feature.properties.name + '</h3>' + '<p>' +
feature.properties.description + '</p>')
.addTo(map);
});
我已经阅读了很多关于在地图上添加图层的内容,知道答案很简单,但我无法实现解决方案,所以请帮忙:)
Here is GitHub 上的项目。
你的问题是你的地图,就像默认情况下在 Mapbox Studio 中创建的所有地图一样,使用自动合成。您实际上没有名为 morganvolter.cj77n1jkq1ale33jw0g9haxc0-2haga
的源,您有一个名为 composite
的源,其中包含许多子层。
您可以找到这样的图层列表:
map.getSource('composite').vectorLayerIds
这表明您有一个名为 akkerman
的矢量图层。 (“locations
”是您的 style 层的名称,而不是您的 source 层的名称)。因此您的查询应该是:
map.querySourceFeatures('composite', {
'sourceLayer': 'akkerman'
});
其中 returns 4 个特征。
有很多关于 Mapbox get features after filter
或 Mapbox get features before filter
的问题。我可以看到有很多帖子四处散布,但其中 none 似乎有 FULL DETAILED
解决方案。我花了一些时间将两个解决方案放在一个函数下,在 jsbin 中试试这个。
这是给感兴趣的人的:
function buildRenderedFeatures(map) {
// get source from a layer, `mapLayerId` == your layer id in Mapbox Studio
var compositeSource = map.getLayer(mapLayerId.toString()).source;
//console.log(map.getSource(compositeSource).vectorLayers);
var compositeVectorLayerLength = map.getSource(compositeSource).vectorLayers.length - 1;
//console.log(compositeVectorLayerLength);
// sourceId === tileset id which is known as vector layer id
var sourceId = map.getSource(compositeSource).vectorLayers[compositeVectorLayerLength].id;
//console.log(sourceId);
// get all applied filters if any, this will return an array
var appliedFilters = map.getFilter(mapLayerId.toString());
//console.log(appliedFilters);
// if you want to get all features with/without any filters
// remember if no filters applied it will show all features
// so having `filter` does not harm at all
//resultFeatures = map.querySourceFeatures(compositeSource, {sourceLayer: sourceId, filter: appliedFilters});
var resultFeatures = null;
// this fixes issues: queryRenderedFeatures getting previous features
// a timeout helps to get the updated features after filter is applied
// Mapbox documentation doesn't talk about this!
setTimeout(function() {
resultFeatures = map.queryRenderedFeatures({layers: [mapLayerId.toString()]});
//console.log(resultFeatures);
}, 500);
}
然后您调用该函数,例如:buildRenderedFeatures(map)
传递创建 Mapbox 地图时已有的 map
对象。
然后您将 resultFeatures
将 return 一个可以使用 for...in
迭代的对象。您可以测试 querySourceFeatures()
代码,我将其注释掉但留待有人需要时使用。
我是 JavaScript 的学习者并且在使用 Mapbox GL JS 时遇到问题:我在 Mapbox Studio 中有一个样式,其中有 one my layer — "locations"。我已将其添加为 tileset。这一层有两个 GeoJSON 点,但我无法在 GL JS 中获取它们。
我发现我应该使用方法 querySourceFeatures(sourceID, [parameters])
,但我在正确填充其参数方面遇到了问题。我写道:
var allFeatures = map.querySourceFeatures('_id-of-my-tyleset_', {
'sourceLayer': 'locations'
});
..它不起作用。
更有趣的是,稍后在代码中我将这一层与方法queryRenderedFeatures
一起使用,没关系:
map.on('click', function(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['locations']
});
if (!features.length) {
return;
}
var feature = features[0];
flyToPoint(feature);
var popup = new mapboxgl.Popup({
offset: [0, -15]
})
.setLngLat(feature.geometry.coordinates)
.setHTML('<h3>' + feature.properties.name + '</h3>' + '<p>' +
feature.properties.description + '</p>')
.addTo(map);
});
我已经阅读了很多关于在地图上添加图层的内容,知道答案很简单,但我无法实现解决方案,所以请帮忙:)
Here is GitHub 上的项目。
你的问题是你的地图,就像默认情况下在 Mapbox Studio 中创建的所有地图一样,使用自动合成。您实际上没有名为 morganvolter.cj77n1jkq1ale33jw0g9haxc0-2haga
的源,您有一个名为 composite
的源,其中包含许多子层。
您可以找到这样的图层列表:
map.getSource('composite').vectorLayerIds
这表明您有一个名为 akkerman
的矢量图层。 (“locations
”是您的 style 层的名称,而不是您的 source 层的名称)。因此您的查询应该是:
map.querySourceFeatures('composite', {
'sourceLayer': 'akkerman'
});
其中 returns 4 个特征。
有很多关于 Mapbox get features after filter
或 Mapbox get features before filter
的问题。我可以看到有很多帖子四处散布,但其中 none 似乎有 FULL DETAILED
解决方案。我花了一些时间将两个解决方案放在一个函数下,在 jsbin 中试试这个。
这是给感兴趣的人的:
function buildRenderedFeatures(map) {
// get source from a layer, `mapLayerId` == your layer id in Mapbox Studio
var compositeSource = map.getLayer(mapLayerId.toString()).source;
//console.log(map.getSource(compositeSource).vectorLayers);
var compositeVectorLayerLength = map.getSource(compositeSource).vectorLayers.length - 1;
//console.log(compositeVectorLayerLength);
// sourceId === tileset id which is known as vector layer id
var sourceId = map.getSource(compositeSource).vectorLayers[compositeVectorLayerLength].id;
//console.log(sourceId);
// get all applied filters if any, this will return an array
var appliedFilters = map.getFilter(mapLayerId.toString());
//console.log(appliedFilters);
// if you want to get all features with/without any filters
// remember if no filters applied it will show all features
// so having `filter` does not harm at all
//resultFeatures = map.querySourceFeatures(compositeSource, {sourceLayer: sourceId, filter: appliedFilters});
var resultFeatures = null;
// this fixes issues: queryRenderedFeatures getting previous features
// a timeout helps to get the updated features after filter is applied
// Mapbox documentation doesn't talk about this!
setTimeout(function() {
resultFeatures = map.queryRenderedFeatures({layers: [mapLayerId.toString()]});
//console.log(resultFeatures);
}, 500);
}
然后您调用该函数,例如:buildRenderedFeatures(map)
传递创建 Mapbox 地图时已有的 map
对象。
然后您将 resultFeatures
将 return 一个可以使用 for...in
迭代的对象。您可以测试 querySourceFeatures()
代码,我将其注释掉但留待有人需要时使用。