<?xml version="1.0" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">

	<channel>
		<title>ThinkGeo and Map Suite White Papers</title>
		<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/afv/topicsview/Default.aspx</link>
		<description>In-depth research and documentation on Map Suite 2.0 technologies.</description>
		<language>en-US</language>
		<generator>ActiveForums  4.2</generator>
		<copyright>Copyright 2003-2010 ThinkGeo LLC</copyright>
		<lastBuildDate>Thu, 13 Nov 2008 05:48:51 GMT</lastBuildDate><image><url>http://gis.thinkgeo.com/Portals/1/logo.png</url><title>ThinkGeo and Map Suite White Papers</title><link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/afv/topicsview/Default.aspx</link></image>
		<item>
			<title>Integrating Map Suite with SQL Reporting Services</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;This article will show you how to combine data-driven reports and location-driven spatial information, by using Map Suite in concert with SQL Reporting Services.  In the included example, we'll build a report and then display its data thematically on a map of the United States with Map Suite Web Edition. The article is based on Map Suite Web version 1.1 and Microsoft SQL Reporting Services with SP1 applied.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://thinkgeo.com/Download/SQLReportsMapBuilderCode.zip&quot; style=&quot;padding-left:19px; background:url(/portals/1/icons/icon_download_2.gif) no-repeat left center;&quot;&gt;Download code for this article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Today many developers are turning to Microsoft SQL Reporting Services&amp;trade; to deliver great looking reports for their end users. And while having a professional looking report containing tabular data is great, sometimes users demand a more graphical representation of the data such as a chart or a map.&lt;/p&gt;
&lt;p&gt;In this article we will step through the process of building a report based on data included in the AdventureWorks2000 database that is installed with SQL Reporting Services. Once we have a sales report showing the sales data, we will add a map of the United States displaying the sales data thematically by state.&lt;/p&gt;
&lt;p&gt;(Note: This article covers the Webforms Edition of Map Suite version 1.1 and Microsoft SQL Reporting Services with SP1 applied. You will also need to have the AdventureWorks2000 sample database installed as well as Visual Studio 2003 and the .NET Framework v1.1. You can download the trial version of Map Suite Webforms Edition by following the link below. A short simple registration is required.)&lt;/p&gt;
&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;Register and download the trial version&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;After you have downloaded and installed the trial version of Map Suite, open Visual Studio.NET, let's get started by creating a new reporting project called MappingReports. To do this open up Visual Studio and click File, New Project and choose Report Project from the Business Intelligence Projects folder. Go ahead and name the project MappingReports and click OK.&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;345&quot; width=&quot;531&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSNewProject.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next, let's setup the shared data source to the AvdentureWorks2000 database. To do this you can right mouse button click on the Shared Data Sources folder underneath your MappingReports project and choose Add New Data source. This will prompt you with the following screen. Go ahead and set your connection properties and click OK.&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;467&quot; width=&quot;367&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSDataConnection.jpg&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Building the Report&lt;/h3&gt;
&lt;p&gt;Now that we have the data source setup, we can add the report and retrieve our sales data. Right mouse button click on the Reports folder under the MappingReports project and choose Add New Report. This will start the new report wizard. Click next to begin. The second screen will prompt you to select a data source. Choose AdventureWorks2000 and click the Next button. Next we will be prompted to design the query to return the report data. We will use the query below to retrieve the total sales amount, orders count and customer count for each state from the AdventureWorks2000 database. Enter the following query and click the Next button:&lt;/p&gt;

&lt;code&gt;SELECT s.Name AS 'State', Sum(o.TotalDue) AS 'TotalSalesAmt', Count(c.CustomerID) AS 'OrderCount', Count(Distinct c.CustomerID) AS 'CustomerCount'
FROM Customer c JOIN CustomerAddress ca ON c.CustomerID = ca.CustomerID
JOIN Address a ON ca.AddressID = a.AddressID
JOIN StateProvince s ON a.StateProvinceID = s.StateProvinceID
JOIN SalesOrderHeader o ON c.CustomerID = o.CustomerID
WHERE s.CountryRegionCode = 'US' GROUP BY s.Name
&lt;/code&gt;

&lt;p&gt;&lt;img height=&quot;456&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSQuery.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now we need to select a report type, for our purposes a tabular report will work the best. Choose Tabular and click the Next button:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;456&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSReportType.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next we are prompted to design our table to hold the tabular data. Highlight all of the available fields and click the Details button and then click the Next button. This will display all the fields from the query into the detail section of our report:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;456&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSDesignTable.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Our next step is to give our report table a style. For this example let's choose corporate and click the Next button:&lt;br /&gt;
&lt;br /&gt;
&lt;img height=&quot;456&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSTableStyle.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Finally we are prompted to give our report a name, let's name the report SalesReport and click the Finish button:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;456&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSReportName.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now that we have a basic report created, let's do a few things to make it look a little more professional. First, we'll drag the table and heading items to a width of 6.5 inches to stop the table headings from wrapping. This will also give us plenty of room to insert the map later on. One other thing we need to do is format the TotalSalesAmt field as currency. To accomplish this, right mouse button click on the TotalSalesAmt field and choose properties. Then choose currency from the format list and click the OK button.&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;321&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSFormatProperties.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As one last step for setting up the report, let's create a parameter for this report so the user can select the type of map they want to see. To do this we need to make sure the report is in layout mode and then choose Report Parameters from the Report menu item. You will be prompted with a report parameters dialog box and it will need to be filled out like the picture below:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;379&quot; width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSReportParameters.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Click the Add button and put MapDisplay in the name field. Also change the prompt to say &amp;quot;Display Map By&amp;quot;. Next we need to add some selectable values for this parameter so let's add the following information to the Available values section:&lt;/p&gt;
&lt;table width=&quot;100%&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;th width=&quot;139&quot;&gt;&lt;b&gt;Label&lt;/b&gt;&lt;/th&gt;
            &lt;th&gt;&lt;b&gt;Value&lt;/b&gt;&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width=&quot;139&quot;&gt;Total Sales Amt&lt;/td&gt;
            &lt;td&gt;TotalSalesAmt&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width=&quot;139&quot;&gt;Number of Orders&lt;/td&gt;
            &lt;td&gt;NumberOfOrders&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width=&quot;139&quot;&gt;Number of Customers&lt;/td&gt;
            &lt;td&gt;NumberOfCustomers&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Building the Map&lt;/h3&gt;
&lt;p&gt;Now that we have the basic report setup it's time to move onto building the map. The map will be added to the report through an external URL so the first thing we need to do is create the URL that will generate the map. To do this we need to add a new ASP.NET project to our solution by clicking File, Add Project, New Project. Then choose ASP.NET Web Application under the Visual Basic Projects folder and give your web application a name of MapBuilder.&lt;br /&gt;
&lt;br /&gt;
&lt;img height=&quot;343&quot; width=&quot;531&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSWebProject.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This will create a new web project with a Webform1.aspx page already added. Let's rename the Webform1.aspx page to something more meaningful by right mouse button clicking on it and changing the name to GetMap.aspx.&lt;/p&gt;
&lt;p&gt;(NOTE: Before moving on to the next steps you will need to install the evaluation version of Map Suite Webforms Edition it can be downloaded &lt;a href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;here&lt;/a&gt;. A short simple registration is required.)&lt;/p&gt;
&lt;p&gt;Now we need to add the Map Suite ASP.NET server control that will be building the map for us. To do this right mouse button click on the Web Forms tab of the control toolbox and choose Add/Remove items and then Browse to the C:\Program Files\Spatially Aware\&amp;#91;YOUR MAP SUITE WEBFORMS VERSION&amp;#93;\WebformsEdition.dll. This will add the map control to your toolbox (The Map Suite Webforms control is represented by a little icon of the world.)&lt;br /&gt;
&lt;br /&gt;
&lt;img height=&quot;334&quot; width=&quot;320&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/AddRemoveItems.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The next step is to drag the map control onto the GetMap.aspx page and set the Map1.Width equal to 600px and the Map1.Height equal to 400px, this will give us the right sized map to fit into our report later on. The last thing we need to do before we can begin coding is set up the web.config entries for the Map control and the connection string to the AdventerWorks2000 database. Open up the web.config file and insert the entries below the &lt;configuration&gt;xml tag:&lt;/configuration&gt;&lt;/p&gt;

&lt;code lang=&quot;html&quot;&gt;&lt;appSettings&gt;
&lt;add key=&quot;connectionString&quot; value=&quot;Server=local;Database=AdventureWorks2000;uid=sa;pwd=YOURPASSWORD;&quot; /&gt;
&lt;/appSettings&gt;
&lt;/code&gt;

&lt;p&gt;In addition, add the following web.config setting defining the http handler for the map control under the &lt;tt&gt;system.web&lt;/tt&gt; XML tag:&lt;/p&gt;

&lt;code lang=&quot;html&quot;&gt;&lt;httpModules&gt;
&lt;add name=&quot;ImageStream&quot; type=&quot;MapSuite.Webforms.ImageStream, WebformsEdition&quot; /&gt;
&lt;/httpModules&gt;
&lt;/code&gt;

&lt;p&gt;One last setup task is to add our map data to the project. To accomplish this right click on the MapBuilder project and choose Add, then Add Existing Item. Then browse to 'C:\Inetpub\wwwroot\MapSuiteVBSampleApps\SampleData\USA' and add the States.SHP, States.SHX and States.DBF files to the project. These files provide the data necessary to draw the map of the United States.&lt;/p&gt;
&lt;p&gt;Now it's time to start coding! Let's begin by declaring some Imports statements at the top so we don't have to type all of those long namespaces. Go ahead and add the following Imports statements to the top of the GetMap.aspx code-behind page GetMap.vb. You can reach the code-behind page by double clicking on the ASPX page or by pressing the F7 function key.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Imports MapSuite
Imports MapSuite.Webforms
Imports MapSuite.Geometry
Imports System.Drawing.Imaging
Imports System.Data.SqlClient
Imports System.Drawing.Drawing2D
&lt;/code&gt;

&lt;p&gt;The first part we'll focus on is the Page_Load event of GetMap.aspx code-behind where we can enter in the code listed below:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
	'Put user code to initialize the page here
	Try
		'Clear the Layers so we start from scratch
		Map1.Layers.Clear()
		'Default the report type to the TotalSalesAmt
		Dim ReportType As String = &quot;TotalSalesAmt&quot;
		'Set the Report Type based upon the Query String passed into the URL
		If Request.QueryString.Count &gt; 0 Then ReportType =
		Request.QueryString(&quot;ReportType&quot;).ToString
		'Set the Map Unit to Decimal Degrees because that is the unit our map data is in
		Map1.MapUnit = MapLengthUnits.DecimalDegrees
		'Load the layer defining the United States
		Dim StatesLayer As New Layer(Me.Server.MapPath(&quot;&quot;) &amp; &quot;\States.shp&quot;, True)
		'Call the BindSalesDataToMap() Function to load are custom sales data
		StatesLayer.CustomFields.Add(BindSalesDataToMap(ReportType))
		'Call the SetMapRendering() Routine to set the display features of the map
		SetMapRendering(StatesLayer, ReportType)
		Map1.Layers.Add(StatesLayer)
		'Set the map to only show the lower 48 states
		Map1.CurrentExtent = New RectangleR(-125, 50, -66, 23)
		'Retrieve Bitmap from the Map Control
		Dim salesMap As Bitmap = Map1.GetBitmap(CInt(Map1.Width.Value), CInt(Map1.Height.Value), False)
		'Write the JPEG of the Map Out using the Response Object
		Response.ContentType = &quot;image/jpeg&quot;
		Response.Charset = &quot;&quot;
		salesMap.Save(Response.OutputStream, ImageFormat.Jpeg)
	Catch ex As Exception
		Throw ex
	End Try
End Sub
&lt;/code&gt;

&lt;p&gt;The above code block starts out by clearing any existing layers loaded into the map. In a real world example you may want to keep the layers loaded, but for simplicity sake in this example we will just load the map from scratch each time. Next we interrogate the query string to see how we need to build the map (we will describe setting the query string parameter in the report a little later on). The next piece of code loads the States Layer object with the files State.shp file we added to our project earlier. We then pass the State layer into two routines called BindSalesDataToMap() and SetMapRendering(). These routines handle the data binding and map formatting which we will get to shortly. Finally, after all of this is completed we add the states layer to the map control and write the resulting image out using the Response object.&lt;/p&gt;
&lt;h3&gt;Binding Custom Sales Data to the Map&lt;/h3&gt;
&lt;p&gt;Now we will look in more detail on how to bind our custom sales data to the map of the United States. Before we can do any binding we must retrieve the same data that our report uses from the AdvetureWorks2000 database. We can do this by using the same SQL statement that we defined for the report earlier. With that completed all we need to do is open up a connection to the database using the connection string we defined earlier in the web.config and execute the SQL statement returning a SQLDataReader object. Now that we have our custom sales data it's time to bind it to the map. We start by dimensioning a &lt;i&gt;salesData&lt;/i&gt; variable as a CustomField object. The CustomField object allows us to bind any custom data to an already existing map layer. In our case this is the states layer.&lt;/p&gt;
&lt;p&gt;The binding is pretty straightforward. We first set the CustomFieldName property to what we want to name our custom data. In this case we will name it &amp;quot;SalesData&amp;quot;. This allows us to reference the custom data through the Map control API just like it was included in the Map from the beginning. Next we have to set the &lt;i&gt;LinkFieldName&lt;/i&gt; property, this property acts as the join argument between our custom data and the data inside the States layer. Since we have our custom data grouped by state name we will join it to the map using the STATE_NAME column that is a column in the States.DBF data file.&lt;/p&gt;
&lt;p&gt;Now that we have the field name and link field setup, all we have left is to add the custom sales data. To do this we iterate through the SqlDataReader adding each row to the custom data property; setting the key equal to the state name and the value equal to the custom sales data that we selected via the report type parameter. Once this is completed we return the CustomField object from the function so it can be added to the states layer object. You can copy and paste the Function below into your GetMap.aspx page to bind the sales data to the map.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Function BindSalesDataToMap(ByVal ReportType As String) As CustomField
	Dim sqlConn As New SqlConnection
	(System.Configuration.ConfigurationSettings.AppSettings(&quot;connectionString&quot;))
	Dim sqlCommand As SqlCommand
	Dim salesDataReader As SqlDataReader
	Try
		Dim sql As String = &quot;Select s.Name as 'State', Sum(o.TotalDue) as 'TotalSalesAmt',
		Count(c.CustomerID) as 'OrderCount', &quot; &amp; _
		&quot;Count(Distinct c.CustomerID) as 'CustomerCount' &quot; &amp; _
		&quot;From Customer c Join CustomerAddress ca on c.CustomerID = ca.CustomerID &quot; &amp; _
		&quot;JOIN Address a ON ca.AddressID = a.AddressID &quot; &amp; _
		&quot;JOIN StateProvince s ON a.StateProvinceID = s.StateProvinceID &quot; &amp; _
		&quot;JOIN SalesOrderHeader o ON c.CustomerID = o.CustomerID &quot; &amp; _
		&quot;Where s.CountryRegionCode = 'US' GROUP BY s.Name &quot;
		sqlConn.Open()
		sqlCommand = sqlConn.CreateCommand
		sqlCommand.CommandText = sql
		salesDataReader = sqlCommand.ExecuteReader
		'Define a Custom Field to hold our sales data
		Dim salesData As New CustomField
		salesData.CustomFieldName = &quot;SalesData&quot;
		'This is the field name in the states.shp that will Link us to our custom sales data
		salesData.LinkFieldName = &quot;STATE_NAME&quot;
		Do While salesDataReader.Read
			'Add the Custom Sales Data
			Select Case ReportType
				Case &quot;TotalSalesAmt&quot;
				salesData.CustomData.Add(salesDataReader(&quot;State&quot;), FormatCurrency
				(salesDataReader
				(&quot;TotalSalesAmt&quot;)))
				Case &quot;NumberOfOrders&quot;
				salesData.CustomData.Add(salesDataReader(&quot;State&quot;), salesDataReader(&quot;OrderCount&quot;))
				Case &quot;NumberOfCustomers&quot;
				salesData.CustomData.Add(salesDataReader(&quot;State&quot;), salesDataReader(&quot;CustomerCount&quot;))
			End Select
		Loop
		Return salesData
	Catch ex As Exception
		Throw ex
	Finally
		sqlConn.Close()
	End Try
End Function
&lt;/code&gt;

&lt;h3&gt;Rendering the Map&lt;/h3&gt;
&lt;p&gt;With the custom sales data included in our map, it's time to set the rendering properties so the map will display in the manner we want. First we start off be defining a Threshold. A Threshold is a mechanism to turn Layers on and off depending upon how far you are zoomed in or zoomed out of the map. In our example it is extremely simple because we always want to show the states Layer no matter what so we just define one Threshold between 0 and 10,000 miles. Next we define a Symbol Renderer that will show all the states with no sales data in a light gray color and add it to the Threshold.&lt;br /&gt;
&lt;br /&gt;
(NOTE: For more information on Layers, Thresholds and Symbol Renderers see this article).&lt;/p&gt;
&lt;p&gt;The last thing to setup in the rendering is the class breaks. Class breaks allow us to show a state in a different color depending upon its sales data. For this example we will use three different class breaks: 1) low sales, 2) medium sales and 3) high sales. This will shade the states with high sales numbers in green, medium sales in light green and low sales in light yellow. Once we have our area symbols defined for the different colors we need to decide on what values will be the class breaking points. As you can see by the case statement below, we set different break points based upon the report type parameter passed in. Finally we create the ClassBreakRenderers using the break points we set and then tie them to the custom data field we created in the BindSalesToMap() function called &amp;quot;SalesData&amp;quot;. Once the ClassBreakRenderers are setup all we need to do is add them to the SymbolRenderers collection on the Threshold and then add the Threshold to the States Layer. You can copy and paste this routine into the GetMap.aspx page as well to setup the map rendering:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub SetMapRendering(ByRef StatesLayer As Layer, ByVal ReportType As String)
	'Create Threshold to Display the Map between 0 and 10,000 miles
	StatesLayer.ThresholdUnit = ThresholdUnits.miles
	Dim threshold As New Threshold(10000, 0)
	'Create Symbol Renderer to render the map in Light Gray for states with no data
	Dim symbolRenderer As New SymbolRenderer(New AreaSymbol(New Pen(Color.Black), New
	HatchBrush(HatchStyle.Percent80, Color.LightGray)))
	threshold.SymbolRenderers.Add(symbolRenderer)
	'Set Color for each of the custom sales data ranges
	Dim lowSales As New AreaSymbol(New Pen(Color.Black), New SolidBrush
	(Color.LightGoldenrodYellow))
	Dim mediumSales As New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.LightGreen))
	Dim highSales As New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.Green))
	Dim lowerBreak As Double
	Dim higherBreak As Double
	'Set the Break Values for the different Report Types
	Select Case ReportType
		Case &quot;TotalSalesAmt&quot;
			lowerBreak = 1000000 '1 Million
			higherBreak = 10000000 ' 10 Million
		Case &quot;NumberOfOrders&quot;
			lowerBreak = 100
			higherBreak = 1000
		Case &quot;NumberOfCustomers&quot;
			lowerBreak = 10
			higherBreak = 50
	End Select
	'Create some Class Break Renders to show different colors by state based upon sales data
	Dim salesClassBreaks As New SymbolClassBreakCollection
	'Create a Class Break for Low Sales as Light Green
	salesClassBreaks.Add(New SymbolClassBreakRenderer.ClassBreak(lowerBreak, lowSales))
	'Create a Class Break Cap For Medium and High Sales to use
	Dim ClassBreakCap As New SymbolClassBreakRenderer.ClassBreakCap(higherBreak, highSales, mediumSales)
	salesClassBreaks.Add(ClassBreakCap)
	'Tie the Class Break Renderers to our new custom field of SalesStats
	Dim salesClassBreakRenderer As New SymbolClassBreakRenderer(&quot;SalesData&quot;, salesClassBreaks)
	'Add the Class Break Renderers
	threshold.SymbolRenderers.Add(salesClassBreakRenderer)
	StatesLayer.Thresholds.Add(threshold)
End Sub
&lt;/code&gt;

&lt;p&gt;At this point we all of the code completed. Set the MapBuilder project as the startup project and set the GetMap.aspx page as the startup page for the project. You can now click the Start button or press the F5 function key to compile and execute the program. You should see your browser pop up with a map similar to the one below:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;400&quot; width=&quot;520&quot; border=&quot;0&quot; style=&quot;border: 1px solid rgb(128, 128, 128);&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSSalesMap.jpg&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Adding the Map to the Report&lt;/h3&gt;
&lt;p&gt;With most of the work behind us, let's now go back to the report and add the map in. Bring the sales report up in layout mode and drag the bottom of the report down some so we have a blank area to insert the map. Drag an image report item from the toolbox onto the report. This will start the image wizard. Go ahead and click the Next button to begin. The first question we have to answer is where the image is located. For this example we need to choose web option.&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;418&quot; width=&quot;500&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSImageWizard.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next we are prompted for the URL of the image, in our case we want to put in the GetMap.aspx URL that we developed to create the map. So enter &lt;tt&gt;http://localhost/MapBuilder/GetMap.aspx&lt;/tt&gt; into the URL settings box and click next.&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;418&quot; width=&quot;500&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSImageWizard2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The image wizard should successfully retrieve the map and show a screen like the one below. Go ahead and click the Finish button to add the map to the report.&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;418&quot; width=&quot;500&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSImageWizard3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After the map has been added to the report you may want to rearrange the report a little so everything fits together nicely.&lt;/p&gt;
&lt;h3&gt;Changing the Map Using Report Parameters&lt;/h3&gt;
&lt;p&gt;Now that we have our map displaying on the report the only thing left to do is change the map based upon what the user chooses from the &amp;quot;Display Map By&amp;quot; report parameter. To add this functionality, make sure your report is in layout mode and click on the image and then choose View, Properties Window from the menu bar. This will display all the properties for the image report item containing the map. The property that we are interested in is the &lt;i&gt;value&lt;/i&gt; property. Click on the value property and choose &lt;expression&gt;from the drop down list. This will open the expression builder dialog which we will use to programmatically set the URL value for the image using the reports &amp;quot;Display Map By&amp;quot; report parameter. Enter the following expression into the expression area so it matches the image below.&lt;/expression&gt;&lt;/p&gt;

&lt;code&gt;=&quot;http://localhost/MapBuilder/GetMap.aspx?ReportType=&quot; &amp; Parameters!MapDisplay.Value
&lt;/code&gt;

&lt;p&gt;&lt;img width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSEditExpression.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Click OK and change the report mode to preview. Try choosing a different value for the &amp;quot;Display Map By&amp;quot; parameter and watch some of the states change colors to representing the different sales data and class breaks. If everything was done correctly you should have a report that looks similar to the one below.&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;520&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SRSSalesReport.jpg&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;In this example we showed that with a minimal amount of code a custom map can be added to a SQL Reporting Services report. We have only scratched the surface of what is possible using mapping technology to give a graphical representation of report data. Several common features like map labeling, point plotting and spatial querying can easily be accomplished using this same type of architecture. One other thing to keep in mind is that the map can easily be changed to include a geographic area of any size. So while this example represents data across the entire United States, the map could easily be built to only display a city, county or a particular state. With end user's demand for information growing year after year, having a tool to show data in a more meaningful way is always helpful.&lt;/p&gt;
&lt;h3&gt;Other Resources&lt;/h3&gt;
&lt;p&gt;There are several other resources at ThinkGeo to help you get started to developing feature rich mapping and spatial applications for Microsoft .NET. Some of those resources are listed below. You can always reach a ThinkGeo support representative by phone toll-free at (866) 847-7510 or via email at &lt;a href=&quot;mailto:support@thinkgeo.com&quot;&gt;support@thinkgeo.com&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Sample Applications&lt;/h3&gt;
&lt;p&gt;There are 35+ sample applications included with Map Suite when you download the trial version that include the source code to show you how to do various operations using the Map Suite component. It is very beneficial to go through those examples and the code. Both VB.NET and C# are included.&lt;/p&gt;
&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://websamples.thinkgeo.com/&quot;&gt;View the Map Suite sample applications online&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Discussion Forums&lt;/h3&gt;
&lt;p&gt;The Map Suite Discussion Forums are a great place to get answers to all of your Map Suite development questions. The ThinkGeo Support Team monitors the forums daily and can help you on your way to being successful with Map Suite.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Visit the Discussion Forums online&lt;/a&gt;&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4762/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 08:53:39 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4762/afv/topic/Default.aspx</guid>
			<slash:comments>3</slash:comments>
		</item>
		<item>
			<title>Using the Spatial Query Capabilities of Map Suite</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;Map Suite has powerful spatial querying abilities. This allows you to find features of a Layer based on spatial criteria such as containment, intersection etc. This capability is built into the API of Map Suite and is easy even for the non-GIS developer to use. This article will introduce these concepts and show you how they can be accomplished with Map Suite.                                                                    &lt;/p&gt;&lt;/div&gt;

&lt;h3&gt;Introduction&lt;/h3&gt;

&lt;p&gt;If you need to build spatial querying capabilities into your maps you can do so quickly and easily using the spatial querying capabilities built into Map Suite. This article will show you the basics of getting started on your way to building your own feature rich spatial applications.&lt;/p&gt;

&lt;p&gt;(NOTE: This article references the SpatialQueriesApp that is available in the sample applications with both the trial and full versions of Map Suite. This article also focuses on the Winforms Edition of Map Suite but most of the concepts and all of the example code applies for the Webforms (ASP.NET) Edition as well.)&lt;/p&gt;

&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;Register and download the trial version&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Opening the Sample Applications in Visual Studio.NET Solution&lt;/h3&gt;

&lt;p&gt;After you have downloaded and installed the full or trial version of Map Suite, you may want to look through the sample applications and source code that are included with the installation. You can view the samples by going to the START menu...All Programs...ThinkGeo...&amp;#91;YOUR MAP SUITE VERSION&amp;#93; and choose either the VB Sample Apps Source Code or C# Sample Apps Source Code menu item. This will open a solution in Visual Studio.NET that includes all of the Map Suite Sample applications as well as the source code. You may also need to add the Map Suite Map Control to your Toolbox in the Visual Studio.NET IDE. You can do this by using the Add/Remove Items feature and browsing to the winformsedition.DLL file that resides in the installation directory of Map Suite (By default this is C:\Program Files\ThinkGeo\&amp;#91;The Version You Have Installed&amp;#93;\).&lt;/p&gt;

&lt;p&gt;Now let's take a look at spatial queries in Map Suite.&lt;/p&gt;

&lt;p&gt;(NOTE: This article assumes the basics of loading Shape Files into Map Suite Layers. For a more detailed explanation of how to load Layers and how Map Suite uses shape data and DBF files, see the &lt;a href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot;&gt;Map Suite Quick Start User's Guides&lt;/a&gt;.)&lt;/p&gt;

&lt;h3&gt;Why Spatial Queries?&lt;/h3&gt;

&lt;p&gt;You might be wondering why you would want to use spatial queries. Some good examples of spatial querying might be the need to know the coverage area for a Wi-Fi system or the proximity of possible hazardous materials to schools so that plans can be made accordingly. These are just a couple of examples of how spatial querying can be a powerful tool.&lt;/p&gt;
&lt;p&gt;So let's jump right into an example using Map Suite and see how you can get started adding these features to your own applications.&lt;/p&gt;

&lt;h3&gt;Setting the Map Mode to a Track Shape&lt;/h3&gt;

&lt;p&gt;The first step in spatial querying is to allow for our user to create a shape that will be used for querying, for example using a rectangle or an ellipse. We can accomplish this by using the Mode property of the Map and one of several mode types from the ModeType Enumeration:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Map1.Mode = ModeType.TrackLine
Map1.Mode = ModeType.TrackPolygon
Map1.Mode = ModeType.TrackRectangle
Map1.Mode = ModeType.TrackCircle
Map1.Mode = ModeType.TrackEllipse
&lt;/code&gt;

&lt;p&gt;Any one of these values will change the cursor to the mode of selection indicated and allow the user to draw a shape. We now need to be able to create the shape based on what was drawn and we can do this using Map Suite's FinishedTrackShape() Event which takes an argument of type BaseShape. Example code from the SpatialQueriesApp sample application is shown below:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub Map1_FinishedTrackShape(ByVal Shape As MapSuite.Geometry.BaseShape) Handles Map1.FinishedTrackShape
	If Not Shape Is Nothing Then
		'-- After a shape is drawn, store the shape and re-run the query
		mQueryBaseShape = Shape
		Call SpatialQuery()
	End If
End Sub
&lt;/code&gt;

&lt;p&gt;The above code captures the BaseShape being passed in and assigns it to the mQueryBaseShape variable which is defined at the Class level as a BaseShape. Immediately after the SpatialQuery() method is called. Let's take a look at that method to get an idea of how Map Suite can now query the data:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub SpatialQuery()
	Dim RecordNumbers() As Integer
	Dim lyr As Layer
	Dim Index As Integer
	'-- Here we want to deselect everything on each layer
	For Each lyr In Map1.Layers
		lyr.Deselects()
	Next
	'-- Identify which layer with which to work
	If RadioButtonCounties.Checked Then
		Index = 0
	ElseIf RadioButtonRoads.Checked Then
		Index = 1
	ElseIf RadioButtonCities.Checked Then
		Index = 2
	End If
	lyr = Map1.Layers.Item(Index)
	'-- Get the record numbers returned by the query
	RecordNumbers = lyr.SpatialQuery(mQueryBaseShape, CType
	(ComboBoxSpatialRules.SelectedIndex, SpatialQueryContainment))
	'-- Select the returned items on the layer - this will highlight the
	'-- features so the user can see the query results
	lyr.Selects(RecordNumbers)
	'-- Redraw the map
	Map1.Refresh()
End Sub
&lt;/code&gt;

&lt;p&gt;There are several things occurring in the above code so let's take a look at each step in detail. We first declare an array of type Integer that will hold the record numbers returned from our query. We then declare an object of type Layer that will be used in an iteration to deselect anything that might have been set to selected in a previous query. We then declare an Index of type Integer which will be set when we determine from the user interface which Layer the user wants to query (see user interface of the SpatialQueriesApp in the sample applications).&lt;/p&gt;

&lt;p&gt;Now that we have our variables declared we want to go ahead and iterate through all available Layers in the map and deselect anything that might be selected as mentioned above. We then check the user interface RadioButtons to see which one the user has selected. In the case of our SpatialQueriesApp sample application, it is either the Counties, Roads or Cities Layer. After we set the appropriate index, we can now get a reference to that Layer in the Map's Layer collection.&lt;/p&gt;

&lt;p&gt;Now comes the magic. With just a simple call to the referenced Layer's SpatialQuery() method, passing in the previously populated BaseShape (mQueryBaseShape) set in the Map's FinishedTrackShape() method and a value from the SpatialQueryContainment Enumeration (NOTE: In the above code, the value is coming from a user interface ComboBox control and then it is cast specifically to type SpatialQueryContainment), an array of record numbers (Integers) is returned. You can then call the Layer's Selects() method and pass in the array. Lastly, we call the Refresh() method on the map.  When we do, the appropriate items on the map that resulted from the query will be automatically highlighted, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery1.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;The SpatialQueryContainment Enumeration&lt;/h3&gt;

&lt;p&gt;Let's take a closer look at the SpatialQueryContainment Enumeration. This provides what type of query operation needs to be performed on the selected Layer features to be queried:&lt;/p&gt;

  &lt;table width=&quot;100%&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; border=&quot;1&quot;&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;th width=&quot;118&quot;&gt;&lt;b&gt;Operation&lt;/b&gt;&lt;/th&gt;
              &lt;th&gt;&lt;b&gt;Result&lt;/b&gt;&lt;/th&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Contained&lt;/td&gt;
              &lt;td&gt;Returns the features that fully contain the querying shape.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Containing&lt;/td&gt;
              &lt;td&gt;Returns the features that the querying shape fully or partially contains.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Fully Containing&lt;/td&gt;
              &lt;td&gt;Returns the features that the querying shape fully contains.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Containing Centroid&lt;/td&gt;
              &lt;td&gt;Returns the features whose centroid is contained by the querying shape.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Fully Outside&lt;/td&gt;
              &lt;td&gt;Returns the features that are fully outside the querying shape.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Outside&lt;/td&gt;
              &lt;td&gt;Returns the features that are fully or partially outside the querying shape.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td width=&quot;118&quot;&gt;Intersecting&lt;/td&gt;
              &lt;td&gt;Returns features that are intersected by the querying shape.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
  &lt;/table&gt;

&lt;p&gt;An example of each of these query operations is shown below so that you can visually see how each is represented:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;(NOTE: The Query Type ComboBox provides reference for which type of query is being shown)&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_Contained.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_Containing.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_FullyContaining.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_ContainingCentroid.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_FullyOutside.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_Outside.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/SpatialQuery_Intersecting.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;As you can see, it is very easy to use spatial queries in your Map Suite application. With only a few lines of code, and some representative data, you can have fully functional spatial analysis maps to your users in very little time. Remember to check out the SpatialQueriesApp sample application to see this code and other features such as traversing the map with operations like Zooming, Panning, Track Zoom etc.&lt;/p&gt;

&lt;h3&gt;Other Resources&lt;/h3&gt;

&lt;p&gt;There are several other resources at ThinkGeo to help you get started to developing feature rich mapping and spatial applications for Microsoft .NET. Some of those resources are listed below. You can always reach a ThinkGeo support representative by phone toll-free at (866) 847-7510 or via email at &lt;a href=&quot;mailto:support@thinkgeo.com&quot;&gt;support@thinkgeo.com&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Sample Applications&lt;/h3&gt;

&lt;p&gt;There are 40+ sample applications included with Map Suite when you download the trail version that include the source code to show you how to do various operations using the Map Suite component. It is very beneficial to go through those examples and the code. Both VB.NET and C# are included.&lt;/p&gt;

&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://websamples.thinkgeo.com/&quot;&gt;View the Map Suite sample applications online&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Discussion Forums&lt;/h3&gt;

&lt;p&gt;The Map Suite Discussion Forums are a great place to get answers to all of your Map Suite development questions. The ThinkGeo Support Team monitors the forums daily and can help you on your way to being successful with Map Suite.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Visit the Discussion Forums online&lt;/a&gt;&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4763/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 10:16:33 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4763/afv/topic/Default.aspx</guid>
			<slash:comments>4</slash:comments>
		</item>
		<item>
			<title>How To Use the Map Rotation Feature in Map Suite 2.53.5</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;After hearing many requests for Map Rotation functionality from the Map Suite user community, we decided to add that feature to Map Suite starting with version 2.53. We approached the goal of having the entire map rotate from the center of its current extent at will through a Projection class called &lt;tt&gt;Rotated&lt;/tt&gt;.  In other words, from the developer's perspective, Map Rotation is simply applying a Projection class to all the Layers and MapShapes, and letting Map Suite take care of everything else automatically.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; For the purposes of this article we have used the Map Suite Desktop Edition to demonstrate Map Rotation, but please note that Map Rotation functionality is also available in the Map Suite Web and Engine editions.&lt;/p&gt;

&lt;h3&gt;Applying Map Rotation&lt;/h3&gt;

&lt;p&gt;For the developer, applying Map Rotation is very straightforward.  Essentially, all vector data (Layers and MapShapes) need to have their projection property set to the projection class &lt;tt&gt;Rotated&lt;/tt&gt;.  But before we do that, we need to declare a form level variable for &lt;tt&gt;Rotated&lt;/tt&gt;.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private mRotated As New MapSuite.Geometry.Rotated()&lt;/code&gt;

&lt;p&gt;We will use &lt;tt&gt;mRotated&lt;/tt&gt; as the projection  for all the Layers and MapShapes of the Map. It is very important that each time you add a new Layer or MapShape to the Map, you apply the &lt;tt&gt;Rotated&lt;/tt&gt; projection to it. Otherwise, the Map Rotation will not apply to that object.&lt;/p&gt;

&lt;p&gt;For a Layer, we add it to the Map the following way:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Dim Layer1 As New Layer(&quot;..\MyLayer.shp&quot;, mRotated, False)&lt;/code&gt;

&lt;p&gt;For a MapShape, we simply set the Projection property to &lt;tt&gt;Rotated&lt;/tt&gt;:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;PointMapShape1.Projection = mRotated&lt;/code&gt;

&lt;p&gt;Now, with all the Layers and MapShapes having their Projection property set to &lt;tt&gt;Rotated&lt;/tt&gt;, we are ready to have the Map Rotation take effect. Each time the map has to rotate, we use the &lt;tt&gt;SetAngle&lt;/tt&gt; method of &lt;tt&gt;Rotated&lt;/tt&gt;.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Map1.CurrentExtent = mRotated.SetAngle(90, Map1.CurrentExtent)&lt;/code&gt;

&lt;p&gt;You can rotate the Map from 0 to 360 degrees counterclockwise by using positive values, or clockwise by using negative values.  So for example, 90 and -270 will have the same effect.&lt;/p&gt;

&lt;p&gt;If you want to rotate incrementally, for example by 10 degrees at a time, you can use the &lt;tt&gt;GetAngle&lt;/tt&gt; property and add 10 as the Angle parameter of &lt;tt&gt;SetAngle&lt;/tt&gt;. Here we are rotating the map by increment of 10 degrees counterclockwise.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Map1.CurrentExtent = mRotated.SetAngle(mRotated.GetAngle + 10, Map1.CurrentExtent)&lt;/code&gt;

&lt;h3&gt;Keeping the Bearings&lt;/h3&gt;

&lt;p&gt;As the Map rotates, it is important to keep bearings and to know where the North is. That is why drawing a North Arrow that always points to the north helps prevent you from getting disoriented. Below is a trick that can be used to draw a bitmap of a North Arrow that always points to the North.&lt;/p&gt;

&lt;p&gt;First, declare a form level variable for the North Arrow bitmap.  Then, in the &lt;tt&gt;AfterMapDraw&lt;/tt&gt; event of the Map, you can write the logic for the rotation:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub Map1_AfterMapDraw(ByVal g As System.Drawing.Graphics) Handles Map1.AfterMapDraw
        Dim Matrix As New Matrix
        Dim ImageX, ImageY, ImageWidth, ImageHeight As Integer
        ImageX = 30 : ImageY = 30 : ImageWidth = 56 : ImageHeight = 69
        Dim pt As New PointF(ImageX + (ImageWidth / 2), ImageY + (ImageHeight / 2))
        Matrix.RotateAt(CSng(-mRotated.GetAngle), pt)
        g.Transform = Matrix
        g.DrawImage(mNorthArrowBitmap, ImageX, ImageY, ImageWidth, ImageHeight)
        g.Dispose()
End Sub
&lt;/code&gt;

&lt;p style=&quot;margin-top:20px;&quot;&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapRotation_01.jpg&quot; alt=&quot;Figure 1&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 1: Street Map with Angle set at 0.&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapRotation_02.jpg&quot; alt=&quot;Figure 2&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 2: Street Map with Angle set at 132. See how the North Arrow tilted to point to the North.&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;In the included &lt;a href=&quot;http://gis.thinkgeo.com/download/MapRotationDemo.zip&quot;&gt;demo application&lt;/a&gt;, we show you two ways to rotate the map. One is by using a Button control where the angle of Map is changed, by a user defined increment, clockwise and counterclockwise. The other method is by using a Roll control that serves as a compass, where you can set the angle of the map using the mouse.  &lt;a href=&quot;http://gis.thinkgeo.com/download/MapRotationDemo.zip&quot;&gt;Download the demo application&lt;/a&gt; to see both methods in action.  (Please note that the demo requires the free evaluation of the Map Suite Desktop GIS .NET control, &lt;a href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;available here&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Another important thing to take into account is the coordinates we get on the Map by rotating it. If we always want to have the real coordinates and not the coordinates from the rotation, we are going to use the &lt;tt&gt;ProjectPointBack&lt;/tt&gt; method of &lt;tt&gt;Rotated&lt;/tt&gt;. The code below will show the real coordinates from the &lt;tt&gt;MouseMove&lt;/tt&gt; event on the status bar:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub Map1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Map1.MouseMove
        Dim RotWorldPointR As PointR = Map1.ToWorldCoordinate(e.X, e.Y)
        Dim RealWorldPointR As PointR = mRotated.ProjectPointBack(RotWorldPointR.X, RotWorldPointR.Y)
        StatusBar1.Panels(0).Text = &quot;X: &quot; &amp; RealWorldPointR.X &amp; &quot;  Y: &quot; &amp; RealWorldPointR.Y
        StatusBar1.Panels(1).Text = DecimalDegrees.DecimalDegreesToDMS(RealWorldPointR)
End Sub
&lt;/code&gt;

&lt;h3&gt;Ruminations&lt;/h3&gt;

&lt;p&gt;Taking the idea of Map Rotation further, nothing stops us from displaying the world with the North down, the South up, the East to the left and the West to the right by applying a 180 angle to the &lt;tt&gt;Rotated&lt;/tt&gt; projection:&lt;/p&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapRotation_03.jpg&quot; alt=&quot;Figure 3&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080; line-height:120%;&quot;&gt;Fig 3. The World with the South on top. This map was created by applying an angle of 180 degrees to a few of the ShapeFiles that come with the &lt;a href=&quot;http://gis.thinkgeo.com/Products/MapDatasetPluginsforNETDevelopers/RenderWorld/tabid/177/Default.aspx&quot;&gt;Render World&lt;/a&gt; product.&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;The map shown above will probably shock many of us, but although this is an unconventional view of the world, it is completely accurate scientifically and it is not breaking any cartographic rules.&lt;/p&gt;

&lt;p&gt;Below are the scientific definitions of the four cardinal directions:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;East:&lt;/b&gt; The direction toward which the Earth rotates about its axis (therefore the direction from which the Sun appears to rise)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;West:&lt;/b&gt; The direction opposite to that of the Earth's rotation axis (therefore the direction towards which the Sun appears to set)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;South:&lt;/b&gt; The direction along the earth's surface toward the pole that is on one's right at the Equator when facing the direction toward which the Earth rotates about its axis (East).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;North:&lt;/b&gt; The direction along the earth's surface toward the pole that is on one's left at the Equator when facing the direction toward which the Earth rotates about its axis (East).&lt;/p&gt;

&lt;p&gt;So according to those definitions, there is no reason why the North must be placed on top. The reason it seems odd to many of us is due to our own western bias, where North has always historically been used as a fundamental direction, placing Europe on the top of the map. But this is completely arbitrary.&lt;/p&gt;

&lt;p&gt;Even the magnetic north, which is the direction along the earth's surface in which horizontal magnetic field strength has its most positive value, is a very transitional thing. Due to the “flipping” of the magnetic poles, perhaps in a few thousand years, the magnetic pole will later lie in the southern hemisphere.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Map Suite developers can now take advantage of Map Rotation to add a totally new dimension of map display to their GIS applications.  Currently, Map Rotation applies only to vector data, Layers and MapShapes, not ImageLayers or GRIDs. We are aware that this is a limitation. The next major release of Map Suite, version 3.0, is planned to support Map Rotation for any data, vector or raster image.&lt;/p&gt;

&lt;h3&gt;Downloads&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:9px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/download/MapRotationDemo.zip&quot; style=&quot;padding-left:20px; background:url(/portals/1/icons/icon_download_2.gif) no-repeat left center;&quot;&gt;&lt;b&gt;Download Map Rotation Demo Application&lt;/b&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;b&gt;Note: You will need to download the &lt;a href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;Map Suite Desktop .NET GIS Control Free Evaluation&lt;/a&gt; in order to run the example in this article.&lt;/b&gt; (Registration Required)&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Have Questions?&lt;/h3&gt;

&lt;p&gt;Do you have any questions or comments about this article?  If so, feel free post your questions on the &lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Map Suite Discussion Forums&lt;/a&gt; or leave feedback at the &lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/afv/topicsview/aff/16/Default.aspx&quot;&gt;ThinkGeo Blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Additional Resources&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite QuickStart Guides&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/APIDocumentation/tabid/194/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite API Documentation&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/FAQs/tabid/196/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite FAQs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About the Author&lt;/h3&gt;

&lt;p&gt;Val Guillou is a GIS analyst and developer at ThinkGeo, a software company specializing in geospatial software with an emphasis on software development tools and GPS tracking solutions.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4785/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Thu, 13 Nov 2008 05:48:51 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4785/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>How To Use GRID with Map Suite</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;This article will introduce the &lt;a href=&quot;http://gis.thinkgeo.com&quot;&gt;Map Suite&lt;/a&gt; developer community to the GRID format and help demonstrate how useful GRID can be. GRID can come handy in numerous situations where you need to create custom map displays, perform interpolation or do spatial analysis. We hope that by reading this article you will see more clearly how to apply GRID to your own industry and reap the benefits it provides.                                  &lt;/p&gt;&lt;/div&gt;

&lt;h3&gt;Introduction&lt;/h3&gt;

&lt;p&gt;For the purposes of this article we have used the Map Suite Desktop Edition to show the functionality of GRID, but please note that GRID functionality is also available in the Map Suite Web and Engine editions.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This article is meant to be used as a tutorial for using GRID as a GIS technique, not as a definitive tool for soil analysis. The soil quality examples included here are fictitious, and the soil quality calculations based on pH and Magnesium levels do not come from an authoritative source in agriculture.&lt;/p&gt;

&lt;h3&gt;GRID Explained&lt;/h3&gt;

&lt;p&gt;A GRID is a raster format that defines a geographic space as an array of equally sized squares (cells) arranged in rows and columns. Each cell stores a numeric value that represents a geographic attribute (such as elevation, surface slope, soil pH, etc.) for that unit of space. Each grid cell is referenced by its x, y coordinate location.&lt;/p&gt;

&lt;h3&gt;File Format&lt;/h3&gt;

&lt;p&gt;The format of the GRID file is  ASCII and contains two main parts, the header and the body. The header consists of the first few lines for references of the grid such as the number of columns, the number of rows, the x and y coordinate of the lower left of the grid, the cell size and the no data value (which will be used in the body of the GRID file to represent a null value). The body contains the cell values listed in the order they would naturally appear from left to right and from top to bottom.&lt;/p&gt;

&lt;h4&gt;Example of ASCII GRID Format:&lt;/h4&gt;

&lt;pre&gt;
ncols         4
nrows         6
xllcorner     0.0
yllcorner     0.0
cellsize      50.0
NODATA_value  -9999
-9999 -9999 5 2
-9999 20 100 36
3 8 35 10
32 42 50 6
88 75 27 9
13 5 1 -9999
etc...
&lt;/pre&gt;


&lt;h3&gt;Getting Started&lt;/h3&gt;

&lt;p&gt;Now that we have covered the theory of the GRID, we are going to use a very concrete example to show how useful GRID can be in practical GIS applications.&lt;/p&gt;

&lt;p&gt;Let's say that we have a point-based shapefile representing some sample points where the pH (acidity level) of the soil was measured on a field.&lt;/p&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_01.png&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 1: Point-based shapefile of sample pH levels.&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_02.png&quot; alt=&quot;Legend&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 2: Map legend.&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;Now with those few sample points, we want the entire field to be covered with a pH value. This is when GRID comes in handy. Using an interpolation method, IDW (Inverse Distance Weighing), we will create a GRID and then display it on the map to show clearly the different pH values throughout the field.&lt;/p&gt;

&lt;h3&gt;Creating the GRID&lt;/h3&gt;

&lt;p&gt;Before creating the GRID, we need to decide the extent of the grid, the size of the cells and the value for no data. In our case, we are going to take a slightly larger extent of the field and we are going to have a cell size of 0.0001 (we are in decimal degrees, so 0.0001 degrees are about 9.6 meters). The no data value is -9999. This means that any cell that is outside the field (where the pH value is irrelevant), we will assign it the -9999 value.&lt;/p&gt;

&lt;p&gt;In the Click event of a Button, we will write the logic to create the GRID.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub btnIDW_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIDW.Click
        Dim gridExtent As New StraightRectangle(Map1.CurrentExtent)
        Dim cellSize As Double = 0.0001
        Dim NoDataValue As Double = -9999

        AddHandler GridLayer.CalculateCellValue, AddressOf CalculateCellValueHandlerIDW
        Dim Result As Boolean = GridLayer.CreateGridFile(&quot;..\PHIDW_2_200_A.grd&quot;, gridExtent, cellSize, NoDataValue)

        If Result = True Then
            MessageBox.Show(&quot;Grid File saved successfully.&quot;, &quot;Information&quot;, MessageBoxButtons.OK, MessageBoxIcon.Information)
        Else
            MessageBox.Show(&quot;Saving Grid File Failed.&quot;, &quot;Information&quot;, MessageBoxButtons.OK, MessageBoxIcon.Information)
        End I
    End Sub
&lt;/code&gt;

&lt;p&gt;At the creation of the GRID, the event CalculateCellValue is going to be raised for each cell to assign a value. So we are going to write the interpolation algorithm in the handler CalculateCellValueHandlerIDW. In our example, we are using IDW interpolation, or Inverse Distance Weighing. This is a common method for interpolation that assigns values to unknown locations based on some scattered set of known points – which is exactly the case in our example. This interpolation has two variables: The number of points to take into account (based on distance) and the power parameter. Playing with those two variables is going to give a result with smoother or sharper peaks.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Notes:&lt;/b&gt; We are using IDW interpolation in this example, but you are free to use any other type of interpolation or algorithm to calculate the cell value. For more information on interpolation, check the following site: &lt;a href=&quot;http://en.wikipedia.org/wiki/Multivariate_interpolation&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://en.wikipedia.org/wiki/Multivariate_interpolation&lt;/a&gt;&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub CalculateCellValueHandlerIDW(ByVal CellExtent As StraightRectangle, ByRef CellValue As Double)
        Dim CellULx As Double = CellExtent.UpperLeftPoint.X
        Dim CellULy As Double = CellExtent.UpperLeftPoint.Y
        Dim CellLRx As Double = CellExtent.LowerRightPoint.X
        Dim CellLRy As Double = CellExtent.LowerRightPoint.Y

        Dim xp As Double = CellExtent.Center.X
        Dim yp As Double = CellExtent.Center.Y
        Dim CellCenterPointShape As New PointShape(xp, yp)
        Dim CenterRecords() As Integer = Map1.Layers(0).QueryByDistance(CellExtent, 15, MapLengthUnits.metres, Map1.MapUnit)

        If CenterRecords.GetLength(0) = 1 Then

            Dim NearestRecords() As Integer = Map1.Layers(1).QueryByDistance(CellCenterPointShape, 200, MapLengthUnits.metres, Map1.MapUnit)
            If NearestRecords.GetLength(0) &gt; 0 Then
                Dim NearestPointShapes() As PointShape = CType(Map1.Layers(1).GetShapes(NearestRecords), PointShape())
                Dim NearestValues(NearestRecords.GetLength(0) - 1) As String
                For i As Integer = 0 To NearestRecords.GetLength(0) - 1
                    NearestValues(i) = Map1.Layers(1).DataQuery(NearestRecords(i), &quot;pH&quot;)
                Next i
                'This is the algorithm for IDW interpolation
                Dim Power As Double = 2
                Dim Zi, Zx1, Zx2, Zx, Di As Double
                For i As Integer = 0 To NearestValues.GetLength(0) - 1
                    Zi = CDbl(NearestValues(i))
                    Di = CellCenterPointShape.DistanceTo(NearestPointShapes(i), Map1.MapUnit, MapLengthUnits.metres, DistanceTypes.Shortest)
                    Zx1 = Zx1 + (Math.Pow((1 / Di), Power) * (Zi))
                    Zx2 = Zx2 + ((Math.Pow((1 / Di), Power)))
                Next
                Zx = Zx1 / Zx2
                CellValue = Zx
            Else
                CellValue = -9999
            End If
        Else
            CellValue = -9999
        End If
    End Sub
&lt;/code&gt;

&lt;p&gt;In our example, we are using a distance of 200 meters to get the sample points within that distance and we are using a power of 2. By specifying a higher power, more emphasis is placed on the nearest points, giving a smoother result. By specifying a lower power, more influence is placed on the points that are farther away, giving a sharper result.&lt;/p&gt;

&lt;h3&gt;Displaying the GRID&lt;/h3&gt;

&lt;p&gt;Now that we have the GRID created, we need to display it. This article will demonstrate two different ways of displaying the GRID.  For the first way, we will apply a specific color to any cell belonging to a certain class. The second method uses a gradient to go from one color to another. The purpose is to show different ways one GRID can be displayed.&lt;/p&gt;

&lt;h3&gt;Using ClassBreaks&lt;/h3&gt;

&lt;p&gt;We are going to display the cells of the GRID in the same way as we did for the original shapefile of sample points. Note that you might want to remove the two shapefiles from the Map so that they do not appear on top of the GRID.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Dim STR_GridFile As String = &quot;..\SoilQuality.grd&quot;
        Dim gridlayer As GridLayer = New GridLayer(STR_GridFile)
        gridlayer.LowerThreshold = 0
        gridlayer.UpperThreshold = Double.MaxValue
        gridlayer.ThresholdUnit = ThresholdUnits.miles
        gridlayer.IsNonValueTransparent = True
        Dim gridranges As RangeCollection = New RangeCollection()
        gridranges.Add(New Range(7.54, 7.9, Color.FromArgb(0, 255, 0)))
        gridranges.Add(New Range(7.21, 7.54, Color.FromArgb(128, 255, 128)))
        gridranges.Add(New Range(7.15, 7.21, Color.FromArgb(224, 251, 132)))
        gridranges.Add(New Range(7.08, 7.15, Color.FromArgb(225, 255, 0)))
        gridranges.Add(New Range(7.0, 7.08, Color.FromArgb(245, 210, 10)))
        gridranges.Add(New Range(6.83, 7.0, Color.FromArgb(255, 128, 0)))
        gridranges.Add(New Range(6.2, 6.83, Color.FromArgb(255, 0, 0)))
        gridlayer.Ranges = gridranges

        Map1.GridLayers.Add(gridlayer)
&lt;/code&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_03.png&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 3: GRID resulting from sample points interpolation displayed with Class Breaks.&lt;/small&gt;
&lt;/p&gt;

&lt;h3&gt;Using Gradient&lt;/h3&gt;

&lt;p&gt;We are going to display the cells of the GRID with a gradient going progressively from red (for low pH) to green (for high pH). Note that in addition to Map, Layer (the vector shapefile layer) has a GRIDLayers collection so that GRID files can be displayed in the desired order. Here we are displaying the GRID file between the Field Layer and the sample points Layer.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Dim STR_GridFile As String = &quot;..\SoilQuality.grd&quot;
        Dim gridlayer As GridLayer = New GridLayer(STR_GridFile)
        gridlayer.LowerThreshold = 0
        gridlayer.UpperThreshold = Double.MaxValue
        gridlayer.ThresholdUnit = ThresholdUnits.miles
        gridlayer.IsNonValueTransparent = True
        Dim gridranges As RangeCollection = New RangeCollection()

        Dim Alpha As Integer = 255
        gridranges.Add(New GradientRange(6.2, Color.FromArgb(Alpha, Color.FromArgb(255, 0, 0)), 7.9, Color.FromArgb(Alpha, Color.FromArgb(0, 255, 0))))
        gridlayer.Ranges = gridranges
     Map1.Layers(0).GridLayers.Add(gridlayer)
&lt;/code&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_04.png&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 4: GRID resulting from sample points interpolation displayed with gradient. The Layer with the sample points appears on top.&lt;/small&gt;
&lt;/p&gt;

&lt;h3&gt;Multi GRID operations&lt;/h3&gt;

&lt;p&gt;One of the big advantages of GRID is to be able to create a new GRID by analyzing and performing calculations on the cell values of an existing GRID, or by combining two existing GRIDs to create a third one. For our next example,  we have a second GRID that represents Magnesium levels throughout the field from 40 to 95 ppm.  We will combine the pH value GRID and the Magnesium level GRID to create a third, composite GRID.&lt;/p&gt;

&lt;h3&gt;Displaying the GRID for Magnesium&lt;/h3&gt;

&lt;p&gt;We are going to display the GRID Magnesium_Level using a gradient. (This previously-created GRID is supplied to us for the purpose of this example.)&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Dim STR_GridFile As String = &quot;..\Magnesium_Level.grd&quot;
        Dim gridlayer As GridLayer = New GridLayer(STR_GridFile)
        gridlayer.LowerThreshold = 0
        gridlayer.UpperThreshold = Double.MaxValue
        gridlayer.ThresholdUnit = ThresholdUnits.miles
        gridlayer.IsNonValueTransparent = True
        Dim gridranges As RangeCollection = New RangeCollection()
        gridranges.Add(New GradientRange(40, Color.FromArgb(254, 215, 186), 90,    Color.FromArgb(105, 46, 1)))
        gridlayer.Ranges = gridranges
        Map1.Layers(0).GridLayers.Add(gridlayer)
&lt;/code&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_05.png&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 5: GRID of Magnesium level in PPM from 40 to 95. The darker color the higher the value.&lt;/small&gt;
&lt;/p&gt;

&lt;h3&gt;Creating a third GRID from pH GRID and Magnesium GRID&lt;/h3&gt;

&lt;p&gt;For our example crop, the combination of a pH value between 7.0 and 7.5 and a high magnesium level represents the best soil. The resulting GRID will represent soil quality for that crop by combining the two GRIDs.  The cell values will be calculated according to a common formula used by agricultural engineers.  We attribute a factor for each pH value and Magnesium level, then we combine the two factors to get the soil quality for that crop.&lt;/p&gt;

&lt;div style=&quot;float:left; margin-right:50px;&quot;&gt;
&lt;table cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; border=&quot;1&quot; bordercolor=&quot;#808080&quot; style=&quot;border-collapse:collapse;&quot;&gt;
&lt;tr style=&quot;background-color:#ddd;&quot;&gt;
	&lt;th&gt;pH Level&lt;/th&gt;
	&lt;th&gt;Factor&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;6.20 to 6.40&lt;/td&gt;
	&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;6.40 to 6.60&lt;/td&gt;
	&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;6.60 to 6.80&lt;/td&gt;
	&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;6.80 to 7.00&lt;/td&gt;
	&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;7.00 to 7.20&lt;/td&gt;
	&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;7.20 to 7.40&lt;/td&gt;
	&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;7.40 to 7.60&lt;/td&gt;
	&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;7.60 to 7.80&lt;/td&gt;
	&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;7.80 to 8.00&lt;/td&gt;
	&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p style=&quot;margin-top:3px;&quot;&gt;&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Table 1: pH factors&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div style=&quot;float:left;&quot;&gt;
&lt;table cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; border=&quot;1&quot; bordercolor=&quot;#808080&quot; style=&quot;border-collapse:collapse;&quot;&gt;
&lt;tr style=&quot;background-color:#ddd;&quot;&gt;
	&lt;th&gt;Mg Level&lt;/th&gt;
	&lt;th&gt;Factor&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;40 to 45&lt;/td&gt;
	&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;45 to 50&lt;/td&gt;
	&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;50 to 55&lt;/td&gt;
	&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;55 to 60&lt;/td&gt;
	&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;60 to 65&lt;/td&gt;
	&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;65 to 70&lt;/td&gt;
	&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;70 to 75&lt;/td&gt;
	&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;75 to 80&lt;/td&gt;
	&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;80 to 85&lt;/td&gt;
	&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
	&lt;td&gt;85 to 90&lt;/td&gt;
	&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p style=&quot;margin-top:3px;&quot;&gt;&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Table 2: Mg factors&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p style=&quot;clear:left;&quot; /&gt;To determine the soil quality, we will combine the pH factor with the Mg factor. For example, if the pH is 6.67 and the Mg level is 55, the soil quality index will be 28 (7 * 4). The soil quality index goes from a minimum of 5 to a maximum of 100.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Private Sub btnSoilQuality_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSoilQuality.Click
        Dim gridExtent As New StraightRectangle(Map1.Layers(0).GridLayers(0).Extent)
        Dim cellSize As Double = 0.0001
        Dim NoDataValue As Double = -9999

        AddHandler GridLayer.CalculateCellValue, AddressOf CalculateCellValueSoilQuality

        Dim Result As Boolean = GridLayer.CreateGridFile(&quot;..\SoilQuality.grd&quot;, gridExtent, cellSize, NoDataValue)

        If Result = True Then
            MessageBox.Show(&quot;Grid File saved successfully.&quot;, &quot;Information&quot;, MessageBoxButtons.OK, MessageBoxIcon.Information)
        Else
            MessageBox.Show(&quot;Saving Grid File Failed.&quot;, &quot;Information&quot;, MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub

Private Sub CalculateCellValueSoilQuality(ByVal CellExtent As StraightRectangle, ByRef CellValue As Double)
        Dim CellULx As Double = CellExtent.UpperLeftPoint.X
        Dim CellULy As Double = CellExtent.UpperLeftPoint.Y
        Dim CellLRx As Double = CellExtent.LowerRightPoint.X
        Dim CellLRy As Double = CellExtent.LowerRightPoint.Y

        Dim xp As Double = CellExtent.Center.X
        Dim yp As Double = CellExtent.Center.Y
        Dim CellCenterPointShape As New PointShape(xp, yp)

        Dim pHValue As Double = Map1.Layers(0).GridLayers(0).GetCellValue(xp, yp)
        Dim MgValue As Double = Map1.Layers(0).GridLayers(1).GetCellValue(xp, yp)

        If pHValue &lt;&gt; -9999 And MgValue &lt;&gt; -9999 Then
            CellValue = GetSoilQualityIndex(pHValue, MgValue)
        Else
            CellValue = -9999
        End If
    End Sub

Private Function GetSoilQualityIndex(ByVal pHValue As Double, ByVal MgValue As Double) As Double
        Dim pHFactor, MgFactor As Integer
      
        If pHValue &lt; 6.4 Then
            pHFactor = 5
        ElseIf pHValue &lt; 6.6 Then
            pHFactor = 6
        ElseIf pHValue &lt; 6.8 Then
            pHFactor = 7
        ElseIf pHValue &lt; 7.0 Then
            pHFactor = 8
        ElseIf pHValue &lt; 7.2 Then
            pHFactor = 9
        ElseIf pHValue &lt; 7.4 Then
            pHFactor = 10
        ElseIf pHValue &lt; 7.6 Then
            pHFactor = 9
        ElseIf pHValue &lt; 7.8 Then
            pHFactor = 8
        Else
            pHFactor = 7
        End If

        If MgValue &lt; 45 Then
            MgFactor = 1
        ElseIf MgValue &lt; 50 Then
            MgFactor = 2
        ElseIf MgValue &lt; 55 Then
            MgFactor = 3
        ElseIf MgValue &lt; 60 Then
            MgFactor = 4
        ElseIf MgValue &lt; 65 Then
            MgFactor = 5
        ElseIf MgValue &lt; 70 Then
            MgFactor = 6
        ElseIf MgValue &lt; 75 Then
            MgFactor = 7
        ElseIf MgValue &lt; 80 Then
            MgFactor = 8
        ElseIf MgValue &lt; 85 Then
            MgFactor = 9
        Else
            MgFactor = 10
        End If

        Return pHFactor * MgFactor

    End Function
&lt;/code&gt;

&lt;p&gt;Now that we have created the GRID for Soil Quality, we are ready to display it.&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;Dim STR_GridFile As String = &quot;..\SoilQuality.grd&quot;
        Dim gridlayer As GridLayer = New GridLayer(STR_GridFile)
        gridlayer.LowerThreshold = 0
        gridlayer.UpperThreshold = Double.MaxValue
        gridlayer.ThresholdUnit = ThresholdUnits.miles
        gridlayer.IsNonValueTransparent = True
        Dim gridranges As RangeCollection = New RangeCollection()
        gridranges.Add(New Range(0, 25, Color.FromArgb(216, 253, 193)))
        gridranges.Add(New Range(25, 40, Color.FromArgb(182, 251, 140)))
        gridranges.Add(New Range(40, 55, Color.FromArgb(137, 248, 71)))
        gridranges.Add(New Range(55, 70, Color.FromArgb(96, 239, 10)))
        gridranges.Add(New Range(70, 85, Color.FromArgb(75, 188, 7)))
        gridranges.Add(New Range(85, 100, Color.FromArgb(52, 131, 5)))
        gridlayer.Ranges = gridranges
        Map1.Layers(0).GridLayers.Add(gridlayer)
&lt;/code&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_06.png&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 6: GRID for soil quality.&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;
	&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/GRID_07.png&quot; alt=&quot;Legend&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999; margin-bottom:5px;&quot; /&gt;&lt;br/&gt;
	&lt;small style=&quot;font-size:11px; color:#808080;&quot;&gt;Fig 7: Soil quality map legend.&lt;/small&gt;
&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;We hope that the simple examples in this article have shown you more clearly how GRID can help you perform and enhance various tasks in your industry. Keep in mind that the examples shown are very simplistic and that GRID is capable for far more sophisticated uses. In the future, we plan to add more white papers related to GRID to show how this technology can be used for a variety of additional tasks, such as surface analysis, diffusion modeling, zonal functions and more types of interpolations.&lt;/p&gt;

&lt;h3&gt;Downloads&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:9px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/download/GridDemo.zip&quot; style=&quot;padding-left:20px; background:url(/portals/1/icons/icon_download_2.gif) no-repeat left center;&quot;&gt;&lt;b&gt;Download GRID Demo Application&lt;/b&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;b&gt;Note: You will need to download the &lt;a href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;Map Suite Desktop .NET GIS Control Free Evaluation&lt;/a&gt; in order to run the example in this article.&lt;/b&gt; (Registration Required)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Have Questions?&lt;/h3&gt;

&lt;p&gt;Do you have any questions or comments about this article?  If so, feel free post your questions on the &lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Map Suite Discussion Forums&lt;/a&gt; or leave feedback at the &lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/afv/topicsview/aff/16/Default.aspx&quot;&gt;ThinkGeo Blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Additional Resources&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite QuickStart Guides&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/APIDocumentation/tabid/194/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite API Documentation&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/FAQs/tabid/196/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite FAQs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About the Author&lt;/h3&gt;

&lt;p&gt;Val Guillou is a GIS analyst and developer at ThinkGeo, a software company specializing in geospatial software with an emphasis on software development tools and GPS tracking solutions.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4784/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Thu, 13 Nov 2008 05:38:13 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4784/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Implementing a Custom Zoom Bar with Map Suite</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;When working with customers, many times I am asked, &quot;How do I implement a custom zoom bar into my application?&quot; At first glance this may seem like a difficult task, but with a little explanation on a few concepts and some sample code, you can easily implement a full-featured zoom bar that meets the needs of your application. In this article I will show you how to build a custom zoom bar using the prebuilt zoom levels defined within Map Suite Web Edition; however, the same concepts apply to building a custom zoom bar using the Map Suite Desktop Edition as well.&lt;/p&gt;&lt;/div&gt;

&lt;h3&gt;Zoom Levels Explained&lt;/h3&gt;

&lt;p&gt;The Map Suite Desktop, Web and Engine products each come with eighteen prebuilt zoom levels to handle the most common zooming scenarios, ranging from worldwide coverage down to local streets.  Having these prebuilt zoom levels at your disposal gives you complete control over how the map is rendered at each zoom level.  For example, if you have a map of the world, you wouldn't want to show a lot of detail like country names or roads when the map is zoomed completely out.  But as you zoom in, typically you would want to turn on more information such as labels and other map features.   With Map Suite you can do just that &amp;#8212; from tailoring ZoomLevel18 for views that show the entire globe, down to customizing ZoomLevel01 for a very detailed zoom area like local streets or small land parcels.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; Map Suite also allows you to specify your own zoom levels if the prebuilt levels don't meet your needs.&lt;/p&gt;

&lt;h3&gt;Getting Started&lt;/h3&gt;

&lt;p&gt;Now that we have covered how zoom levels work, let's get to the fun part: building our sample application with a custom zoom bar.  To get started, you will need to create a new ASP.NET web application in Visual Studio 2005. Next, you will need to reference the &lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteWeb/tabid/148/Default.aspx&quot;&gt;Map Suite Web Edition .NET Control&lt;/a&gt; and drag it on to the web page. Also, don't forget to add the HTTP Handler section to your Web.config file so the map control can render properly.&lt;/p&gt;

&lt;p&gt;Now let's add some code to the Page_Load event to initialize the Map and load up our layer representing all the countries in the world.  Additionally, we will write some code to color these countries in a reddish hue and turn on country name labeling for zoom levels one to fourteen.&lt;/p&gt;

&lt;h5&gt;Page_Load Code:&lt;/h5&gt;

&lt;code lang=&quot;csharp&quot;&gt;if (!IsPostBack)
	{
		// Set property of map control
		Map1.MapUnit = MapLengthUnits.DecimalDegrees;
		Map1.Mode = Map.ModeType.Pan;
		Rectangle Rect = new Rectangle(0, 0, (int)Map1.Width.Value, (int)Map1.Height.Value);
		Map1.CanvasGeoBrush = new GeoLinearGradientBrush(Rect, GeoColor.GeographicColors.Ocean1, GeoColor.GeographicColors.Ocean2, GeoLinearGradientMode.ForwardDiagonal);
		Map1.AjaxEnabled = true;
		
		// Load world countries layer
		Layer cntryLayer = new Layer(this.Server.MapPath(&quot;&quot;) + @&quot;\SampleData\world\cntry02.shp&quot;, true);
		//Color Countries with labels for all zoom level 14 and below
		cntryLayer.ZoomLevel01.GeoStyle = GeoAreaStyles.GetHueFamilyStyle(6, GeoColor.KnownColors.Red, GeoColor.KnownColors.Gray);
		cntryLayer.ZoomLevel01.GeoTextStyle = GeoTextStyles.Country1(&quot;CNTRY_NAME&quot;);
		cntryLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel14;
		//Color Countries with no labels to higest zoom levels
		cntryLayer.ZoomLevel14.GeoStyle = GeoAreaStyles.GetHueFamilyStyle(6, GeoColor.KnownColors.Red, GeoColor.KnownColors.Gray);
		cntryLayer.ZoomLevel14.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
		Map1.Layers.Add(cntryLayer);
		
		// Save some values in session
		Session.Add(&quot;FullScale&quot;, Map1.CurrentScale);
	}
&lt;/code&gt;

&lt;p&gt;Once you have this code implemented, you should be able to run your project and have a map displaying similar to the one below.&lt;/p&gt;

&lt;p&gt;&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/ZoomBar01.jpg&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999;&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;HTML Code&lt;/h3&gt;

&lt;p&gt;Now that we have a simple map displaying, it's time to take it to the next step and create our custom zoom bar using standard HTML.  To do this, we will create a rather large zoom bar which has a button for each of the eighteen prebuilt zoom levels within Map Suite.  If eighteen zoom levels seem like too many, remember that you have complete control over the number of zoom levels and you can implement the number that makes sense for your application.  Below is the HTML that you'll need in order to implement a zoom bar with all eighteen levels. As you will notice, for each Zoom Button we make an AJAX call and pass in the level that each button represents.  Once you have the HTML implemented, the next step is to add the server side code to zoom the map in to the proper level.&lt;/p&gt;

&lt;h5&gt;HTML Code:&lt;/h5&gt;

&lt;code lang=&quot;html&quot;&gt;&lt;!-- Zoom Bar --&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93; Local
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93; City
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93; Area
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93; Country
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93;
&lt;/p&gt;
&lt;p class=&quot;ZoomButton&quot;&gt;
	&amp;#91;script removed&amp;#93; World
&lt;/p&gt;
&lt;/code&gt;

&lt;h3&gt;Server Side Code&lt;/h3&gt;

&lt;p&gt;With the zoom bar now implemented in the webpage, it's time to write some server side code to capture the AJAX event and zoom the map in to the proper level.  To handle the AJAX event raised from the JavaScript click event on the zoom bar button, we need to implement the Map's AjaxPostback event, write a case statement based on the argument from each zoom bar button and set the map zoom level accordingly.  Below is some sample code showing how to implement this functionality.&lt;/p&gt;

&lt;h5&gt;Map1_AjaxPostback Code:&lt;/h5&gt;

&lt;code lang=&quot;csharp&quot;&gt;protected void Map1_AjaxPostback(object sender, AjaxPostbackEventArgs e)
	{
		switch (e.EventName)
		{
			case &quot;ClickLevel1&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel01);
				break;
			case &quot;ClickLevel2&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel02);
				break;
			case &quot;ClickLevel3&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel03);
				break;
			case &quot;ClickLevel4&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel04);
				break;
			case &quot;ClickLevel5&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel05);
				break;
			case &quot;ClickLevel6&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel06);
				break;
			case &quot;ClickLevel7&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel07);
				break;
			case &quot;ClickLevel8&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel08);
				break;
			case &quot;ClickLevel9&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel09);
				break;
			case &quot;ClickLevel10&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel10);
				break;
			case &quot;ClickLevel11&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel11);
				break;
			case &quot;ClickLevel12&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel12);
				break;
			case &quot;ClickLevel13&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel13);
				break;
			case &quot;ClickLevel14&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel14);
				break;
			case &quot;ClickLevel15&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel15);
				break;
			case &quot;ClickLevel16&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel16);
				break;
			case &quot;ClickLevel17&quot;:
				Map1.CurrentScale = GetScaleFromZoomlevel(Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel17);
				break;
			case &quot;ClickLevel18&quot;:
				Map1.CurrentScale = (Double)Session&amp;#91;&quot;FullScale&quot;&amp;#93;;
				break;
			case &quot;ZoomIn&quot;:
				Map1.ZoomIn(20);
				break;
			case &quot;ZoomOut&quot;:
				Map1.ZoomOut(20);
				break;
			case &quot;TrackZoom&quot;:
				Map1.Mode = Map.ModeType.TrackZoomIn;
				break;
			case &quot;PreviousExtent&quot;:
				Map1.GetPreviousExtent();
				break;
			case &quot;ToggleExtent&quot;:
				Map1.ToggleMapExtents();
				break;
			case &quot;FullExtent&quot;:
				Map1.CurrentExtent = Map1.Layers&amp;#91;0&amp;#93;.Extent;
				break;
			case &quot;PanLeft&quot;:
				Map1.Pan(PanDirection.Left, 20);
				break;
			case &quot;PanRight&quot;:
				Map1.Pan(PanDirection.Right, 20);
				break;
			case &quot;PanUp&quot;:
				Map1.Pan(PanDirection.Up, 20);
				break;
			case &quot;PanDown&quot;:
				Map1.Pan(PanDirection.Down, 20);
				break;
			case &quot;PanNorthEast&quot;:
				Map1.Pan(45, 20);
				break;
			case &quot;PanNorthWest&quot;:
				Map1.Pan(315, 20);
				break;
			case &quot;PanSouthEast&quot;:
				Map1.Pan(135, 20);
				break;
			case &quot;PanSouthWest&quot;:
				Map1.Pan(225, 20);
				break;
			// Click zoom level button in zoom bar
			default:
				break;
		}
	
		// Sent value back and we will deal with it in client by &quot;CustomCallback&quot; function
		Map1.AjaxReturnArgs = &quot;Level&quot; + GetLevelNumber(Map1.CurrentScale).ToString();
	}
&lt;/code&gt;

&lt;p&gt;As you can see from the code above, for each click level we are calling a function named GetScaleFromZoomLevel and passing in the associated zoom level.  This function returns the new zoom level by calculating the midpoint of the zoom level's scale.  Once the new scale is calculated, all that remains is to set this scale to the Map's Current Scale property.  The code for the GetScaleFromZoomLevel function that returns the zoom level's midpoint is shown below for your reference.&lt;/p&gt;

&lt;code lang=&quot;csharp&quot;&gt;private double GetScaleFromZoomlevel(PresetZoomLevel presetZoomLevel)
{
	return (presetZoomLevel.UpperExtent + resetZoomLevel.LowerExtent) / 2;
}
&lt;/code&gt;

&lt;p&gt;Now the only thing left to do is return the zoom level that we are currently at, so that the zoom bar buttons can be updated accordingly.  This is accomplished by utilizing the GetLevelNumber function and the Map's AjaxReturnArgs property. In case you're not familiar with the AjaxReturnArgs property, it s a mechanism for passing data back to the client code.  At the end of the Map1_AjaxPostback event handler you will see the following line of code, which sets the AjaxReturnArgs property to the Zoom Level we are currently displaying:&lt;/p&gt;

&lt;code lang=&quot;csharp&quot;&gt;Map1.AjaxReturnArgs = &quot;Level&quot; + GetLevelNumber(Map1.CurrentScale).ToString();&lt;/code&gt;

&lt;p&gt;In case you were curious what the GetLevelNumber function does, it takes the CurrentScale of the map, compares it against all of the zoom levels and returns the current zoom level.  The code for this function is provided below for your reference.&lt;/p&gt;

&lt;h5&gt;GetLevelNumber Function Code:&lt;/h5&gt;

&lt;code lang=&quot;csharp&quot;&gt;public int GetLevelNumber(double scale)
	{
		int result;
		if (scale &lt; 0)
		{
			throw new Exception(&quot;The Width of your Map should be more than 0&quot;);
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel01.UpperExtent)
		{
			result = 1;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel02.UpperExtent)
		{
			result = 2;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel03.UpperExtent)
		{
			result = 3;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel04.UpperExtent)
		{
			result = 4;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel05.UpperExtent)
		{
			result = 5;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel06.UpperExtent)
		{
			result = 6;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel07.UpperExtent)
		{
			result = 7;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel08.UpperExtent)
		{
			result = 8;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel09.UpperExtent)
		{
			result = 9;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel10.UpperExtent)
		{
			result = 10;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel11.UpperExtent)
		{
			result = 11;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel12.UpperExtent)
		{
			result = 12;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel13.UpperExtent)
		{
			result = 13;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel14.UpperExtent)
		{
			result = 14;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel15.UpperExtent)
		{
			result = 15;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel16.UpperExtent)
		{
			result = 16;
		}
		else if (scale &lt; Map1.Layers&amp;#91;0&amp;#93;.ZoomLevel17.UpperExtent)
		{
			result = 17;
		}
		else
		{
			result = 18;
		}
		return result;
	}
&lt;/code&gt;

&lt;h3&gt;Client Side JavaScript Code&lt;/h3&gt;

&lt;p&gt;Now that the server side code is completed and the map is zoomed into the proper level, the next step is to update the zoom bar button images to identify which zoom level is currently being displayed on the map.  To accomplish this, we will need to implement the CustomCallback JavaScript function on the client side.  This will allow us to analyze the return arguments from the server side code and update each zoom bar button image accordingly.  For an example on how to implement this, please see the code below:&lt;/p&gt;

&lt;h5&gt;CustomCallback Javascript Code:&lt;/h5&gt;

&lt;code lang=&quot;script&quot;&gt;&lt;!--Get value from server and set the status of zoom button--&gt;
	&amp;#91;script removed&amp;#93;
		function CustomCallback(ajaxReturnArgs)
		{
			if(ajaxReturnArgs != '')
			{
				var ImageButton;
				ImageButton = document.getElementById('Level1');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level2');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level3');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level4');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level5');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level6');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level7');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level8');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level9');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level10');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level11');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level12');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level13');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level14');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level15');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level16');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level17');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById('Level18');
				ImageButton.src='./images/zoombar_off.png';
				
				ImageButton = document.getElementById(ajaxReturnArgs);
				ImageButton.src='./images/zoombar_on.png';
			}
		}
	&amp;#91;script removed&amp;#93;
&lt;/code&gt;

&lt;p&gt;Once you have this JavaScript function implemented, the appropriate zoom bar button should be highlighted in green, like the &quot;Country&quot; zoom bar button is in the screen shot below.&lt;/p&gt;

&lt;p&gt;&lt;IMG src=&quot;http://gis.thinkgeo.com/portals/1/articles/ZoomBar02.jpg&quot; alt=&quot;Sample Application Screenshot&quot; class=&quot;Figure&quot; style=&quot;border:1px solid #999;&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;In conclusion, you now can see how to build your own custom zoom bar to meet your specific needs.   Having this flexibility allows you to control the zoom levels, zoom bar location and overall look of the zoom bar implementation.  This can be very important when making the mapping screen easy to use for end users.  Below, I have listed several links where you can download the full source code and project to get more familiar with the sample application described in this article.  Finally, if you have any questions or suggestions please feel to post comments on the ThinkGeo Blog or Discussion Forums, as these are both great ways for us to hear from the Map Suite community.&lt;/p&gt;

&lt;h3&gt;Downloads&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://download.thinkgeo.com/zoombardemo.zip&quot;&gt;Download Project and Source Code for Map Suite Zoom Bar Example&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite Web ASP.NET Control&lt;/a&gt; (Registration Required)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You will need to download and install the Map Suite Web Edition in order to run the example in this article.&lt;/p&gt;

&lt;h3&gt;Have Questions?&lt;/h3&gt;

&lt;p&gt;Do you have any questions or comments about this article?  If so, feel free post your questions on the &lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Map Suite Discussion Forums&lt;/a&gt; or leave feedback at the &lt;a href=&quot;http://blog.thinkgeo.com&quot; target=&quot;_blank&quot;&gt;ThinkGeo Blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Additional Resources&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite QuickStart Guides&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/APIDocumentation/tabid/194/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite API Documentation&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/FAQs/tabid/196/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite FAQs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About the Author&lt;/h3&gt;

&lt;p&gt;Clint Batman is co-founder and President of ThinkGeo, a software company specializing in geospatial software with an emphasis on software development tools and GPS tracking solutions.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4779/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 12 Nov 2008 08:43:28 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4779/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Using Map Suite Explorer to Help You Build GIS Apps</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;Map Suite Explorer is a free tool that is included with each Map Suite Desktop, Web, and Engine .NET GIS component. It transforms the Map Suite API into an easy-to-use, user-friendly format that allows for ShapeFile viewing and rendering experimentation without the hassle of writing code. This article will show you how you can use Map Suite Explorer to help you write your GIS applications.                                       &lt;/p&gt;&lt;/div&gt;

&lt;h3&gt;Introduction&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/tabid/125/Default.aspx&quot;&gt;Map Suite GIS software&lt;/a&gt; has many powerful features, from reprojection and spatial queries to ShapeFile editing and customized labelers.  While these features allow a developer the ultimate in control, they can also deter developers with limited Map Suite experience from learning the basics about the Map Suite API.&lt;/p&gt;

&lt;p&gt;As a support representative, I see many questions about creating renderers, loading layers, and creating thresholds.  To assist with these questions, I sometimes reference Map Suite Explorer as a resource for this information.&lt;/p&gt;

&lt;h3&gt;What is Map Suite Explorer?&lt;/h3&gt;

&lt;p&gt;Map Suite Explorer is a free tool that is included with both the evaluation and full versions of each &lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/tabid/125/Default.aspx&quot;&gt;Map Suite Desktop, Web, and Engine .NET GIS component&lt;/a&gt;.  It is not a .NET mapping control; rather, it transforms the Map Suite API into an easy-to-use, user-friendly format that allows for ShapeFile viewing and rendering experimentation without the hassle of writing code.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note!&lt;/b&gt; You will still need to use the &lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteDesktop/tabid/137/Default.aspx&quot;&gt;Desktop&lt;/a&gt;, &lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteWeb/tabid/148/Default.aspx&quot;&gt;Web&lt;/a&gt; or &lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteEngine/tabid/153/Default.aspx&quot;&gt;Engine&lt;/a&gt; controls to render a map your application. Map Suite Explorer itself is an application and uses the Map Suite control to render maps.&lt;/p&gt;

&lt;h3&gt;How is Map Suite Explorer Going to Help Me?&lt;/h3&gt;

&lt;p&gt;One example is that rather than writing out the code to load a layer, apply a threshold and a renderer, you can instead use Map Suite Explorer's GUI interface to complete this task in seconds.&lt;/p&gt;

&lt;p&gt;To begin, you will need to either &lt;a href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;download an evaluation edition&lt;/a&gt; or &lt;a href=&quot;https://onlinestore.thinkgeo.com/onlinestore/Step1.aspx?onlinestoreid=b17ef9e4-c118-4246-8e80-39b6e49f4ab6&quot; target=&quot;_blank&quot;&gt;purchase a full version&lt;/a&gt; of the Map Suite Desktop, Web, or Engine .NET GIS components. (You may need to register on our site to download an evaluation.)&lt;/p&gt;

&lt;p&gt;After installing Map Suite, navigate to Start-&gt;Programs-&gt;ThinkGeo and chose the folder of your product. Next, click on &lt;b&gt;Map Suite Explorer&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Let's start by loading a Layer (ShapeFile) and adding a Threshold and a SymbolRenderer.&lt;/p&gt;

&lt;p&gt;First, we load the layer by clicking File-&gt;Add New Layer, or clicking the button named &quot;Add New Layer&quot; on the far left of the toolbar.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_01.png&quot; alt=&quot;Adding a new layer&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here I have selected the &lt;tt&gt;STATES.SHP&lt;/tt&gt; file from the &lt;tt&gt;C:\Program Files\ThinkGeo\Map Suite Desktop Edition 2.0\SampleData\USA&lt;/tt&gt; folder.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_02.png&quot; alt=&quot;Selecting STATES.SHP&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click Open and immediately you will see the STATES layer displayed on the map.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_03.png&quot; alt=&quot;The STATES layer on the map&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you need to review several ShapeFiles quickly, you can easily add additional Layers using the same method, or by right-clicking on the &lt;b&gt;Layers&lt;/b&gt; node in the tree view.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_04.png&quot; alt=&quot;Right-clicking on the Layers node&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Right-clicking on the nodes will bring up menus where you can add many different elements to the map. Now that we have a Layer, let's render it in a different color.  Map Suite Explorer will automatically assign a color to a Layer unless there is a Threshold set, which is why a SymbolRenderer did not need to be specified right away.&lt;/p&gt;

&lt;p&gt;By right-clicking on the &lt;b&gt;Thresholds&lt;/b&gt; node, you will have the option to &lt;b&gt;Add a Threshold&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Note this relationship: You &lt;b&gt;add&lt;/b&gt; a &lt;b&gt;Threshold&lt;/b&gt; to the &lt;b&gt;STATES Layer&lt;/b&gt;. In code this would be: &lt;code&gt;Layer.Thresholds.Add(name of threshold)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_05.png&quot; alt=&quot;Adding a threshold&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that we have a threshold, our map is blank. This is because we have only defined &lt;b&gt;&lt;i&gt;when&lt;/i&gt;&lt;/b&gt; we want a Layer to be displayed.  We now need to define &lt;b&gt;&lt;i&gt;how&lt;/i&gt;&lt;/b&gt; we want the Layer displayed.&lt;/p&gt;

&lt;p&gt;To do this, right-click on &lt;b&gt;SymbolRenderers&lt;/b&gt; for &lt;b&gt;NewThreshold1&lt;/b&gt; and select &lt;b&gt;Add a SymbolRenderer&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_06.png&quot; alt=&quot;Adding a SymbolRenderer&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We now need to define &lt;b&gt;&lt;i&gt;what&lt;/i&gt;&lt;/b&gt; symbol we want to be displayed by the SymbolRenderer. Right-click on the &lt;b&gt;Symbols&lt;/b&gt; node.  For the STATES ShapeFile, we'll choose &lt;b&gt;Add AreaSymbol&lt;/b&gt; since our ShapeFile contains area shapes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_07.png&quot; alt=&quot;Adding an AreaSymbol&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Immediately you should see the outline of the states show up.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_08.png&quot; alt=&quot;The outline of the states on your map view&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By changing the &lt;b&gt;Pen&lt;/b&gt; and &lt;b&gt;Brush&lt;/b&gt; settings, we can control &lt;b&gt;&lt;i&gt;how&lt;/i&gt;&lt;/b&gt; the layer is rendered.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_09.png&quot; alt=&quot;The map view using a blue pen and red brush&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Okay, Now We Can Change the Colors of the Map, But Other Than the Simple Relationships Demonstrated by the Tree, How Will This Help Me Code?&lt;/h3&gt;

&lt;p&gt;Map Suite has a feature to create either C#, VB.NET, or XML code that you can use to create your feasibility demos for management, or to see how the code is structured.&lt;/p&gt;

&lt;p&gt;By right-clicking on the &lt;b&gt;Map1&lt;/b&gt; node, you get the option to:&lt;/p&gt;

&lt;ul style=&quot;font-weight:bold;&quot;&gt;
	&lt;li&gt;Generate VB Code&lt;/li&gt;
	&lt;li&gt;Generate C# Code&lt;/li&gt;
	&lt;li&gt;Generate XML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this example, I chose &lt;b&gt;Generate VB Code&lt;/b&gt; and here is the result:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_10.png&quot; alt=&quot;VB code generated by Map Suite Explorer&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With a couple of minor changes to this code, you can have a working map very quickly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://gis.thinkgeo.com/portals/1/articles/MapSuiteExplorer_11.png&quot; alt=&quot;A map rendered by the VB code from Map Suite Explorer&quot; class=&quot;Figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you may notice, the code is quite verbose as it sets every single properly of the Map, Layer, Threshold, and SymbolRenderer.  While I would not recommend using Map Suite Explorer to write your production code, it can be very helpful in understanding the structure of the Map Suite API.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Through this introduction to Map Suite Explorer, we have learned to load and render layers as well as create code that can be helpful in building demo applications.  Additionally, Map Suite Explorer has shown it can display relationships between objects in the &lt;a href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/tabid/125/Default.aspx&quot;&gt;Map Suite .NET GIS components&lt;/a&gt;. Although this information is available in the documentation, Map Suite Explorer's visual representation of those relationships may prove to be more intuitive and helpful.&lt;/p&gt;

&lt;p&gt;Please see the downloadable code below that demonstrates how you could use Map Suite Explorer-created code to jump start your experience with Map Suite!&lt;/p&gt;

&lt;h3&gt;Downloads&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://download.thinkgeo.com/ExplorerSample.zip&quot; class=&quot;lightbluearrow&quot;&gt;Map Suite Explorer Sample Code in VB.NET&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Have Questions?&lt;/h3&gt;

&lt;p&gt;Do you have questions or comments about this article?  Feel free post your questions on the &lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Map Suite Discussion Forums&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Additional Resources&lt;/h3&gt;

&lt;ul style=&quot;list-style-type:none; margin-left:0; padding-left:0;&quot;&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite QuickStart Guides&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none; padding-bottom:6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/APIDocumentation/tabid/194/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite API Documentation&lt;/a&gt;&lt;/li&gt;
	&lt;li style=&quot;list-style-type:none;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/FAQs/tabid/196/Default.aspx&quot; target=&quot;_blank&quot;&gt;Map Suite FAQs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About the Author&lt;/h3&gt;

&lt;p&gt;Ryan Desemo is one of ThinkGeo's lead customer support representatives and a technological guru.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4778/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 12 Nov 2008 08:32:20 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4778/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Building Scalable Mapping &amp; GIS Apps with Web Services</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;With the emergence of popular online mapping applications over the past few years, more businesses are seeing a need to build mapping and GIS (Geographic Information Systems) functionality into their own custom applications. While online services like Google Maps &amp;amp; Virtual Earth work well in some cases, many times programmers need more control over the map data, map rendering, GIS capabilities, security and overall architecture. In this article, I will show you how to build a scalable mapping application utilizing a web service and how to consume the web service from a client application.&lt;/p&gt;&lt;/div&gt;

&lt;h3&gt;Getting Started&lt;/h3&gt;

&lt;p&gt;Typically, when I get ready to build a new mapping application, I take a look at how the application will be used and try to break the map data into two separate categories:&lt;/p&gt;

&lt;ul&gt;
    &lt;li style=&quot;padding-bottom: 8px;&quot;&gt;&lt;b&gt;Base Map&lt;/b&gt; &amp;ndash; The base map is made up of the relatively static map data that you always want to show. Typically, these base maps are made up of common features like political boundaries, water features, roads and points of interest. For this example, I'm going to keep the base map very simple and just use an outline of the United States. If I wanted to use a more detailed base map, I would utilize one of the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/MapDatasetPluginsforNETDevelopers/tabid/128/Default.aspx&quot;&gt;Map Suite Data Plugins&lt;/a&gt; to take care of the map data and rendering logic.&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;Dynamic Map Data&lt;/b&gt; &amp;ndash; This type of map data changes frequently and will need to be updated regularly. Typically, this type of data is stored in a database that is updated by the application or other outside sources. In this example, I will again keep it simple and simulate plotting the location of two customers in the United States.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you have an idea of the two different types of map data we will be dealing with, we can get started building the web service that will serve up our base maps.&lt;/p&gt;

&lt;h3&gt;The Web Service&lt;/h3&gt;

&lt;p&gt;The main goal we need to accomplish with this web service is to provide a high performance, scalable way to render the base maps. These base maps will then be consumed by our sample application. Encapsulating the logic to render the base maps into a web service allows us several advantages. These include centralized map data storage, map data only being loaded into memory once for all users, and finally, you can easily scale web services with a load balancer if demand grows.&lt;/p&gt;

&lt;p&gt;To achieve maximum performance, we are going to utilize the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteEngine/tabid/153/Default.aspx&quot;&gt;Map Suite Engine Edition .NET component&lt;/a&gt;. This component will do the heavy lifting of rendering the map image that will be consumed by our sample application. To get started, you will need to create a new ASP.NET web service project in Visual Studio 2005. Once the new project is loaded, the first thing you will need to do is write the web service initialization code. To do this, you will need to add a &lt;tt&gt;Global.asax&lt;/tt&gt; file to your web service. The &lt;tt&gt;Global.asax&lt;/tt&gt; code below is where the MapEngine object is instantiated and the map data is loaded so it can be used for all web service requests.&lt;/p&gt;

&lt;h5&gt;Global.asax Code:&lt;/h5&gt;

&lt;code lang=&quot;csharp&quot;&gt;using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using MapSuite;

namespace MapWebServiceExample
{
	public class Global : System.Web.HttpApplication
	{
		protected void Application_Start(object sender, EventArgs e)
		{
			//Instantiate the MapEngine component
			MapEngine mapServer = new MapEngine();
			//Create the Layer Object that loads the data for the USA outline
			Layer stateLayer = new Layer(this.Server.MapPath(&quot;&quot;) + @&quot;\SampleData\STATES.shp&quot;);
			//Set the color of the states to use the State1 geostyle
			GeoStyle stateGeoStyle = GeoAreaStyles.GetSimpleAreaStyle
				(GeoColor.GeographicColors.State1, GeoColor.KnownColors.Black);
			stateLayer.ZoomLevel01.GeoStyle = stateGeoStyle;
			//Apply this color &amp; style to all zoom levels
			stateLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
			//Add the state layer to the map
			mapServer.Layers.Add(stateLayer);
			//Store the map engine object to Application state
			Application.Add(&quot;mapServer&quot;, mapServer);
		}
		
		protected void Application_End(object sender, EventArgs e)
		{
			//Clear the application
			Application.Clear();
		}
	}
}
&lt;/code&gt;

&lt;p&gt;Now that we have written the code to initialize the web service, the next step is to create a WebMethod that our client application can call to retrieve the map image. To accomplish this, you will need to add a new web service page to your solution with an &lt;tt&gt;.asmx&lt;/tt&gt; extension.  For this example, I called the web service page &lt;tt&gt;MapService.asmx&lt;/tt&gt; and exposed one public WebMethod called GetMapImage. The GetMapImage method takes in a few parameters so we can create the proper map image for the consuming application. These parameters include:&lt;/p&gt;

&lt;ul style=&quot;list-style-type: none;&quot;&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;uLX&lt;/tt&gt;&lt;/span&gt; &amp;ndash; upper left x coordinate of the map image requested&lt;/li&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;uLY&lt;/tt&gt;&lt;/span&gt; &amp;ndash; upper left y coordinate of the map image requested&lt;/li&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;lRX&lt;/tt&gt;&lt;/span&gt; &amp;ndash; lower right x coordinate of the map image requested&lt;/li&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;lRY&lt;/tt&gt;&lt;/span&gt; &amp;ndash; lower right y coordinate of the map image requested&lt;/li&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;height&lt;/tt&gt;&lt;/span&gt; &amp;ndash; height of image requested&lt;/li&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;width&lt;/tt&gt;&lt;/span&gt; &amp;ndash; width of the image requested&lt;/li&gt;
    &lt;li&gt;&lt;span style=&quot;width: 60px;&quot;&gt;&lt;tt&gt;quality&lt;/tt&gt;&lt;/span&gt; &amp;ndash; quality of compressed image returned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these parameters, we can now create the specified map image in our web utilizing the map engine object that we initialized in the &lt;tt&gt;Global.asax&lt;/tt&gt; file.  To see how this is accomplished, refer to the code below:&lt;/p&gt;

&lt;h5&gt;MapService.asmx Code:&lt;/h5&gt;

&lt;code lang=&quot;csharp&quot;&gt;using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using MapSuite;
using MapSuite.Geometry;

namespace MapWebServiceExample
{
	/// &lt;summary&gt;
	/// Summary description for Service1
	/// &lt;/summary&gt;
	&amp;#91;WebService(Namespace = &quot;http://tempuri.org/&quot;)&amp;#93;
	&amp;#91;WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)&amp;#93;
	&amp;#91;ToolboxItem(false)&amp;#93;
	public class MapService : System.Web.Services.WebService
	{
	&amp;#91;WebMethod&amp;#93;
		public byte&amp;#91;&amp;#93; GetMapImage(double uLX, double uLY, double lRX, double lRY, int height, int width, short quality)
		{
			// Handle threading and retrieve the map engine
			System.Threading.Monitor.Enter(Application&amp;#91;&quot;mapServer&quot;&amp;#93;);
			MapEngine map1;
			map1 = Application&amp;#91;&quot;mapServer&quot;&amp;#93; as MapEngine;
			//Create the Rectangle for the Map Area we want to return using cooridnates
			RectangleR fullExtent = new RectangleR(new PointR(uLX, uLY), new PointR(lRX, lRY));
			//Create new map bitmap and retrieve graphics object from it.
			Bitmap bmp = new Bitmap(width, height);
			Graphics g = Graphics.FromImage(bmp);
			//Pass the graphic objects into the map engine to draw the image
			map1.GetMap(g, fullExtent, width, height, MapLengthUnits.DecimalDegrees, 0);
			//Dispose of graphic object and handle threading
			g.Dispose();
			System.Threading.Monitor.Exit(Application&amp;#91;&quot;mapServer&quot;&amp;#93;);
			
			//Create a new memory stream to hold the image
			MemoryStream MemoryStream = new MemoryStream();
			
			//Get codecs
			ImageCodecInfo&amp;#91;&amp;#93; icf = ImageCodecInfo.GetImageEncoders();
			EncoderParameters encps = new EncoderParameters(1);
			EncoderParameter encp = new EncoderParameter(Encoder.Quality, (long)quality);
			
			//Set quality and save the map to the memory stream
			encps.Param&amp;#91;0&amp;#93; = encp;
			bmp.Save(MemoryStream, icf&amp;#91;1&amp;#93;, encps);
			MemoryStream.Close();
			//stream the image back to the client
			return MemoryStream.ToArray();
		}
	}
}
&lt;/code&gt;

&lt;h3&gt;The Client Application&lt;/h3&gt;

&lt;p&gt;Now that we have the web service built, we move our focus onto the client application that will consume the web service and plot the customer locations. For this example, we are going to build a ASP.NET web application utilizing the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteWeb/tabid/148/Default.aspx&quot;&gt;Map Suite Web ASP.NET server control&lt;/a&gt;; however, the web service can be consumed just as easily in a desktop client application utilizing the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteDesktop/tabid/137/Default.aspx&quot;&gt;Map Suite Desktop .NET control&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get started, you will need to create a new ASP.NET web application in Visual Studio 2005. Next, you will need to reference the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteWeb/tabid/148/Default.aspx&quot;&gt;Map Suite Web Edition .NET Control&lt;/a&gt; and drag it on to the web page. Also, don't forget to add the HTTP Handler section to your &lt;tt&gt;Web.config&lt;/tt&gt; file so the map control can render properly. Finally, you will need to add a web reference to the web service that was created earlier.&lt;/p&gt;

&lt;p&gt;Once you have your application ready to start coding, you will need to put some code into the Page_Load event handler and the Map_BeforeLayerDraw event handler, along with some additional coding to display the customer points and handle zooming in and out. The Page_Load event handler code accomplishes a couple things. First, it sets the MapUnit property, which tells the map control which coordinate system to use. In this example, the coordinate system we will be working with is decimal degrees, also known as longitude &amp;amp; latitude coordinates. Next, we write some code to set the initial zoom level and default the map to pan mode. Finally, the last bit of code in the Page_Load calls the DisplayCustomerPoints function, which handles the task of displaying our dynamic customer points on the map.&lt;/p&gt;

&lt;p&gt;You may be asking yourself, where does the web service fit in? By writing some code in the Map_BeforeLayersDraw event handler, we will be able to call the web service and draw our base map of the United States on the map control. To do this, we must first instantiate the web service and call the GetMapImage web method. Once we receive the byte array from the web service that contains the map image, the final task is to draw the map image on the map control using the graphics object passed into the event handler.&lt;/p&gt;

&lt;p&gt;To make the application a little bit more user friendly, I have added &amp;ldquo;zoom in&amp;rdquo; and &amp;ldquo;zoom out&amp;rdquo; buttons to allow the user to zoom in and out. To see this code and all of the code mentioned above, please review the below:&lt;/p&gt;

&lt;h5&gt;Default.aspx Code:&lt;/h5&gt;

&lt;code lang=&quot;csharp&quot;&gt;using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Drawing;
using MapSuite;
using MapSuite.Geometry;

public partial class _Default : System.Web.UI.Page
{
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!IsPostBack)
		{
			//Set our Map Unit so we can use longitude &amp; latitude coordinates
			Map1.MapUnit = MapSuite.Geometry.MapLengthUnits.DecimalDegrees;
			//Tell the map control that we are going to control the extent
			Map1.AutoFullExtent = false;
			//Default the zoom/extent to show the lower 48 states
			Map1.CurrentExtent = new RectangleR(-125, 55, -66, 18);
			//Set the default mode of the map to panning
			Map1.Mode = MapSuite.WebEdition.Map.ModeType.Pan;
			//Enable Ajax capabilites for the map control
			Map1.AjaxEnabled = true;
			//Call the function so we can plot our customer points
			DisplayCustomerPoints();
		}
	}

	protected void Map1_BeforeLayersDraw(System.Drawing.Graphics G)
	{
		//Insantiate the webservice
		localhost.MapService MapMaker = new localhost.MapService();
		//Call the GetMapImage WebMethod
		byte&amp;#91;&amp;#93; images = MapMaker.GetMapImage(Map1.CurrentExtent.UpperLeftPoint.X,
		 Map1.CurrentExtent.UpperLeftPoint.Y,
		 Map1.CurrentExtent.LowerRightPoint.X,
		 Map1.CurrentExtent.LowerRightPoint.Y,
		 Convert.ToInt32(Map1.Height.Value),
		 Convert.ToInt32(Map1.Width.Value),
		 -1);
		//Create a new Bitmap Object using the image stream
		MemoryStream MemoryStream = new MemoryStream(images);
		Bitmap NewImage = new Bitmap(MemoryStream);
		//Draw the image onto the map control
		G.DrawImageUnscaled(NewImage, 0, 0);
	}

	protected void DisplayCustomerPoints()
	{
		//Create a Dynamic Data Layer to hold our customers
		DynamicLayer customers = new DynamicLayer();

		//Create Customer Point for LA
		PointMapShape custLA = new PointMapShape(new PointShape(-118.24, 34.05));
		//Use a Graphic for the customer symbol
		PointSymbol symLA = new PointSymbol
			(new Bitmap(this.Server.MapPath(&quot;&quot;) + @&quot;\images\customer.png&quot;));
		custLA.ZoomLevel01.GeoStyle.SymbolRenderers.Add(new SymbolRenderer(symLA));
		//Label the customer icon
		custLA.ZoomLevel01.GeoTextStyle = GeoTextStyles.GetSimpleTextStyle
			(null, &quot;Arial&quot;, 9, GeoFontStyle.Bold, GeoColor.KnownColors.Black);
		//Apply to all zoom levels
		custLA.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
		//Name the Customer
		custLA.Name = &quot;LA Customer&quot;;
		//Add the customer to the Dynamic Data Layer
		customers.MapShapes.Add(custLA);
		
		//Create Customer Point for KC
		PointMapShape custKC = new PointMapShape(new PointShape(-94.62, 39.11));
		//Use a Graphic for the customer symbol
		PointSymbol symKC = new PointSymbol
			(new Bitmap(this.Server.MapPath(&quot;&quot;) + @&quot;\images\customermale.png&quot;));
		custKC.ZoomLevel01.GeoStyle.SymbolRenderers.Add(new SymbolRenderer(symKC));
		//Label the customer icon
		custKC.ZoomLevel01.GeoTextStyle = GeoTextStyles.GetSimpleTextStyle
			(null, &quot;Arial&quot;, 9, GeoFontStyle.Bold, GeoColor.KnownColors.Black);
		//Apply to all zoom levels
		custKC.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
		//Name the Customer
		custKC.Name = &quot;Kansas City Customer&quot;;
		//Add the customer to the Dynamic Data Layer
		customers.MapShapes.Add(custKC);
		
		//Add Dynamic Data Layer to Map Control
		Map1.DynamicLayers.Add(customers);
	}

	protected void btnZoomIn_Click(object sender, EventArgs e)
	{
		//Zoom the map in by 20%
		Map1.ZoomIn(20);
	}
	protected void btnZoomOut_Click(object sender, EventArgs e)
	{
		//Zoom the map out by 30%
		Map1.ZoomOut(30);
	}
}
&lt;/code&gt;

&lt;p&gt;Once you have all of this coding completed, you should be able to run your client application and get a result similar to the screen shot below:&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;Sample Application Screenshot&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/ScalableMappingAppsSample.jpg&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Leveraging web services can allow you to build extremely scalable mapping and GIS solutions.  By utilizing the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteEngine/tabid/153/Default.aspx&quot;&gt;Map Suite Engine .NET Component&lt;/a&gt; in the web service, you can centralize all of your base map generation and large map datasets. In addition, you can still enjoy the developer experience of using the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteWeb/tabid/148/Default.aspx&quot;&gt;Map Suite ASP.NET&lt;/a&gt; &amp;amp; &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteDesktop/tabid/137/Default.aspx&quot;&gt;Desktop controls&lt;/a&gt; to handle all user interactions and display of dynamic map data, among other things. This article barely scratches the surface of what can be accomplished with mapping &amp;amp; GIS web services in conjunction with a rich user interface. The downloadable code can be used as a good starting point for building your own scalable .NET GIS mapping applications.&lt;/p&gt;

&lt;h3&gt;Downloads&lt;/h3&gt;

&lt;ul style=&quot;list-style-type: none; margin-left: 0pt; padding-left: 0pt;&quot;&gt;
    &lt;li style=&quot;list-style-type: none; padding-bottom: 6px;&quot;&gt;&lt;a href=&quot;http://gis.thinkgeo.com/download/MapWebServiceExample.zip&quot;&gt;Map Web Service &amp;amp; Client Example Code in C#&lt;/a&gt;&lt;/li&gt;
    &lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;Map Suite Engine .NET Component &amp;amp; Web ASP.NET Control&lt;/a&gt; (Registration Required)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You will need to download and install these Map Suite components in order to run the example in this article.&lt;/p&gt;

&lt;h3&gt;Have Questions?&lt;/h3&gt;

&lt;p&gt;Do you have questions or comments about this article?  Feel free post your questions on the &lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Map Suite Discussion Forums&lt;/a&gt; or leave feedback at the &lt;a target=&quot;_blank&quot; href=&quot;http://blog.thinkgeo.com&quot;&gt;ThinkGeo Blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Additional Resources&lt;/h3&gt;

&lt;ul style=&quot;list-style-type: none; margin-left: 0pt; padding-left: 0pt;&quot;&gt;
    &lt;li style=&quot;list-style-type: none; padding-bottom: 6px;&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot;&gt;Map Suite QuickStart Guides&lt;/a&gt;&lt;/li&gt;
    &lt;li style=&quot;list-style-type: none; padding-bottom: 6px;&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Support/APIDocumentation/tabid/194/Default.aspx&quot;&gt;Map Suite API Documentation&lt;/a&gt;&lt;/li&gt;
    &lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Support/FAQs/tabid/196/Default.aspx&quot;&gt;Map Suite FAQs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About the Author&lt;/h3&gt;

&lt;p&gt;Clint Batman is co-founder and President of ThinkGeo, a software company specializing in geospatial software with an emphasis on software development tools and GPS tracking solutions.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4766/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 10:52:37 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4766/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Implementing Geocode USA Into a SQL Stored Procedure</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;This article will show you how to implement Geocode USA within a managed stored procedure in SQL Server 2005. The simple procedure involves preparing your files, configuring your database environment, creating an assembly and then building your stored procedure from that assembly.                                                                                                                                         &lt;/p&gt;&lt;/div&gt;


&lt;p style=&quot;line-height: 1.4em;&quot;&gt;
	&lt;img height=&quot;16&quot; width=&quot;16&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/icon_sql.png&quot; style=&quot;margin-right: 3px; vertical-align: middle;&quot; alt=&quot;&quot; /&gt; &lt;a href=&quot;http://thinkgeo.com/Download/GeocodeCLR/GeocodeSample.zip&quot;&gt;Download Tutorial Materials&lt;/a&gt;&lt;br /&gt;
&lt;img height=&quot;16&quot; width=&quot;16&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/icon_vsproject.png&quot; style=&quot;margin-right: 3px; vertical-align: middle;&quot; alt=&quot;&quot; /&gt; &lt;a href=&quot;http://thinkgeo.com/Download/GeocodeCLR/Demo.zip&quot;&gt;Download Demo Application&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;Steps&lt;/h3&gt;

&lt;h4&gt;1. Prepare Files&lt;/h4&gt;

&lt;p&gt;Unzip the &lt;a href=&quot;http://thinkgeo.com/Download/GeocodeCLR/GeocodeSample.zip&quot;&gt;GeocodeSample.zip&lt;/a&gt; file to &lt;tt&gt;C:\GeocodeSample.&lt;/tt&gt; Please note that the included GeocodeUSA.dll is from the free evaluation edition of Geocode USA; if you are a licensed user of the full version, you will want to use your own copy of GeocodeUSA.dll instead.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;Contents of the GeocodeSample.zip file&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_01.png&quot; /&gt;&lt;/p&gt;

&lt;h4&gt;2. Configure Database Environment&lt;/h4&gt;

&lt;p&gt;Open the SQL Server 2005 Surface Area Configuration tool and select the &lt;b&gt;Surface Area Configuration for Features&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;The SQL Server 2005 Surface Area Configuration tool&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_02.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Enable the &lt;b&gt;CLR Integration&lt;/b&gt; so that you can CREATE ASSEMBLY.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;How to enable CLR integration&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_03.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Open SQL Server Management Studio and create a new database. In this example we used: &lt;b&gt;GeocodeSample&lt;/b&gt;. (The Database Owner must be a SQL server account, not a domain account.)&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;Creating a new database&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_04.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once the database has been created, use the following SQL command to alter the database and set TRUSTWORTHY to ON, so that you can use UNSAFE PERMISSION SET.&lt;/p&gt;

&lt;code&gt;ALTER DATABASE GeocodeSample SET TRUSTWORTHY ON&lt;/code&gt;

&lt;p&gt;Create a new assembly and choose the SQLGeocodeUSA.dll from the &lt;b&gt;Path to Assembly&lt;/b&gt; file browser. Be sure to set the &lt;b&gt;Permission Set&lt;/b&gt; as &lt;b&gt;Unsafe&lt;/b&gt;.  Click OK.  Now you will see two assemblies: &lt;tt&gt;GeoCodeUSA&lt;/tt&gt; and &lt;tt&gt;SQLGeocodeUSA&lt;/tt&gt;. Double-check that the &lt;b&gt;Permission Set&lt;/b&gt; is set to &lt;b&gt;Unsafe&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;Creating a new assembly and setting the Permission Set to Unsafe&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_05.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now you can create a stored procedure from the assembly.  For example:&lt;/p&gt;

&lt;code&gt;CREATE PROCEDURE ReverseGeocode
	-- Set default value, idx files directory
	@GeocodeIdxFolder nvarchar(200)='C:\GeocodeIdx2006fe',
	@Longitude float = 0.0,
	@Latitude float = 0.0
AS
	EXTERNAL NAME
		SQLGeocodeUSA.SQLGeocodeUSAEngine.ReverseGeoCode
&lt;/code&gt;

&lt;p&gt;Then, you can use this procedure as common stored procedure:&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;EXECUTE &amp;#91;GeocodeSample&amp;#93;.&amp;#91;dbo&amp;#93;.&amp;#91;ReverseGeoCode&amp;#93;;&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Longitude = -95.2808458305725,&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Latitude = 38.9553176794061&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;Which gives you these results:&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;Results of the above SQL query&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_06.png&quot; /&gt;&lt;/p&gt;

&lt;h4&gt;3. Instantly Configuring the Database Environment&lt;/h4&gt;

&lt;p&gt;First, start SQL Server Management Studio.  Open the GeocodeSample.sql file, then execute the SQL statement.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;Executing the GeocodeSample.sql statement&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_07.png&quot; /&gt;&lt;/p&gt;

&lt;h4&gt;4. Client Demonstration&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;http://thinkgeo.com/Download/GeocodeCLR/Demo.zip&quot;&gt;Demonstration code&lt;/a&gt; is also provided. The SQLGeocodeUSA project is a class library project, which acts as a bridge between the Geocode USA core and SQL Server 2005. You can use the SQLGeocodeClientDemo to demonstrate how to call the stored procedure in client code.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border: 1px solid rgb(153, 153, 153);&quot; class=&quot;Figure&quot; alt=&quot;The GeocodeSample demo application&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/GeocodeCLR_08.png&quot; /&gt;&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4765/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 10:40:17 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4765/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Building Thematic Maps Using Class Break Renderers and Map Suite</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;In Map Suite, the SymbolClassBreakRenderer class allows for multiple symbols to be defined that correlate to ranges or class breaks.  For example, you can use class breaks to produce a map that visually shows different population sizes. You can use this powerful feature to render your maps based on many types of differing values -- this article will show you the way.                                                                    &lt;/p&gt;&lt;/div&gt;


&lt;h3&gt;Introduction&lt;/h3&gt;

&lt;p&gt;If you need to build thematic maps (maps that provide information on a specific themes such as spatial distribution of population, timber volumes, weather, vegetation etc.) you can do so quickly and easily using the SymbolClassBreakRenderer Class in Map Suite. This article will show you the basics of getting started on your way to building your own feature rich mapping and spatial applications.&lt;/p&gt;

&lt;p&gt;(NOTE: This article references the ClassBreakRendererApp that is available in the sample applications with both the trial and full versions of Map Suite. This article also focuses on the Winforms Edition of Map Suite but most of the concepts and all of the example code applies for the Webforms (ASP.NET) Edition as well.)&lt;/p&gt;

&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://gis.thinkgeo.com/Products/MapSuiteFreeTrialDownloads/tabid/152/Default.aspx&quot;&gt;Register and download the trial version&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Opening the Sample Applications in Visual Studio.NET Solution&lt;/h3&gt;

&lt;p&gt;After you have downloaded and installed the full or trial version of Map Suite, you may want to look through the sample applications and source code that are included with the installation. You can view the samples by going to the START menu...All Programs...ThinkGeo...&amp;#91;YOUR MAP SUITE VERSION&amp;#93; and choose either the VB Sample Apps Source Code or C# Sample Apps Source Code menu item. This will open a solution in Visual Studio.NET that includes all of the Map Suite Sample applications as well as the source code. You may also need to add the Map Suite Map Control to your Toolbox in the Visual Studio.NET IDE. You can do this by using the Add/Remove Items feature and browsing to the winformsedition.DLL file that resides in the installation directory of Map Suite (By default this is C:\Program Files\ThinkGeo\&amp;#91;The Version You Have Installed&amp;#93;\).&lt;/p&gt;

&lt;p&gt;Now let's take a look at the SymbolClassBreakRenderer Class and how to use it.&lt;/p&gt;

&lt;h3&gt;Overview of the SymbolClassBreakRenderer Class&lt;/h3&gt;

&lt;p&gt;The SymbolClassBreakRenderer Class has the purpose of providing information to Map Suite in helping it determine when and how a portion of the map should be rendered based on a set of ranges or minimum and maximum values. The SymbolClassBreakRenderer is made up of two items: 1) The name of the column in the DBF that will provide the values for our class breaks and 2) a SymbolClassBreakCollection of SymbolClassBreakRenderers.ClassBreaks. For example, in the ClassBreakRendererApp sample application included with Map Suite there are several SymbolClassBreakRenderers.ClassBreaks added to a SymbolClassBreakCollection that define how the percentages of the Hispanic population within each Census tract of Travis County, Texas should be represented in terms of being rendered on the map.&lt;/p&gt;

&lt;p&gt;Let's take a look at some sample code so that this is clearer. Our first step is to set up the map by setting the MapUnit property to the proper value, loading a Layer from a Shape File (&lt;tt&gt;.shp&lt;/tt&gt;), setting the ThresholdUnit property on the Layer and creating a new Threshold that we can add our SymbolClassBreakRenderer to:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;'-- Set length units for shape files
Map1.MapUnit = MapSuite.Geometry.MapLengthUnits.DecimalDegrees

Dim Layer As New Layer(&quot;C:\Program Files\ThinkGeo\YOUR MAPSUITE VERSION\sampledata\usa\austin\austintracts.shp&quot;)

'-- Set layer's length units to miles because that is what we want to work with
Layer.ThresholdUnit = ThresholdUnits.miles

'-- Only show this layer when map is zoomed in showing less than 10,000
'-- miles across
Dim Threshold As New Threshold(10000, 0)
&lt;/code&gt;

&lt;p&gt;For a more detailed explanation of the above code, shape data and DBF files, see the Map Suite Quick Start User's Guide.&lt;/p&gt;

&lt;p&gt;Now that we have our Map, Layer and Threshold defined we can start building our SymbolClassBreakRenderer.ClassBreaks that will define how we want the map to display the percentages. To do this we will be defining a SymbolClassBreakCollection as mentioned earlier and adding SymbolClassBreakRenderer.ClassBreaks to it. In the example we want to use the below defined ranges:&lt;/p&gt;

  &lt;table width=&quot;300&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; border=&quot;1&quot; style=&quot;margin-bottom:18px;&quot;&gt;
     &lt;tr&gt;
         &lt;th width=&quot;105&quot;&gt;&lt;b&gt;Percentage (%)&lt;/b&gt;&lt;/th&gt;
         &lt;th&gt;&lt;b&gt;Display As&lt;/b&gt;&lt;/th&gt;
     &lt;/tr&gt;
     &lt;tr&gt;
         &lt;td width=&quot;105&quot;&gt;Less than 15&lt;/td&gt;
         &lt;td&gt;Light Goldenrod Yellow&lt;/td&gt;
     &lt;/tr&gt;
     &lt;tr&gt;
         &lt;td width=&quot;105&quot;&gt;15 - 30&lt;/td&gt;
         &lt;td&gt;Light Green&lt;/td&gt;
     &lt;/tr&gt;
     &lt;tr&gt;
         &lt;td width=&quot;105&quot;&gt;30 - 45&lt;/td&gt;
         &lt;td&gt;Lime Green&lt;/td&gt;
     &lt;/tr&gt;
     &lt;tr&gt;
         &lt;td width=&quot;105&quot;&gt;45 - 59&lt;/td&gt;
         &lt;td&gt;Green&lt;/td&gt;
     &lt;/tr&gt;
     &lt;tr&gt;
         &lt;td width=&quot;105&quot;&gt;More than 60&lt;/td&gt;
         &lt;td&gt;Dark Green&lt;/td&gt;
     &lt;/tr&gt;
  &lt;/table&gt;

&lt;p&gt;Now that we know what we need to define for our class breaks, let's look at the code for accomplishing this. Note that we also introduce a new Class called the SymbolClassBreakRenderer.ClassBreakCap. It is explained further in the comments of the code and below:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;'-- Define our SymbolClassBreakCollection to hold our class breaks
Dim ClassBreaks As New SymbolClassBreakCollection

'-- First break is 'below 15%'
ClassBreaks.Add(New SymbolClassBreakRenderer.ClassBreak(15, New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.LightGoldenrodYellow))))

'-- Next break is 'below 30%'
ClassBreaks.Add(New SymbolClassBreakRenderer.ClassBreak(30, New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.LightGreen))))

'-- Next break is 'below 45%'
ClassBreaks.Add(New SymbolClassBreakRenderer.ClassBreak(45, New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.LimeGreen))))

'-- Every class break needs a cap. With a cap of 60, here, we are saying
'-- that everything below the cap, or 'below 60%' (which means 45% or
'-- above but below 60%)should be displayed one way and those over the cap
'-- ('60% or above') should be displayed another way.
Dim ClassBreakCap As New SymbolClassBreakRenderer.ClassBreakCap(60, New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.DarkGreen)), New AreaSymbol(New Pen(Color.Black), New SolidBrush(Color.Green)))

'-- Add the ClassBreakCap to the SymbolClassBreakCollection
ClassBreaks.Add(ClassBreakCap)
&lt;/code&gt;

&lt;p&gt;Note that each constructor for a SymbolClassBreakRenderer.ClassBreak takes an argument of type Double as a maximum value (all values that fall below the value should be rendered) and a SymbolRenderer. The SymbolClassBreakRenderer.ClassBreakCap Class takes break value that puts a sort of end or &amp;quot;topper&amp;quot; on the class breaks by defining how to render values that fall in the range below the value and the last defined SymbolClassBreakRenderer.ClassBreak as well as the value and anything above. In the last line of code we add the SymbolClassBreakRenderer.ClassBreakCap to the SymbolClassBreakCollection.&lt;/p&gt;

&lt;p&gt;Note, for more information on the SymbolRenderer Class, see the &lt;a href=&quot;http://gis.thinkgeo.com/Support/QuickStartGuides/tabid/197/Default.aspx&quot;&gt;Map Suite QuickStart Guides&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Using the SymbolClassBreakRenderer Class&lt;/h3&gt;

&lt;p&gt;Now we can finally use the SymbolClassBreakRenderer Class by defining what column we will use from the DBF (.dbf) file that is associate with our Shape Date File (.shp). In this case, the column we want to use is 'perchisp01'. This will give us our percentages. If we provide that along with the SymbolClassBreakCollection of our class breaks, Map Suite will automatically render each area appropriately. Below is the code for doing this:&lt;/p&gt;

&lt;code lang=&quot;vb&quot;&gt;'-- Add layer and class break render to map so it can be displayed
Dim ClassBreakRenderer As New SymbolClassBreakRenderer(&quot;perchisp01&quot;, ClassBreaks)

Threshold.SymbolRenderers.Add(ClassBreakRenderer)

Layer.Thresholds.Add(Threshold)

Map1.Layers.Add(Layer)

'-- Force map to redraw completely
Map1.Refresh()
&lt;/code&gt;

&lt;p&gt;In the above code we simply create the new SymbolClassBreakRenderer as described earlier, add it to the SymbolRenderer Collection of the Threshold, add the Threshold to the Layer, and the Layer to the Map. Our last step is to call the Refresh() method of the map so that it can redraw it completely. When we run this code in the ClassBreakRenderersApp sample application, it renders like this:&lt;/p&gt;

&lt;p&gt;&lt;img height=&quot;463&quot; width=&quot;550&quot; border=&quot;0&quot; src=&quot;http://gis.thinkgeo.com/portals/1/articles/ClassBreakRenderer.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it is very easy to use SymbolClassBreakRenderers in your Map Suite application. With only a few lines of code, and some representative data, you can have professional looking thematic analysis maps to your users in very little time. Remember to check out the ClassBreakRenderersApp sample application to see this code and other features such as traversing the map with operations like Zooming, Panning, Track Zoom etc. as well as SymbolDisplayer class used for creating legends like the one shown on left side of the image above.&lt;/p&gt;

&lt;h3&gt;Other Resources&lt;/h3&gt;

&lt;p&gt;There are several other resources at ThinkGeo to help you get started to developing feature rich mapping and spatial applications for Microsoft .NET. Some of those resources are listed below. You can always reach a ThinkGeo support representative by phone toll-free at (866) 847-7510 or via email at &lt;a href=&quot;mailto:support@thinkgeo.com&quot;&gt;support@thinkgeo.com&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Sample Applications&lt;/h3&gt;

&lt;p&gt;There are 35+ sample applications included with Map Suite when you download the trial version that include the source code to show you how to do various operations using the Map Suite component. It is very beneficial to go through those examples and the code. Both VB.NET and C# are included.&lt;/p&gt;

&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://websamples.thinkgeo.com/&quot;&gt;View the Map Suite sample applications online&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Discussion Forums&lt;/h3&gt;

&lt;p&gt;The Map Suite Discussion Forums are a great place to get answers to all of your Map Suite development questions. The ThinkGeo Support Team monitors the forums daily and can help you on your way to being successful with Map Suite.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/Default.aspx&quot;&gt;Visit the Discussion Forums online&lt;/a&gt;&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4764/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 10:29:15 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4764/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>The Technologies Behind GIS Development</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;If you are new to geographic information systems (GIS) and neocartography, this article is a good primer.  Providing a background on GIS and geographical information science, the article takes a view to software development with GIS and the disciplines and technologies used therein. The application of Microsoft's .NET Framework, spatial data formats, geomatics and other tech is covered in detail.&lt;/p&gt;&lt;/div&gt;

&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Background on GIS&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;GIS&lt;/b&gt; is an abbreviation for &amp;quot;&lt;b&gt;geographical information system&lt;/b&gt;.&amp;quot; GIS is an advanced computer technology or computer system that utilizes an analytic framework&amp;ndash;a geographic information system&amp;ndash;to solve problems, integrate and manage data, as well as understand past, present, or future situations. A GIS is capable of storing, integrating, managing, analyzing, and displaying information that is geographically referenced. The geographical information system enables users to create and manage spatial data and the attributes associated with that data. In a very broad sense, GIS is a map tool that allows users to create searches and analyze and edit spatial data. Further, GIS has many useful applications in the areas of academics, business, and government. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Geographical Information Science&lt;/b&gt; is the science behind GIS, which lays the foundation of principles and theories upon which a geographical information system is built. Geographic information systems can be used in many areas, such as the following: resource management (managing offices, stores, targets, and tracking carriers), asset tracking (vehicle tracking and fleet tracking), development (developing map controls, geocoders, reverse geocoders, and .NET Components), route planning (determining evacuation routes and emergency response times in the case of toxic spills or natural disasters), and cartography (the science of map making).&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;GIS and Geography&lt;/h4&gt;
&lt;p&gt;Geographical information systems all utilize the science and discipline of Geography. Moreover, GIS uses geographical data to link information or attributes to location data. For example, a geographic information system might link people (attributes) to addresses (location data) or buildings (attributes) to parcels or streets (location data). A geographical information system will take this information and create layers to show the relationships between the attributes and data and combine these layers to provide insight into a user's questions. Geographical data in GIS can be viewed three main ways: Database View, Map View, and the Model View.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;GIS Views&lt;/h4&gt;
&lt;p&gt;The Database View of geographical data is based on a GIS's database, which is a geographic database of the world. This geographic database, also called a geo-database, is a very structured database that describes and defines the world in geographic terms. In a Database type view, users define how certain geographic objects will be represented and viewed. Objects that have a similar representation are stored in the geographical database as classes. Further, each dataset in the geographic database will represent a specific geographic representation of the world. These datasets include the following types: raster datasets (digital elevation models and imagery), networks, terrains, datasets of vector-based features (sets of points, polygons, and lines), cartographic datasets (maps), and address datasets. &lt;br /&gt;
&lt;br /&gt;
The second type of GIS view is the Map View. This type of view involves viewing information on sets of maps to see geographical features and the relationships between these features. Another feature of the map view is that geographic information can be used as windows into a geographical information system's database in a process called geovisualization. This process allows information in the database to be searched, analyzed, and edited. The geovisualization process involves working with a GIS's maps, often referred to as &amp;quot;intelligent maps,&amp;quot; and other GIS views, such as summary charts and tables, schematic views of network relationships, and time-based views. In addition to being used as windows into a geographical system's database, maps are the main interface through which a user interacts with a GIS and utilizes its applications. Further, the maps are capable of performing a number of valuable functions, such as data analysis, data queries, data compilations, and cartography. &lt;br /&gt;
&lt;br /&gt;
The third and last view of a GIS is the Model View. The Model View utilizes a process called geoprocessing, which takes information from existing datasets and applies analytic functions to these existing datasets in order to derive new datasets. This geoprocessing results in the creation of a model, which was created for the purpose of answering a question posed by the user. Geoprocessing is utilized in almost all phases of GIS, including data compilation, data management, advanced cartography modeling, and analysis. The database, map, and model views are important parts of all geographical information systems and used at all levels of application in GIS.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;GIS Information Sets&lt;/h4&gt;
&lt;p&gt;Geographical information systems analyze and display geographic information in a series of information sets. These information sets include geographic datasets, maps, workflow models, metadata documents, and data models. &lt;br /&gt;
&lt;br /&gt;
Geographical datasets are databases of geographical information that include networks, topologies, terrains, attributes, and surveys. Maps provide interactive views of geographical data and support advanced GIS applications when interacting with geographical data. Workflow models are collections of geoprocessing procedures that enable users to automate tasks and analyze information. Metadata documents are documents that describe other elements and allow users to access shared geographic knowledge. Finally, data models define the behavior, schema, and integrity rules of geographic datasets and play a vital role in geographic information systems.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;GIS Development&lt;/h4&gt;
&lt;p&gt;GIS development utilizes a geographical information system, GIS technology, the Microsoft .NET framework, and the Global Positioning System (GPS) to build software applications, such as .NET map controls; .NET components; vehicle, fleet, and asset tracking applications; and geocoding and reverse geocoding applications. Many different technologies and file formats are used in GIS development. Some of these technologies and common file formats are as follows: Geomatics, Spatial Analysis, Geospatial Analysis, Cartography, NET Framework, .NET languages (C# and VB.NET), Map SDK (Software Development Kit), GIS SDK (Software Development Kit), Shapefiles, JPEG 2000 format, ECW format, GeoTIFF format, and MrSID format. Software engineers use some or all of the above tools and file formats to develop their GIS applications that can be deployed over the web, on a desktop PC, or even on a mobile or portable device such as a PDA or Pocket PC.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Overview of the Disciplines and Technologies behind GIS Development&lt;/h4&gt;
&lt;p&gt;This section of the article will discuss the disciplines, tools, techniques, and file formats that are commonly used by software engineers in GIS development. The common technologies and tools that a GIS developer uses come from a wide range of disciplines, such as Geomatics, Spatial and Geospatial Analysis, Geography, Geographical Information Science, Cartography, Computer Science, and Software Development. Each of these disciplines and their technologies will be discussed in greater detail in the next few sections.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Geomatics&lt;/h4&gt;
&lt;p&gt;Geomatics is the science that studies the mathematics of the earth and focuses on measuring, managing, and analyzing Earth-based data that is spatially referenced. Spatially referenced data is data that is identified according to its location. In addition to this, Geomatics also involves the practice of modeling spatial geometry, making observations about spatial positions, and estimating spatial positions. Geomatics has applications across many disciplines and professions and uses data acquired from many sources, such as air and sea-borne sensors, satellites, and ground instruments. Some of the disciplines which rely on Geomatics are Computer Science, Remote Sensing and Photogrammetry, Cartography, Surveying, Geographic Information Systems, geodesy, navigation, and the Global Positioning System (GPS). &lt;br /&gt;
&lt;br /&gt;
Another view of Geomatics is that it is a branch of the Geographic Information System and specializes in the areas of measuring and surveying Earth-based data. In a broader sense, the science of Geomatics specialized in the tools and techniques that enable and support remote sensing, land surveying, Cartography, and Geographic Information Systems. Finally, in the United States, the application of Geomatics is often called Geospatial Technology.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Spatial Analysis&lt;/h4&gt;
&lt;p&gt;Spatial Analysis is the term for the process of analyzing spatial model results and geographical data. In order to understand geographical information, spatial analysis is often required. Spatial Analysis enables Geospatial Engineers to estimate, evaluate, predict, and interpret geographical information and data. One of the main methods of spatial analysis is raster analysis. Raster analysis involves the analysis of raster cells, which are grid cells in a matrix. A raster is a data structure that is composed of rows and columns that are used to store images. In a raster data type, data consists of rows and columns of cells in which a single value is stored in each cell. Many satellites transmit raster images of the earth's surface. &lt;br /&gt;
&lt;br /&gt;
The other types of spatial analysis methods are topological overlay and contiguity analysis, surface analysis, and linear analysis. Spatial analysis plays an important role in population analysis and natural disaster analysis. Interestingly, the history of spatial analysis can be traced back to 1854 when John Snow used it to find the source of a cholera outbreak in London.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Geography&lt;/h4&gt;
&lt;p&gt;The discipline of Geography is closely tied to Geographic Information Systems and has a history that dates back some 4,300 years ago to ancient Mesopotamia where the first city maps were created. Geography studies the location and spatial variation of both natural and human phenomenon on Earth. The study of geography contributes to, as well as draws from, many other disciplines, such as geology, climatology, oceanography, geodesy, cartography, and GIS. The study of geography can roughly be divided into the areas of human geography and physical geography, both of which contain many subfields of study. &lt;br /&gt;
&lt;br /&gt;
With the emergence of geographic information systems and advanced computer technology, geography is becoming increasingly more quantitative, and geographers can now use this technology to better investigate their theories of spatial phenomenon. Modern geography now combines cartography (map making) with geographic information systems to better understand spatial relationships.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Geographic Information Systems&lt;/h4&gt;
&lt;p&gt;Geographical Information Systems (GIS) is a computer system that creates and manages spatial data and the attributes associated with the spatial data. The roots of GIS run very deep with a history that can be traced back to almost 35,000 years ago when prehistoric people left cave paintings that depicted hunting scenes complete with track lines and tallies that showed the migration patterns of the animals they hunted. These early paintings follow the two-element structure that is the trademark of all modern geographic information systems, which is a graphic file linked to an attribute database. &lt;br /&gt;
&lt;br /&gt;
A good GIS is capable of relating information from many different sources. Further, a good GIS can analyze sources of information that are in different forms. In order for this to work, a geographic information system must know the locations of the variables in the source data by marking the variables with x, y, z designations, which represent longitude, latitude, and elevation, respectively. Any variable that can be located spatially can be entered into a GIS and many types of data in map form can be entered into a GIS. In addition to spatial and map data, satellite images that are developed through remote sensing can also be analyzed to produce map-like layers of digital information. &lt;br /&gt;
&lt;br /&gt;
Data representation is an important aspect of a geographic information system. In a geographic information system, data represents objects in the real world. Data for real world objects can be divided into two abstractions&amp;ndash;discrete objects, a building for example&amp;ndash;and continuous fields, the elevation of an object for example. In addition, there are two main methods for storing these abstractions&amp;ndash;raster and vector. &lt;br /&gt;
&lt;br /&gt;
Raster data stores data in cells that are organized in a series of rows and columns. Each of these cells holds a single value. Most raster data consists of images, however, there is also a value stored for each cell which can be discrete, continuous, or null. A null value is stored if there is no data available. &lt;br /&gt;
&lt;br /&gt;
Vector data uses lines, geometries, and polygons to represent objects. An example of this would be polygons used to represent an in area, out area, or spatial fence in vehicle tracking applications. Vector data models can also apply topography rules when representing objects, such as not allowing polygons to overlap when displaying spatial fences. &lt;br /&gt;
&lt;br /&gt;
Geographic Information System users spend much of their time feeding data into the GIS. This activity is known as data capture, and the data that is captured is stored in a digital format. There are several methods used in data capturing. One method evolves taking existing data that is printed on paper maps and scanning it to produce digital data. This method of data capture produces raster data that can be processed to produce vector data. The next method involves entering survey data from a survey instrument or global positioning system directly into a GIS. Another method of data capture uses satellite remote sensing to collect raster data that can be processed to identify objects. &lt;br /&gt;
&lt;br /&gt;
Geocoding and reverse geocoding are other common techniques used in geographic information systems. Geocoding calculates spatial locations from street addresses and requires a reference theme to Geocode individual addresses. A reference theme can be a road centerline file that contains address ranges. Geocoding uses this reference theme to estimate individual addresses by examining the address ranges that are derived from a database. A geographic information system will then place a dot to approximate the location of the address on the road centerline. &lt;br /&gt;
&lt;br /&gt;
Reverse geocoding returns an estimated street address number for a given coordinate. This process requires a user to take a set of coordinates or click a road centerline theme, and the geographic information system will return an estimated street address for the coordinates. A GIS does this by estimating the street address from a predetermined range that is assigned to the road segment where the coordinates are located. &lt;br /&gt;
&lt;br /&gt;
A GIS is also commonly used in cartography to display graphics that help make relationships between map elements more visible. GIS cartographic work enables users to graphically see the results of analysis in order to better understand them. Also, other information stored in the GIS database, such as a list of addresses, can also be used in analysis.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Cartography&lt;/h4&gt;
&lt;p&gt;Cartography is the study and practice of map making. Traditionally, maps were created by hand using pens and paper, but today computers have revolutionized cartography. Now maps are created using mapping software, usually CAD or GIS software. Cartography is important in GIS development because maps serve as the visual representation of spatial data. Cartography utilizes special map symbols to represent geographic phenomenon and to visualize the world in an abstract form. &lt;br /&gt;
&lt;br /&gt;
There are two main map types in cartography: general and thematic. General maps are those that are designed for general users. General maps contain a wide variety of features and are usually produced in a series. A topographic map, a map showing a surface and its elevation points, is an example of a general map. Thematic maps, on the other hand, are targeted towards specific users and focus on specific geographic themes. For example, a thematic map might be designed to show social data or represent the distribution of languages throughout a continent.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Computer Science&lt;/h4&gt;
&lt;p&gt;Computer science is the study of information and computations and their applications in computer systems. One important area of computer science that is used in GIS development is computer programming. Computer programming uses computer programming languages to create a program to solve a computational problem. Software engineering is an aspect of computer science with a focus on designing and developing software applications to achieve practical goals. &lt;br /&gt;
&lt;br /&gt;
Software engineering involves the use of computer programming and high-level programming languages that are object oriented, such as C# and VB.NET. The previous two examples, C# and VB.NET are referred to as .NET languages and are supported by the Microsoft .NET Framework, which is discussed in detail in the next section. Computer programs written in these .NET languages were developed to be executed by the Common Language Runtime or CLR. This CLR is a multiple language execution environment that is part of the .NET Framework. &lt;br /&gt;
&lt;br /&gt;
Object-oriented languages are commonly used to write the code for software applications in GIS development and are used in conjunction with various Software Development Kits, or SDKs. The two most common SDKs used in GIS development are Map SDK and GIS SDK. An SDK is essentially a GIS toolkit or a Map toolkit that includes many tools, sample code, libs, and documentation to help software developers write and develop to Microsoft technologies and products when creating their GIS applications.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;.NET Framework&lt;/h4&gt;
&lt;p&gt;Microsoft's .NET Framework is a platform created by Microsoft that supports software development. The benefit of .NET is that it allows cross-language development, meaning that applications can be developed using a variety of languages. In addition to this, .NET provides a large standard library of structures types and data types. &lt;br /&gt;
&lt;br /&gt;
The .NET Framework was created for several key reasons. The first reason is that the .NET Framework provides interoperability between old code and new code. This enables new libraries to use code from old libraries. The Common Runtime Language (CLR) is another important key feature of .Net. Programming languages on .NET compile into an intermediate language or IL. This IL allows all .NET languages to be run on any computer that supports Common Language Runtime. Another key feature of the .NET Framework is the Common Type System or CTS, which defines a library of data types and programming constructs that are supported by CLR. The CTS defines how these data types and constructs may or may not interact with each other. This feature of .NET allows development in multiple programming languages. Another important key feature of .NET is the Base Class Library (BCL). The BCL provides a library of class types to all languages that use the .NET Framework. &lt;br /&gt;
&lt;br /&gt;
Finally, there is a scaled-down version of the .Net Framework that can be used on small portable devices, such as Pocket PCs and PDAs. This is called the .NET Compact Framework. In addition to the .NET Framework, GIS developers use the Microsoft Visual Studio .NET integrated development environment to write and compile their programs.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;GIS File Formats&lt;/h4&gt;
&lt;p&gt;GIS development utilizes many different file formats, such as Shapefiles, JPEG 2000, ECW, GeoTIFF, and MrSID. A GIS file format is the standard by which geographical information is encoded into a file, and these file formats are created by both government agencies and GIS software developers. &lt;br /&gt;
&lt;br /&gt;
Shapefiles are data types that are commonly used in GIS software products. A Shapefile stores geometric locations and its associated attributes in a vector storage format. Although a Shapefile can store geometric locations, it is not capable of storing topological information. Shapefiles are both a powerful and useful file format because they store the geometrical data types of lines, points, and polygons, as well as the attributes that these data types or shapes represent. Shapes and their corresponding attributes can represent an infinite variety of geographical data. &lt;br /&gt;
&lt;br /&gt;
JPEG 2000 is an image compression file format that can operate at higher compression ratios than a JPEG file without producing blurry artifacts. In addition to this feature, the JPEG 2000 format allows for more progressive and sophisticated downloads. &lt;br /&gt;
&lt;br /&gt;
ECW (enhanced &amp;ndash;compression wavelet) file format is a wavelet compression image file format that is optimal for satellite and aerial imagery. Also, ECW is an efficient format for compressing very large images. &lt;br /&gt;
&lt;br /&gt;
GeoTIFF is a format that allows geo-referenced information to be embedded within a TIFF file. Additional information, such as coordinate systems, ellipsoids, and projections are also included to help establish the exact spatial reference for the file. &lt;br /&gt;
&lt;br /&gt;
MrSid is an acronym that stands for Multi-resolution Seamless Image Database and is a file format developed specifically for GIS. MrSID allows massive amounts of image data to be displayed as satellite imagery in map software. MrSid files are easy to steam over the internet because of their quality levels. A software package, GeoExpress, allows GIS developers to read and write MrSID files. Finally, the technology behind MrSID uses lossless wavelet compression to create images.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;The Future of GIS Development&lt;/h4&gt;
&lt;p&gt;In the future, geographical information systems will be used more widely in government, business, science, and industry. With the emergence of Google Maps, vehicle and fleet tracking, asset tracking, satellite tracking, and the need to plot and study geographical data in order to better understand natural disasters and phenomenon, GIS development will likely continue to expand by adding new disciplines, tools, and technologies. GIS technologies are being used throughout the world to help people find places, navigate trips, and plan events. As the planet becomes increasingly interconnected, GIS development will play a major role in this event and, as a result, grow in importance.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4761/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 08:41:08 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4761/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Map Data Sources</title>
			<description>&lt;div style=&quot;width:750px; background: #e0eaf0 url(/portals/1/in_this_article.jpg) no-repeat left top; margin-bottom:20px; padding:45px 15px 20px 15px;&quot;&gt;&lt;p style=&quot;margin:0; font-size:12px; color:#333;&quot;&gt;When you're developing your GIS software application, you're going to need spatial data to bring it all together. But where can you obtain that data? This article looks at sources of data and provides examples of sources used in ThinkGeo's own Map Suite and Cygnus Track products. It discusses vector data and its structure, and names sources of free data and premium data alike, both online and offline.&lt;/p&gt;&lt;/div&gt;

&lt;h2 style=&quot;margin: 22px 0px 14px;&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;ThinkGeo's Map Suite product line and GPS tracking solution&amp;mdash;Cygnus Track&amp;mdash;both use map data sources for their mapping and tracking applications. The Map Suite products, such as Geocode USA, utilize TIGER&amp;reg; data from the U.S. Census Bureau to develop highly optimized datasets that enable users to find addresses anywhere within the United States. The map datasets for Cygnus Track can be fully customized to use a wide variety of map data sources. This custom map data integration feature allows Cygnus Track users to integrate high resolution satellite and street maps into the system to reflect any part of the world. Many of the types of map data used in ThinkGeo's mapping and asset tracking products, as well as the providers of these map data sources, will be discussed in this article. &lt;br /&gt;
&lt;br /&gt;
In order to develop a better understanding of the applications of map data sources and datasets, it is perhaps a good idea to begin with a general overview of the ThinkGeo products that utilize various map datasets. This next section will provide a brief discussion of the .NET components in the Map Suite product line as well as an overview of Cygnus Track, ThinkGeo's resource and asset tracking solution.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Map Suite Products&lt;/h4&gt;
&lt;p&gt;The Map Suite 2.0 product line of .NET Development Components consists of Map Suite Desktop, Map Suite Web, Map Suite Engine, Map Suite Pocket PC, and Map Suite Geocode USA. The Map Suite 2.0 product line provides a set of mapping controls and tools that enable C# and VB.NET software developers to build their own geospatial applications for both desktop and web applications. Further, Map Suite 2.0 fully supports Microsoft Visual Studio 2005 and the .NET Framework 2.0. &lt;br /&gt;
&lt;br /&gt;
Map Suite Desktop is a .NET mapping component that allows software developers to build detailed desktop mapping applications. Utilizing Microsoft's .NET Framework v1.1, the APIs for Map Suite Desktop Edition 2.0 incorporate the very latest technology to produce a versatile and user-friendly mapping component. In addition, Map Suite Desktop provides intuitive, streamlined interfaces to help make desktop spatial applications fast and easy. Cutting through the cryptic APIs, which are normally associated with building spatial applications, Map Suite Desktop offers the non-GIS developer the right tools to build spatial applications. &lt;br /&gt;
&lt;br /&gt;
Map Suite Web Edition is an ASP.Net server control that enables C# and VB.NET software developers to build detailed internet mapping applications. Utilizing Microsoft's .NET Framework, the APIs for Map Suite Web Edition allow a developer to easily develop mapping applications on the Web in any of the .NET languages. &lt;br /&gt;
&lt;br /&gt;
Map Suite Engine is a feature-rich low level .NET component that C# and VB.NET software developers can use to generate map images for presentations. Map Suite Engine features a non-visual component library that is specifically designed to generate maps. With this tool, developers can roll their own mapping control in Winforms or integrate a mapping solution with a legacy ASP web on the internet. &lt;br /&gt;
&lt;br /&gt;
Map Suite Pocket PC is a .NET mapping component that enables C# and VB.NET software developers to generate mapping presentations on portable devices using the .NET Compact Framework 2.0. Map Suite Pocket PC features a sophisticated and easy-to-use component library that simplifies map building. By utilizing Map Suite Pocket PC, developers can build full-featured spatial and mapping solutions for Window CE devices and other portable devices. &lt;br /&gt;
&lt;br /&gt;
Map Suite Geocode USA is a .NET geocoding engine that includes a highly optimized dataset encompassing the entire United States. Map Suite Geocode USA features a fast and easy-to-use .NET interface that enables C# and VB.NET software developers to take a United States address and quickly find its geographical location. In addition to geocoding, Map Suite Geocode USA also features reverse geocoding functionality which allows a developer to take a longitude and latitude point and find the closest address to that location. By writing just a few lines of code, a developer can integrate geocoding and reverse geocoding into a single software application. Finally, Geocode USA utilizes the most up-to-date TIGER&amp;reg; dataset from the U.S. Census Bureau to enhance its geocoding capabilities. This enables developers to geocode addresses anywhere within the United States.&lt;/p&gt;
&lt;h4 style=&quot;margin: 22px 0px 14px;&quot;&gt;Cygnus Track&lt;/h4&gt;
&lt;p&gt;Cygnus Track is a web-based GPS tracking application that enables owners to manage and track their vehicles and assets. Cygnus Track combines GPS technology, vehicle and asset tracking, and satellite communications networking to produce a GIS product that can be used to track vehicles, fleets, and other mobile assets through tracking devices. These tracking devices, such as cell phones or pagers, can be carried by drivers or mounted into the vehicles. Cygnus Track is based on an ASP.NET model and built on the Microsoft .NET platform, which allows the application to be accessed on any Internet browser, such as Microsoft Internet Explorer. &lt;br /&gt;
&lt;br /&gt;
Cygnus Track is hardware independent, allowing owners to use current GPS tracking devices or the tracking devices of their choice. Cygnus Track can be integrated with any GPS tracking device and can be customized to integrate any geographical dataset, which gives owners maximum flexibility in their asset and resource tracking. Cygnus Track includes two types of map data for its maps: United States and World.&lt;/p&gt;
&lt;h2 style=&quot;margin: 22px 0px 14px;&quot;&gt;Map Data&lt;/h2&gt;
&lt;p&gt;Map data is simply the data that is required to represent a map, and data, in the general meaning of the term, is a collection of facts, information, and instructions organized in a format that enables it to be both communicated to and processed by a computer. This type of data format is referred to as digital data because it is data represented in a computer compatible format, which is a format that can be read by a computer. For map data and GIS (Geographical Information System) development, the following file formats are commonly used: Shapefiles, JPEG 2000, ECW, GeoTIFF, and MrSID. Finally, map data is often grouped in a dataset, which is a set of data that has a common theme or similar attributes. &lt;br /&gt;
&lt;br /&gt;
Both Map Suite and Cygnus Track use map data from various map data sources in their applications. The Map Suite .NET Components utilize TIGER&amp;reg;/Line data from the U.S. Census Bureau to expand and enhance the capability and functionality of their map controls. For example, the Map Suite products can be integrated with mapping datasets such as TIGER&amp;reg; street data to enrich the GIS development process and expand the maps with more detailed features like road, railway, and county landmark features. In addition, Map Suite .NET components require a Shapefile (.shp) format for the map datasets used in their mapping and geospatial applications. Shapefiles are the most widely used file format in the GIS community and all of the Map Suite components currently support the Shapefile format. &lt;br /&gt;
&lt;br /&gt;
Cygnus Track's design allows external high-resolution street and satellite maps to be integrated with its United States and World map datasets. The map data sources most commonly used in Cygnus Track data integration are Vector data, which must be in an ESRI shapefile file format, and Raster Imagery Data, which must be used in the following file formats: GeoTIFF, MRSID, ECW, and JPEG 2000. &lt;br /&gt;
&lt;br /&gt;
In the following sections, TIGER&amp;reg; data and the main source for this data, the U.S. Census Bureau, will be discussed in detail as well as Vector Map data. Following these sections, the two major sources for premium map data&amp;mdash;Tele Atlas and Navteq&amp;mdash;will be discussed. Finally, at the end of this article, the two primary internet resources for map data&amp;mdash;&lt;a target=&quot;_blank&quot; href=&quot;http://geodata.gov&quot;&gt;geodata.gov&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://data.geocomm.com&quot;&gt;data.geocomm.com&lt;/a&gt;&amp;mdash;will be briefly discussed.&lt;/p&gt;
&lt;h2 style=&quot;margin: 22px 0px 14px;&quot;&gt;U.S. Census Bureau and TIGER&amp;reg; Data&lt;/h2&gt;
&lt;p&gt;With a history that stretches back to the early years of American independence, the United States Census Bureau is the leading source for reliable data about the nation's economy and people. The U.S. Census Bureau has the strategic goal of meeting the needs of businesses, policymakers, nonprofit organizations, and the public by providing current measures of the U.S. economy, population, and governments. Further, the activities of the U.S. Census Bureau include conducting large-scale surveys, updating geographic infrastructures, and collecting, processing, and disseminating data. To support its mapping and geospatial needs for Decennial Census, the U.S. Census Bureau developed the TIGER&amp;reg; system and digital database. &lt;br /&gt;
&lt;br /&gt;
TIGER&amp;reg; is an acronym that stands for &amp;quot;Topologically Integrated Geographic Encoding and Referencing.&amp;quot; The TIGER&amp;reg; format is used by the U.S. Census Bureau to describe land attributes such as roads, lakes, rivers, railways, landmarks, hydrology, and buildings. The topological structure of the TIGER&amp;reg; database defines the relationship of these land attributes to each other as well as the location of the attributes. The TIGER&amp;reg; database design is based on the theories of topology, graph theory, and related areas of mathematics in order to produce an accurate mathematical description of the geography of the United States. &lt;br /&gt;
&lt;br /&gt;
The goal of the TIGER&amp;reg; database is to provide automated access to, as well as retrieval of, relevant geographic information about the United States. The U.S. Census Bureau uses the TIGER&amp;reg; System to automate the mapping and geographical activities used in its sample surveys and decennial census programs. In addition to this, the TIGER&amp;reg; System supports the creation and maintenance of a digital geographic database that covers the United States, Puerto Rico, the U.S. Virgin Islands, Midway Islands, American Samoa, the Commonwealth of the Northern Mariana Islands, and Guam. The U.S. Census Bureau also uses the TIGER&amp;reg; system to produce maps for its enumeration and publication programs and to assign individual addresses to geographic entities and census blocks. &lt;br /&gt;
&lt;br /&gt;
TIGER&amp;reg; data files, also called TIGER&amp;reg;/Line files, are digital data that describes geographic features such as roads, rivers, lakes, railways, legal boundaries, buildings, etc. The TIGER&amp;reg; data files also contain information on the latitude and longitude of the geographic features, the names of the features, the types of features, the geographic relationship of one feature to the next, and the address ranges of most streets. In order to use Tiger&amp;reg; data in GIS development applications, a user needs to first import the TIGER&amp;reg; data by using either GIS or mapping software, such as a GIS toolkit, GIS SDK (Software Development Kit), or a map toolkit or map SDK. Finally, TIGER&amp;reg; data files are created by the U.S. Census Bureau's TIGER&amp;reg; database and are considered a public product. The most recent version of TIGER&amp;reg;/Line data is the 2004 Second Edition TIGER&amp;reg;/Line Files.&lt;/p&gt;
&lt;h2 style=&quot;margin: 22px 0px 14px;&quot;&gt;Vector Map Data&lt;/h2&gt;
&lt;p&gt;A vector is one method of data type that can be used to store spatial information. Vector data is an abstraction of the real world where positional data is represented in the form of coordinates, and the basic units of spatial information are points, lines, and polygons. Points represent X, Y, Z locations on the earth; lines represent anything that has a length; and polygons represent anything that has a boundary. Moreover, vector data is made up of lines or arcs, and the beginning and end points of these lines or arcs meet at nodes. Vector data stores geographical features that are defined by their boundaries and explicit topology. Finally, vector data models are the most commonly used spatial data models in GIS development. A vector data model represents a geographical feature as a row in a table, and each geographical feature is defined by an X, Y, Z location on the earth's surface. &lt;br /&gt;
&lt;br /&gt;
Produced by the National Geospatial-Intelligence Agency (NGA), Vector Map, Vector Smart Map, or VMAP is a collection of databases providing vector-based GIS data that covers the earth at various levels or scales of detail. These levels of detail are levels of resolutions for viewing the earth and its geographical features. These levels are as follows: Level 0 (Low Resolution), Level 1 (Medium Resolution), and Level 2 (High Resolution). &lt;br /&gt;
&lt;br /&gt;
Level 0 resolution (VMAP 0) is global coverage and in the public domain. This level also provides a worldwide coverage of geospatial data on a small scale of 1:1,000,000 and is available on CD-ROM or as a direct download from the National Geospatial-Intelligence Agency (NGA). Level 0 is an improved and updated version of NGA's Digital Chart of the World (DCW). The entire coverage for Vector Map Level 0 resolution is divided into four major datasets: North America (NOAMER); Europe and North Asia (EURNASIA); South America, Africa, and Antarctica (SOAMAFR); and South Asia and Australia (SASAUS). The data structure for VMAP follows the Vector Product Format (VPF). &lt;br /&gt;
&lt;br /&gt;
Level 1 resolution (VMAP 1) is a medium scale resolution and features a dataset that is divided into 234 geographical titles. However, only 55 of these titles are available for download from NGA. Some of the datasets that are available for download from NGA include the following: United States, Mexico, Libya, Costa Rica, Russia, and Iraq. The scale of coverage for Level 1 is 1:250,000 and Level 1 VMAP is only partly in the public domain. &lt;br /&gt;
&lt;br /&gt;
Finally, Level 2 resolution (VMAP 2) is a large scale resolution, which is a scale of 1:50,000. In addition to the levels of resolution, VMAP geospatial data is topologically structured and separated into nine thematic layers: boundaries, hydrography, elevation, industry, physiography, transportation, utilities, population, and vegetation. Each thematic layer contains a set of files that describes the features in each layer, and each thematic layer is stored as a single coverage. VMAP is designed to be used and analyzed by a GIS (Geographic Information System) and can also be used to produce map background displays for a wide range of situations. &lt;br /&gt;
&lt;br /&gt;
Various tools can be used to read and convert VMAP data. For example, VPFView, developed by NIMA, can be used to render simple plots and export GIS data to other GIS file formats. VPFView is available from NGA as part of the NIMAMUSE package. Another tool that can be used is OGR with ODGI driver. OGR is capable of converting VMAP format to standard GIS file formats, such as Shapefiles. Since NGA is a government agency, nearly all GIS data created by NGA is free and openly available in accordance with the Freedom of Information Act. Therefore, much of the VMAP data is offered as part of the public domain. Although GIS data is open to the United States public, governments in other countries still view this data as a state monopoly, and it is strictly prohibited for use by the public. &lt;br /&gt;
&lt;br /&gt;
The National Geospatial-Intelligence Agency (NGA) is the creator of the VMAP database system and is a Department of Defense combat support agency. The goal of NGA is to provide accurate and timely geospatial information to support national security efforts. In addition to this, NGA provides its customers with access to the world's best geospatial and imagery intelligence. NGA was established in 1996 under the title of National Imagery and Mapping Agency, but changed its name in 2003 to reflect its expanded function in the areas of imagery and geospatial intelligence.&lt;/p&gt;
&lt;h2 style=&quot;margin: 22px 0px 14px;&quot;&gt;Premium Sources for Map Data&lt;/h2&gt;
&lt;p&gt;There are several vendors of premium map data available, such as Tele Atlas and NAVTEQ. The map data provided by these vendors is readily available for integration with ThinkGeo's mapping and GPS satellite-tracking products. &lt;br /&gt;
&lt;br /&gt;
Tele Atlas provides digital maps and digital map data for Geographic Information Systems (GIS), Location Based Services (LBS), and automotive navigation systems. Tele Atlas's map databases cover 51 countries and are available in a variety of formats. In addition, Tele Atlas provides accurate map data to support commercial and government mapping applications. One of Tele Atlas's products in particular, Dynamap, provides raw mapping data for end users to develop professional maps. Dynamap provides highly accurate digital map data that can be used in many GIS applications. &lt;br /&gt;
&lt;br /&gt;
NAVTEQ is one of the world's largest providers of premium digital map data. NAVTEQ digital map data is most commonly used in vehicle navigational systems that are sold in North America and Europe. In addition to use in vehicle navigation systems, NAVTEQ's map data is also commonly used in numerous GIS solutions around the world. NAVTEQ digital map data features road geometry and dozens of road attributes in over 40 countries. &lt;br /&gt;
&lt;br /&gt;
NAVTEQ data provides an accurate representation of road networks and up to 160 attributes, such as areas of restrictive access, physical barriers and gates, turn restrictions, one-way streets, and relative road heights. Besides the automotive industry, GIS development, and internet navigation sites, NAVTEQ data is also used in express mail services, efficient field management services, emergency and government routing plans, and vehicle tracking applications. &lt;br /&gt;
&lt;br /&gt;
NAVTEQ digital map data is regularly tested by field researchers who continuously drive roads around the world to ensure that NAVTEQ data reflects current real-world conditions. Finally, NAVTEQ offers its users regular updates for its digital map data and these updates can also be added to older digital maps.&lt;/p&gt;
&lt;h2 style=&quot;margin: 22px 0px 14px;&quot;&gt;Internet Resources for Map Data&lt;/h2&gt;
&lt;p&gt;There are two primary resources on the internet for reliable map data. These resources are &lt;a target=&quot;_blank&quot; href=&quot;http://geodata.gov&quot;&gt;geodata.gov&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://data.geocomm.com&quot;&gt;data.geocomm.com&lt;/a&gt;. Geodata.gov helps users find data and map services, develop maps, cooperate on data acquisitions, and browse community information. The geodata.gov site is essentially a Geographic Information portal that is open to the public so that users can easily acquire geospatial information and data from a single source. &lt;br /&gt;
&lt;br /&gt;
When a user registers with the geodata.gov site, searches, maps, and geography can be saved for later use. On the website, geography can be easily accessed for local governments and geographic data for federal, state, and local government can be accessed. GIS developers and users can access a wide variety of map data, such as live data and maps, downloadable data, offline data, and map files. In addition, data is divided into several different categories, such as administrative and political; farming and agriculture; biology and ecology; cultural, society, and demographic; geological and geophysical; and oceans and coasts. Finally, geodata.gov offers users several free GIS software tools like ArcExplorer Web. &lt;br /&gt;
&lt;br /&gt;
Geocomm.com is another commonly used GIS portal on the NET and is an online resource for free GIS data to use with GIS and CAD software applications. Geocomm.com also offers free downloadable software tools and demos to help users get started with their GIS applications. Some of the GIS data that can be accessed from geocomm.com include: Digital Chart of the World (DCW), Digital Raster Graphics, Digital Elevation Model data, Landsat Thematic Mapper data, and Digital Line Graph data. The mission of geocomm.com is to be an online leader of geographic products and services for GIS developers and enthusiasts. The geocomm.com website promotes open and free exchange of geospatial information between users of the site. &lt;br /&gt;
&lt;br /&gt;
In conclusion, ThinkGeo products, such as Map Suite and Cygnus Track, rely on map data from a wide variety of sources for their mapping and geospatial applications. For example, the Map Suite products utilize TIGER&amp;reg;/Line data from the U.S. Census Bureau to expand their look and functionality. Reliable map data is essential for the building and rendering of unique and accurate maps. In order to help customers realize the goal of building accurate, reliable, and unique maps, ThinkGeo has a staff of dedicated GIS developers and software engineers with extensive GIS experience, which ensures that map data integration is smooth and trouble-free. In addition to this, ThinkGeo uses mapping data from only the most reliable and accurate map data sources in the world, such as the U.S. Census Bureau.&lt;/p&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4760/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Wed, 05 Nov 2008 08:17:40 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4760/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Creating ShapeFiles From Scratch in Map Suite 2.x</title>
			<description>&lt;p&gt;Map Suite has the ability to edit existing ShapeFiles, but what if you want to create your own? The code below should get you started, but if you want to explore more shapefile editing check out our EditShapeFile sample application included with the evaluation download.&lt;/p&gt;

&lt;p&gt;Below is a very simple example of creating a point based shapefile from scratch. It adds three records and fills the value for the field &quot;Name&quot;.&lt;/p&gt;

&lt;p style=&quot;font-size: 14px;&quot;&gt;&lt;b&gt;C#&lt;/b&gt;&lt;/p&gt;
&lt;code lang=&quot;csharp&quot;&gt;private DatabaseColumns Columns = new DatabaseColumns();
private DatabaseColumn Column1;
Column1.FieldType = FieldDataType.fdtString;
Column1.Length = 15;
Column1.DecimalLength = 0;
Column1.Name = &quot;Name&quot;;
Columns.Add(Column1);
Map1.CreateNewShapefile(ShapeTypeEnum.Point, &quot;C:\\thinkgeo\\temp&quot;, &quot;Test&quot;, Columns);
Layer Layer = new Layer(&quot;C:\\thinkgeo\\temp\\test.shp&quot;, false);
Layer.BeginEdit();
int Shape1 = Layer.AddShape(new PointShape(-98, 19));
Layer.UpdateTableData(1, &quot;Name&quot;, &quot;Record1&quot;);
int Shape2 = Layer.AddShape(new PointShape(-97, 15));
Layer.UpdateTableData(2, &quot;Name&quot;, &quot;Record2&quot;);
int Shape3 = Layer.AddShape(new PointShape(-98, 20));
Layer.UpdateTableData(3, &quot;Name&quot;, &quot;Record3&quot;);
Layer.CommitEdit();
&lt;/code&gt;

&lt;p style=&quot;font-size: 14px; margin-top: 25px;&quot;&gt;&lt;b&gt;VB.NET&lt;/b&gt;&lt;/p&gt;
&lt;code lang=&quot;vb&quot;&gt;Dim Columns As New DatabaseColumns
Dim Column1 As DatabaseColumn
Column1.FieldType = FieldDataType.fdtString
Column1.Length = 10
Column1.DecimalLength = 0
Column1.Name = &quot;Name&quot;
Columns.Add(Column1)

Dim Column2 As DatabaseColumn
Column2.FieldType = FieldDataType.fdtDouble
Column2.Length = 5
Column2.DecimalLength = 2
Column2.Name = &quot;Acres&quot;
Columns.Add(Column2)
Dim strPath As String = &quot;C:\Projects\ThinkGeo\&quot;
Dim strName As String = &quot;Steve&quot;
Map1.CreateNewShapefile(ShapeTypeEnum.Polygon, strPath, strName, Columns)

Map1.MapUnit = MapSuite.Geometry.MapLengthUnits.DecimalDegrees

Dim Layer As New Layer(strPath &amp; strName, False)
Layer.BeginEdit()
Dim Shape As New Polygon()
Dim dblacres As Double = 90.31
Dim shape1 As Integer = Layer.AddShape(Shape)

Layer.UpdateTableData(shape1, &quot;Acres&quot;, dblacres.ToString)
Layer.UpdateTableData(shape1, &quot;Name&quot;, &quot;Record1&quot;)
Layer.CommitEdit()
Layer.BuildIndex()
Layer.BuildRecID(&quot;Recid&quot;, True)
&lt;/code&gt;</description>
			<link>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4730/afv/topic/Default.aspx</link>
			<dc:creator>ThinkGeo</dc:creator>
			<pubDate>Mon, 25 Feb 2008 11:34:32 GMT</pubDate>
			<guid>http://gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/18/aft/4730/afv/topic/Default.aspx</guid>
			<slash:comments>0</slash:comments>
		</item><atom:link href="http://gis.thinkgeo.com/DesktopModules/ActiveForums/feeds.aspx?portalid=1&amp;forumid=18&amp;tabid=143&amp;moduleid=623" rel="self" type="application/rss+xml" />
	</channel></rss>