DC Event Mapper

May 10th, 2005

Here’s another Google Map app that maps events in Washington DC. It’s useful to get a sense of what’s going on in certain areas. I use it all the time now. Event Mapper

Here’’s another little one that lets you calculate the distance between various points you select on the map. Distance Calculator

You can find some others I’ve created here

I think my fascination with Google Maps has gone just a bit too far so I’m putting an end to it. Also, I’‘m running out of things to map.

Hacking Google Maps

May 10th, 2005

After weeks of going through Google’s javascript code I finally have a working hack. Here’s most of the code used to create the DC Event Mapper.

http://www.naffis.com/eventmapper/

This one basically retrieves data in XML format to feed the Google API and then separately does an XSLT transform to create the table and the associated click to view functionality.

Javascript:
<script type="text/javascript">
        var ae = "";
        var av = "";
        var ct = 1;
        var req;
        var urlc = 1 + 1;

        function isEmpty(s) {
              return ((s == null) || (s.length == 0))
          }

        function gid(i) {
            return document.getElementById(i);
        }

        function remove_points() {
            while (_m.locations.length > 0) {
                _m.removeLocation(_m.locations[0]);
            }
        }

        function get_xml_url(xmltype) {
            return 'http://www.naffis.com/emapper/xml/getXml.php?zip_code=' + gid("zip_code").value + '&type=' + xmltype;
        }

        function update(zip) {
            gid("zip_code").value = zip;
            update_map();
            update_list();
        }

        function update_map() {
            try {
                var msg = gid('eventmessage');
                if (xmlhttp) {
                    xmlhttp.open("GET", get_xml_url('map'), true);
                    xmlhttp.onreadystatechange=function() {
                        if (xmlhttp.readyState == 4) {
                            if (xmlhttp.status == 200) {
                                remove_points();
                                _m.clearOverlays();
                                _m.loadVPageStr(xmlhttp.responseText);
                                if(_m.locations.length > 0) {
                                    var found = true;
                                    for(i = 0; i < _m.locations.length; i++) {
                                        if(_m.locations[i].id == 'A')
                                            found = false;
                                    }
                                    if(found)
                                        msg.innerHTML = _m.locations.length + (_m.locations.length != 1 ? ' Records' : ' Record') + ' Found.';
                                    else
                                        msg.innerHTML = 'Sorry, no data is available. Please enter a different zip code.';
                                }
                                else
                                    msg.innerHTML = 'Sorry, no data is avaialable.';
                            }
                            else {
                                msg.innerHTML = 'Sorry, no data is available.';
                            }
                        }
                    }
                    xmlhttp.send(null);
                }
            }
            catch(e){
                alert(e);
            }
        }

        function update_list() {

            try {

                var table = new Active.XML.Table;
                table.setURL(get_xml_url("list"));
                table.request();
                var columns = ["mapid", "Person", "Address"];
                if(isEmpty(gid("zip_code").value))
                    var columns = ["mapid", "City"];

                //    create ActiveWidgets Grid javascript object
                var obj = new Active.Controls.Grid;
                obj.setColumnProperty("texts", columns);
                obj.setDataModel(table);

                var alternate = function(){
                        return this.getProperty("row/order") % 2 ? "#fcfaf6" : "#ffffff";
                    }

                var mark = function(){
                        var i = this.getProperty("row/index");
                        return (i==2 || i==4 || i==5) ? true : false;
                      }

                var row = new Active.Templates.Row;
                row.setStyle("background", alternate);
                row.setClass("mark", mark);
                row.setEvent("onmouseover", "mouseover(this, 'active-row-highlight')");
                row.setEvent("onmouseout", "mouseout(this, 'active-row-highlight')");
                obj.setTemplate("row", row);

                obj.setAction("click",
                    function(src){
                        var d = src.getProperty("item/index");
                        var loc = _m.locations[0];
                        for(i = 0; i < _m.locations.length; i++) {
                            if(_m.locations[i].id == d)
                                loc = _m.locations[i];
                        }
                        _m.showInfoWindowFromXML(loc);
                    }
                );

                window.setTimeout(function(){
                        try {
                            document.getElementById("events").innerHTML = obj;
                        }
                        catch(e){
                            alert(e);
                        }
                    }, 100);
                }
        catch(e){
            alert(e);
        }
    }

    </script>
<script type="text/javascript">
    if (window._load) {
        window._load();
    }
    </script>
</pre>
<pre>
    <script type="text/javascript">
    if (window._display) {
        var _x='<?xml version="1.0"?><page><center lat="37.062500" lng="-95.677068"/><span lat="62.625000" lng="105.459315"/></page>';
        window._display(_x, 500, 420);
        update_map();
        update_list();
        gid('eventmessage').innerHTML = 'Enter a zip code to map sex offenders.';
    }
    </script>
var xmlhttp;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
    try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            xmlhttp = false;
        }
    }
@else
    xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    xmlhttp = new XMLHttpRequest();
}

var _u=navigator.userAgent.toLowerCase();
function _ua(t) {
    return _u.indexOf(t) != -1;
}

function _uan(t) {
    if (!window.RegExp) {return 0;}
    var r=new RegExp(t + "([0-9]*)");
    var s=r.exec(_u);
    var ret=0;
    if (s.length >= 2) {ret=s[1];}
    return ret;
}

function _activeX() {
    var success=false;
    eval('try {new ActiveXObject("Microsoft.XMLDOM");success=true;} catch (e) {}');
    return success;
}

function _compat() {
    return ((_ua('opera') && (_ua('opera 7.5') || _ua('opera/8'))) ||(_ua('safari') && _uan('safari/') >= 125) ||(_ua('msie') &&!_ua('msie 4') && !_ua('msie 5.0') && !_ua('msie 5.1') &&!_ua('msie 3') && !_ua('powerpc') && _activeX()) ||(document.getElementById && window.XSLTProcessor &&window.XMLHttpRequest && !_ua('netscape6') &&!_ua('netscape/7.0')));
}

var _c=_compat();
function _load() {
    if (!_c) 
        return;
    document.write('<' + 'script src="http://maps.google.com/maps?file=js" type="text/javascript"><' + '/script>');
}

function _display(_x, width, height) {
    if (!_c) 
        return;
    document.getElementById('loading').style.display='none';

    var _cont=document.getElementById('map');
    _m=new _Map(_cont, null, width, height, 0);
    _m.loadVPageStr(_x);
    _m.showMapControl();
    if (_m.mapTypes.length > 1) {
        var _e=document.getElementById('maptoggle');
        _m.createSpecToggleLinks(_e, true);
    }          
}
geocodepanel.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <xsl:apply-templates select="location"/>
  </xsl:template>

  <xsl:template match="location">
    <table>
      <tr>
        <xsl:if test="icon/@class != 'noicon'">
          <td style="vertical-align: top; padding-right: 4px;">
            <a>
          <xsl:attribute name="href">javascript:showLocationInfo('<xsl:value-of select="@id"/>')</xsl:attribute>
              <img style="width:24px; height:38px" alt="">
                <xsl:attribute name="src">http://www.naffis.com/eventmapper/images/icon.png</xsl:attribute>
              </img>
            </a>
          </td>
        </xsl:if>
        <td style="padding-bottom: 0.5em; padding-top: 1px">
          <xsl:apply-templates select="info"/>
        </td>
      </tr>
    </table>
  </xsl:template>

  <xsl:template match="info">
    <div>
      <xsl:apply-templates select="address/line"/>
    </div>
  </xsl:template>

  <xsl:template match="line">
    <div><xsl:value-of select="."/></div>
  </xsl:template>

</xsl:stylesheet>
infostyle_statemap.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <xsl:apply-templates select="location"/>
      </xsl:template>

    <xsl:template match="location">
        <div style="padding-right: 8px; padding-left: 3px; margin-top: 2px">
            <xsl:apply-templates select="info"/>
        </div>
      </xsl:template>

      <xsl:template match="info">

        <xsl:variable name="page" select="../@arg0"/>

        <div style="font-weight: bold; padding: 2px;">
            Sex Offender:   
            <a target="_blank" style="background:white; color:#3300FF; text-decoration:underline;">
                   <xsl:attribute name="href">
                    <xsl:value-of select="url"/>        
                   </xsl:attribute>                    
                <xsl:value-of select="name"/>
            </a>
        </div>

           <div style="padding: 2px;">
            <a target="_blank" style="background:white; color:#3300FF; text-decoration:underline;">
                   <xsl:attribute name="href">
                    <xsl:value-of select="url"/>        
                   </xsl:attribute>                               
                <img border="0" height="80" width="60" align="left">
                       <xsl:attribute name="src">
                        <xsl:value-of select="imgsrc"/>        
                       </xsl:attribute>
                </img>
            </a>

            <font style="font-weight: bold;">
            <xsl:value-of select="type"/>:
            </font>
            <br />
            <xsl:value-of select="address1"/>
            <br />
            <xsl:value-of select="address2"/>

           </div>   

    </xsl:template>

</xsl:stylesheet>