CO Flag  
COmaps.org: Colorado Interactive Maps and Demographic Data
Powered by Google Maps
 

Dynamic Maps
Information
  • Available Soon
    Election Data
Links
- Data Sources

Google Map Drawing Instructions

Each section is delinated, explaning the process used to generate the maps seen on this site. If you wish to make your own maps, please reference Map Data Files link, as it contains a less complicated version of the discussion below.

This page explains everything in detail, with the Map Data files link provides scripts so you do not have to care about the how, and just make a map for a website.

Table of Contents
Introduction

The initial justification for this site was due to the nature of the Secretary of State site, which shows the districts using image that appear to be from a 1985 DOS program. In addition, elections results from prior years were only available in pdf documents, with no means to do any further analysis of the data presented.

Google Maps had released their API, allowing for people to generate Google Maps within their own pages, using a far better technique for the generation of data on a much easier to read mapping site. Using data from the reapportionment committee, I made polylines out of the Geographic Information System (GIS) data, and promptly ran into multiple problems. This page will document those along the way, and summarize them at the end.

For Google Maps, markers, lines, and filled polygons can be generated using a list of latitude and longitude points that are connected together to produce an image that overlays onto the current view of the map. For districts, the data is loaded from an XML file, which is then used to access the points within and generate the line or polygon that shows the district. In the case of searchable click map, that click is translated into the latitude and longitude of that point, and the districts are returned to your browser in the same way that the district maps are loaded. For ease of use, the data is stored separately from the map so it can be used multiple times. A house district map is used three times, in the searchable district page, the house districts page, and the specific district page.

To explain the overall process for a single map, three steps take place. The XML file is first loaded, then translated into something Google Maps can understand. It is then overlayed onto the map, and PHP provides all of the data currently contained on that map. This portion is not covered here, as I would not consider myself skilled at this portion of the analysis.

XML Formats

There are two may ways to store XML data for geographic points: GPX and KML. GPX is the standard used in many GPS systems, such as the ones from Garmin. KML is the Keyhole Markup Language, made popular due to its use in Google Earth. Both of these systems are not used here.

Neither of these systems work well for this sort of data. The format for GPX data was too complex, requiring a far greater quantity of identification required that I believed to be needed for this data set. I am a minimalist, and this did not excite me. For KML, I tried to use the KML format for my data, but Javascript is not a processing language that allowed for a quick response to the program. KML files of most districts do exist, and I have links to this data on the Map Files Page. KML files store latitude longitude data in a CSV format, which must be translated somehow into an array. This analysis takes too much memory at the moment, unless I have missed a critical error somewhere. Therefore, I made a poor substitute of my own devising.

In XML, Elements are defined in <>, while Attributes are contained within an element, in quotes. This will help better explain what is going on in the next few sections

<element attribute1="value1" attribute2="value1"/>

I have made single district files from the KML format in most cases, reducing the amount to the bare minimum. An example is below:

<district>    
 <marker lng="-103" lat="39.5" tag="hd04"/>
 <line tag="hd04">
   <pt lng="-102.74761" lat="37.64364"/>
   <pt lng="-103.74761" lat="37.64364"/>
   <pt lng="-103.74761" lat="38.64364"/>
   <pt lng="-102.74761" lat="37.64364"/>
 </line>
</district>


Going through this line by line, the <district> and </district> tags enclose the entire data set, similar to <html> for a web page. These can be anything, but are generally used a document indentifier, such as for KML.

<markers01 lng="-103" lat="39.5" number="01" color="#F00000" scale="9"/>

In this line, a marker Element is defined, along with a number of Attributes to that marker. The longitude (lng) and latitude (lat) of that point are defined, along with an indentification tag (tag). When an Element is closed with /> instead of a single > symbol, there needs to be no closing </marker> in the XML

<line tag="hd04">

For the line Element, there is a tag Attribute once again, and closed with only a > symbol, as the points are contained within the line.

<pt lng="-102.74761" lat="37.64364"/>

The next four lines define point Elements (pt), with longitude (lng) and latitude (lat) Attributes.

 </line>
</district>

These two line close the line element and the overall document, respectively.

In Javascript, it is easier (and generally cleaner script) to use Attributes.

Loading XML

Loading XML can be accomplished in using your own script (the hard way), or using the Google Maps API. The GMap class can load XML using GXML.create(), and GDownloadUrl(). I have done it both ways, but the GDownloadUrl() function is easier to control.

Using your own script: If you decide to use your own script, you have to account for different methods on how to load the XML, dependent on whether you have IE or not IE. This is a simplification, but produces more complex coding when you try to load multiple XML files. If you know what you are doing, go ahead. Otherwise, stick with GDownloadURL().

GXML.create() : This used to be the only method to load XML through the Google Maps API, and did all of the required coding from the previous paragraph for you. If you are loading multiple XML files, I would recommend GDownloadURL(), but in certain cases, this function is perfectly fine. I will not define how to use this one, however.

GDownloadURL() : A generic downloader, meaning you can load non-XML files as well as XML. There is a function to translate the data from this function into XML. This is given in detail at the Google Maps site. I will not go into this, lest I lead someone astray with my poor explanations.

Loading XML
A snippet of Javascript used is given below. This is more than what API documentation has, which is the only reason it is here.

// === Convert_XML -- A defined function ===

Convert_XML = function(doc)
{
// === GXML.parse -- will parse the data using XML standards ===

var datapass = GXml.parse(doc);

// Send the data to a function to generate the lines/polygons/markers

Function_Polygon (datapass);
}

// Form the correct file names for each XMLfile

var xml_file_name = "xml/disthd01.xml";

GDownloadUrl (xml_file_name, Convert_XML);

In simple terms, you first define a function, in my case, a function that takes the downloaded data and uses GXml.parse to parse the XML file just downloaded. Then it sent to the polygon generation function (long and complicated)

and GDownloadUrl() is used to get this file located at xml_file_name. The convienent thing about GDownloadURl is that until the file is downloaded, the function (Convert_XML) will not be called. Therefore, multiple files can be loaded without conflicting with one another.

Converting XML to Google Maps
So, to the point people care about - making the map.

A demo map is provided of the Bolder Boulder 2006 race course. The XML file for this data is also available here.

1.  Get the marker and create
Once loaded, the javascript finds the "marker+key" term, in this case markers01, and reads all of the variables contained there.  The lat and lng are the latitude and longitude of the marker point, the number refereces the marker icon to load.  These are used to mark the marker in the right point and put the correct HTML into the info box.  The color determines the polyline color, and the scale will set the zoom on the map, which doesn't work in IE, sometimes.

2.  Create and Overlay the Polygon (or Polylines)
The point array that makes the district boundary is now parsed into lat/long points. These are loaded from pt elements. Dependent on the browser and apparently other unknown factors, After 300 points are read, the line is overlayed to the Google map. This prevents the warnings from your web browser that the Javascript file is taking too much processing time. The color line is determined from the color value in markers01.

3.  Load the data for the representative
ImportXML will load the contact information for the senator/representative of the chosen district. In a similar manner to loading the XML for a map, the data in placed into a table where the element name becomes the top line and the value within become the second line.

4.  Hiding/Showing the Rest of the Data
ImportXML also will remove data loaded if the paragraph element already contains text, allowing you to hide and show the data at will.  Thankfully, XML is cached, so this takes up no bandwith. One loads the data through ImportXML, except using different files in the case of the data that needs to be shown.  

And that is that - the Javascript file can be seen in omnidemo.js - with minor changes to prevent errors from occuring due to missing data in the demo files.  For districts, the pt elements must end and start with the same point, or else there is a gap in the line.  A simple district is shown in this demo and its XML file.

Polygon Searches

Polygon searches are covered in detail in a variety of other sites, but I'll at least explain how I do it briefly. If you wat specifics, see the links at the end of this section.

To find a whether or not a single district contains the data point we are looking for, you need to test districts in some manner. You can sequentially search all of the districts, or do an optimization protocol beforehand.

In this case, there is a list of points which denotes all districts, and the distance between those points and the clicked point or zipcode point is calculated. The shortest distances are calculated first. Multiple points for the larger districts are use to ensure a short check time.

Then the polygon point check is calculated, and this is repeated for all three data sets. These are reported to the javascript, and the districts are loaded onto the map in the same manner as all of the previous work.

Determining whether a point is inside of a polygon:
UC-Davis Page
UC-Irvine Page
University of Western Australia Page
alienryderflex.com Page

Additional Problems

Issues
As of now, the main two issues to be aware of is that polylines should not be excessive in length, and Safari will crash if a single GPolygon contains over 100 points. This is due some coding in Safari. It apparently also occurs in some old version of Firefox/Mozilla. Maybe.

To fix the polyline problem, you can split polylines every 300 points by creating a conditional within the while loop that generates polylines every 300 points, and starts the next polyline using the last point from the previous line. These will appear as seamless lines.

The second problem, for now, appears to be unnoticed or unfixable. I determine the browser type (which is bad, I know), and call the polyline method instead of the GPolygon method.


If for some reason you wish to view the old version, that is still available and located here.


Click to expand/contract
Senate Districts House Districts Congressional County Maps Regional Maps Homepage