What I need to put "url" in mapbox addSource - mapbox-gl-js

This is my first time using mapbox and I can't figure out how to addSource when map load.
Below is the sample code.
I uploaded 'KML' file for tilesets and I want to use this tileset for source, but I don't know how to write 'url' part.
I also want to know what is 'source-layer'. What should I write in the 'source-layer?
I am sorry I know this is very basic question, but I really need to know.
Please help me.
Thanks.
map.on('load', function() {
// Add the source to query. In this example we're using
// county polygons uploaded as vector tiles
map.addSource('counties', {
"type": "vector",
"url": "mapbox://mapbox.82pkq93d" <<---here
});
map.addLayer({
"id": "counties",
"type": "fill",
"source": "counties",
"source-layer": "original", <<---source layer
"paint": {
"fill-outline-color": "rgba(0,0,0,0.1)",
"fill-color": "rgba(0,0,0,0.1)"
}
}, 'place-city-sm'); // Place polygon under these labels.
});

EDIT:
Your tile url should also be fine like this:
mapbox://{}
It is a bit tricky to find in the documentation: When uploading KML you are creating tileset for which you should get a map ID. With the map ID you can either request separate tiles using a tile url like this:
/v4/{map_id}/{zoom}/{x}/{y}{#2x}.{format}
You can use the tile url when adding a source
map.addSource({
type: 'vector',
tiles: ['https://api.mapbox.com/v4/{map_id}/{zoom}/{x}/{y}.mvt']
});
Or you can request a TileJSON metadata object and use this to add the source:
map.addSource({
type: 'vector',
url: 'https://api.mapbox.com/v4/{map_id}.json' // <-- tileJSON url
});
For your source layer question: Vector tiles include multiple "layers" of data/geometry, when adding a map layer you need to define which source-layer the map layer refers to. E.g. you can have a single vector tile set consisting of line strings and points (two different source-layers), but your map layer should only render on of them. You can either check to tile JSON to see what source-layers are included in your tile set or create a map style in mapbox studio, using your uploaded tile set as a source.

Related

How to use Ordance Survey vector tiles with React-Leaflet?

I'm unsure of the correct syntax to add Ordnance Survey vector tiles to a React-Leaflet application.
The example code at https://labs.os.uk/public/os-data-hub-examples/os-vector-tile-api/vts-3857-basic-map loads some vector tile libraries from Mapbox:
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.13.1/mapbox-gl.js"></script>
<script src="https://unpkg.com/mapbox-gl-leaflet/leaflet-mapbox-gl.js"></script>
then uses this JavaScript syntax to load the OS vector tiles:
// Load and display vector tile layer on the map.
var gl = L.mapboxGL({
style: 'https://api.os.uk/maps/vector/v1/vts/resources/styles?key=' + apiKey,
transformRequest: url => {
return {
url: url += '&srs=3857'
}
}
});
(I've verified that my OS api key works in the stand-alone demo.)
How can accomplish the equivalent using React and Leaflet?
I'm using React-Leaflet to add Leaflet functionality to my React app, and I've tried adding react-leaflet-vector-tile-layer - I've verified that this works for vector tile layers supplied by Mapbox Studio:
<VectorTileLayer
styleUrl="mapbox://styles/my-org/my-style"
accessToken="my-key"
/>
I'm trying to use this approach for the Ordnance Survey vector tile layer too but it's not working as I probably have the syntax wrong:
<VectorTileLayer
styleUrl="https://api.os.uk/maps/vector/v1/vts/resources/styles?key=my-key"
/>
No error message is shown but the OS vector tile layer does not appear on the map. In the developer console I can see a PBF file has been downloaded but it doesn't draw on the map. Could this be because I'm missing the transformRequest function in their example? Assuming it's required, how can I add this transformation request when using react-leaflet-vector-tile-layer?
The answer came from Ted Piotrowski, the developer of the react-leaflet-vector-tile-layer library. I needed to add the transformRequest parameter using this syntax:
<VectorTileLayer
styleUrl="https://api.os.uk/maps/vector/v1/vts/resources/styles?key=my-key"
transformRequest={url => { return { url: url += '&srs=3857' }}}
/>

Mapbox GL JS unclustered point icon-image

I'm trying to display a clustered map with Mapbox GL JS.
Using this example from the documentation: https://www.mapbox.com/mapbox-gl-js/example/cluster/, I'd like to show a marker icon instead of a circle for unclustered points.
I modified the last addLayer call like this :
map.addLayer({
id: "unclustered-point",
type: "symbol",
source: "companies",
filter: ["!has", "point_count"],
layout: {
"icon-image": "marker-15", // THIS SHOULD BE A MARKER
"icon-size": 5 // ZOOMED FOR DEMO
},
});
Here is the result I got :
Why can't I get access to Maki Icons like it is suggested here : Mapbox GL js available icons
Without a link to your (non) working example, it's hard to diagnose fully, but one possibility is that that icon is not included in your style.
You could try starting from a style that definitely includes them, like these: https://github.com/mapbox/mapbox-gl-styles

How to use a remote wmts and generate its tiles in mapbox

according to How to implement a tile source to mapbox-gl i have an issue on a raster tile source in mapbox gl JS, which probably seems to fit to your declaration that mapbox only supports x/y/z and not lat/lon tile coordinates. I've trouble on this with the following tile source (WMTS): https://www.wmts.nrw.de/geobasis/wmts_nw_dop20/1.0.0/WMTSCapabilities.xml.
I want to include this wmts as source and add as layer like this:
map.on("load", function() {
map.addSource("wmts-layer", {
"type": "raster",
"tiles":['https://www.wmts.nrw.de/geobasis/wmts_nw_dop20/tiles/nw_dop20/EPSG_3857_16/{z}/{x}/{y}.jpeg'],
"tileSize": 256
});
map.addLayer({
"id": "wmts-layer",
"source": "wmts-layer",
"type": "raster",
"visibility": "visible",
"source-layer": "nw_dop20",
});
});
it does not work at all, Tiles get loaded but are empty images!
Can anyone point out whats the problem here?
cheers phil
You seem to be using Mapbox-GL-JS correctly (although you don't need source-layer). For whatever reason, that service is returinng blank tiles for example.
Thank you for investigation Steve,
this is really weird and for some reason the service seems to be unusable in mapbox gl as it serves different coordinates on each zoomlevel than it is specified in the tilescheme of mapbox (tms or xyz)!
see:
https://github.com/mapbox/mapbox-gl-js/issues/6089

Using a custom Mapbox Style's internal GeoJSON data as a source

I'm currently trying to render a map, with data coming from shapefiles (transformed into GeoJSON), upon uploading to Mapbox's servers.
My demo output can be viewed at:
https://ciatph.github.io/amia-lowres-hover.html
I would like to inquire if I have rendered the map efficiently, as used in the demo page. So far, I have:
Uploaded a GeoJSON Dataset
Exported the Dataset into a Tileset
Added the Tileset into a Style
Used the Style to load an initial base map
Used the uploaded Dataset as a data source for another Layer (on top of the initial map). This Layer listens and responds to mouse hover and click events
Used the uploaded Dataset as a data source for another Layer with Filters to color the hovered region differently for the created Layer in step #5.
Screenshot of relevant Mapbox script
My questions for this approach are:
Is there a way to use the Style's internal (GeoJSON) Dataset for the map.addSource() part, such that it doesn't need to be re-loaded or redefined again for creating interactive Layers? I'm concerned of network activity if its being re-downloaded again at this point. I'm also interested to know if this is possible, because we have large GeoJSON data that are almost 100MB in size. This gets automatically converted into Tileset upon moving from Amazon S3 temporary servers to mapbox, and there are no Dataset created to play with the map.addSource() part
I can use Mapbox's default styles for basemap, (i.e., mapbox://styles/mapbox/streets-v9), and omit step #4. If I go for this approach, will the Dataset loading (for step #5) be efficient and fast enough for large data, as opposed if its used or loaded via Style?
I hope you can help me with my queries and enlighten me of more salable and efficient approaches. Thank you.
Let's start by clarifying your current situation:
Your style contains a vector tileset with id ciatph.cj64in9zo1ksx32mr7ke3g7vb-93srz, referred to in your style as amia-lowres-tileset within the composite vector tile source.
It is also accessible as a dataset through the ID ciatph/cj64in9zo1ksx32mr7ke3g7vb, since you uploaded it as a dataset.
Your script is loading the dataset at runtime.
I don't see any reason you need to refer to the dataset instead of the tileset. So, remove the code that adds the dataset, and update the two styles to refer to the tileset (source: "composite") instead.
// Only used for coloring hover effect. Data informatiion be retrieved from styles alone
/*
map.addSource("dataSource", {
"type": "geojson",
'data': 'https://api.mapbox.com/datasets/v1/ciatph/cj64in9zo1ksx32mr7ke3g7vb/features?access_token=pk.eyJ1IjoiY2lhdHBoIiwiYSI6ImNqNXcyeTNhcTA5MzEycHFpdG90enFxMG8ifQ.gwZ6uo6pvx4-RZ1lHODcBQ'
});
*/
// add layer to color the raw source data
map.addLayer({
'id': 'municipalities',
"type": "fill",
"source": "composite",
"source-layer": "amia-lowres-tileset",
"layout": {},
"paint": {
"fill-color": "#627BC1",
"fill-opacity": 0.5
}
});
// add a conditional layer to play over the source data on hover event
map.addLayer({
"id": "state-fills-hover",
"type": "fill",
"source": "composite",
"source-layer": "amia-lowres-tileset",
"layout": {},
"paint": {
"fill-color": "#ff4",
"fill-opacity": 1
},
"filter": ["==", "MUNI_CITY", ""]
});
https://codepen.io/stevebennett/pen/OjvMWO

How to loop through geojson layers on leaflet map?

I have already added geojson features to my leaflet map. I want to be able to loop through those geojson features. WHen I do map.eachLayer(function(layer) {...}) it only shows be the tile layer and none of the geojson that are added.
Rather than map.eachLayer, you should be using the .eachLayer method on the L.geoJson itself. For example:
var geoJsonLayer = L.geoJson(myGeoJson).addTo(map);
geoJsonLayer.eachLayer(function(layer) {
layer.bindPopup(layer.feature.properties.name);
});
You can also specify a function to be applied to each feature at the time you create the L.geoJson, using the onEachFeature option.