Quickstart Guides¶
Xamarin.Forms Quickstart Guide¶
This will introduce you to ThinkGeo Mobile Maps by getting a nice looking map up and running with ThinkGeo background map along with some external data on a Xamarin.Forms application. By the end of this guide, you should have a basic understanding of how to use the Mobile Maps controls.
Step 1: Install Prerequisites¶
Visual Studio will help guide you to setup your XamarinForms environment for both iOS and Android. Refer to the Xamarin for Visual Studio guide for more info.
Android Prerequisites¶
- Xamarin
- The Android SDK
- An Android Emulator
iOS Prerequisites¶
To develop on Mac, you need:
- XCode, which provides iOS emulator.
- A development IDE, it could be Visual Studio for Mac, Xamarin Studio or others.
- Xamarin.
- A provisioning profile is needed if you want to test on an iOS device.
To develop on Windows, you need:
- A development IDE, such as Visual Studio or Xamarin Studio
- Xamarin.
- A Mac machine with XCode installed and on the same network as your Windows machine.
Step 2: Set Up a New Project¶
Create a new project and select the Mobile App (Xamarin.Forms)
project template. Name your application ThinkGeoMobileQuickstart
and select the Blank application project template.
Once created, there will be 3 projects in the solution:
ThinkGeoMobileQuickstart
- The is where our shared will liveThinkGeoMobileQuickstart.Android
- Android specific code (no modifications will be needed to this project in this demo)ThinkGeoMobileQuickstart.iOS
- iOS specific code (no modifications will be needed to this project in this demo)
Go ahead and run the application. By default, Visual Studio will set you up with an Android emulator if you do not already have one. If you wish to debug the application for iOS, set your starting project to ThinkGeoMobileQuickstart.iOS
and Visual Studio will assist you to connect to your remote Mac machine.
Step 3: Implement the code¶
Once your blank application is up and running, install the following NuGet packages for each project:
ThinkGeoMobileQuickstart
ThinkGeo.UI.XamarinForms
ThinkGeoMobileQuickstart.Android
ThinkGeo.UI.XamarinForms.Android
ThinkGeoMobileQuickstart.iOS
ThinkGeo.UI.XamarinForms.iOS
Open the MainPage.xaml
found in the ThinkGeoMobileQuickstart
project and add the following XML namespace to the ContentPage
:
<!-- MainPage.xaml -->
xmlns:ThinkGeo="clr-namespace:ThinkGeo.UI.XamarinForms;assembly=ThinkGeo.UI.XamarinForms"
Next, replace all elements in the StackLayout
with a single MapView
:
<!-- MainPage.xaml -->
<ThinkGeo:MapView x:Name="mapView" VerticalOptions="FillAndExpand"/>
Now that the MapView
has been added to the MainPage, we need to setup the map on the code side. For that, you will need to add two usings to MainPage.xaml.cs
:
// MainPage.xaml.cs
using ThinkGeo.Core;
using ThinkGeo.UI.XamarinForms;
Next, override the ContentPage
's OnAppearing
method to setup the map:
// MainPage.xaml.cs
protected override void OnAppearing()
{
base.OnAppearing();
// Set the map's unit of measurement to meters(Spherical Mercator)
mapView.MapUnit = GeographyUnit.Meter;
// Add Cloud Maps as a background overlay. The keys provided below are just demo keys
var thinkGeoCloudVectorMapsOverlay = new ThinkGeoCloudVectorMapsOverlay("9ap16imkD_V7fsvDW9I8r8ULxgAB50BX_BnafMEBcKg~", "vtVao9zAcOj00UlGcK7U-efLANfeJKzlPuDB9nw7Bp4K4UxU_PdRDg~~", ThinkGeoCloudVectorMapsMapType.Light);
mapView.Overlays.Add(thinkGeoCloudVectorMapsOverlay);
// Set the map extent
mapView.CurrentExtent = new RectangleShape(-10000000, 10000000, 10000000, -10000000);
}
Build the project and make sure it builds successfully.
Step 4: Activate a Free Evaluation License¶
If you try to run the application now, "A license is needed" exception will be thrown if a valid .mapsuitelicense
file is not found. A free 60-day license can be created using the following steps:
Launching ThinkGeo Product Center¶
- Run
ThinkGeo.ProductCenter.exe
to open the product center. This can be found in thebin
folder of theThinkGeoMobileQuickstart.Android
orThinkGeoMobileQuickstart.iOS
project. (ThinkGeo.ProductCenter.exe
can only be opened on Windows, there's a CLI version for Mac.) - Click on
Log In
in the upper-right corner, input the username/password to login or clickCreate a new account
to create a free ThinkGeo account.
Activating and Creating an Android License¶
- Click on the
ThinkGeo UI Mobile for Android
tab and activate an evaluation license. - To generate a runtime license for the sample app, you'll need to find the package name for your sample project. In Visual Studio, this can be found by right-clicking on the
ThinkGeoMobileQuickstart.Android
project in the solution explorer and navigating toProperties -> Android Manifest -> Package Name
- Copy the
Package Name
to theRuntime License
input box to the right of the Product Center and clickCreate
. Save the newly created license to theAssets
folder of the solution (ThinkGeoMobileQuickstart.Android\Assets
). - Add the license to the project in the solution explorer by right-clicking on the
Assets
folder and selectingAdd -> Existing Item
. - Right-click on the license and select
Properties
. Ensure that theBuild Action
is set toAndroidAsset
Activating and Creating an iOS License¶
- Click the
ThinkGeo UI Mobile for iOS
tile and then click onStart Evaluation
(orActivate License
if you already have purchased a full license). Now you can see a textbox with text placeholderBundle Identifer
on the right. - Get the project's bundle identifier in
info.plist
, copy and paste it to the 'bundle dentifier' textbox in product center. - Click 'Create' and save the license file (the file name would be
<bundle-identifer>.mapsuitelicense
) to the solution's root folder. - Add the license to the project in the solution explorer by right-clicking the project and elect
Add -> Existing Item...
. - Right-click the license file in the solution explorer, select
Properties
and change theBuild Action
toBundleResource
.
Rebuild the solution after adding the license files and then run the application. If all is well, you should see a map!
Step 5: Adding an External Data Source¶
Now let's add an external data source (Shape File) to the map.
- Download WorldCapitals.zip shapefile and unzip it in your project under a new folder called
SampleData
. - Include those files to the project. Multi-select them and change the Build Action to "EmbeddedResource".
Unfortunately, reading from the filesystem is a bit tricky with Xamarin. So, we will need to take our EmbeddedResource shapefiles and copy them to the LocalApplicationData directory before we can display them on the map. To do this, we can run some code on application startup in App.xaml.cs
:
// App.xaml.cs
public App()
{
InitializeComponent();
}
protected override async void OnStart()
{
await CopyAssets();
MainPage = new MainPage(); // Moved from App constructor
}
/// <summary>
/// Copies all embedded resources to the LocalApplicationData directory
/// </summary>
private async Task CopyAssets()
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(App)).Assembly;
foreach (var resourceName in assembly.GetManifestResourceNames())
{
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// Change the replace value to whatever your project's name is
string[] parts = resourceName.Replace("ThinkGeoMobileQuickstart.", "").Split('.');
string localPath = "";
for (int i = 0; i < parts.Length; i++)
{
// Default delimiter to '/' for the directory structure
var delimiter = "/";
// Use '.' delimiter for file extensions
if (i == parts.Length - 1) delimiter = ".";
// Don't use a delimiter for the first part
if (i == 0) delimiter = "";
localPath += $"{delimiter}{parts[i]}";
}
string targetFilePath = Path.Combine(appDataPath, localPath);
string targetDir = Path.GetDirectoryName(targetFilePath);
if (!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir);
if (!File.Exists(targetFilePath))
{
using (var targetStream = File.Create(targetFilePath))
{
Stream sourceStream = assembly.GetManifestResourceStream(resourceName);
await sourceStream.CopyToAsync(targetStream);
sourceStream.Close();
}
}
}
}
There's a few important notes about the above code. First, we need to copy these files asynchronously, so we needed to add the async keyword to the OnStart
method. Second, we moved the assignment of the MainPage
to the OnStart
method after we finished copying the assets. Finally, EmbeddedResources are always named ProjectName.Path.To.File.txt
. So, when we copy the files to the filesystem, we are stripping ProjectName.
.
Now, that we can copy over the WorldCapital shapefile, let's add it to the map:
// MainPage.xaml.cs
protected override void OnAppearing()
{
base.OnAppearing();
//...
// Create a new Feature Layer using the WorldCapitals.shp Shapefile.
ShapeFileFeatureLayer worldCapitalsFeatureLayer = new ShapeFileFeatureLayer(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SampleData/WorldCapitals.shp"));
// Set the pointstyle to black circle with the size of 8.
worldCapitalsFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyle.CreateSimpleCircleStyle(GeoColors.White, 8, GeoColors.Black);
// Apply the point style from zoomlevel01 to zoomlevel20, that's across all the zoomlevels.
worldCapitalsFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Convert the world capital featurelayer from DecimalDegrees, which is the projection of the raw data, to Spherical Mercator, which is the projection of the map.
worldCapitalsFeatureLayer.FeatureSource.ProjectionConverter = new ProjectionConverter(Projection.GetDecimalDegreesProjString(), Projection.GetSphericalMercatorProjString());
// Add the Layer to an Overlay and add the overlay to the map.
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(worldCapitalsFeatureLayer);
mapView.Overlays.Add(layerOverlay);
}
Now, when you run the application, the shapefiles will be added to the LocalApplicationData directory which then allows it to be displayed on the map!
Summary¶
You now know the basics of using the ThinkGeo Map controls and are able to get started adding functionality into your own applications. Let's recap what we have learned about the object relationships and how the pieces of ThinkGeo UI work together:
- It is of the utmost importance that the units (feet, meters, decimal degrees, etc.) be set properly for the Map control based on the data.
- FeatureLayers provide the data used by a Map control to render a map.
- A Map is the basic control that contains all of the other objects that are used to tell how the map is to be rendered.
- A Map has many layers. A Layer correlates one-to-one with a single data source and typically of one type (point, polygon, line etc).
- A FeatureLayer can have several ZoomLevels. ZoomLevels help to define ranges (upper and lower) of when a Layer should be shown or hidden.
You are now in a great position to look over the other samples available and explore our other features.
Quick Start: Display a Simple Map on iOS¶
This will introduce you to ThinkGeo Mobile Maps by getting a nice looking map up and running with ThinkGeo background map along with some external data on a Xamarin iOS application. By the end of this guide, you should have a basic understanding of how to use the Mobile Maps controls.
Step 1: Install Prerequisites¶
In order to develop and debug Xamarin iOS applications, you'll need to have a few prerequisites set up.
To develop on Mac, You need:
- XCode, which provides iOS emulator.
- A development IDE, it could be Visual Studio for Mac, Xamarin Studio or others.
- Xamarin. It has been installed by default in Visual Studio for Mac or Xamarin Studio, might need to be manually installed in other IDEs.
- A provisioning profile is needed if you want to test on an iOS device.
To develop on Windows, you need:
- A Mac Machine in the same network as your build server. XCode needs to be installed on that machine.
- And on your Windows machine, you need:
- A development IDE, such as Visual Studio or Xamarin Studio
- Xamarin. Make sure it is well installed.
Even it sounds complicated, Microsoft in fact has made it very straightforward to connect to a MAC and develop Xamarin on Windows. So if you are a .NET developer get used to Visual Studio, feel free to stay on Windows for Xamarin development. This quick start guide is based on Visual Studio on Windows and there's no problem at all to start your application on Mac.
Here a few handy links for installation and setup of these prerequisites using Visual Studio:
Step 2: Set Up a New Project¶
Once these prerequisites have been installed, let's create a new iOS App (Xamarin) project in Visual Studio and select Single View App template. Here is a guide to creating a sample project for reference.
Go ahead and run the project once it is created, and Visual Studio will help you to locate the MacOS server and initialize the connection. If everything goes well, you should see the iOS emulator get launched on Windows and the default project runs in the emulator.
Step 3: Implement the code¶
Install NuGet Package ThinkGeo.UI.iOS
to the project:
dotnet add package ThinkGeo.UI.iOS
Add the required usings to the ViewController.cs file:
using ThinkGeo.Core;
using ThinkGeo.iOS.UI
Update ViewDidLoad()
method in ViewController.cs
as following:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
// Creat a new MapView, which is the canvas of the map, and add it to the View.
MapView mapView = new MapView(View.Frame);
View.AddSubview(mapView);
// Set the Map Unit to Meter and set the map's current extent to North America.
mapView.MapUnit = GeographyUnit.Meter;
mapView.CurrentExtent = new RectangleShape(-13939426, 6701997, -7812401, 2626987);
// Create a new ThinkGeoCloud Overlay using Client ID / Client Secret, and add it the overlay to MapView.
string clientKey = "9ap16imkD_V7fsvDW9I8r8ULxgAB50BX_BnafMEBcKg~";
string secret = "vtVao9zAcOj00UlGcK7U-efLANfeJKzlPuDB9nw7Bp4K4UxU_PdRDg~~";
ThinkGeoCloudVectorMapsOverlay thinkGeoCloudMapsOverlay = new ThinkGeoCloudVectorMapsOverlay(clientKey, secret);
mapView.Overlays.Add(thinkGeoCloudMapsOverlay);
mapView.Refresh();
}
Step 4: Apply an Evaluation License for Free¶
Build the project and make sure it builds through. "A license is needed" exception will be thrown if you run it though and here is how to fix it:
- Run
ThinkGeo.ProductCenter.exe
to open the product center. This can be found in thebin
folder of the project. (ThinkGeo.ProductCenter.exe
can only be opened on Windows, there's a CLI version for Mac.) - Click on
Log In
in the upper-right corner, input the username/password to login or clickCreate a new account
to create a ThinkGeo account for free. - Once logged in, click on
ThinkGeo UI Mobile for iOS
tile and then click onStart Evaluation
(it would beActivate License
if you already purchased), now you can see a textbox with textholderBundle Identifer
on the right. - Now we need to generate a license for the project following the steps below:
- Get the project's bundle identifier in
info.plist
, copy and paste it to the 'bundle dentifier' textbox in product center. - Hit 'Create' and save the license file (the file name would be
bundle-identifer.apsuitelicense
) to the solution's root folder. - Add the license to the project in the solution explorer by right-clicking the project and elect
Add -> Existing Item...
. - Right-click the license file in the solution explorer, select
Properties
and change theBuild Action
toBundleResource
.
- Get the project's bundle identifier in
Now go ahead and run the application and the map will be displayed properly.
Step 5: Adding an External Data Source¶
Now let's add an external data source (Shape File) to the map.
- Download WorldCapitals.zip shapefile and unzip it in your project under a new folder called
SampleData
. - Include those files to the project. Multi-select them and change the Build Action to "Content".
- Now add the following code to
ViewDidLoad()
method.
// Create a new Feature Layer using the WorldCapitals.shp Shapefile.
ShapeFileFeatureLayer worldCapitalsFeatureLayer = new ShapeFileFeatureLayer("SampleData/WorldCapitals.shp");
// Set the pointstyle to black circle with the size of 8.
worldCapitalsFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyle.CreateSimpleCircleStyle(GeoColors.White, 8, GeoColors.Black);
// Apply the point style from zoomlevel01 to zoomlevel20, that's accross all the zoomlevels.
worldCapitalsFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Convert the world capital featurelay from DecimalDegrees, which is the projection of the raw data, to Spherical Mercator, which is the projection of the map.
worldCapitalsFeatureLayer.FeatureSource.ProjectionConverter = new ProjectionConverter(Projection.GetDecimalDegreesProjString(), Projection.GetSphericalMercatorProjString());
// Add the Layer to an Overlay and add the overlay to the map.
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(worldCapitalsFeatureLayer);
mapView.Overlays.Add(layerOverlay);
iOS Summary¶
You now know the basics of using the ThinkGeo Map controls and are able to get started adding functionality into your own applications. Let's recap what we have learned about the object relationships and how the pieces of ThinkGeo UI work together:
- It is of the utmost importance that the units (feet, meters, decimal degrees, etc.) be set properly for the Map control based on the data.
- FeatureLayers provide the data used by a Map control to render a map.
- A Map is the basic control that contains all of the other objects that are used to tell how the map is to be rendered.
- A Map has many layers. A Layer correlates one-to-one with a single data source and typically of one type (point, polygon, line etc).
- A FeatureLayer can have several ZoomLevels. ZoomLevels help to define ranges (upper and lower) of when a Layer should be shown or hidden.
You are now in a great position to look over the other samples available and explore our other features.
Quick Start: Display a Simple Map on Android¶
This will introduce you to ThinkGeo Mobile Maps by getting a nice looking map up and running with some external data and styling on a Xamarin Android application. By the end of this guide, you should have a basic understanding of how to use the Mobile Maps controls.
Step 1: Set Up Prerequisites¶
In order to develop and debug Xamarin Android applications, you'll need to have a few prerequisites set up. These include:
- Xamarin
- The Android SDK
- An Android emulator
Here a few handy links for installation and setup of these prerequisites using Visual Studio:
Step 2: Set Up a New Project¶
Once these prerequisites have been installed, you'll need to create a new Xamarin Android project in your editor of choice. Please refer to your editor's instructions on how to create this project. Here is a guide to creating a sample project using Visual Studio for reference.
Step 3: Add NuGet Packages¶
You'll need to install the ThinkGeo.UI.Android NuGet package. We strongly suggest you use your editor's built in NuGet package manager if possible. If you're not using an IDE you can install it via the the dotnet CLI from inside the project folder where your project file exists.
dotnet add package ThinkGeo.UI.Android
Step 4: Set up the App Template and add the MapView element¶
Open up the main app layout file. In Visual Studio, this should be under the path Resources\layout\activity_main.axml
, and add the ThinkGeo.UI.Android.MapView
element
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ThinkGeo.UI.Android.MapView
android:id="@+id/androidMap"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Step 5: Add Namespaces to MainActivity.cs¶
Add the required usings to the MainActivity.cs file:
using ThinkGeo.Core;
using ThinkGeo.UI.Android;
Step 6: Add the Map Background Overlay¶
Create a new method called ShowMap
in the MainActivity.cs file, and add the code below:
public void ShowMap()
{
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
MapView androidMap = FindViewById<MapView>(Resource.Id.androidMap);
// Set the Map Configuration.
androidMap.MapUnit = GeographyUnit.Meter;
androidMap.ZoomLevelSet = new ThinkGeoCloudMapsZoomLevelSet();
androidMap.CurrentExtent = new RectangleShape(-20000000, 20000000, 20000000, -20000000);
// Add the Cloud Maps Overlay
ThinkGeoCloudRasterMapsOverlay thinkGeoCloudMapsOverlay = new ThinkGeoCloudRasterMapsOverlay("9ap16imkD_V7fsvDW9I8r8ULxgAB50BX_BnafMEBcKg~", "vtVao9zAcOj00UlGcK7U-efLANfeJKzlPuDB9nw7Bp4K4UxU_PdRDg~~");
androidMap.Overlays.Add("CloudRasterMapsOverlay", thinkGeoCloudMapsOverlay);
}
Then, remove the SetContentView
call and call this method from the OnCreate
method in the MainActivity.cs file:
// Remove this call from 'OnCreate'
// SetContentView(Resource.Layout.activity_main);
// Add this call to the 'OnCreate' method
ShowMap();
Step 7: Run the Sample & Register For Your Free Evaluation¶
The first time you run the application, you will be presented with an error requiring a ThinkGeo license to proceed with running the app. In order to register and generate a license for this project, you'll need to perform the following steps:
- Run the ThinkGeo.ProductCenter.exe to open the product center. This can be found in the
bin
folder of your project atpath\to\project\bin\Debug\
. - Click on
Log In
in the upper-right corner andCreate a new account
- Follow the steps on the website to register for your account
- Return to Product Center and log in using your new credentials.
- Click on the
ThinkGeo UI Mobile for Android
tab and activate an evaluation license. - To generate a runtime license for the sample app, you'll need to find the package name for your sample project. In Visual Studio, this can be found by right-clicking on the project in the solution explorer and navigating to
Properties -> Android Manifest -> Package Name
- Copy the
Package Name
to theRuntime License
input box to the right of the Product Center and clickCreate
. Save the mewly created license to theAssets
folder of the solution (path\to\project\Assets
). - Add the license to the project in the solution explorer by right-clicking on the
Assets
folder and selectingAdd -> Existing Item
. - Right-click on the license and select
Properties
. Ensure that theBuild Action
is set toAndroidAsset
You should now be able to see your app with our Cloud Maps layer!
Step 8: Adding an External Data Source - Requesting Permissions¶
Now that you have the basic map set up, you can add custom data to the map. Depending on the data, this can be complex or quite simple. We'll be going over the simple basics of adding custom data.
Download the WorldCapitals.zip shapefile data and unzip it in your project under a new folder in the Assets
folder called AppData
. In order to move this data into storage on the Android device, we'll need to set up our app to request some basic permissions as well.
First, we need to add the required permissions to the Android manifest. This can be done by right-clicking on the project in the solution explorer and navigating to Properties -> Android Manifest
, and finding Required Permissions
near the bottom of the page. We need to ensure that the READ_EXTERNAL_STORAGE
and WRITE_EXTERNAL_STORAGE
options are checked.
Next, we need to set up the method to request permissions. Add the following fields to your MainActivity class:
readonly string[] StoragePermissions =
{
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.WriteExternalStorage
};
const int RequestStorageId = 0;
Add the following usings:
using Android;
using Android.Content.PM;
Then, add the following method to your MainActivity.cs class. This method will handle requesting permissions:
public void RequestRequiredPermissions()
{
const string readPermission = Manifest.Permission.ReadExternalStorage;
const string writePermission = Manifest.Permission.WriteExternalStorage;
if (!(CheckSelfPermission(readPermission) == (int)Permission.Granted) || !(CheckSelfPermission(writePermission) == (int)Permission.Granted))
{
RequestPermissions(StoragePermissions, RequestStorageId);
}
else
{
ShowMap();
}
}
Add the following code to the OnRequestPermissionsResult
method in the MainActivity.cs
:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
switch (requestCode)
{
case RequestStorageId:
{
if(grantResults.Length > 0 && grantResults[0] == Permission.Granted)
{
ShowMap();
}
else
{
Toast.MakeText(this,
"Storage Permissions Denied", ToastLength.Short).Show();
}
}
break;
}
}
Finally, replace the ShowMap
call in the OnCreate
method with a call to the RequestRequiredPermissions
method:
// Replace 'ShowMap()' in the 'OnCreate' method
RequestRequiredPermissions();
Step 9: Adding an External Data Source - Importing Data¶
Now that we have storage permissions set up, we can store the data locally on the Android device. Create a new folder named SampleData
under the Assets
folder in the solution, then add the map data to it. Make sure the resources’ build action is AndroidAsset
.
Now, we can add a method to copy the data to the external storage for the application to use.
private void CopySampleData(string targetDirectory)
{
if (!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory);
foreach (string filename in Assets.List("SampleData"))
{
string sourcePathFilename = Path.Combine("SampleData", filename);
string targetPathFilename = Path.Combine(targetDirectory, filename);
if (!File.Exists(targetPathFilename))
{
string targetPath = Path.GetDirectoryName(targetPathFilename);
if (!Directory.Exists(targetPath)) Directory.CreateDirectory(targetPath);
Stream sourceStream = Assets.Open(sourcePathFilename);
FileStream fileStream = File.Create(targetPathFilename);
sourceStream.CopyTo(fileStream);
fileStream.Close();
sourceStream.Close();
}
}
}
Now we can call this method when we initialize our map, in the ShowMap
method.
public void ShowMap()
{
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
// Copy the required Shapefiles to Device.
string targetDirectory = Path.Combine(Environment.ExternalStorageDirectory.ToString(), "SampleData");
CopySampleData(targetDirectory);
This method will copy data to the target path, if the folder does not exist.
Step 10: Add a Point Data Layer¶
Now we can add the data from the shapefile to the map, in the ShowMap()
method:
// Add a shapefile layer with point style.
var capitalLayer = new ShapeFileFeatureLayer(Path.Combine(Environment.ExternalStorageDirectory.ToString(), @"SampleData/WorldCapitals.shp"));
// Create an overlay to add the layer to and add that overlay to the map.
var customDataOverlay = new LayerOverlay();
customDataOverlay.Layers.Add(capitalLayer);
androidMap.Overlays.Add(customDataOverlay);
Step 11: Styling and Labeling the Data¶
We won't be able to see the points until a style is defined for it. Adding a style is very straightforward, but extremely extensible and powerful.
var capitalStyle = new PointStyle()
{
SymbolType = PointSymbolType.Circle,
SymbolSize = 8,
FillBrush = new GeoSolidBrush(GeoColors.White),
OutlinePen = new GeoPen(GeoColors.Black, 2)
};
capitalLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = capitalStyle;
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
Step 12: Reprojecting the Data¶
If you run the app now, you'll notice that there is just a single point shape in the center of the map! This is because the data is in a completely different projection from the map. We can easily fix that, though, by adding a ProjectionConverter
to the layer from Decimal Degrees(4326) to Spherical Mercator(3857).
// Set the projection of the capitalLayer to Spherical Mercator
capitalLayer.FeatureSource.ProjectionConverter = new ProjectionConverter(4326, 3857);
Now, the data shows up properly on the map!
Step 13: Zoom Into the Data¶
Now, we can make the map zoom into an area based on the extent of the data we added above. In order to do that, we must first open the layer for spatial queries to be made.
// Open capitalLayer for it to be ready for spatial queries. Then, set the extent of the map to the full view of the data.
capitalLayer.Open();
mapView.CurrentExtent = capitalLayer.GetBoundingBox();
Android Summary¶
You now know the basics of using the ThinkGeo Map controls and are able to get started adding functionality into your own applications. Let's recap what we have learned about the object relationships and how the pieces of ThinkGeo UI work together:
- It is of the utmost importance that the units (feet, meters, decimal degrees, etc.) be set properly for the Map control based on the data.
- FeatureLayers provide the data used by a Map control to render a map.
- A Map is the basic control that contains all of the other objects that are used to tell how the map is to be rendered.
- A Map has many layers. A Layer correlates one-to-one with a single data source and typically of one type (point, polygon, line etc).
- A FeatureLayer can have several ZoomLevels. ZoomLevels help to define ranges (upper and lower) of when a Layer should be shown or hidden.
You are now in a great position to look over the other samples available and explore our other features.
Need Help?¶
If you run into any issues with running the samples, please let us know in the Community Forums.
If you have any questions about the product or sales, please contact us at sales@thinkgeo.com.