I am trying to request a static image of a map from Mapbox that has a polygon overlay.
I keep getting a 422 Unknown response.
Below is the url encoded geojson:
https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/geojson(%7B%22type%22%3A%22FeatureCollection%22%2C%22features%22%3A%5B%7B%22id%22%3A%224c97769717bde5d3ece6aa37ad153a26%22%2C%22type%22%3A%22Feature%22%2C%22geometry%22%3A%7B%22type%22%3A%22Polygon%22%2C%22coordinates%22%3A%5B%5B%5B-97.35498290052888%2C47.07901887872825%5D%2C%5B-97.34567101592366%2C47.07901887872825%5D%2C%5B-97.34553174426712%2C47.06840297785641%5D%2C%5B-97.35539079875348%2C47.06965221312885%5D%2C%5B-97.36672817535712%2C47.069627161422176%5D%2C%5B-97.36668040297414%2C47.07906677293954%5D%2C%5B-97.35498290052888%2C47.07901887872825%5D%5D%5D%7D%2C%22properties%22%3A%7B%22title%22%3A%22%22%7D%7D%5D%7D)/auto,13/500x300?access_token=MY_MAPBOX_ACCESS_TOKEN
Below is the geojson structure I have stored in my database field that gets url encoded:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-98.38294, 47.06659],
[-98.38322, 47.05229],
[-98.36687, 47.05221],
[-98.36675, 47.06654],
[-98.38294, 47.06659]
]
]
},
"properties": {
"title": ""
}
}]
}
Any help would be greatly appreciated.
The error you receive back with this request is a descriptive one:
{"message":"The auto parameter cannot be used with additional location parameters, bearing, or pitch."}
The problem with this request is not your overlay data, but rather the fact that you are attempting to include additional position arguments after auto (e.g. /auto,13/) which is not supported.
If you remove ,13 from the request, then the image renders as expected:
I'm developing an integration that will programmatically create product entries in Salesforce, and part of that process needs to be the addition of product images. I'm using the Connect API and am able to make a GET call to the right folder like this (I've scrambled the IDs and what not for this example):
https://example.salesforce.com/services/data/v52.0/connect/cms/delivery/channels/0591G0000000006/contents/query?folderId=9Pu1M000000fxUMSYI
That returns a payload like this:
{
"currentPageUrl": "/services/data/v52.0/connect/cms/delivery/channels/0ap1G0000000006/contents/query?page=0&pageSize=250",
"items": [
{
"contentKey": "MCZ2YVCGLNSBETNIG5P5QMIS4KNA",
"contentNodes": {
"source": {
"fileName": "PET Round.jpg",
"isExternal": false,
"mediaType": "Image",
"mimeType": "image/jpeg",
"nodeType": "MediaSource",
"referenceId": "05T0R000005MthL",
"resourceUrl": "/services/data/v52.0/connect/cms/delivery/channels/0ap1G0000000007/media/MCY2YVCGLNSBETNIG5P4QMIS4KNA/content",
"unauthenticatedUrl": "/cms/delivery/media/MCZ2YVCGLNSBETNIG5P4QMIS4KNA",
"url": "/cms/delivery/media/MCY2YVCGLNSBETNIG5P4QMIS4KNA"
},
"title": {
"nodeType": "NameField",
"value": "844333"
}
},
"contentUrlName": "844333",
"language": "en_US",
"managedContentId": "20T0R0000008U9qUAE",
"publishedDate": "2021-08-18T16:20:57.000Z",
"title": "844333",
"type": "cms_image",
"typeLabel": "Image",
"unauthenticatedUrl": "/cms/delivery/v52.0/0DB1G0000008tfOWAU/contents/20Y0R0000008y9qUAE?oid=00D0R000000OI7GUAW"
}
]
}
I am also able to retrieve images by contentKey with a GET call like this:
https://example.salesforce.com/services/data/v52.0/connect/cms/delivery/channels/0ap1G0000000007/media/MCZ2ZVCGLNSBETMIG5P4QMIS4KNA/content
Anyone know what the endpoint should look like and what parameters etc it should have? I'm having trouble finding anything for this specific scenario in the docs but surely there's a way.
Thanks!
The task I need is:
input: geolocation coordinates from gps, radius
ouput: list of pois (just names) to user can choose
just need analogue for google nearby search (since their cost is too high for a production)
questions:
1) what API is more preferable for this? examples are appreciated
2) do I need own data for pois or there is build in date in mapbox for these purposes?
The Mapbox Tilequery API lets you do exactly this. Here is a step-by-step tutorial explaining how to work with this API, and this API playground lets you experiment with the API. The data queried by the API is determined by the tileset passed as a parameter to your API request. As noted in the linked documentation, tutorial, and playground, you can either use existing Mapbox tilesets are create your own tileset with custom data, depending on your use case.
Note that, depending on the structure of the underlying data in the tileset you use, you might need to do a little extra work to convert a feature returned by the Tilequery API into a name of a POI. For example, consider the response body for below API request which makes use of the default mapbox.mapbox-streets-v8 tileset:
https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/tilequery/-93.1204,44.9472.json?radius=25&limit=5&dedupe&access_token=YOUR_MAPBOX_ACCESS_TOKEN
One particular feature returned by the response body is:
{
"type": "Feature",
"id": 4,
"geometry": {
"type": "Point",
"coordinates": [
-93.12041537130386,
44.947199821761615
]
},
"properties": {
"extrude": "true",
"height": 3,
"min_height": 0,
"type": "house",
"underground": "false",
"tilequery": {
"distance": 1.2132887872688276,
"geometry": "polygon",
"layer": "building"
}
}
}
Although there is no POI name here, you could use the returned coordinates in conjunction with the Mapbox reverse geocoding API endpoint to retrieve names and other relevant POI properties for the POI located at said coordinate.
conversation with Mapbox support
Hi Artemii,
It's Alex from Mapbox Support, happy to help!
You will want to use the Mapbox Tilequery API. The option you will want to utilize is radius. Please be advised that queries will use tiles from the maximum zoom of the tileset, and will only include the intersecting tile plus eight surrounding tiles when searching for nearby features. That means that if your tileset has a maximum extent of z20, the maximum radius that you can search is only a few meters. Here is an API playground that you can test the API out with.
I hope this was helpful!
Hi Alex,
thanks for the quick reply, one more question:
request:
https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/tilequery/55.9414,54.7295.json?radius=25&limit=50&dedupe&geometry=point&access_token=YOUR_MAPBOX_ACCESS_TOKEN
response:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 8,
"geometry": {
"type": "Point",
"coordinates": [
55.94845533370972,
54.72732387401962
]
},
"properties": {
"house_num": "32",
"tilequery": {
"distance": 8.949637333832088,
"geometry": "point",
"layer": "housenum_label"
}
}
},
{
"type": "Feature",
"id": 23629792230,
"geometry": {
"type": "Point",
"coordinates": [
55.948566645383835,
54.72761119224691
]
},
"properties": {
"class": "general",
"filterrank": 4,
"maki": "marker",
"name": "Башинформсвязь",
"name_script": "Cyrillic",
"sizerank": 16,
"type": "Telecommunication",
"tilequery": {
"distance": 23.898768437893523,
"geometry": "point",
"layer": "poi_label"
}
}
}
]
}
question: I understand that I can find info about places I got in the response using reverse geocoding API, but is there another approach to do this? Ideally, I would like to get poi's names from one tilquery request, because in case of using two API's (tilquery + geocoding) I will have to query 4-5 queries instead of only 1 (just worrying because it impacts on cost).
Hi Artemii,
There is a parameter in the Tilequery API called layers that you can use to target a specific layer of your style.
https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/tilequery/55.9414,54.7295.json?radius=25&limit=50&dedupe&geometry=point&layers=poi_label&access_token=
Which gets this response:
{ "type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 32316157590,
"geometry": {
"type": "Point",
"coordinates": [
55.94142526388168,
54.7295828683082
]
},
"properties": {
"category_en": "Supermarket",
"category_zh-Hans": "超市",
"class": "food_and_drink_stores",
"filterrank": 1,
"maki": "grocery",
"name": "Магнит",
"name_script": "Cyrillic",
"sizerank": 16,
"type": "Supermarket",
"tilequery": {
"distance": 9.367370433680872,
"geometry": "point",
"layer": "poi_label"
}
}
}
]
}
You can take this response object and return all the information from the POI. The "name" property is the name of the POI. Was there other properties that you were looking for from the reverse geocoding that are not being returned by the tilequery? It would be helpful for you to share a full example of a workflow using both tilequery and reverse geocoding, and to hear more about your exact use case, and how this tilequery/reverse geocoding operation fits into your larger application workflow.
Hi Alex,
request (without poi label since it doesn't find few bars I know. But if you add this label you only see one result) : https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/tilequery/55.9485,54.7275.json?radius=14&limit=50&dedupe&access_token=YOUR_MAPBOX_ACCESS_TOKEN request
response:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 5,
"geometry": {
"type": "Point",
"coordinates": [
55.9485,
54.7275
]
},
"properties": {
"extrude": "true",
"height": 15,
"min_height": 0,
"type": "building",
"underground": "false",
"tilequery": {
"distance": 0,
"geometry": "polygon",
"layer": "building"
}
}
},
{
"type": "Feature",
"id": 1297495121,
"geometry": {
"type": "Point",
"coordinates": [
55.94833781213748,
54.727526546045794
]
},
"properties": {
"class": "path",
"iso_3166_1": "RU",
"iso_3166_2": "RU-BA",
"len": 4450,
"oneway": "false",
"structure": "none",
"surface": "paved",
"type": "footway",
"tilequery": {
"distance": 10.859473551200084,
"geometry": "linestring",
"layer": "road"
}
}
},
{
"type": "Feature",
"id": 23629792230,
"geometry": {
"type": "Point",
"coordinates": [
55.948566645383835,
54.72761119224691
]
},
"properties": {
"class": "general",
"filterrank": 4,
"maki": "marker",
"name": "Башинформсвязь",
"name_script": "Cyrillic",
"sizerank": 16,
"type": "Telecommunication",
"tilequery": {
"distance": 13.10152056398561,
"geometry": "point",
"layer": "poi_label"
}
}
},
{
"type": "Feature",
"id": 7,
"geometry": {
"type": "Point",
"coordinates": [
55.94869895433047,
54.7274698331467
]
},
"properties": {
"extrude": "true",
"height": 3,
"min_height": 0,
"type": "building",
"underground": "false",
"tilequery": {
"distance": 13.251093067012334,
"geometry": "polygon",
"layer": "building"
}
}
}
]
}
If we decode the first pair of coordinates(55.9485, 54.7275) using reverse geocoding (https://docs.mapbox.com/search-playground), we get Smoky People, ул. Ленина, 32, Уфа, Республика Башкирия 450077, Russia and if we decode all pairs, we will be able to find more cafes and bars (poi's).
Hey Artemii,
The reason for the varied results are the sources of the queries.
The Tilequery API searches for things that are on our Mapbox Streets v8 tileset (which our Mapbox Streets v11 style uses). The data in this tileset majorly comes from OpenStreetMap. If there are missing or outdated places on the map, this is the perfect opportunity to help us improve our map! If you do want to add or edit anything, head to openstreetmap.org, create an account, and make improvements directly. You'll have the option to go through an interactive tutorial to get you started. There are more details for advanced editing here as well: https://labs.mapbox.com/mapping. The Mapbox Streets tileset is updated regularly as features are edited or added to the map, which means that if you edit OpenStreetMap, you will eventually see your changes reflected on your Mapbox map.
The Geocoding API contains data sources from governments, open data projects, and private companies. In some cases, results from the Geocoding API may differ from Mapbox Streets or OpenStreetMap data. Check out this documentation on how geocoding works at Mapbox.
I think the best way to reduce the amount of API calls you make would be to pick one API, either reverse geocoding or Tilequery, and stick with it. With OpenStreetMaps, as tedious as it sounds, you do have the ability to add any POIs you know are missing, or cross reference other sources to add POIs to the map, which will make the place visible on the map as well as appear in your tilequery. With the Geocoding API, due to the nature of some sources and licensing, not all the places that you can search are visible on the map.
In Mapbox studio classic, you just click where you want a new "marker" and it creates one. I want to do the same thing in the new mapbox studio but that feature doesn't seem to exist. Please note, I do not have a dataset to upload, I need to create a dataset through Mapbox Studio.
If anybody has any insight for me that would be super!
You can add your data to Mapbox Studio along with this custom svg marker. I styled it similar to the old Leaflet L.marker: https://github.com/Ccantey/icons/blob/master/svgs/placeMarker-Blue-Shadow.svg
Then in the layout properties you can set "marker-symbol"/"icon-image" to "myMarker-Blue-Shadow":
map.addSource("pointclick", {
"type": "geojson",
"data": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [e.lngLat.lng, e.lngLat.lat]
},
"properties": {
"title": "mouseclick",
"marker-symbol": "myMarker-Blue-Shadow"
}
}
});
map.addLayer({
"id": "pointclick",
type: 'symbol',
source: 'pointclick',
"layout": {
"icon-image": "{marker-symbol}",
"icon-size":1,
"icon-offset": [0, -13]
},
"paint": {}
});