====== Map Suite Quick Start Guide For iOS ======
public override void ViewDidLoad()
{
base.ViewDidLoad();
MapView mapView = new MapView(View.Frame);
View.AddSubview(mapView);
}
==== Map Suite Android "Quickstart Sample" ====
The first step in creating our "Quickstart Sample" application is to set references to the ''ThinkGeo.MapSuite.iOS'' , ''ThinkGeo.MapSuite'' and ''ThinkGeo.MapSuite.Shapes'' workspaces at the very top of our code, since we'll use many classes within them. Add the references like this:
using ThinkGeo.MapSuite;
using ThinkGeo.MapSuite.Drawing;
using ThinkGeo.MapSuite.iOS;
using ThinkGeo.MapSuite.Shapes;
using ThinkGeo.MapSuite.Styles;
==== Display World Map ====
Now, Let's add a base overlay to display the world map which is called "WorldStreetAndImageryOverlay".
public override void ViewDidLoad()
{
base.ViewDidLoad();
MapView mapView = new MapView(View.Frame);
View.Add(mapView);
// Set the Map Unit to DecimalDegrees, the Shapefile’s unit of measure.
mapView.MapUnit = GeographyUnit.DecimalDegree;
// Create a WorldStreetAndImageryOverlay.
WorldStreetAndImageryOverlay worldStreetAndImageryOverlay = new WorldStreetAndImageryOverlay();
// Add a WorldStreetAndImageryOverlay .
mapView.Overlays.Add("WorldStreetAndImageryOverlay", worldStreetAndImageryOverlay);
// Set a proper extent for the map. The extent is the geographical area you want it to display.
mapView.CurrentExtent = new RectangleShape(-134, 70, -56, 7);
mapView.Refresh();
}
Now the project is ready, Map Suite Runtime license is required for running and debugging your product. Please open the Product Center, then generate your license. For more details, please refer to (http://wiki.thinkgeo.com/wiki/map_suite_runtime_license_guide_for_mobile).
If we compile and run what we have now, our map should look like the one below. (see Figure 9).
{{mapsuite10:ios:Map_Suite_iOS_QSG_ShowBaseMap.png?300}}
\\
//Figure 9. A sample map of Europe.//
==== Map Suite iOS "Quickstart Sample" ====
In creating our "Quickstart Sample" application, our first step is to set references to the ''ThinkGeo.MapSuite'', ''ThinkGeo.MapSuite.Shapes'' and ''ThinkGeo.MapSuite.iOS'' workspaces at the very top of our code, since we'll use many classes within them. Set the reference like this:
using ThinkGeo.MapSuite;
using ThinkGeo.MapSuite.Drawing;
using ThinkGeo.MapSuite.iOS;
using ThinkGeo.MapSuite.Layers;
using ThinkGeo.MapSuite.Shapes;
using ThinkGeo.MapSuite.Styles;
Now let's look at a code sample to bring this concept to fruition. We'll look at ShapeFiles relating to the entire world. In our example, we have one such ShapeFile:
*world wide country borders (cntry02.shp)
(NOTE: The data used here can be found in the attached sample above in the "\AppData" folder. The data files' build action should be “Content”.)
Our next step is to define and add our layers. All of the following code can be placed in the "ViewDidLoad" event of the form. Here is the code to use for our example.
public override void ViewDidLoad()
{
base.ViewDidLoad();
MapView mapView = new MapView(View.Frame);
View.Add(mapView);
// Set the Map Unit to DecimalDegrees, the ShapeFile’s unit of measure.
mapView.MapUnit = GeographyUnit.DecimalDegree;
WorldStreetAndImageryOverlay worldStreetsAndImageryOverlay = new WorldStreetAndImageryOverlay();
// Add a WorldStreetsAndImageryOverlay.
mapView.Overlays.Add("WorldStreetsAndImageryOverlay", worldStreetsAndImageryOverlay);
// Create a new Layer and pass the path to a ShapeFile into its constructor.
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer("AppData/cntry02.shp");
// Set the worldLayer with a preset Style, as AreaStyles.Country1 has YellowGreen background and black border, our worldLayer will have the same render style.
AreaStyle areaStyle = new AreaStyle();
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 233, 232, 214));
areaStyle.OutlinePen = new GeoPen(GeoColor.FromArgb(255, 118, 138, 69), 1);
areaStyle.OutlinePen.DashStyle = LineDashStyle.Solid;
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = areaStyle;
// This setting will apply from ZoomLevel01 to ZoomLevel20, which means the map will be rendered in the same style, no matter how far we zoom in or out.
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
LayerOverlay layerOverlay = new LayerOverlay();
// Add the ShapeFile layer to the layer overlay
layerOverlay.Layers.Add(worldLayer);
// Add the layerOverlay to map.
mapView.Overlays.Add(layerOverlay);
// Set a proper extent for the map. The extent is the geographical area you want it to display.
mapView.CurrentExtent = new RectangleShape(-134, 70, -56, 7);
// We now need to call the Refresh() method of the Map view so that the Map can redraw based on the data that has been provided.
mapView.Refresh();
}
If you compile and run what you have now, your map should look like the one below. (see Figure 10).
{{mapsuite10:ios:Map_Suite_iOS_QSG_ShowAreaStyle.png?300}}
\\
//Figure 10. A Sample map of Europe.//
So what has occurred here? We've created a layer and added it to the map and the map has rendered it according to its default style parameters. Also, We have used ZoomLevel to display the map the way that we want.
**NOTE:** It is important that the "MapUnit" property of a map object be set using the "GeographyUnit" enumeration. This is because the coordinates stored in a ShapeFile can be in DecimalDegrees (a format of latitude and longitude), feet, meters, or another unit system. Our map has no way to know what the ShapeFile's unit of measurement is until we set it. This information is normally found somewhere in the ShapeFile's documentation (also referred to as its metadata), or within its supplemental data file, as discussed in the section on ShapeFiles. It may also come as a separate .txt, .xml, or .html file that begins with the same file name as the main ShapeFile.
==== Navigate the Map ====
With the code above, you can both display a map and navigate it. You can pan by touch on the device and move finger around; zoom in/out by pinch on the screen with two fingers; double tap to zoom in to the next zoom level. Very powerful for just couple lines of code, isn’t it?
That was an easy start! Now, let's add another Shapefile to the sample so that we will have a total of two layers:
- World country borders ("cntry02.shp")
- World capitals ("capital.shp")
public override void ViewDidLoad()
{
base.ViewDidLoad();
MapView mapView = new MapView(View.Frame);
View.Add(mapView);
// Set the Map Unit to DecimalDegrees, the ShapeFile’s unit of measure.
mapView.MapUnit = GeographyUnit.DecimalDegree;
WorldStreetAndImageryOverlay worldStreetsAndImageryOverlay = new WorldStreetAndImageryOverlay();
// Add a WorldStreetsAndImageryOverlay.
mapView.Overlays.Add("WorldStreetsAndImageryOverlay", worldStreetsAndImageryOverlay);
// Create a new Layer and pass the path to a ShapeFile into its constructor.
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer("AppData/cntry02.shp");
// Set the worldLayer with a preset Style, as AreaStyles.Country1 has YellowGreen background and black border, our worldLayer will have the same render style.
AreaStyle areaStyle = new AreaStyle();
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 233, 232, 214));
areaStyle.OutlinePen = new GeoPen(GeoColor.FromArgb(255, 118, 138, 69), 1);
areaStyle.OutlinePen.DashStyle = LineDashStyle.Solid;
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = areaStyle;
// This setting will apply from ZoomLevel01 to ZoomLevel20, which means the map will be rendered in the same style, no matter how far we zoom in or out.
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer("AppData/capital.shp");
// Similarly, we use the presetPointStyle for cities.
PointStyle pointStyle = new PointStyle();
pointStyle.SymbolType = PointSymbolType.Square;
pointStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.White);
pointStyle.SymbolPen = new GeoPen(GeoColor.StandardColors.Black, 1);
pointStyle.SymbolSize = 6;
PointStyle stackStyle = new PointStyle();
stackStyle.SymbolType = PointSymbolType.Square;
stackStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.Maroon);
stackStyle.SymbolPen = new GeoPen(GeoColor.StandardColors.Transparent, 0);
stackStyle.SymbolSize = 2;
pointStyle.CustomPointStyles.Add(stackStyle);
capitalLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = pointStyle;
// This setting also applies from ZoomLevel01 to ZoomLevel20, so city symbols will be rendered in the same style, no matter how far we zoom in or out.
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
LayerOverlay layerOverlay = new LayerOverlay();
// Add the ShapeFile layer to the layer overlay
layerOverlay.Layers.Add(worldLayer);
layerOverlay.Layers.Add(capitalLayer);
// Add the layerOverlay to map.
mapView.Overlays.Add(layerOverlay);
// Set a proper extent for the map. The extent is the geographical area you want it to display.
mapView.CurrentExtent = new RectangleShape(-134, 70, -56, 7);
// We now need to call the Refresh() method of the Map view so that the Map can redraw based on the data that has been provided.
mapView.Refresh();
}
And the result is as following (Figure 11):
{{mapsuite10:ios:Map_Suite_iOS_QSG_ShowPointStyle.png?300}}
\\
//Figure 11. A map of Europe with the additional borders and capitals layers displayed.//
===== How to Use TextStyle =====
A TextStyle is used to label items on map. As every ShapeFile has a relative .dbf file that includes descriptions for every record, the most common way to use TextStyles is for labeling. For example, WorldCapital Shapefile's corresponding .dbf file contains the field "CITY_NAME". We can use this field to label the cities on our map.
{{mapsuite10:ios:Map_Suite_iOS_QSG_DBFDetails.png}}
Map Suite includes several built-in TextStyles to help us quickly apply attractive city labels. We can simply pick the TextStyle we like and use it.
public override void ViewDidLoad()
{
base.ViewDidLoad();
MapView mapView = new MapView(View.Frame);
View.Add(mapView);
// Set the Map Unit to DecimalDegrees, the ShapeFile’s unit of measure.
mapView.MapUnit = GeographyUnit.DecimalDegree;
WorldStreetAndImageryOverlay worldStreetsAndImageryOverlay = new WorldStreetAndImageryOverlay();
// Add a WorldStreetsAndImageryOverlay.
mapView.Overlays.Add("WorldStreetsAndImageryOverlay", worldStreetsAndImageryOverlay);
// Create a new Layer and pass the path to a ShapeFile into its constructor.
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer("AppData/cntry02.shp");
// Set the worldLayer with a preset Style, as AreaStyles.Country1 has YellowGreen background and black border, our worldLayer will have the same render style.
AreaStyle areaStyle = new AreaStyle();
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 233, 232, 214));
areaStyle.OutlinePen = new GeoPen(GeoColor.FromArgb(255, 118, 138, 69), 1);
areaStyle.OutlinePen.DashStyle = LineDashStyle.Solid;
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = areaStyle;
// This setting will apply from ZoomLevel01 to ZoomLevel20, which means the map will be rendered in the same style, no matter how far we zoom in or out.
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer("AppData/capital.shp");
// Similarly, we use the presetPointStyle for cities.
PointStyle pointStyle = new PointStyle();
pointStyle.SymbolType = PointSymbolType.Square;
pointStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.White);
pointStyle.SymbolPen = new GeoPen(GeoColor.StandardColors.Black, 1);
pointStyle.SymbolSize = 6;
PointStyle stackStyle = new PointStyle();
stackStyle.SymbolType = PointSymbolType.Square;
stackStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.Maroon);
stackStyle.SymbolPen = new GeoPen(GeoColor.StandardColors.Transparent, 0);
stackStyle.SymbolSize = 2;
pointStyle.CustomPointStyles.Add(stackStyle);
capitalLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = pointStyle;
// This setting also applies from ZoomLevel01 to ZoomLevel20, so city symbols will be rendered in the same style, no matter how far we zoom in or out.
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// We create a new Layer for labeling the capitals.
ShapeFileFeatureLayer capitalLabelLayer = new ShapeFileFeatureLayer("AppData/capital.shp");
// We use the preset TextStyle. Here we pass in "CITY_NAME", the name of the field containing the values we want to label the map with.
GeoFont font = new GeoFont("Arial", 9, DrawingFontStyles.Bold);
GeoSolidBrush txtBrush = new GeoSolidBrush(GeoColor.StandardColors.Maroon);
TextStyle textStyle = new TextStyle("CITY_NAME", font, txtBrush);
textStyle.XOffsetInPixel = 0;
textStyle.YOffsetInPixel = -6;
capitalLabelLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = textStyle;
capitalLabelLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Since the map is drawn with tiles, the label needs to draw on the margin to make sure the text is complete after joining the tiles together.
// Create a new Layer Overlay to hold the layer we just created
LayerOverlay layerOverlay = new LayerOverlay();
// Add the ShapeFile layer to the layer overlay
layerOverlay.Layers.Add(worldLayer);
layerOverlay.Layers.Add(capitalLayer);
layerOverlay.Layers.Add(capitalLabelLayer);
// Add the layerOverlay to map.
mapView.Overlays.Add(layerOverlay);
// Set a proper extent for the map. The extent is the geographical area you want it to display.
mapView.CurrentExtent = new RectangleShape(-134, 70, -56, 7);
// We now need to call the Refresh() method of the Map view so that the Map can redraw based on the data that has been provided.
mapView.Refresh();
}
The result should look like this (Figure 12):
{{mapsuite10:ios:Map_Suite_iOS_QSG_ShowTextStyle.png?300}}
\\
//Figure 12. Map of Europe with TextStyle applied.//
Now that we know how to render text and symbols, let's create customized Styles and TextStyles. We'll also specify different ranges of ZoomLevels, and apply varying customized Styles and TextStyles to the same layer at different ZoomLevel ranges.
public override void ViewDidLoad()
{
base.ViewDidLoad();
MapView mapView = new MapView(View.Frame);
View.Add(mapView);
// Set the Map Unit to DecimalDegrees, the ShapeFile’s unit of measure.
mapView.MapUnit = GeographyUnit.DecimalDegree;
WorldStreetAndImageryOverlay worldStreetsAndImageryOverlay = new WorldStreetAndImageryOverlay();
// Add a WorldStreetsAndImageryOverlay.
mapView.Overlays.Add("WorldStreetsAndImageryOverlay", worldStreetsAndImageryOverlay);
// Create a new Layer and pass the path to a ShapeFile into its constructor.
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer("AppData/cntry02.shp");
// Set the worldLayer with a preset Style, as AreaStyles.Country1 has YellowGreen background and black border, our worldLayer will have the same render style.
AreaStyle areaStyle = new AreaStyle();
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 233, 232, 214));
areaStyle.OutlinePen = new GeoPen(GeoColor.FromArgb(255, 118, 138, 69), 1);
areaStyle.OutlinePen.DashStyle = LineDashStyle.Solid;
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = areaStyle;
// This setting will apply from ZoomLevel01 to ZoomLevel20, which means the map will be rendered in the same style, no matter how far we zoom in or out.
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer("AppData/capital.shp");
// Similarly, we use the presetPointStyle for cities.
PointStyle pointStyle = new PointStyle();
pointStyle.SymbolType = PointSymbolType.Square;
pointStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.White);
pointStyle.SymbolPen = new GeoPen(GeoColor.StandardColors.Black, 1);
pointStyle.SymbolSize = 6;
PointStyle stackStyle = new PointStyle();
stackStyle.SymbolType = PointSymbolType.Square;
stackStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.Maroon);
stackStyle.SymbolPen = new GeoPen(GeoColor.StandardColors.Transparent, 0);
stackStyle.SymbolSize = 2;
pointStyle.CustomPointStyles.Add(stackStyle);
// We can customize our own Style. Here we pass in a color and a size.
capitalLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.White, 7, GeoColor.StandardColors.Brown);
// The Style we set here is available from ZoomLevel01 to ZoomLevel05. That means if we zoom in a bit more, it will no longer be visible.
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05;
capitalLayer.ZoomLevelSet.ZoomLevel06.DefaultPointStyle = pointStyle;
// This setting also applies from ZoomLevel01 to ZoomLevel20, so city symbols will be rendered in the same style, no matter how far we zoom in or out.
capitalLayer.ZoomLevelSet.ZoomLevel06.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// We create a new Layer for labeling the capitals.
ShapeFileFeatureLayer capitalLabelLayer = new ShapeFileFeatureLayer("AppData/capital.shp");
// We use the preset TextStyle. Here we pass in "CITY_NAME", the name of the field containing the values we want to label the map with.
GeoFont font = new GeoFont("Arial", 9, DrawingFontStyles.Bold);
GeoSolidBrush txtBrush = new GeoSolidBrush(GeoColor.StandardColors.Maroon);
TextStyle textStyle = new TextStyle("CITY_NAME", font, txtBrush);
textStyle.XOffsetInPixel = 0;
textStyle.YOffsetInPixel = -6;
// We can customize our own TextStyle. Here we pass in the font, size, style and color.
capitalLabelLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("CITY_NAME", "Arial", 8, DrawingFontStyles.Italic, GeoColor.StandardColors.Black, 3, 3);
// The TextStyle we set here is available from ZoomLevel01 to ZoomLevel05.
capitalLabelLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05;
capitalLabelLayer.ZoomLevelSet.ZoomLevel06.DefaultTextStyle = textStyle;
capitalLabelLayer.ZoomLevelSet.ZoomLevel06.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Since the map is drawn with tiles, the label needs to draw on the margin to make sure the text is complete after joining the tiles together.
// Create a new Layer Overlay to hold the layer we just created
LayerOverlay layerOverlay = new LayerOverlay();
// Add the ShapeFile layer to the layer overlay
layerOverlay.Layers.Add(worldLayer);
layerOverlay.Layers.Add(capitalLayer);
layerOverlay.Layers.Add(capitalLabelLayer);
// Add the layerOverlay to map.
mapView.Overlays.Add(layerOverlay);
// Set a proper extent for the map. The extent is the geographical area you want it to display.
mapView.CurrentExtent = new RectangleShape(-134, 70, -56, 7);
// We now need to call the Refresh() method of the Map view so that the Map can redraw based on the data that has been provided.
mapView.Refresh();
}
Can you imagine what the map will look like now? Below is the result. At first it looks like Figure 7, then like Figure 8 as you zoom in further.
{{mapsuite10:ios:Map_Suite_iOS_QSG_ShowLowZoomLevel.png?300}}
\\
//Figure 7. A map of Europe with two ZoomLevels, before zooming in.//
{{mapsuite10:ios:Map_Suite_iOS_QSG_ShowHeightZoomLevel.png?300}}
\\
//Figure 8. The same map with two ZoomLevels, after zooming in.//
===== Summary =====
You now know the basics of using the Map Suite Map control and can start adding this functionality to your own applications. Let's recap what we've 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 requirements of your data.
- Shapefiles provide the data used by a Map control to render a map.
- A Map is the basic control that contains all the other objects used to indicate how the map should be rendered.
- A Map has one-to-many Layers. A Layer correlates one-to-one with a Shapefile (.shp).
- A Layer can have one-to-many ZoomLevels. ZoomLevels help to define ranges (upper and lower scales) of when a Layer should be shown or hidden.