querySourceFeature returns empty array - mapbox-gl-js

I am using mapbox to try and query all features of the mapbox tileset and return them as geojson. From what I understand, to query features that are no visible on the screen, you must use querysourcefeatures. My tileset only shows up at zoom 14 so I am having trouble querying all the features in the dataset at once and then applying a filter. Is this possible? It stills like querySourceFeatures returns an empty array.
function addLayers() {
map.addSource('plutonew-c03oxi', {
'type': 'vector',
'url': 'mapbox://samtpr.4ehwzn0r'
});
map.addLayer({
"id": "parcels_fill",
"type": "fill",
"source": "plutonew-c03oxi",
"source-layer": "plutonew-c03oxi",
'layout': {
'visibility': 'visible'
},
paint: {
'fill-color': 'blue',
'fill-outline-color': 'gray',
"fill-opacity": ["case",
["boolean", ["feature-state", "hover"], false],
0.5,
0
]
}
});
var features = map.querySourceFeatures('plutonew-c03oxi', {filter: ["==", ['get','ZIPCODE'], zipcode_val]});

From what I understand, to query features that are no visible on the screen, you must use querysourcefeatures
You may have misunderstood. querySourceFeatures allows you to query features that are present within the vector tiles currently loaded and displayable within the current viewport and zoom level. Unlike queryRenderedFeatures they don't have to actually be rendered through a visible layer, however.
In this case it sounds like you're hoping to gain access to features that are not available at the current zoom level, which is not possible.

Related

Tile out of range error when using wmts on Geoserver with Mapbox

I'd like to render a layer from geoserver with using WMTS.
I'm using mapbox-gl to render a map and layers.
The website I'm referring to is https://docs.geoserver.org/stable/en/user/styling/mbstyle/source.html.
This shows how to create a layer on geoserver and render it on a mapbox map.
However, I'm getting an error TileOutOfRange when I request tiles.
For example, when I request tiles with this url,
http://<my_server>:8080/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=myspace:japan&STYLE=&TILEMATRIX=EPSG:4326:8&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL=221&TILEROW=102.
I get this error message.
Column 221 is out of range, min: 440 max:462.
Here below is my code to fetch a layer that I created on geoserver.
map.on("load", () => {
map.addSource("test", {
type: "vector",
tiles: ["http://<my_server>:8080/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=myspace:japan&STYLE=&TILEMATRIX=EPSG:4326:{z}&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL={x}&TILEROW={y}"],
generateId: true,
minZoom: 0,
maxZoom: 14,
});
map.addLayer({
"id": "test",
"type": "fill",
"source": "test",
"source-layer": "japan",
"layout": { "visibility": "visible" },
"paint": {}
});
});
It would be much appreciated if anyone gave me a way to solve this.
Thank you.
I made sure that I checked this box application/vnd.mapbox-vector-tile in the tile caching settings.
I left out 900913 from the default gridset settings, since my data is EPSG:4326.
When creating a layer, I made sure that I clicked Compute from data and Compute from native bounds to set bounding boxes.

How I can I get geojson boundary array from existing layer using mapbox gl?

I am using one of the custom tileset of tilling service in mapbox. I loaded that custom tile layer in map using below code.
map.addSource('california', {
type: 'vector',
url: 'mapbox://xyz.california'
});
map.addLayer({
'id': 'terrain-data',
'type': 'fill',
'source': 'california',
'source-layer': 'california',
'layout': {},
'paint': {
'fill-color': 'black',
'fill-opacity': 0.5
}
});
Above code is filling out the inner area with black color. But I want to fill out the outer area of that polygon. Only one way I know to do that is getting difference of whole map with that polygon by using turf.js. After that I will be able to fill the outside area.
Now the question is how can I get the geojson ploygon array of above added layer? So I can calculate the difference.
You can't easily get the complete geometry of a polygon from a vector tile set, because it has already been cut up into tiles. You would have to either find a way to merge them together, or get your geometry into the front end as a complete geojson first.

How do I get a single set of country boundaries from Mapbox country boundaries

https://codepen.io/m12n/pen/XWNRZMg?editors=0010
mapboxgl.accessToken =
"pk.eyJ1IjoiaW50ZWxsaWdlbmNlZnVzaW9uIiwiYSI6ImNrM2l2cnk1NzBibGIzbm5yaHNycXltZmYifQ.tPEnnW5NAPmInCJDYVfJxA";
var map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/dark-v10",
zoom: 8,
center: [-71.4935, 41.5852]
});
map.on("load", function () {
map.addSource("countries-no-simplification", {
type: "vector",
url: "mapbox://mapbox.country-boundaries-v1"
});
map.addLayer({
id: "countries-simplification-data",
type: "fill",
source: "countries-no-simplification",
"source-layer": "country_boundaries",
paint: {
"fill-color": "#ff69b4",
"fill-opacity": 0.3
}
});
});
The above code and pen shows usage of the MapBox county boundaries where I fill the layer with a colour and a low opacity.
Because the source has multiple world views I get both boundaries for disputed countries showing at the same time, and therefore get the effect shown (stronger colouring).
Eventually I actually want to apply a colour based on a specific datapoint, but for now I would be happy with being able to render only a single set of boundaries (a single world view?).
I cant seem to figure out how to get only one such set of boundaries from the source.
You can apply a filter to keep the boundaries of a specific world view (US, CN, IN, etc.) and remove disputed boundaries. Example:
map.addLayer({
id: "countries-simplification-data",
type: "fill",
source: "countries-no-simplification",
"source-layer": "country_boundaries",
filter: [
'all',
['match', ['get', 'worldview'], ['all', 'US'], true, false],
["!=", "true", ["get", "disputed"]],
],
paint: {
"fill-color": "#ff69b4",
"fill-opacity": 0.3
}
});

How to display stacked locations in a mapbox layer?

I'm very new to mapboxgl and trying to create a map that allows users to filter points over time. I customized this tutorial with my data to get the initial map up and running:
https://docs.mapbox.com/help/tutorials/show-changes-over-time/
everything worked really well until I loaded my data and realized that many points shared the same coordinates.
Some googling revealed this answer:
Multiple markers - Same coordinates
Both the idea of using offsets or spidering feel like reasonable solutions. Unfortunately, it is not clear to me how to apply those to the data as I loaded it. I believe that the relevant portion of the script is:
map.on('load', function() {
map.addLayer({
id: 'year',
type: 'circle',
source: {
type: 'geojson',
data: './grandpascan.geojson' // replace this with the url of your own geojson
},
paint: {
'circle-radius': [
'interpolate',
['linear'],
['number', ['get', 'Pages']],
0, 4,
5, 24
],
'circle-color': [
'interpolate',
['linear'],
['number', ['get', 'Pages']],
0, '#2DC4B2',
1, '#3BB3C3',
2, '#669EC4',
3, '#8B88B6',
4, '#A2719B',
5, '#AA5E79'
],
'circle-opacity': 0.8
},
If that is correct, how can I identify those points for styling? They do not appear to be markers that can easily addressed in CSS, although I may be completely misunderstanding how this all fits together.
thanks!
The code here is creating a layer within the map, of type circle. You could offset locations using the circle-translate property.
If you want to use CSS transforms to offset markers, you should create them as Marker objects which exist in HTML, outside the map.

Share the same source between layers

I want to change the style of my layer on a certain zoom (circle to symbol). When I cross zoom 5, what I thought I could do was to remove my previous layer, then create a new one with the old source. Actually, it gives me an error.
If I create a new source with the same data everything works fine, the error is about the source. What I don't understand is that the source is still present as I can interact with it.
Please find my fiddle, open the console to see :
the zoom (wait for zoom 5)
the data contained by the source
the error
glMap.addSource('yacht', {
type: 'geojson',
data: data,
buffer: 256
});
glMap.addLayer({
"id": "yachtL",
"type": "circle",
"interactive": true,
//'style': '/bright-v8.json',
"source": "yacht",
'layout': {},
'paint': {
'circle-color': '#262626',
'circle-opacity': 0.8
}
}/*, "cargoL"*/);
removeSpinner();
Give the new layer a new id, then it will work. Currently they both have the id of 'yachtL'.