mapView.js

Summary

No overview generated for 'mapView.js'


Method Summary
static void mapView(container)
           The mapView class is a view that implements the Google Maps API to display tabulator queries and their associated information on a map window.
static void mapViewDoubleClick(event)
          

/**
 * The mapView class is a view that implements the Google Maps API to display
 * tabulator queries and their associated information on a map window.
 * MapView currently supports both latitude and longitude points, and also
 * has minimal geocoding support. ~jambo
 */
function mapView(container) {

    //The necessary vars for a View...
    /**The name field - a string.*/
    this.name="Map";
    /**States of all queries that the view currently know about.
     * 0=undrawn, 1=drawn, 2=can't draw. queryStates[q.id]=int*/
    this.queryStates=[];
    /**the HTML DOM node provided for this view.*/
    this.container=container;

    //The vars specific to a mapView...
    var map, geocoder;
    /**allMarkers stores the arrays of each marker set for each drawn query.
     * allMakers[q.id] yields the markers array associated with a query.*/
    var allMarkers=[];

    //Initialize the map.
    if (GBrowserIsCompatible() && map==undefined) {
        map = new GMap2(this.container);
        map.setCenter(new GLatLng(55,-90),4);
        map.addControl(new GSmallMapControl);
        if(geocoder==null) {
            geocoder = new GClientGeocoder();
        }
        map.checkResize();
    }

    this.onActive = function () {
        if(map!=null)
        {
            map.checkResize();
            
        }
    }

    /**drawQuery draws a given query to the map and sets its state
     * to be 1 (drawn).  Does not draw if queryStates[q.id]==2.*/
    this.drawQuery = function (q) {
        if(this.queryStates[q.id]!=null && this.queryStates[q.id]==2)
            return;
        var markers=[];        //Will be used to temp store markers.
        this.onBinding = function (bindings) {
            //Handles bindings returned with a callback for the query.
            tinfo("making a marker w/ bindings " + bindings);
            var nv = q.vars.length;
            var info, t, marker, point, lat, lng, i; //info holds the info bubble's DOM node
            info = document.createElement('div');
            info.setAttribute('ondblclick','mapViewDoubleClick(event)');
            t=document.createElement('table');
            info.appendChild(t);
            for (i=0; i<nv; i++) {
                var obj = bindings[q.vars[i]];
                var geoType = q.vars[i].mapUsed;
                if(geoType!=null) {    //Found some data to use for mapping.
                    switch (geoType) {
                        case 'lat':
                            lat=obj.value; break;
                        case 'long':
                           lng=obj.value; break;
                        case 'based_near':
                            lat = kb.the(obj, kb.sym('http://www.w3.org/2003/01/geo/wgs84_pos#lat'), undefined).value;
                            lng = kb.the(obj, kb.sym('http://www.w3.org/2003/01/geo/wgs84_pos#long'), undefined).value;
                            break;
                        case 'address':
                            var street, city, country, post;
                            street=kb.the(obj, kb.sym('http://www.w3.org/2000/10/swap/pim/contact#street'), undefined).value;
                            city=kb.the(obj, kb.sym('http://www.w3.org/2000/10/swap/pim/contact#city'), undefined).value;
                            country=kb.the(obj, kb.sym('http://www.w3.org/2000/10/swap/pim/contact#country'), undefined).value;
                            post=kb.the(obj, kb.sym('http://www.w3.org/2000/10/swap/pim/contact#postalCode'), undefined).value;
                            geocoder.getLatLng(street+" "+city+" "+country+" "+post, function(newPoint) {
                                if(point==null && newPoint!=null) {  //if query didn't find another coord, and geocoding worked
                                    marker = new GMarker(newPoint);
                                    map.addOverlay(marker);
                                    markers[markers.length]=marker;  //place our marker in the next index.
                                    this.centerAndZoomOnMarkers(map, markers);
                                    info.appendChild(document.createTextNode("("+newPoint.lat() +", "+newPoint.lng()+")"));
                                    GEvent.addListener(marker, "click", function() {
                                        marker.openInfoWindow(info);
                                    });
                                }
                            }); break;
                        default:
                            terror("Error in onBinding for MapView: findGeoType returned unknown type: "+geoType);
                            break;
                    }
                }
                else {    //Data that isn't meant to be mapped.
                    var tr = document.createElement('tr');
                    var td, tt;
                    tt= document.createElement('td')
                    tt.appendChild(document.createTextNode(q.vars[i].label))
                    tr.appendChild(tt);
                    if(obj.termType=='symbol' && isImage(obj.uri.substring(obj.uri.length-4))) {
                        td=matrixTD(obj,true);
                        }
                    else {
                        td=matrixTD(obj);
                    }
                    tr.appendChild(td);
                    t.appendChild(tr);
                }
            }

            //Add the completed point to the map -- but only if we actually got a point.
            if((lat!=undefined && lng!=undefined) || point!=undefined)
            {
                if(lat!=undefined && lng!=undefined) {
                    point = new GLatLng(lat, lng);
                }
                info.appendChild(document.createTextNode("("+point.lat() +", "+point.lng()+")"));
                marker = new GMarker(point);
                map.addOverlay(marker);
                markers[markers.length]=marker;  //place our marker in the next index.
                this.centerAndZoomOnMarkers(map, markers);
                GEvent.addListener(marker, "click", function() {
                    marker.openInfoWindow(info);
                });
            }
        }
        if(this.queryStates[q.id]!=2) {
            kb.query(q, this.onBinding, myFetcher);
            this.queryStates[q.id]=1;
            allMarkers[q.id]=markers;
        }
        map.checkResize();
    } //this.drawQuery


    /**Removes query q from the map area.  Also sets queryStates[q.id]=0.
     * Does nothing if q is not actually drawn. Deletes markers array.*/
    this.undrawQuery = function (q) {
        var i;
        if(this.queryStates[q.id]==1) {
            var markers=allMarkers[q.id];
            for(i=0; i<markers.length; i++) {
                map.removeOverlay(markers[i]);
            }
            delete allMarkers[q.id];
            this.queryStates[q.id]=0;
        }
    }

    /**Adds a query --effectively makes the view aware that the query exists.
     * Also does some preprocessing-checks to see if the map can actually
     * handle this query.*/
    this.addQuery = function (q) {
        var canBeMapped = this.findMapVars(q);
        if(canBeMapped)
            this.queryStates[q.id]=0;
        else
            this.queryStates[q.id]=2;
    }

    /**Removes a query--undraws the query and then deletes the queryStates
     * entry for that query.*/
    this.removeQuery = function (q) {
        this.undrawQuery(q);
        delete this.queryStates[q.id];
    }

    /**As of yet unused.  Will, however, undraw all active queries.*/
    this.clearView = function () {
        var i;
        for(i=0; i<this.queryStates.length; i++){
            if(this.queryStates[i]!=null && this.queryStates[i]==1) {
                this.undrawQuery(q);
            }
        }
    }

    //mapView-specific functions..
    /**Obviously, centers and zooms a map on an array of markers, based on
     * the average coordinates of all of the markers.*/
    this.centerAndZoomOnMarkers = function (map, markers) {
        var bounds = new GLatLngBounds(markers[0].getPoint(), markers[0].getPoint());
        var i;
        for (i=1; i<markers.length; i++) {
            bounds.extend(markers[i].getPoint());
        }
        var lat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) / 2.0;
        var lng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) / 2.0;
        if(bounds.getNorthEast().lng() < bounds.getSouthWest().lng()){
            lng += 180;
        }
        var center = new GLatLng(lat,lng)
        map.setCenter(center, map.getBoundsZoomLevel(bounds)-1);
    } 

    /**Used to preprocess queries.  Looks for lats and longs, addresses.
     * @returns true if q can be mapped, false otherwise.*/
    this.findMapVars = function (q) {
        var ns = q.pat.statements.length, pred, canBeMapped=false;
        var gotLat=false, gotLong=false;
        for(i=0; i<ns; i++) {
            pred=q.pat.statements[i].predicate.uri;
            switch(pred) {
                case 'http://xmlns.com/foaf/0.1/based_near':
                    q.pat.statements[i].object.mapUsed='based_near';canBeMapped=true; break;
                case 'http://www.w3.org/2000/10/swap/pim/contact#address':
                    q.pat.statements[i].object.mapUsed='address';canBeMapped=true; break;
                case 'http://www.w3.org/2003/01/geo/wgs84_pos#lat':
                    q.pat.statements[i].object.mapUsed='lat';
                    gotLat=true;
                    if(gotLong)
                        canBeMapped=true;
                    break;
                case 'http://www.w3.org/2003/01/geo/wgs84_pos#long':
                    q.pat.statements[i].object.mapUsed='long';
                    gotLong=true;
                    if(gotLat)
                        canBeMapped=true;
                    break;
                default:
                    break;
            }
        }
        return canBeMapped;
    } 
} // mapView

function mapViewDoubleClick(event) {
    var target = getTarget(event);
    var aa = getAbout(kb, target);
    if (!aa) return;
    if (aa && aa.termType == 'symbol')
        GotoURI(aa.uri);
}


Documentation generated by JSDoc on Fri Jul 14 19:24:50 2006