Your first map
This walkthrough puts an interactive map on screen. It assumes you have installed the SDK.
Put the view on screen
- Android
- iOS
- NativeScript
<com.massifmaps.ui.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
let mapView = MSFMapView()
view = mapView
<massifmaps:MassifMapView loaded="{{ onMapReady }}" />
Then build the map
The surface API is the shortest way in and the one every example is written against: a layer is a JSON spec, and the same code reads the same in every language.
- Kotlin
- Swift
- TypeScript (NativeScript)
val map = MassifMap.attach(mapView)
map.addLayer("basemap", Spec.of("vector")
.set("source", Spec.of("http")
.set("url", "https://example.com/tiles/{z}/{x}/{y}.pbf")
.set("maxZoom", 14))
.set("style", Spec.of("mbvt")
.set("cartocss", Spec.of("cartocss").set("css", "#water { polygon-fill: #9cc3e0; }"))))
// Longitude first, in degrees — no projection conversion to get wrong.
map.camera().moveTo(Position(-0.8164, 51.2131), 5.0)
let map = MassifMap.attach(mapView)
map.addLayer("basemap", Spec("vector")
.set("source", Spec("http")
.set("url", "https://example.com/tiles/{z}/{x}/{y}.pbf")
.set("maxZoom", 14))
.set("style", Spec("mbvt")
.set("cartocss", Spec("cartocss").set("css", "#water { polygon-fill: #9cc3e0; }"))))
map.camera().moveTo(Position(-0.8164, 51.2131), zoom: 5)
const map = MassifMap.attach(mapView);
map.addLayer('basemap', {
type: 'vector',
source: { type: 'http', url: 'https://example.com/tiles/{z}/{x}/{y}.pbf', maxZoom: 14 },
style: { type: 'mbvt', cartocss: { type: 'cartocss', css: '#water { polygon-fill: #9cc3e0; }' } }
});
map.camera().moveTo([-0.8164, 51.2131], { zoom: 5 });
Any {z}/{x}/{y}.pbf endpoint on the OpenMapTiles schema works. For a real style, point at a
style project instead of inline CartoCSS — see style sets,
and the style CLI if you are converting one from MapBox.
The same thing with the object API
The classic class-per-capability API is still fully supported, and is what the Javadoc / Jazzy reference documents.
- Kotlin
- Swift
val source = HTTPTileDataSource(0, 14, "https://example.com/tiles/{z}/{x}/{y}.pbf")
val style = CartoCSSStyleSet("#water { polygon-fill: #9cc3e0; }")
val baseLayer = VectorTileLayer(source, MBVectorTileDecoder(style))
mapView.layers.add(baseLayer)
// Coordinates are in the layer's projection (EPSG:3857 by default), so they need converting.
val proj = baseLayer.dataSource.projection
mapView.setFocusPos(proj.fromWgs84(MapPos(-0.8164, 51.2131)), 0f)
mapView.setZoom(5f, 0f)
let source = MSFHTTPTileDataSource(minZoom: 0, maxZoom: 14,
baseURL: "https://example.com/tiles/{z}/{x}/{y}.pbf")
let style = MSFCartoCSSStyleSet(cartoCSS: "#water { polygon-fill: #9cc3e0; }")
let baseLayer = MSFVectorTileLayer(dataSource: source,
decoder: MSFMBVectorTileDecoder(style: style))
mapView.getLayers()?.add(baseLayer)
let proj = baseLayer!.getDataSource()!.getProjection()!
mapView.setFocus(proj.fromWgs84(MSFMapPos(x: -0.8164, y: 51.2131)), durationSeconds: 0)
mapView.setZoom(5, durationSeconds: 0)
The object API is generated by SWIG, so class names map 1:1 across languages with a platform prefix or namespace:
| Concept | Android (Java/Kotlin) | iOS (Objective-C/Swift) |
|---|---|---|
| Map view | com.massifmaps.ui.MapView | MSFMapView |
| Position | com.massifmaps.core.MapPos | MSFMapPos |
| Vector tile layer | com.massifmaps.layers.VectorTileLayer | MSFVectorTileLayer |
The surface API has no such split — an id and a spec are the same string everywhere.
Where to go from here
- Examples — every one is a single file, in Java, Objective-C and TypeScript.
- Surface API — ids, specs, paths and events, and the generated reference.
- Vector objects — markers, lines, polygons, popups.
- Offline maps — MBTiles, PMTiles and packaged tiles.
- Features — 3D terrain, contours, hillshade and more.