====== Map Suite Quick Start Guide For MVC ======
@using ThinkGeo.MapSuite;
@using ThinkGeo.MapSuite.Drawing;
@using ThinkGeo.MapSuite.Layers;
@using ThinkGeo.MapSuite.Mvc;
@using ThinkGeo.MapSuite.Styles;
Then, we can add the map and shape file reference code as below:
@{Html.ThinkGeo().Map("Map1", 800, 600)
.MapBackground(new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF")))
.CurrentExtent(-131.22, 55.05, -54.03, 16.91)
.MapUnit(GeographyUnit.DecimalDegree)
.StaticOverlay(overlay =>
{
// We create a new Layer and pass the path to a ShapeFile into its constructor.
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/Countries02.shp"));
// Set the worldLayer to use a preset 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 we can see the world the same style all the time no matter how far we zoom in or out.
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// We need to add the worldLayer to the map's Static Overlay.
overlay.Layer(worldLayer);}).Render();
}
Now it is time to press F5 to start the application. If you have not set up a developer license, the Map Suite Product Center will pop up. You will need to generate your developer license. For more details, please refer to http://wiki.thinkgeo.com/wiki/map_suite_developer_license_guide.
Once the developer license is ready, run the application. Your map should look like the one below: (See Figure 3)
\\
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowAreaStyle.png}}\\
//Figure 3. A sample map of United States.//
\\
So what has occurred here? We have created a layer and added it to the map and the map has rendered 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 ShapeFiles only store binary vector coordinates, which can be in DecimalDegrees, feet, meters, or numerous other unit systems. Our map has no idea what the unit of measurement is until we set it. This information is normally found somewhere in the documentation or within the supplemental data file as discussed in the section on ShapeFiles.
==== Navigate the Map ====
With the above code, you can both display a map and navigate it. You can pan by dragging the map, zoom in by double-clicking, track zoom in by drawing a rectangle with your left mouse button mouse while holding the shift key, or zoom in and out by using the mouse wheel. 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:
- The borders of every country in the world ("countries02.shp")
- The capitals of the world countries ("WorldCapitals.shp")
Change the code in your View page following the example below. You don't need to make any changes to the controller.
@{Html.ThinkGeo().Map("Map1", 800, 600)
.MapBackground(new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF")))
.CurrentExtent(-131.22, 55.05, -54.03, 16.91)
.MapUnit(GeographyUnit.DecimalDegree)
.StaticOverlay(overlay =>
{
// World layer
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/Countries02.shp"));
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;
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(worldLayer);
// Capital layer
ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/WorldCapitals.shp"));
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;
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(capitalLayer);
})
.Render();
}
The result is as follows (Figure 4):
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowPointStyle.png}}
\\
//Figure 4. Map of Europe with 2 layers.//
==== How to Use the TextStyle ====
A TextStyle is used to label items on map. As every ShapeFile has a related .dbf file that includes descriptions for each record, the most common way to use the TextStyle is for labeling features. For example, the ShapeFile containing capitals of the world has a corresponding .dbf file contains the field “CITY_NAME”. We can use this field to label the cities on our map.
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_DBFDetails.png}}
Map Suite has many TextStyles built in to help us quickly design attractive labels for the cities on our map. We can just pick the TextStyle we like and use it.
@{Html.ThinkGeo().Map("Map1", 800, 600)
.MapBackground(new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF")))
.CurrentExtent(-131.22, 55.05, -54.03, 16.91)
.MapUnit(GeographyUnit.DecimalDegree)
.StaticOverlay(overlay =>
{
// World layer
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/Countries02.shp"));
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;
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(worldLayer);
// Capital layer
ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/WorldCapitals.shp"));
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;
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;
capitalLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = textStyle;
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(capitalLayer);
})
.Render();
}
The result is as follows (Figure 5):
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowTextStyle.png}}
\\
//Figure 5. Map of Europe with a TextStyle.//
Now that we know how to render text and render symbols, let's define two different ZoomLevels in one single layer and create our own custom Style and TextStyle.
@{Html.ThinkGeo().Map("Map1", 800, 600)
.MapBackground(new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean))
.CurrentExtent(-131.22, 55.05, -54.03, 16.91)
.MapUnit(GeographyUnit.DecimalDegree)
.StaticOverlay(overlay =>
{
// All of this code can alternatively be placed in the controller.
// Please reference the sample applications that came with your copy of Map Suite MVC Edition for detail.
// World layer
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/Countries02.shp"));
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;
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(worldLayer);
// Capital layer
ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/WorldCapitals.shp"));
// We can customize our own Style. Here we pass in a color and a size.
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 = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.White, 7, GeoColor.StandardColors.Brown);
// The Style we set here is applied from ZoomLevel01 to ZoomLevel05. That means if we zoom in a bit more, this particular style will not be visible anymore.
capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05;
capitalLayer.ZoomLevelSet.ZoomLevel06.DefaultPointStyle = pointStyle;
// The Style we set here is applied from ZoomLevel06 to ZoomLevel20. That means if we zoom out a bit more, this particular style will not be visible anymore.
capitalLayer.ZoomLevelSet.ZoomLevel06.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(capitalLayer);
// Label layer
ShapeFileFeatureLayer capitalLabelLayer = new ShapeFileFeatureLayer(Server.MapPath("~/App_Data/WorldCapitals.shp"));
// We can customize our own TextStyle. Here we pass in the font, the size, the style and the color.
capitalLabelLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("CITY_NAME", "Arial", 8, DrawingFontStyles.Italic, GeoColor.StandardColors.Black, 3, 3);
// The TextStyle we set here is applied from ZoomLevel01 to ZoomLevel05.
capitalLabelLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05;
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.ZoomLevel06.DefaultTextStyle = textStyle;
// The TextStyle we set here is applied from ZoomLevel06 to ZoomLevel20.
capitalLabelLayer.ZoomLevelSet.ZoomLevel06.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
overlay.Layer(capitalLabelLayer);
})
.Render();
}
Can you imagine what the map will look like now? Figure 7 below is the result. At first it looks the same as it did in Figure 6. Now zoom in, and watch the map change to resemble Figure 7 as you do.
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowLowZoomLevel.png}}
\\
//Figure 6. A map of European cities with two ZoomLevels, before zooming in.//
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowHighZoomLevel.png}}
\\
//Figure 7. The same map with two ZoomLevels, after zooming in.//
===== Perform an AJAX HTTP request to the Action of the Controller =====
Map Suite MVC Edition provides a large number of client APIs that allow us to easily operate the map on client side, just as we have done on the server side in the above example code. For complete details on the available client APIs, please reference the “JavaScript API Documentation” link in your Map Suite MVC Edition program group, or see [[http://download.thinkgeo.com/docs/MVC/ClientAPI/Default.htm|this page]].
Here we will show you how to perform an AJAX request to update the DynamicOverlay of the map according to the different parameters passed in from the client.
====Client APIs used====
ajaxCallAction: function (controller, action, params, callback)
====Parameters====
* **controller** {String} - The name of the controller
* **action** {String} - The name of the action
* **params** {object} - The parameters in JSON format
* **callback** {function} - The callback function which is used to process the data sent from the server
We will need to access the parameters passed from here in the action, and apply the MapActionFilterAttribute to the specified action of the controller.
The code in your View page should look like this:
@{Html.ThinkGeo().Map("Map1", 800, 600)
.MapBackground(new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF")))
.CurrentExtent(-131.22, 55.05, -54.03, 16.91)
.MapUnit(GeographyUnit.DecimalDegree)
.CustomOverlays(overlays =>
{
overlays.WorldMapKitWmsWebOverlay();
overlays.LayerOverlay("ShapeOverlay", false, TileType.MultipleTile);
})
.Render();
}
Show US States
Show US Cities
Now copy and paste the code below about the accessed action into your “HomeController” page:
[MapActionFilter]
public void UpdateOverlay(Map map, GeoCollection
If we compile and run the application now, it should look like the screenshot below:
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowUSStates.png}}
You can click the checkboxes for "Show US States" or "Show US Cities" to load different layers to the map. For example, if you check the "Show US States" box, the map should look like this:
{{mapsuite10:mvc:Map_Suite_Mvc_QSG_ShowUSCities.png}}
This completes this scenario. The next thing you might want to do is to make it run on another machine that does not have a developer license. A runtime license is the one we are looking for. Here is the guide to generate a runtime license: http://wiki.thinkgeo.com/wiki/map_suite_runtime_license_guide_for_desktop
===== Summary =====
You now know the basics of using Map Suite MVC Edition and are able to start adding this 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 unit of measurement (feet, meters, decimal degrees, etc.) be set properly for the map, based on the requirements of your data.
-ShapeFiles (and other data sources like Oracle, Postgre, SQL 2008, etc.) provide the data used by Map Suite to render a map.
-A Map is the basic class that contains all of the other objects that are used to define how the map will be rendered.
-A Map has one-to-many Layers. A Layer contains the data (from ShapeFile or other data sources) for drawing.
-A layer can have one-to-many ZoomLevels. ZoomLevels help to define ranges of when a layer should be shown or hidden.
-Compared to Map Suite WebForms, MVC provides many more client APIs which are used to operate the map and easily communicate with the server side.