User Tools

Site Tools


map_suite_windows_phone_edition_quick_start_guide

Map Suite Windows Phone Edition Quick Start Guide

Note: The page was created before Map Suite 10. Map Suite 10.0 organized many classes into new namespaces and assemblies as well as had a few minor breaks in compatibility. The majority of previously built code should work without modification assuming the new namespaces are added. For guidance on upgrading your existing code, please check out MapSuite 10 Upgrade Guide.

The Map Suite Windows Phone Edition illustrated QuickStart Guide will guide you through the process of creating a sample application and will help you become familiar with Map Suite. This edition of the QuickStart Guide supports Map Suite Windows Phone Edition 7.0.0.0 or higher.

Welcome to Map Suite™ Windows Phone Edition from ThinkGeo, a full-featured mapping control that makes it easy for any Microsoft .NET developer to add mapping functionality to a Windows Phone application quickly and efficiently. Using the intuitive object model, even developers inexperienced in Geographic Information Systems (GIS) can have fully functional maps working in minutes. The purpose of this guide is to help you quickly get started building your own spatially aware applications. Like any new software, there is some learning to be done along the way. How do we start to learn how to take advantage of the power of Map Suite? The best way is to make a sample application with it. (For the purposes of this guide, let's assume we have installed the Map Suite Windows Phone Evaluation Edition 7.0 to the default folder “C:\Program Files (x86)\ThinkGeo\Map Suite Windows Phone Evaluation Edition 7.0”.

Download the Sample

Important Note

Before you begin, you'll need to download and install all of the tools and packages below:

Please check here for more detailed: System requirements for Windows Phone Emulator.

Setting up the Environment

Let's start with a new Windows Phone Application in Visual Studio 2012 IDE and call it “HelloWorld” (see Figures 1, 2).


Figure 1. Creating a new project in the Visual Studio 2012 IDE.


Figure 2. Select “Windows Phone Application” and name it “HelloWorld”.


Figure 3. Select “Windows Phone OS 8.0” as the “Target Windows Phone OS Version“ .

Adding the Map Control to the Visual Studio IDE Toolbox

When you first open the Visual Studio 2012 IDE after installing Map Suite, you may not see the control in the Toolbox. You will need to follow these steps to add the control.

1. First of all, double-click “MainPage.xaml” in the “HelloWorld” project. Make sure your toolbox contains Windows Phone controls, and then hover over the Toolbox and right-click anywhere on the list of controls. You will get a pop-up menu. Select “Choose Items…” (See Figure 4)


Figure 4. Select “Choose Items”.

2. The “Choose Toolbox Items” dialog will appear. Within this dialog, switch to the “Windows Phone Components” tab, and then click the “Browse…” button. Finally, navigate to the “C:\Program Files (x86)\ThinkGeo\Map Suite Windows Phone Evaluation Edition 7.0\Developer Reference\WindowsPhoneEdition\Client\WindowsPhoneEdition.dll” file.


Figure 5. The “Map” control will appear in the “Choose Toolbox Items” list. Click OK to confirm this operation.

3. You should now have the Map control available in your Toolbox as shown in Figure 6 below.


Figure 6. Windows Phone Map is now available in the toolbox.

4. Let's go to the XAML code area and delete the auto-generated content of the Grid element. (See Figure 7)


Figure 7. Delete the auto-generated content of the Grid element.

5. Drag the map icon from the toolbox into the XAML code, and then set its name to “Map1” and its size to 480×768. (See Figure 8)


Figure 8. The Windows Phone map namespace is added to the XAML automatically.

How to display a simple map at the client side

1. Add “WindowsPhoneMapSuiteCore.dll” to the “HelloWorld” project reference.

2. Add an event handler for the Map's “Loaded” event in XAML code:

<my:Map Name="Map1" Width="480" Height="768" Loaded="Map1_Loaded"/>

Then in the code-behind, add the following code:

using System.Windows;
using Microsoft.Phone.Controls;
using ThinkGeo.MapSuite.WindowsPhoneCore;
using ThinkGeo.MapSuite.WindowsPhoneEdition;
 
namespace HelloWorld
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
 
        private void Map1_Loaded(object sender, RoutedEventArgs e)
        {
            Map1.MapUnit = GeographyUnit.DecimalDegree;
 
            WorldMapKitWmsWindowsPhoneOverlay baseOverlay = new WorldMapKitWmsWindowsPhoneOverlay();
 
            Map1.Overlays.Add(baseOverlay);
 
            Map1.CurrentExtent = new RectangleShape(-131.22, 55.05, -54.03, 16.91);
        }
    }
}

In the code, we are using WorldMapKitWmsWindowsPhoneOverlay as the base map; you can choose to use Bing Maps, Google Maps or OpenStreetMap as well.

If you compile and run the app in the emulator, your map should look like the one below. (See Figure 9)


Figure 9. Display a simple map.

With the code above, not only can you display a map, but you can also navigate it. You can pan by dragging the map, navigate by using the controls at the top left corner of the map, or zoom in and out by pinching and stretching. Very powerful for just a couple lines of code, isn't it?

How to render your own Shapefiles at the client side

1. Add Shapefiles (SHP, SHX, DBF, IDS, IDX…) into your project, and set their build action to “Content”.


Figure 10. Adding Shapefiles to the “HelloWorld” project.

These Shapefiles will be integrated into the XAP file and run at the client side. Later, we'll introduce a way to render your map at the server side.

2. In the code-behind, add the following code:

using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Resources;
using Microsoft.Phone.Controls;
using ThinkGeo.MapSuite.WindowsPhoneCore;
using ThinkGeo.MapSuite.WindowsPhoneEdition;
 
namespace HelloWorld
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
 
        private void Map1_Loaded(object sender, RoutedEventArgs e)
        {
            WriteFileToIsolatedStorage("Resource/MajorCities.shp");
            WriteFileToIsolatedStorage("Resource/MajorCities.DBF");
            WriteFileToIsolatedStorage("Resource/MajorCities.IDX");
            WriteFileToIsolatedStorage("Resource/MajorCities.SHX");
            WriteFileToIsolatedStorage("Resource/MajorCities.IDS");
 
            Map1.MapUnit = GeographyUnit.DecimalDegree;
 
            WorldMapKitWmsWindowsPhoneOverlay baseOverlay = new WorldMapKitWmsWindowsPhoneOverlay();
            Map1.Overlays.Add(baseOverlay);
 
            LayerOverlay layeroverlay = new LayerOverlay();
            Map1.Overlays.Add("LayerOverlay", layeroverlay);
 
            ShapeFileFeatureLayer shapeFileLayer = new ShapeFileFeatureLayer("MajorCities.SHP");
            shapeFileLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.Capital1;
            shapeFileLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = new TextStyle("AREANAME", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColor.SimpleColors.Black));
            shapeFileLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            layeroverlay.Layers.Add(shapeFileLayer);
 
 
            Map1.CurrentExtent = new RectangleShape(-131.22, 55.05, -54.03, 16.91);
            Map1.Refresh();        }
 
        private static void WriteFileToIsolatedStorage(string fileName)
        {
            IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
            string isolatedStorageFileName = Path.GetFileName(fileName);
            if (!isoStore.FileExists(isolatedStorageFileName))
            {
                StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new Uri(fileName, UriKind.RelativeOrAbsolute));
                Stream stream = new IsolatedStorageFileStream(isolatedStorageFileName, FileMode.CreateNew, FileAccess.ReadWrite, isoStore);
                byte[] bytes = new byte[1024];
                long blockCount = streamResourceInfo.Stream.Length / bytes.Length;
                for (int i = 0; i < blockCount; i++)
                {
                    streamResourceInfo.Stream.Read(bytes, 0, bytes.Length);
                    stream.Write(bytes, 0, bytes.Length);
                }
                int restBytesCount = (int)(streamResourceInfo.Stream.Length - bytes.Length * blockCount) % bytes.Length;
                streamResourceInfo.Stream.Read(bytes, 0, restBytesCount);
                stream.Write(bytes, 0, restBytesCount);
                stream.Flush();
                stream.Close();
            }
        }
    }
}

Here we are using ShapeFileFeatureLayer, which reads the files from isolated storage directly.

If you compile and run the app in the emulator, your map should look like the one below. (See Figure 11)


Figure 11. Rendering your own Shapefiles at the client side.

How to use the TextStyle

The TextStyle is used to label items on your map. Because every Shapefile has a related .dbf file that includes descriptions for each record, the most common way to use the TextStyle is for labeling. For example, the Shapefile containing the locations of the major cities of the US has a corresponding .dbf file that contains the field “AREANAME”. We can use this field to label the cities on our map. (See Figure 12)


Figure 12. The AREANAME column in the DBF file.

Map Suite has many TextStyles built in that will help us quickly design attractive labels for the states on our map. We can just pick the TextStyle we like and use it.

Based on the code we have in the last section, we simply need to add the following line of code to the “Map1_Loaded” method:

shapeFileLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = new TextStyle("AREANAME", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColor.SimpleColors.Black));

Compile and run the app in the emulator and your map should look like the one below. (See Figure 13)


Figure 13. Rendering Shapefiles at the client side with a TextStyle for labels.

How to render your own Shapefiles at the server side

If there are too many shapes drawn at the client side, the performance of the application will slow down. To get around this, you can choose to render an overlay on the server side. The following steps will show you how to do that.

1. Create another “ASP.NET Web Application” project in the “HelloWorld” solution.


Figure 14. Create a new Web Application project.

Select “ASP.NET Web Application” and set its name to “HelloWorldConnector”.

Then click “OK” to add this project to the existing solution.

2. Add “MapSuiteCore.dll” and “WindowsPhoneMapConnector.dll” to the newly created Web project’s references. They are located in “C:\Program Files (x86)\ThinkGeo\Map Suite Windows Phone Evaluation Edition 7.0\Developer Reference\WindowsPhoneEdition\Server”.

Also add “WindowsBase.dll” to the project's references.

Next, add the Shapefiles we need to render to the project's “App_Data” folder and set their “Build Action” to “Content”.


Figure 15. Adding Shapefiles to the “HelloWorldConnector” project.

3. Add the following configuration to the web.config in the “handlers” section under the “system.webServer” section:

<add name="GeoTileResource" path="HellowWorldConnector.axd" verb="*" preCondition="integratedMode" type="ThinkGeo.MapSuite.WindowsPhoneEdition.TileHandler"/>

Next, add the following configuration to the web.config file in the “HttpHandlers” section:

<add path="HellowWorldConnector.axd" verb="*" type="ThinkGeo.MapSuite.WindowsPhoneEdition.TileHandler"/>

Finally, add the following configuration to the web.config file in the “appSetting” section:

<add key="PluginsPath" value="\Bin"/>

This configuration sets the path from which plugins will be read. You are free to change this to another folder, but if you do, you will need to copy all of the plugins you build into that folder.

4. Delete the “Default.aspx” file, as this web application's purpose is to provide the Windows Phone application with rendered images, not to show any web pages.

5. Add a new class to this project and name it “HelloWorldConnectorPlugin”.

Then add the following code to this class:

using System.Web;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WindowsPhoneEdition;
 
namespace HelloWorldConnector
{
    public class HelloWorldConnectorPlugin : ConnectorPlugin
    {
        private GeoCollection<ServerLayerOverlay> serverLayerOverlays;
 
        public override GeoCollection<ServerLayerOverlay> ServerLayerOverlays
        {
            get { return serverLayerOverlays; }
        }
 
        public HelloWorldConnectorPlugin()
        {
            serverLayerOverlays = new GeoCollection<ServerLayerOverlay>();
 
            ShapeFileFeatureLayer usStatesLayer = new ShapeFileFeatureLayer(HttpContext.Current.Server.MapPath("~/app_data/USStates.shp"));
            usStatesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            usStatesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.State1;
 
            ServerLayerOverlay serverLayerOverlay = new ServerLayerOverlay("HelloWorldOverlay");
            serverLayerOverlay.Layers.Add(usStatesLayer);
 
            serverLayerOverlays.Add(serverLayerOverlay);
        }
    }
}

At this point, compile the project and copy the resulting DLL to the folder specified in web.config. Now you have finished building the server piece. The next step is to add the rendered results to the client application.

6. Based on what we already have done in the last section, we only need to add the following code to the “Map1_Loaded” method to make it work:

ServerLayerOverlay serverLayerOverlay = new ServerLayerOverlay("HelloWorldOverlay", new Uri("http://192.168.0.80:9000/HellowWorldConnector.axd"));
Map1.Overlays.Add(serverLayerOverlay);

NOTE: The WindowsPhone Emulator provided by “WindowsPhone SDK 8” is unable to works with http://localhost/, so here there are 2 options that we can take to work around the problem before running the application:

  • Deploy the HelloWorldConnector site to IIS, and then access the service using http://[IP] rather than http://localhost.
  • Using the IIS express in Visual Studio, in this way, we need to do more configurations in Visual Studio. Please refer to http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj684580(v=vs.105).aspx#BKMK_Settingupprojectstodemonstratetheproblemandthesolution for more detail.

For example. in this Quick Start, we take the first one. We deploy the site to the test machine’s IIS and take its IP http://192.168.0.80:9000 to access the service provided by Asp.NET applicaiton, the code should be looks like as following:

ServerLayerOverlay serverLayerOverlay = new ServerLayerOverlay("HelloWorldOverlay", new Uri("http://192.168.0.80:9000/HellowWorldConnector.axd"));
Map1.Overlays.Add(serverLayerOverlay);

Please make sure this code is located before the code that adds the LayerOverlay, otherwise the images of US states will cover the images of US major cities.

Compile and run the app in the emulator and your map should look like the one below. (See Figure 16)


Figure 16. Rendering your own Shapefiles at the server side.

Note: If you want to access the connector from a Windows Phone handset, you need to deploy the web application to a public-facing Internet Information Services (IIS) server and change the code that creates the ServerLayerOverlay to point to your server's public URL.

Summary

You now know the basics of using Map Suite Windows Phone Edition and are able to start adding this functionality into your own applications. As you begin developing with Map Suite, you'll want to keep the following in mind:

  1. It is of the utmost importance that the units of measurement (feet, meters, decimal degrees, etc.) be set properly for the map, based on the requirements of your data.
  2. A Map is the basic class that contains all of the other objects that are used to define how the map will be rendered.
  3. A Map has one-to-many Overlays. An Overlay contains one-to-many Layers. A Layer contains the data (from Shapefiles or other data sources) for drawing.
  4. A Layer can have one-to-many ZoomLevels. ZoomLevels help to define ranges of when a layer should be shown or hidden.

Download Sample Code From This Exercise - C# (253 KB)

map_suite_windows_phone_edition_quick_start_guide.txt · Last modified: 2017/03/17 02:43 by tgwikiupdate