-
Notifications
You must be signed in to change notification settings - Fork 12
Getting Started
This is a basic guide on how to get started with CARTO Mobile SDK in Xamarin. It's made a common use-case: you have some map-based that you want to visualize on a mobile map, and possibly in web as well. Then you may want to add some interactions with your map view.
Table of contents
- Uploading your data to carto.com, create a map visualization (optional)
- Creating a license key for your app in carto.com key management
- Android
- iOS
- Creating a minimal mobile app
- Adding Carto Mobile SDK for Xamarin package
- Adding CARTO MapView to your app
- Android
- iOS
- Configuring map using viz.json of your CARTO visualization (optional)
- Android
- iOS
- Adding additional data: pins, user location etc. to the map
- Android
- iOS
- Additional materials
- Open http://carto.com, create new accountor sign in with an existing one
- If you wish to show your existing data, import your map data to carto.com Editor/Builder. See guides about about this in CARTO Docs page
- Create new Map. You can use various thematic maps, or just set colors and other styles for your map. See how the map works on the web. In fact you can use exactly same map image in web and mobile.
- Click Share map, and in this page you will get a URL ending with viz.json, the same json is used in Carto.js as well.
- Open carto.com and go to Settings (your avatar icon in top right of Dashboard) > Your API Keys. You should find Mobile Apps tab, where you can add new apps. If you do not have Mobile Apps, then contact mobile-support@carto.com to activate it.
- Add new app, select Android as type and provide your app's Package name (in AndroidManifest.xml). This will generate your License Key that you need to register for CARTO's services
- Add new app, select iOS as type and provide your app's Bundle Identifier (in Info.plist under Identity). This will generate your License Key that you need to register for CARTO's services
- Create a new Single View Application in Xamarin (if you wish to develop multi-platform, choose Single View Application under Native and tick Use Shared Library)
-
Right click Packages -> Add Package
-
Search for Carto Mobile SDK for Xamarin (NB! Be sure to have ticked Show pre-release packages) and add it
-
Additionally, download nutibright-v3 style file and add it as an Asset if you're developing Android (make sure its Build Action is AndroidAsset) or Resource if you're developing iOS (make sure its Build Action is BundleResource)
- Remove the template code (Button and click counter) from MainActivity.cs
- Remove tempate code from Main.axml
Your Main.axml should look like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<carto.ui.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Or, alternatively, if you prefer to write your view programmatically, it should look like:
using Android.Content;
using Carto.Ui;
namespace CartoSample.Droid
{
public class MyMapView : MapView
{
public MyMapView(Context context) : base (context)
{
}
}
}
At this point your MainActivity.cs should look like:
[Activity(Label = "Carto Xamarin Sample", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : Activity
{
const string LICENSE = "<YOUR-LICENSE-KEY>";
protected MapView MapView { get; set; }
protected Projection BaseProjection = new EPSG3857();
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Register license
MapView.RegisterLicense(LICENSE, ApplicationContext);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
MapView = (MapView)FindViewById(Resource.Id.mapView);
// Set our view from a View.cs file
MapView = new MyMapView(this);
SetContentView(MapView);
// 2. Add base map
AssetPackage styleAssets = new ZippedAssetPackage(AssetUtils.LoadAsset("nutibright-v2a.zip"));
CartoOnlineVectorTileLayer baseLayer = new CartoOnlineVectorTileLayer("nutiteq.osm", styleAssets);
MapView.Layers.Add(baseLayer);
// 3. Set default location and zoom
MapPos berlin = BaseProjection.FromWgs84(new MapPos(13.38933, 52.51704));
MapView.SetFocusPos(berlin, 0);
MapView.SetZoom(10, 0);
}
}
NB! Do not SetContentView() twice in your application. Two approaches here are written as an example
Open your Main.storyboard file and click on your "View", then under Properties and Identity change the Name to Map and Class to MapView, from standard UIView. This lets the storyboard know it's supposed to inherit from MapView. It should look like this:

Now that your View know's it's not a UIView, let's do the same to the controller. It should inherit from GLKit.GLKViewController. You then register your license and set up a basic map.
Your controller should look like this:
public partial class ViewController : GLKit.GLKViewController
{
const string LICENSE = "<YOUR-LICENSE-KEY>";
protected MapView MapView { get { return View as MapView; } }
protected Projection BaseProjection = new EPSG3857();
public ViewController(IntPtr handle) : base(handle)
{
MapView.RegisterLicense(LICENSE);
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Initialize map
var styleAsset = AssetUtils.LoadAsset("nutibright-v2a.zip");
var baseLayer = new CartoOnlineVectorTileLayer("nutiteq.osm", new ZippedAssetPackage(styleAsset));
MapView.Layers.Add(baseLayer);
// 3. Set default location and zoom
MapPos berlin = BaseProjection.FromWgs84(new MapPos(13.38933, 52.51704));
MapView.SetFocusPos(berlin, 0);
MapView.SetZoom(10, 0);
}
}
You should now see a basic world map.
Add MyCartoVisBuilder.cs to shared project, as this is common logic:
public class MyCartoVisBuilder : CartoVisBuilder
{
MapView mapView;
public MyCartoVisBuilder(MapView mapView)
{
this.mapView = mapView;
}
public override void SetCenter(MapPos mapPos)
{
mapView.SetFocusPos(mapView.Options.BaseProjection.FromWgs84(mapPos), 1.0f);
}
public override void SetZoom(float zoom)
{
mapView.SetZoom(zoom, 1.0f);
}
public override void AddLayer(Layer layer, Variant attributes)
{
// Add the layer to the map view
mapView.Layers.Add(layer);
}
}
Add the following method to your activity class:
void UpdateVis(string url)
{
ThreadPool.QueueUserWorkItem(delegate
{
MapView.Layers.Clear();
// Create VIS loader
CartoVisLoader loader = new CartoVisLoader();
loader.DefaultVectorLayerMode = true;
MyCartoVisBuilder builder = new MyCartoVisBuilder(MapView);
try
{
loader.LoadVis(builder, url);
}
catch (Exception e)
{
Toast.MakeText(this, e.Message, ToastLength.Short);
}
});
}
Add the following snippet to your activity's OnCreate:
// 4. Load vis
string url = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json";
UpdateVis(url);
Add the following method to your ViewController:
void UpdateVis(string url)
{
InvokeInBackground(delegate {
MapView.Layers.Clear();
// Create VIS loader
CartoVisLoader loader = new CartoVisLoader();
loader.DefaultVectorLayerMode = true;
MyCartoVisBuilder builder = new MyCartoVisBuilder(MapView);
try
{
loader.LoadVis(builder, url);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
});
}
Add the following snippet to your Controller's ViewDidLoad:
// 4. Load vis
string url = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json";
UpdateVis(url);
Run your app and it should show this map (if you use sample URL):

You can add Points, Markers, Polylines, Polygons, even 3D objects to the map with our SDK.
Here is most basic sample: add simple Marker. With our SDK you do not add directly objects to map, as we try to keep them organized as Layers. So, you add first a special in-memory data source where objects are kept, then a VectorLayer which uses the DataSource, and finally add the Layer to the map. For Markers in VectorLayer you need to define also style.
To achieve this, we're going to use Extension methods (not a requirement). Create a static class called MapExtensions to the shared projet. It should look like this:
public static class MapExtensions
{
public static void AddMarkerToPosition(this MapView map, double x, double y)
{
// Create a new layer
Projection projection = map.Options.BaseProjection;
LocalVectorDataSource datasource = new LocalVectorDataSource(projection);
VectorLayer layer = new VectorLayer(datasource);
// Add layer to map
map.Layers.Add(layer);
MarkerStyleBuilder builder = new MarkerStyleBuilder();
builder.Size = 30;
builder.Color = new Carto.Graphics.Color(0, 255, 0, 255);
// Set marker position and style
MapPos position = projection.FromWgs84(new MapPos(x, y));
MarkerStyle style = builder.BuildStyle();
// Create marker and add it to the source
Marker marker = new Marker(position, style);
datasource.Add(marker);
}
}
Then simply call it from your Activity or Controller as such (a good place for calling it would be after setting the VIS layer):
MapView.AddMarkerToPosition(24.646469, 59.426939);
The coordinates point to Tallinn, Estonia. The result should look like this:

We have sample apps for all major mobile platforms:
- Android: https://github.com/CartoDB/mobile-android-samples
- iOS: https://github.com/CartoDB/mobile-ios-samples
- .NET for Xamarin (Android, iOS) and Windows Phone 10: https://github.com/CartoDB/mobile-dotnet-samples