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
- Web
<com.massifmaps.ui.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
let mapView = MSFMapView()
view = mapView
<Page xmlns:massifmaps="@nativescript-community/ui-massifmaps/ui">
<massifmaps:MassifMap mapReady="{{ onMapReady }}" />
</Page>
<canvas id="map" style="width: 100%; height: 100vh; display: block"></canvas>
The page must be cross-origin isolated - see the web guide.
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)
- JavaScript (web)
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), 5f)
let map = MassifMap.attach(mapView)!
try map.addLayer("basemap", spec: Spec.of("vector")
.set("source", value: Spec.of("http")
.set("url", value: "https://example.com/tiles/{z}/{x}/{y}.pbf")
.set("maxZoom", value: 14))
.set("style", value: Spec.of("mbvt")
.set("cartocss", value: Spec.of("cartocss").set("css", value: "#water { polygon-fill: #9cc3e0; }"))))
map.camera.move(to: MSFPosition(lng: -0.8164, lat: 51.2131), zoom: 5)
import { api } from '@nativescript-community/ui-massifmaps';
// In the view's mapReady handler: attaching before the map is ready throws.
const map = api.attach(args.object);
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 });
import { createMap } from '@massif-maps/web';
const map = await createMap(document.getElementById('map'));
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; }' } }
});
// Zoom numbers on the web are MapLibre's: 4 here shows what 5 shows on Android and iOS.
map.camera().moveTo([-0.8164, 51.2131], { zoom: 4 });
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 map's base projection (EPSG:3857 by default), so they need converting.
val proj = mapView.options.baseProjection
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(cartoCSSStyleSet: style))
mapView.getLayers()?.add(baseLayer)
let proj = mapView.getOptions()!.getBaseProjection()!
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, TypeScript and JavaScript, and runs live on the web.
- 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.