We are attempting to overlay MapBox vector tiles on a MapKit map, so far to no avail. The MKTileOverlay obviously doesn't support MVTs, so what MapKit function would allow us to overlay these tiles (including features, zoom levels, etc.) to our existing Apple Map?
Using raster tiles is not an option for our use case. The tiles must be vector tiles.
func addMap() {
let url = "https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/1/0/0.mvt?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
let tileOverlay = MKTileOverlay(urlTemplate: url)
mapView.addOverlay(tileOverlay)
}
From the Apple MapKit docs for MKTileOverlay, raster or bitmap images are required.
An overlay that covers an area of the map with tiles of bitmap images.
Since MapKit for iOS expects rasters, it is possible to make use of the Mapbox Raster Tiles API to serve up raster versions of your Mapbox tiles.
Your Swift URL would look like this:
let url = "https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/{z}/{x}/{y}#2x?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
You can see an example of what the Mapbox Raster Tile API serves (this is noted in the Mapbox Docs).
curl https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/9/89/206#2x?access_token=YOUR_MAPBOX_ACCESS_TOKEN
Related
I use google maps for my iOS app which primarily displays custom tiles.
I subclass the GMSSyncTileLayer and request the tile using URLSession.shared when I get the data back I pass it to the receiver like this:
let image = UIImage(data: D) ?? kGMSTileLayerNoTile
receiver.receiveTileWith(x: x, y: y, zoom: zoom, image: image)
This is correct according to the Google maps documentation and it successfully renders my tiles:
However, the instant the user pinches to zoom in the tiles are removed from the map and the custom tiles don't show up until the next level of tiles loads.
This behavior is different from MKMapKit and MapBox. They both scale custom tiles before the next level loads. Google maps does this for it's own base tiles. Any idea how to get the same behavior for custom tiles on Google maps iOS SDK?
I'm trying to build a mapping application that will be largely focused around custom tile overlays. Is it possible to load a map that does not contain a basemap layer, e.g. satellite or the basic map?
Desktop Apple Photos has an option to show the "grid" but that doesn't seem to exist in the MKMapType docs. Nor can you set map.mapType to nil.
Any ideas?
I haven't played with it yet, but it looks like there are some MKTileOverlay and MKTileOverlayRenderer classes that you could experiment with?
Edit
I created an MKTileOverlay and added it to my mapView to successfully remove the built-in map images:
let tileOverlay = MKTileOverlay(urlTemplate: "")
tileOverlay.canReplaceMapContent = true
mapView.addOverlays([tileOverlay])
I'm providing an MKMapView with an MKTileOverlay that replaces the map content. The backing tile provider only goes up to zoom level 15. If the user zooms in beyond zoom level 15 it upscales the level 15 tiles on the map instead of going blank.
However, if there is an MKPolygon or MKPolyline present in the map sector, it will only display the shape. It will no longer render the backing tile under it. This only happens when you overzoom.
I've seen some discussiong about overzooming in MapKit but they all seem to be related to versions prior to iOS 7 when a large amount of the Maps appear to have been changed.
Does anyone have experience with this?
I realized that I was completely misinterpreting the functionality that MapKit provides for Map Tiles.
When I zoomed in and saw that my Tiles were rendering I assumed it was an overzoom feature. When the areas that had Polygons were not rendering the Map Tiles as these zoom levels I thought the Polygon Renderer was somehow shutting off the tile Renderer. As it turns out, because the only active renderer at that zoomed in level was the Polygon renderer that was the only part of the canvas being redrawn, so the rest of the canvas was just still showing what it already had on there.
In laymans' terms:
The Map Tile Renderer tells the map "I can draw this large area at zoom levels 0-5." The Polygon Renderer tells the map "I can draw this small area at all zoom levels."
When I'm at zoom level 5 both the Map Tile Renderer and the Polygon Renderer kick off and draw the regions they can handle. When I move into zoom level 6 only the Polygon Renderer kicks off. The map says "I have a renderer that can draw in this region so I'm going to redraw it with that information." Because the Map Tile Renderer doesn't provide tiles for zoom level 6 it won't kick off. The rest of the map still has tiles because there is no renderer that can draw for it, so the map just keeps what it already has on the canvas.
tl;dr: I mistook MapKit not making superfluous draw calls as an overzooming feature.
I have an .mbtiles file and I am using it for offline map (iOS MapBox SDK). But my .mbtiles doesn't have enough data (just simple green rectangle). I want to draw some lines(roads) between points (I download it from my rest API). I found the solution to use RMShape, but I want to use already drawn map. I create my .mbtiles from osm and TileMill. Help me out please.
WhirlyGlobe-Maply SDK can help you achieve this.
It has a mapview and a globe view which you implement on your viewcontroller.
Then you create a layer using your mbtile file as shown below:
let tileSource = MaplyMBTileSource(mbTiles: "your-mbtile-filename")
You add this layer on the globe or map to display the tiles.
And using SDK's function like addShapes(), you can add, circles, vectors, labels, text and icons on the map/globe.
I tried adding lat and long lines programatically. Also tried adding some labels and spheres.
This is how it looks ->
WhirlyGlobe-Maply using mbtile and drawing on top of it
I'd like to draw a grid into my map, that represents the size of a tile at a certain zoom level. So for example I'd like to have a grid on my mapview that shows the outline of a zoom level 10 tile. So the outline of where this tile would be. No matter if the mapview itself is at zoom level 5 or 15, it should display the outline of where that tile would be placed.
The problem I have is how to calculate the proper rect that represents each visible "tile".
Any help is sooo much appreciated!!!
Or maybe the answer to following question would help:
How can I convert a MKMapRect to a MKTileOverlayPath?
I find that MapKit is way too limited when you want to start doing more and more with maps.
I would reccomend using Google Maps SDK for iOS: https://developers.google.com/maps/documentation/ios/start
and then using GMSTileLayer for the tiles:
https://developers.google.com/maps/documentation/ios/reference/interface_g_m_s_tile_layer
In the long run, replacing MapKit with Google maps gives you far more features and options and has better geolocation and reverse geolocation than Apple
You can also look at Mapbox. Between using TileMill to create a grid layer by setting the Map background to a pattern image, you could then only export zoom level 10 and either host it on Mapbox or export it to MBTiles format (SQLite-based). Then one of the Mapbox mobile toolkits could serve the tiles out as an overlay on your map.