Welcome to Map Suite™ from ThinkGeo, a full featured mapping control that makes it easy for any Microsoft .NET Developer to add mapping functionality to a Microsoft .NET 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 get started quickly to building your own spatially aware applications. Like any new software, there is some learning to be done.
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.
Setting Up the Environment
Let's start with a new Web Site project in the Visual Studio.NET IDE and call it MexicoMap (see Figure 1), we can set the location to "File System" to make it easier.
Figure 1. Creating a new project in the Visual Studio.NET IDE.
The project MexicoMap is created in a new solution called MexicoMap. The wizard creates several files including a web.config file and a Webform called Default.aspx.
Next we need to put a Map control on the Form from our Toolbox. The Map control is located on the Toolbox under Windows Forms (see Figure 2). If you do not see these controls, you will need to add them to your Toolbox manually.
Adding the Map Controls to the Visual Studio.NET IDE Toolbar
- When you first open the Visual Studio.NET IDE after installing Map Suite, you may not see the controls in the Toolbox. You will need to follow these steps to add the controls.
Hover on Toolbox and right click anywhere on list of controls. You will get a pop-up menu. Choose "Choose Items...".
- A dialogue box to Choose Toolbox Items will appear. You will need to select the .NET Framework Components tab and then click the Browse button. Finally navigate to the "C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0" folder and select the WebEdition.dll.
- You should now have the Map Control available in your Toolbox as shown in Figure 2 below.
Figure 2. The Map Control under the Toolbox window.
Adding the Map Control to your Web Form
Draw the Map control on the web form by clicking on the Map Control object in the Toolbox and then dragging and dropping (using the left mouse button) to the size you desire. You can leave the name of the Map control to Map1. Our map will display in it.
web.config
To display the map rendered by Map Suite properly, you must include an HTTP Handler Definition in web.config of your web project, specifically, in the system.web section:
XML
<httpHandlers>
<add verb="GET" path="aspnet_image_processor.axd" type="MapSuite.WebEdition.ImageStreamHandler, WebEdition"/>
</httpHandlers>
This allows Map Suite to send the resulting map back to the requesting client in an image stream.
Now that we have our HTTP Handler set up and a Map Control added, we are ready to add the code.
Map Suite Web "Hello Mexico" Sample
After this section, you will be able to draw a map with the MapControl using your own data. At the very beginning, let's have a look at the data and the important objects we will use.
Shapefiles
Simply put, shapefiles are used by Map Suite to provide data that we will use to draw our map. Shapefiles store binary vector coordinates to be used by the component and has a .shp extension. Shapefiles have two other supplementary files that help Map Suite to work with the data. One is called the .shx file. Its purpose is to provide a simple index of the main shape file. It tells the Map Suite component when to start reading binary data and when to stop. It is much like a directory for reading the binary data, sort of a lookup mechanism. The second supplementary file is the .dbf file. This file holds tabular data associated with the main shapefile. For example, the shapefile may have the coordinates for a line to be drawn that represents a road. The .dbf file may have information to tell you what the name of the road is, or what type of road it is (such as county, state, interstate etc.). All three files need to reside in the same directory as the main shape file, but the Map Suite component only expects you to designate the name and file path of the main shape file. Next, when we discuss layers, you will start understanding a little more about how Maps are constructed in Map Suite using the shape data.
Layers
A Layer in a Map correlates to a single shapefile such as networks of roads. You can think of layers much like actual terrain in the real world. The bare earth might be a layer and has either physically defined boundaries, such as a fence around a military installation, or legal boundaries, such as the border of a country. Another layer on top of that might be roads that are built upon the bare earth. It is important to understand this when working with Layers as they need to be added in the logical order you might expect so that they can be seen from above. In other words, you would not want to lay down roads and then cover them with earth so they could not be seen or used by vehicles.
How do we create and add Layers? First, you should know that there are three types of GeoStyles that layers represent and they are defined a little later in this document. As mentioned above, it follows logically that you would create and add layers based on how they should be viewed so naturally you might start with some polygons such as the outline of a country and all of the regions within it. You might then lay down lines such as rivers and roads and then finally you might lay down points such as cities or places of interest. Keep in mind again that logic will dictate what works best. For instance, laying down roads and then rivers would put rivers on top of roads when it should more than likely be the other way around (the exception here might be a tunnel!).
Map
A Map object is the highest level object that encompasses Layers and some other objects. For now, you can think of a Map as a set of Layers waiting to be rendered at different intervals based on actions performed such as moving in and out or panning across the surface to view another part of the map.
Map Suite Web "Hello Mexico"
Our first step is to set a reference to the Map Suite workspace, at the very top of our code before any other code, so that we do not have to use the fully qualified name of the Map Suite classes in our code. This can be done in the "code-behind" of the Form by selecting the Form and hitting the F7 function key.
C#
using MapSuite;
using MapSuite.Geometry;
using MapSuite.WebEdition;
VB.NET
Imports MapSuite
Imports MapSuite.Geometry
Imports MapSuite.WebEdition
Now let's look at a code sample to bring this concept to fruition. We'll look at Shapefile relating to the country of Mexico. In our example, we have one shapefile:
- The outline of Mexico and its borders (mexico.shp)
(NOTE: The data used in this sample can be found in the installation folder under CSSampleApps\SampleApps\SampleData\Mexico. Figure 3 is an example)
Figure 3. The data used in this sample.
Our next step is to define and add our Layers but before we do that we have to set the MapUnits property of the Map control to DecimalDegrees. The reason for this is that is what the shapefile's unit of measure is inherently in.
All of the following code can be placed in the Page_Load event of the web form. We also will want to put in a check for whether the page is posting back. This is so our Map control can load and render the data once during initial load instead of repeatedly every time a post back to the web server is made, such as when a user wants to zoom in. So let's put in the code to check for post back first, and then we'll put our other code inside that structure.
C#
protected void Page_Load(
object sender,
EventArgs e)
{
if (!IsPostBack)
{
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer mexicoLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp");
Map1.Layers.Add(mexicoLayer);
}
}
VB.NET
Protected Sub Page_Load(
ByVal sender
As Object,
ByVal e
As EventArgs)
Handles Me.Load
If Not IsPostBack
Then
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim mexicoLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp")
map1.Layers.Add(mexicoLayer)
End If
End Sub
If you compile and run what you have, your map should now look similar to the one below. The color of your map may be different, as Map Suite uses a random color to fill in. (see Figure 4).
Figure 4. A simple map of Mexico.
So what has occurred here? We have created a Layer and added it to the Map Control and it has rendered it how it sees fit. How do we control that? This is where ZoomLevels become useful. Before we go to the next step, let's first add some navigation capabilities to our Map such as zooming in and out. Sounds like a lot of work doesn't it? Actually, it is very easy with Map Suite as this type of functionality is built right into the control and is easily activated. Below is a sidebar describing how to implement this functionality.
NOTE: It is very important that the MapUnit property of a Map object be set using the Map Suite.Geometry.MapLengthUnits Enumeration, that’s because shapefiles only store binary vector coordinates, which can be in DecimalDegree, feet, etc and our map have no idea about what it is until we set explicitly. The MapUnit can be in Decimal Degrees, feet, meters etc. This information is normally found somewhere in the documentation or within the supplemental data file as discussed in the section on Shapefiles. Below is an example:
C#
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
VB.NET
map1.MapUnit = MapLengthUnits.DecimalDegrees
This will ensure that the map is drawn correctly and the Layers render correctly and provide expected behavior.
Zooming In and Zooming Out
Map’s default mode is Track Zoom In, which allows us to draw a rectangle using the click-n-drag motion of the mouse and the map will automatically zoom into the area we designate with our rectangle. This allows you to zoom directly down into a certain area of the map quickly.
We want to add the ability to zoom in and out. Add two more Link Button Controls to the Webform, one with the text "Zoom In" and another with "Zoom Out" (let's name the buttons lnkZoomIn and lnkZoomOut).
Now that we have our Link Button Controls, let's put the appropriate code in the Click events of each. Below is the code for the Zoom In button. Double click on the button to add the code.
C#
protected void lnkZoomIn_Click(
object sender,
EventArgs e)
{
Map1.ZoomIn(30);
}
VB.NET
Protected Sub lnkZoomIn_Click(
ByVal sender
As Object,
ByVal e
As EventArgs)
Handles lnkZoomIn.Click
Map1.ZoomIn(30)
End Sub
The above code is telling the Map to zoom in using a percentage. Each click of the button will send the view of the Map inward by the designated percentage and each click back will move the Map backwards by the designated percentage.
Now add the code for the Zoom Out button:
C#
private void btnZoomOut_Click(
object sender, System.EventArgs e)
{
Map1.ZoomOut(30);
}
VB.NET
Private Sub btnZoomOut_Click(
ByVal sender
As Object,
ByVal e
As System.EventArgs)
Handles lnkZoomOut.Click
Map1.ZoomOut(30)
End Sub
How to Use GeoStyle
As we have already displayed the data on the map control, it's time to specify its appearance, make the data display in the way we want. It's time to introduce the GeoStyle and ZoomLevel objects.
GeoStyle
GeoStyle is the way you color and draw your map data. You can specify the color of the country, the width of a road, the shape (triangle, circle, cross etc) of a point.
Map Suite has many preset GeoStyles built in, we have the styles of roads, rivers, cities, countries,etc. This makes it easier to create great looking maps without a lot of hassle.
PresetZoomLevels
GeoStyle defines the way we represents the data, ZoomLevels define the situation at which we want to display them. The reason why we need it is that we may want to display a small town when we are zoomed into a state, but we definitely don't want to display when we are zoomed out looking at the entire country. Every ZoomLevel is a scope, with 2 boundaries as LowerExtent and UpperExtent.
Map Suite includes 18 presetZoomLevels, from ZoomLevel01 to ZoomLevel18. We have already chosen the 18 most common scales at which you may want to change the way your data looks. What is scale? If the 1000-inch length road is 1 inch length on the map, then we say the scale of this map is 1: 1000. Let's say ZoomLevel02 is the scope between 1:1000 to 1:2000, which means every state with the scale between 1:1000 to 1:2000 belongs to ZoomLevel2. If you want the GeoStyle be available between 1:1000 to 1:2000, we can simply code the following:
mexicoLayer.ZoomLevel02.GeoStyle = GeoAreaStyles.Country1
PresetZoomLevels has a very useful property called "ZoomLevel.ApplyUntilZoomLevel"; you can very easily extend your ZoomLevels with it. Let's say you want the GeoStyle be available in ZoomLevel02 thru ZoomLevel10. We can simply code as follows:
mexicoCityLayer.ZoomLevel02.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel10
Now let's have a look at the sample code and see how to use them.
C#
protected void Page_Load(
object sender,
EventArgs e)
{
if (!IsPostBack)
{
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer mexicoLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp");
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1;
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Map1.Layers.Add(mexicoLayer);
}
}
VB.NET
Protected Sub Page_Load(
ByVal sender
As Object,
ByVal e
As EventArgs)
Handles Me.Load
If Not IsPostBack
Then
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim mexicoLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp")
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Map1.Layers.Add(mexicoLayer)
End If
End Sub
And the result is as following (Figure 5):
Figure 5. Mexico map with GeoStyle.
That was easy, wasn't it? Let's add another shapefile to the sample so we will have a total of two layers:
- The outline of Mexico and its borders (mexico.shp),
- The cities of Mexico (cities.shp)
C#
protected void Page_Load(
object sender,
EventArgs e)
{
if (!IsPostBack)
{
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer mexicoLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp");
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1;
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Layer mexicoCityLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\cities.shp");
mexicoCityLayer.ZoomLevel01.GeoStyle = GeoPointStyles.City1;
mexicoCityLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Map1.Layers.Add(mexicoLayer);
Map1.Layers.Add(mexicoCityLayer);
VB.NET
Protected Sub Page_Load(
ByVal sender
As Object,
ByVal e
As EventArgs)
Handles Me.Load
If Not IsPostBack
Then
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim mexicoLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp")
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Dim mexicoCityLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\cities.shp")
mexicoCityLayer.ZoomLevel01.GeoStyle = GeoPointStyles.City1
mexicoCityLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Map1.Layers.Add(mexicoLayer)
Map1.Layers.Add(mexicoCityLayer)
The result is the following (Figure 6):
Figure 6. Mexico map with 2 layers.
How to Use GeoTextStyle
GeoTextStyle
GeoTextStyles are used to label items on a map. As every shape file has a relative DBF file, which includes descriptions for every record, the most common way is to use them for labeling. For example, the corresponding DBF file for the MexicoCity shape file has the field "Name", and we can use this field for labeling.
Similarly, Map Suite has many GeoTextStyles built in; we can just pick the one we like and use it.
C#
protected void Page_Load(
object sender,
EventArgs e)
{
if (!IsPostBack)
{
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer mexicoLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp");
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1;
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Layer mexicoCityLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\cities.shp");
mexicoCityLayer.ZoomLevel01.GeoStyle = GeoPointStyles.City1;
mexicoCityLayer.ZoomLevel01.GeoTextStyle = GeoTextStyles.City1("name");
mexicoCityLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Map1.Layers.Add(mexicoLayer);
Map1.Layers.Add(mexicoCityLayer);
}
}
VB.NET
Protected Sub Page_Load(
ByVal sender
As Object,
ByVal e
As EventArgs)
Handles Me.Load
If Not IsPostBack
Then
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim mexicoLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp")
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Dim mexicoCityLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\cities.shp")
mexicoCityLayer.ZoomLevel01.GeoStyle = GeoPointStyles.City1
mexicoCityLayer.ZoomLevel01.GeoTextStyle = GeoTextStyles.City1("name")
mexicoCityLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Map1.Layers.Add(mexicoLayer)
Map1.Layers.Add(mexicoCityLayer)
End If
End Sub
The result is the following (Figure 7):
Figure 7. Mexico map with GetTextStyle.
Now we know how to render text, render symbols and how to set ZoomLevels. Now let's define two different ZoomLevels in one single layer. Let's try to create our own custom GeoStyle and GeoTextStyle.
C#
protected void Page_Load(
object sender,
EventArgs e)
{
if (!IsPostBack)
{
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer mexicoLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp");
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1;
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Layer mexicoCityLayer = new Layer(@"C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\cities.shp");
mexicoCityLayer.ZoomLevel01.GeoStyle = GeoPointStyles.City1;
mexicoCityLayer.ZoomLevel01.GeoTextStyle = GeoTextStyles.City1("name");
mexicoCityLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel12;
mexicoCityLayer.ZoomLevel13.GeoStyle = GeoPointStyles.GetSimpleCircleStyle(GeoColor.GeographicColors.City1, 3);
mexicoCityLayer.ZoomLevel13.GeoTextStyle = GeoTextStyles.GetSimpleTextStyle("name", "Arial", 8, GeoFontStyle.Bold, GeoColor.SimpleColors.DarkRed);
mexicoCityLayer.ZoomLevel13.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
Map1.Layers.Add(mexicoLayer);
Map1.Layers.Add(mexicoCityLayer);
}
}
VB.NET
Protected Sub Page_Load(
ByVal sender
As Object,
ByVal e
As EventArgs)
Handles Me.Load
If Not IsPostBack
Then
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim mexicoLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\mexico.shp")
mexicoLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.Country1
mexicoLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Dim mexicoCityLayer As Layer = New Layer("C:\Program Files\ThinkGeo\Map Suite Web Edition 2.0\CSSampleApps\SampleData\Mexico\cities.shp")
mexicoCityLayer.ZoomLevel01.GeoStyle = GeoPointStyles.City1
mexicoCityLayer.ZoomLevel01.GeoTextStyle = GeoTextStyles.City1("name")
mexicoCityLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel12
mexicoCityLayer.ZoomLevel13.GeoStyle = GeoPointStyles.GetSimpleCircleStyle(GeoColor.GeographicColors.City1, 3)
mexicoCityLayer.ZoomLevel13.GeoTextStyle = GeoTextStyles.GetSimpleTextStyle("name", "Arial", 8, GeoFontStyle.Bold, GeoColor.SimpleColors.DarkRed)
mexicoCityLayer.ZoomLevel13.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18
Map1.Layers.Add(mexicoLayer)
Map1.Layers.Add(mexicoCityLayer)
End If
End Sub
Can you imagine what the map will look like now? Below is the result. At first it appears like figure 8, but hit the ZoomIn button and watch the map change to figure 9 as you zoom in:
Figure 8. Mexico Map with two ZoomLevels, before Zoom In
Figure 9. Mexico Map with two ZoomLevels, after Zoom In
Summary
You now know the basics of using the Map Suite Map control and be 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 Map Suite 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.
- Shapefiles 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 one-to-many Layers. A Layer correlates one-to-one with a shape file (.shp).
- A Layer can have one-to-many ZoomLevels. ZoomLevels help to define ranges (upper and lower) of when a Layer should be shown or hidden.
If you have questions about anything covered in this QuickStart Guide, the ThinkGeo Support Team is ready and available to help. If we can be of any assistance, please contact us using the below information:
Free Discussion Forums:
ThinkGeo Discussion Forums
Pre-Sales & Customer Support:
ThinkGeo Customer Portal
Support Phone:
(866) 847-7510
Web Site:
http://thinkgeo.com