Mapbox-gl-js gives typeerror: 't' is undefined with tiles - mapbox-gl-js

Link to problem: https://khuts.org/webmap/osm-bright-style/mines.html
Neither the mapbox-street layer nor the tile layer show.
This map has an mbtiles file served using tileserver-php. The error refers to tile-coord.js, which does not seem to have any property 't' in it.
How do I resolve this?

Seeing your comment here, you need to change how you create your data source. vector sources don't accept a data option, you either need to supply tiles (an array of tile urls) or an url (an url pointing to a TileJSON file):
map.addSource('my-source', {
type: 'vector',
// either "tiles"
tiles: ['http://my-tile-server/{z}/{x}/{y}'],
// or "url"
url: 'http://my-tile-server/tiles.json'
});
If you are using tileserver-php, it supports both:
- tile urls (z/x/y)
- tile jsons
See its documentation of "Supported Protocols": https://github.com/klokantech/tileserver-php#supported-protocols

Related

MapBox change feature properties of Vector map

I am modifying features from layer and would like to use similar to "setData()" to a vector layer? From googling some places i read that its not possible to use that setData function to vectors and only to geojsons.
What i am doing is first i get the feature properties from layer
let features = this.map.queryRenderedFeatures({layers:["maakunta-fills"]}).map(item=>{
const copied = {...item}
copied.properties.modified = "some_modified_value"
return copied;
});
and then my wish is i can do something like : this.map.getSource("sourcename").setData(features)
But mapbox will throw error by saying setData is not function (i assume because this "sourcename" is a vector tile. Which looks like this:
this.map.addSource("maakunta", {
type: "vector",
tiles: [tileServiceURL + "base.maakunta/{z}/{x}/{y}.pbf"],
promoteId: "id"
});
The best way to do this is by using setFeatureState. It will not change the vector data but you can change the style and intercept any click events and push the updated data. This of course is limited to the current client session. Ideally you would be updating the source data in a database for example so that when a new user views a new db tile request they will have access to the new data.

geoman - how to access the resulting GeoJSON object after a feature has been removed in removalMode

I have a FeatureCollection from which I remove single Features. I can get the removed feature by adding an event listener pm:remove like following:
layer.on('pm:remove', e => {
// do stuff regarding the removed feature
console.log(e.layer.feature)
});
I would like to also have access to the resulting FeatureCollection (from which the feature has been removed). how can I "console.log()" that?
Are you added the layer to a LayerGroup / FeatureGroup? Then you can call layergroup.toGeoJSON()
Or if you use the default and adding the layers to the map, you can call map.pm.getGeomanLayers(true).toGeoJSON().
true means that it returns a L.FeatureGroup instead of an array with the layers.

Flask-Admin GeoAlchemy2 example doesn't show a map

I'm trying to run this example about how to use Flask-Admin displaying maps: https://github.com/flask-admin/flask-admin/tree/master/examples/geo_alchemy.
In README.rst, there's this instruction:
You will notice that the maps are not rendered. To see them, you will have to register for a free account at Mapbox and set the MAPBOX_MAP_ID and MAPBOX_ACCESS_TOKEN config variables accordingly.
I already have a valid MAPBOX_ACCESS_TOKEN, and I went to MapBox to look for a MAPBOX_MAP_ID. There I read that MAP_ID was deprecated, and now I'll have to obtain a tileset ID, and it's described as a label composed by <my_mapbox_user_name>.the_tileset_ID itself.
So I located the code as they described in the instructions (in my case, mapbox-streets-v8) and fulfilled the config.py parameters:
MAPBOX_MAP_ID = '<my_mapbox_user_name>.mapbox-streets-v8'
MAPBOX_ACCESS_TOKEN = 'pk.eyJ1...'
However, I couldn't see any map displayed or any error message.
How can I fix it?
I think there is a small bug in file Lib\site-packages\flask_admin\static\admin\js\form.js. The original URL generated to get a tile is:
https://api.mapbox.com/styles/v1/mapbox/<MAPBOX_MAP_ID parameter>/tiles/12/2258/2457?access_token=<MAPBOX_ACCESS_TOKEN parameter>
However, the correct one is:
https://api.mapbox.com/styles/v1/<MAPBOX_MAP_ID parameter>/tiles/12/2258/2457?access_token=<MAPBOX_ACCESS_TOKEN parameter>
That is, I had to remove the mapbox word from the URL.
To do that I made some changes in form.js file:
//var mapboxUrl = 'https://api.mapbox.com/styles/v1/mapbox/'+window.MAPBOX_MAP_ID+'/tiles/{z}/{x}/{y}?access_token='+window.MAPBOX_ACCESS_TOKEN
var mapboxUrl = 'https://api.mapbox.com/styles/v1/'+window.MAPBOX_MAP_ID+'/tiles/{z}/{x}/{y}?access_token='+window.MAPBOX_ACCESS_TOKEN
Then, it's working now:

Mapbox WMTS support in OpenLayers

I have created a Mapbox style using Mapbox Studio and set it to be used over WMTS. The URL of the style is:
https://api.mapbox.com/styles/v1/username/styleId/wmts?access_token=token
where styleId, username and token are variable fields.
When I try to create a WMTS layer in OpenLayers using the url above, the tileGrid is created successfully using createFromCapabilitiesMatrixSet but I get a response error Invalid query param layer from Mapbox.
After some investigation, I noticed that:
The response error persists for all query parameters that are appended from OpenLayers when creating the tile load function. It looks like that Mapbox does not recognise them properly.
OpenLayers website and Mapbox also give examples on using XYZ layers for integration between them.
So, is this some kind of unsupported feature of OpenLayers or do I need to configure anything additional when creating the WMTS OpenLayers?
It's much simpler to set up as a standard OpenLayers XYZ layer using
url: 'https://api.mapbox.com/styles/v1/username/styleId/tiles/{z}/{x}/{y}?access_token=token'
as in the examples.
Mapbox provides WMTS support for compatibility with some other systems. It can also be used in OpenLayers, the setup would be
var parser = new ol.format.WMTSCapabilities();
fetch('https://api.mapbox.com/styles/v1/username/styleId/wmts?access_token=token').then(function(response) {
return response.text();
}).then(function(text) {
var layer = new ol.layer.Tile({
source: new ol.source.WMTS(
ol.source.WMTS.optionsFromCapabilities(parser.read(text), {
layer: 'styleId',
matrixSet: 'EPSG:3857'
})
)
});
....
....
....
....
});
Both methods will ultimately load the same tile urls, so there's no advantage in using WMTS where XYZ is supported.

Leaflet offline map without map tiles

We developed a web page where we are showing health facility locations of a country on a map. We used Leaflet for the map display. We actually do not need to display the online map tiles in the background. If we can only show a vector country map that would also be OK. I came to know that tiles can be downloaded and saved offline in Leaflet etc, but not interested in that direction.
What I want is available in this page
Where Leaflet is used but the world map online tiles are not displayed. But the code is quite complex to understand. Is there any easy example or guidance to do what I need?
This is actually quite easy when using a L.GeoJSON layer. First off you would need to find the correct GeoJSON for the region you want to display. For instance, here are some for the US: http://eric.clst.org/Stuff/USGeoJSON. Next create a map like you would normally do:
var map = new L.Map('map', {
'center': [0, 0],
'zoom': 0
});
Then you would need to fetch/load your GeoJSON data into your script using ajax via jQuery or something else and use that to initialize a GeoJSON layer and add that to your map:
// jQuery ajax request
$.ajax({
// url with your geojson data file
'url': 'my.geo.json',
// return json object, not as string
'dataType': 'json',
// on success handle result
'success': function (result) {
// Initialize GeoJSON layer and add to map
var layer = new L.GeoJSON(result).addTo(map);
// Fit map to bounds of your GeoJSON
map.fitBounds(layer.getBounds());
}
});
That's it. You can find lots of GeoJSON datasets online and if you want to know more about the L.GeoJSON i would recommend reading the reference i linked earlier and this tutorial: http://leafletjs.com/examples/geojson.html