Data Driven Maps Part 2: KML Choropleth Maps
April 20th, 2012 | Published in Uncategorized
A Keyhole Markup Language (KML) file is a XML like file that contains information that can be overlaid on a google map. And KML files are great ways to create a choropleths over a highly used api like google maps.
There are a couple of caveats with this project. First, I have stored the co-ordinates in a database because it is a simple solution. Second, the google map api has an upper limit on the file size of about 3 mb. This being the case in the following code I have manually removed some of the smaller islands in part because they tend to be groups of island and add lot of lines to the final KML file.
So lets look at some code.
using System; using System.IO; using System.Linq; using GoogleKMLTest.data; namespace GoogleKMLTest.classes { internal class CreateKMLFile { #region Variables private readonly GoogleKMLDataContext _db = new GoogleKMLDataContext(); #endregion #region Create KML File /// <summary> /// Creates thes the KML file. /// </summary> public void CreatetheKMLFile() { // Local Variables var t2 = new FileInfo(@"C:\\kml\\test.kml"); StreamWriter tex = t2.CreateText(); var myRand = new Random(); // Set Header SetHeader(tex); // Add style colors SetStyleColors(tex); // Add an empty line tex.WriteLine(); // Removing smaller island countries to get under the google limit var q = (from t in _db.tbl_Google_Maps where t.Country != "American Samoa" && t.Country != "Antigua and Barbuda" && t.Country != "British Virgin Islands" && t.Country != "Faroe Islands" && t.Country != "Federated States of Micronesia" && t.Country != "Fiji" && t.Country != "French Polynesia" && t.Country != "Kiribati" && t.Country != "Maldives" && t.Country != "Marshall Islands" && t.Country != "Northern Mariana Islands" && t.Country != "Pacific Islands (Palau)" && t.Country != "Solomon Islands" select new {t.Country}).Distinct(); // Loop through the rest of the countries foreach (var item in q) { // Get sub co-ordinates var item1 = item; IQueryable<tbl_Google_Map> q2 = (from t in _db.tbl_Google_Maps where t.Country == item1.Country select t); // Start placemark tex.WriteLine("\t<Placemark>"); tex.WriteLine("\t\t<name>" + item.Country + "</name>"); tex.WriteLine("\t\t<visibility>0</visibility>"); tex.WriteLine("\t\t<styleUrl>#" + myRand.Next(1, 6) + "</styleUrl>"); tex.WriteLine("\t\t<MultiGeometry>"); // Loop through sub co-ordinates foreach (tbl_Google_Map item2 in q2) { tex.WriteLine("\t\t\t<Polygon>"); tex.WriteLine("\t\t\t\t<outerBoundaryIs>"); tex.WriteLine("\t\t\t\t\t<LinearRing>"); tex.WriteLine("\t\t\t\t\t\t<coordinates>" + item2.CoOrdinates + "</coordinates>"); tex.WriteLine("\t\t\t\t\t</LinearRing>"); tex.WriteLine("\t\t\t\t</outerBoundaryIs>"); tex.WriteLine("\t\t\t\t<tesselate>1</tesselate>"); tex.WriteLine("\t\t\t</Polygon>"); } // Close placemark tex.WriteLine("\t\t</MultiGeometry>"); tex.WriteLine("\t</Placemark>"); } // Close KML file tex.WriteLine("</Document>"); tex.WriteLine("</kml>"); tex.Close(); } /// <summary> /// Sets the header. /// </summary> /// <param name="tex">The tex.</param> private void SetHeader(StreamWriter tex) { tex.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); tex.WriteLine("<kml xmlns=\"http://earth.google.com/kml/2.0\">"); tex.WriteLine("<Document>"); } /// <summary> /// Sets the style colors. /// </summary> /// <param name="tex">The tex.</param> private void SetStyleColors(StreamWriter tex) { // Color One tex.WriteLine("\t<Style id=\"1\">"); tex.WriteLine("\t\t<LineStyle>"); tex.WriteLine("\t\t\t<width>.05</width>"); tex.WriteLine("\t\t\t<color>ff000000</color>"); // Border Color tex.WriteLine("\t\t</LineStyle>"); tex.WriteLine("\t\t<PolyStyle>"); tex.WriteLine("\t\t\t<outline>1</outline> "); tex.WriteLine("\t\t\t<fill>1</fill>"); tex.WriteLine("\t\t\t<color>ffc8e8fe</color>"); // Background Color tex.WriteLine("\t\t</PolyStyle>"); tex.WriteLine("\t</Style>"); // Color Two tex.WriteLine("\t<Style id=\"2\">"); tex.WriteLine("\t\t<LineStyle>"); tex.WriteLine("\t\t\t<width>.05</width>"); tex.WriteLine("\t\t\t<color>ff000000</color>"); // Border Color tex.WriteLine("\t\t</LineStyle>"); tex.WriteLine("\t\t<PolyStyle>"); tex.WriteLine("\t\t\t<outline>1</outline> "); tex.WriteLine("\t\t\t<fill>1</fill>"); tex.WriteLine("\t\t\t<color>ff84bbfd</color>"); // Background Color tex.WriteLine("\t\t</PolyStyle>"); tex.WriteLine("\t</Style>"); // Color Three tex.WriteLine("\t<Style id=\"3\">"); tex.WriteLine("\t\t<LineStyle>"); tex.WriteLine("\t\t\t<width>.05</width>"); tex.WriteLine("\t\t\t<color>ff000000</color>"); // Border Color tex.WriteLine("\t\t</LineStyle>"); tex.WriteLine("\t\t<PolyStyle>"); tex.WriteLine("\t\t\t<outline>1</outline> "); tex.WriteLine("\t\t\t<fill>1</fill>"); tex.WriteLine("\t\t\t<color>ff598dfc</color>"); // Background Color tex.WriteLine("\t\t</PolyStyle>"); tex.WriteLine("\t</Style>"); // Color Four tex.WriteLine("\t<Style id=\"4\">"); tex.WriteLine("\t\t<LineStyle>"); tex.WriteLine("\t\t\t<width>.05</width>"); tex.WriteLine("\t\t\t<color>ff000000</color>"); // Border Color tex.WriteLine("\t\t</LineStyle>"); tex.WriteLine("\t\t<PolyStyle>"); tex.WriteLine("\t\t\t<outline>1</outline> "); tex.WriteLine("\t\t\t<fill>1</fill>"); tex.WriteLine("\t\t\t<color>ff4865ef</color>"); // Background Color tex.WriteLine("\t\t</PolyStyle>"); tex.WriteLine("\t</Style>"); // Color FIve tex.WriteLine("\t<Style id=\"5\">"); tex.WriteLine("\t\t<LineStyle>"); tex.WriteLine("\t\t\t<width>.05</width>"); tex.WriteLine("\t\t\t<color>ff000000</color>"); // Border Color tex.WriteLine("\t\t</LineStyle>"); tex.WriteLine("\t\t<PolyStyle>"); tex.WriteLine("\t\t\t<outline>1</outline> "); tex.WriteLine("\t\t\t<fill>1</fill>"); tex.WriteLine("\t\t\t<color>ff0000b3</color>"); // Background Color tex.WriteLine("\t\t</PolyStyle>"); tex.WriteLine("\t</Style>"); } #endregion } }
Once overlaid the result looks like this. You can download the project and sql db file here.
Related Posts
K-Means Document ClusteringProblems with Html.DropDownList
Euclidean Distance Score
Cheap GPS and Code Project Tutorial