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