Data Driven Maps Part 2: KML Choropleth Maps

Data Driven Maps Part 2: KML Choropleth Maps

April 20th, 2012  |  Published in Programming, Visualization

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 Clustering
Problems with Html.DropDownList
Euclidean Distance Score
Cheap GPS and Code Project Tutorial

Archives