Hacking Google Maps

Posted 05/10/2005 by dnaffis 0 CommentsAdd Your Comment

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>

Leave a Reply

Dave is the cofounder of Intridea and leads Intridea's product development efforts.

Before Intridea, Dave spent years at both AOL and IMAKE and received a Masters in Systems Engineering from the University of Virginia.