-1

Now on google.com/maps page when I click on the name/label of a country or city, this area are highlighted and opens left popup window with information.

Is it possible to realize the same thing with the Google Maps API? To highlight label on mouse over, to highlight boundaries of country, state or city on click and to get selected by user label/name in js.

I looked Google Maps API JavaScript documentation but similar functionality not found.

Thanks!


Sorry for imprecise question.

Is there any way to set clickable country / city names on map with API, like on google.com/maps page?

Max IV.
  • 9
  • 2
  • 1
    sure it's possible but you need a data source for boundaries – charlietfl Feb 05 '17 at 16:09
  • Upvoted as no comment for downvoting – Datadimension Feb 05 '17 at 16:10
  • @DataMechanics voting is anonymous by design here – charlietfl Feb 05 '17 at 16:10
  • yes charlie but being constructive requires conversation - surely you should comment on your reasoning – Datadimension Feb 05 '17 at 16:12
  • @DataMechanics hover over downvote button will see that a main reason is "lack of research effort". In this case some web searching wouldn't have gotten past the "is it possible" part. Basic research is expected before asking http://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users/261593#261593 – charlietfl Feb 05 '17 at 16:19
  • @charlietfl very valid point - and I was not aware of the hover feature. Thanks for clarification. You are correct and I am reversing my decision if the question gets unlocked – Datadimension Feb 05 '17 at 16:38

1 Answers1

-1

Recommend a 'barebones' GMap class. As it happens I am just re-visiting this myself so try this code (it might need some changes)

    /**
 *  'GMap'
 *  extends googlemaps to allow simpler coding in other apps, should be loaded after the main google maps
 *  a new instance of a google map is contructed calling this with identical arguments to the standard class and then returned
 *  the map name must be unique and reserved as a global by the client code, eg var pagemap outside of function, so the external callbacks
 *  can use this name to run a function against, eg pagemap.queryMove_do
 *
 */

function GMap(mapId, options) {
  this.name = null;
  this.map = null;
  this.bounds = null; //view point boundary
  this.gui_reg;
  this.mapoptions;
  this.calledbackonload;
  this.polygons = {};
  this.lngoffset = {'direction': '', referenceelem: ''};
  this.infowindows = {};
  this.infowindowindex = 0;
  GMap.prototype.__construct = function (mapId, options) {
    var mapbuffer = new Data_buffer(); //this has to be vague as 3rd party api data is not always the same format, simply return data to the logged map interface objects

    if (typeof window.MAP_INTERFACE_CTRL === 'undefined') {//if not created, global constant to co-ordinate ajax requests with map objects and 3rd party API, and allow funneling back to local objects
      window.MAP_INTERFACE_CTRL = new Data_buffer(); //this has to be vague as 3rd party api data is not always the same format, simply return data to the logged map interface objects
    }
    options.panControlOptions = model.array_defaults(
            options.ctrlcfg,
            {
              position: google.maps.ControlPosition.RIGHT_BOTTOM
            }
    );
    options.zoomControlOptions = model.array_defaults(
            options.ctrlcfg,
            {
              position: google.maps.ControlPosition.RIGHT_CENTER
            }
    );
    this.mapoptions = model.array_defaults(
            options,
            {
              center: new google.maps.LatLng(54.5, -7),
              zoom: 6,
              minzoom: 15,
              maxzoom: 21
            }
    );
    this.gui_reg = {location: {address: new Array()}};
    this.name = mapId;
    this.map = new google.maps.Map(document.getElementById(mapId), this.mapoptions);
    var selfobj = this;
    google.maps.event.addListener(//processes client registration for registered events
            this.map,
            'dragend', //center changed causes too many requests
            function () {
              selfobj.update_client_go("location");
            }
    );
//create invisible scratchpad
    if ($('#map_pool').length == 0) {
      $('body').append("<div id='map_pool'></div>");
      $('#map_pool').hide();
    }
    /*
     callback_obj = this;
     google.maps.event.addListener(this.map, 'tilesloaded', function(evt) {
     callback_obj.map.setZoom(9);
     });*/
  }

  /*****************************************************************/
  /* METHODS FOR BOTH GMAP AND CLIENT */
  /*****************************************************************/

  /*
   * defines offset of mapcentre away from an element such as custom controls
   * which overlay a large amount of map
   * positive or negative according to offset direction where the element might be on the
   * left or the right
   */
  GMap.prototype.set_lng_offset = function (elemid, dir) {
    var direction = 'right';
    if (dir == 'left') {
      direction = dir;
    }
    this.lngoffset = {direction: direction, referenceelem: elemid};
  }

  /*
   * returns lng offset according to definitions and current map situation
   */
  GMap.prototype.calc_lng_offset = function () {
//get lng width of map
    var eastlng = this.map.getBounds().getNorthEast().lng();
    var westlng = this.map.getBounds().getSouthWest().lng();
    var lngspan;
    if (westlng <= 0 && eastlng >= 0) {
      lngspan = Math.abs(westlng) + eastlng;
    } else if (westlng >= 0 && eastlng <= 0) {
      lngspan = (180 - westlng) + (180 - Math.abs(eastlng));
    } else if (westlng < 0 && eastlng < 0) {
      lngspan = Math.abs(eastlng) + westlng;
    } else {
      lngspan = eastlng - westlng;
    }

//get px width of map and referenced element
    var mapwidth = $("#" + this.name).width();
    var offsetpx = $("#" + this.lngoffset.referenceelem).width();
    //convert this px to lng offset for map by multiplying by lngpx
    var lngperpx = lngspan / mapwidth; //calc lng/px as lngpx
    //calc the offset lng
    var offsetlng = offsetpx * lngperpx;
    if (this.lngoffset.direction == 'left') {
      var offsetlng = 0 - offsetlng;
    }
    return offsetlng;
  }

  /*
   * returns an object with north south east west and centre coordinates of the current view
   * args.precision states number of figures after decimal returned - if not give a full result is returned.
   * @returns {float north,float east,float south,float west,float lat,float lng}
   */
  GMap.prototype.get_viewport_coords = function (args) {
    if (args == undefined) {
      args = {};
    }
    var coords = {};
    coords.north = this.map.getBounds().getNorthEast().lat();
    coords.east = this.map.getBounds().getNorthEast().lng();
    coords.south = this.map.getBounds().getSouthWest().lat();
    coords.west = this.map.getBounds().getSouthWest().lng();
    coords.lat = this.map.getCenter().lat();
    coords.lng = this.map.getCenter().lng();
    if (args.precision != undefined) {
      coords.north = coords.north.toFixed(args.precision);
      coords.east = coords.east.toFixed(args.precision);
      coords.south = coords.south.toFixed(args.precision);
      coords.west = coords.west.toFixed(args.precision);
    }
    return coords;
  }

  /*
   *    'map_query'
   *    takes a text query and queries to google for info
   *
   *    required due to APIs not being the same, a uuid is registered globally and a global process used to redirect
   *    because of this the global process must identify a map object by UUID and only expect a single argument as an object literal (JSON)
   *    this is then passed back to the object that initiated the ajax or UUID request
   *
   *    @param OBJECT query_cfg to send to gmap geocode
   *      @param string query_cfg.type states what type of query and what action to take, allowing multiple use for this method
   *      @param string query_cfg.query_data a string containing address data such as '<postcode>, <street>, <property>'
   *      @param string query_cfg.callback to return the data to
   */
  GMap.prototype.geo_query = function (query_cfg) {

//package pre query data and set defaults if not set
    query_cfg = model.array_defaults(
            query_cfg,
            {
              clientid: this.name,
              callback: 'update_client_do'//client code can set its own callback,else set callback to this
            }

    );
    var geo_queryid = MAP_INTERFACE_CTRL.callback_push(query_cfg);
    switch (query_cfg.type) {
      case "location"://returns location data at given lat lng coords
        var gcoder = new google.maps.Geocoder();
        gcoder.geocode({'location': {lat: query_cfg.lat, lng: query_cfg.lng}}, function (results, status) {
          var server_response = {results: results, status: status};
          eval("MAP_INTERFACE_CTRL.callback_pop('" + geo_queryid + "',server_response)");
        });
        break;
      case "address_latlng":
        var gcoder = new google.maps.Geocoder();
        gcoder.geocode({'address': query_cfg.query_data}, function (results, status) {
          var server_response = {results: results, status: status};
          eval("MAP_INTERFACE_CTRL.callback_pop('" + geo_queryid + "',server_response)");
        });
        break;
      case "sv_pano_latlng"://gets streetview pano for given lat lng
        var sv_service = new google.maps.StreetViewService();
        sv_service.getPanoramaByLocation(query_cfg.latlng, query_cfg.radius, function (results, status) {
          var server_response = {results: results, status: status};
          eval("MAP_INTERFACE_CTRL.callback_pop('" + geo_queryid + "',server_response)");
        });
        break;
      case "viewport_range"://returns lat lng for viewport and centre to callback
        var gcoder = new google.maps.Geocoder();
        var bounds = this.bounds;
        var center = this.map.getCenter();
        gcoder.geocode({address: change_request}, function (results, status) {
          callback_obj.viewport_range_do(results, status)
        });
        break;
    }
  }

  /*
   *    'formatted_geo_result'
   *    interprets geocoded results to a standard uniform independent of map api
   *    @param OBJECT geo_result data returned (in this map interface from google)
   */
  GMap.prototype.formatted_geo_result = function (geodata) {
    var formatted = {};
    var itemdefaults = {
      address: '',
      lat: null,
      lng: null
    }
    for (var i in geodata.results) {
      var item = {
        address: geodata.results[i].formatted_address,
        lat: geodata.results[i].geometry.location.lat(),
        lng: geodata.results[i].geometry.location.lng(),
      }
      formatted[i] = model.array_defaults(item, itemdefaults);
    }
    return formatted;
  }
  /*
   *    'map_change'
   *    takes a request and processes and changes map accordingly
   *
   *    callerobj is optional, if not given then callback will be back to this map object
   *    if a callerobj is given this must be to an object which can accept it
   *    (if callerobj is a top level function it needs to pass the object as keyword window - not 'window')
   *    The callback method is named as query type with _do appended eg address_move_do
   *    Some query types require the caller object to handle the query and DO NOT have a method defined in the map object
   *    If this map object DOES have the callback but a callback_obj is given then it will override this map object
   *
   *    @param string change_request free text to send to gmap object
   *    @param string change_type states what type of query and what action to take, allowing multiple use for this method
   *    @param string callback function to run on change completion.
   */
  GMap.prototype.map_change = function (change_type, change_data, callback) {
    switch (change_type) {
      case "lat_lng":
        this.map.panTo({lat: change_data.latlng.lat, lng: change_data.latlng.lng + this.calc_lng_offset()});
        break;
      case "address"://to address_latlng as translation for this map object
        this.geo_query({type: "address_latlng", clientid: this.name, callback: "map_change_do", change_type: change_type, query_data: change_data});
        break;
    }
    if (callback != undefined) {
      this.loadedCallback(callback);
    }
  }

  /*
   *    'map_change_do'
   *    processes any ajax return required by map_change
   *
   *    @param string change_request free text to send to gmap object
   *    @param string change_type states what type of query and what action to take, allowing multiple use for this method
   */
  GMap.prototype.map_change_do = function (pre_data, callback_data) {
    switch (pre_data.change_type) {
      case "address":
        this.map_change("lat_lng", {latlng: {lat: callback_data.results[0].geometry.location.lat(), lng: callback_data.results[0].geometry.location.lng()}}); //callback_data.results[0].geometry.location.lat()
        break;
    }
  }

  /*
   * permanently deletes all objects such as map markers (pins) etc
   */
  GMap.prototype.clearmapobjects = function () {
    this.map.clearMarkers();
  }

  GMap.prototype.panotestA = function () {
    var locquery = "framlingham tech centre";
    this.map_change("address", locquery);
    this.map.setZoom(20);
    this.geo_query("location", locquery)
    this.geo_query({type: "address_latlng", clientid: this.name, callback: "panotestB", query_data: locquery});
  }
  GMap.prototype.panotestB = function (pre_data, callback_data) {
    var pin = this.add_pin(callback_data.results[0].geometry.location.lat(), callback_data.results[0].geometry.location.lng(), {infopop: {content: 'hello', streetview: true}});
  }
  /*
   *    'add_pin'
   *    adds a pin to a map
   *
   *    @param float lat is latitude position
   *    @param float lng is longitude position
   *    @param object info_args other pin constructs such as the info displayed while clicking it
   *    @return object marker
   */
  GMap.prototype.add_pin = function (lat, lng, info_args) {
    info_args = model.array_defaults(
            info_args,
            {
              width: 16,
              height: 16,
              animation: google.maps.Animation.DROP,
              icon: {
                url: "http://" + ROOTUC + "//css/images/icons/ROYOdot_a.gif"
              },
              infopop: null
            }
    );
    /*
     var icon = {
     url: info_args.icon.url,
     size: new google.maps.Size(20, 20),
     origin: new google.maps.Point(0, 0),
     anchor: new google.maps.Point(0, 0)
     };
     */
    var iconImage = new google.maps.MarkerImage(
            info_args.icon.url, // url to image inc http://
            null, // desired size
            null, // offset within the scaled sprite
            null, // anchor point is half of the desired size
            new google.maps.Size(info_args.width, info_args.height) // required size
            );
    var pin = new google.maps.Marker({
      position: new google.maps.LatLng(lat, lng),
      map: this.map,
      title: info_args.label,
      icon: iconImage,
      optimized: false, //to allow for animations
      animation: info_args.animation,
    });

    if (info_args.infopop != null) {
      /*content is forced into div with black font as google default
       * is white text on white background ?!?!?!
       */

      info_args.infopop = model.array_defaults(
              info_args.infopop,
              {
                fontcolor: '#000000',
                infowidth: '40em',
                streetview: false
              });
      //standard google defs
      var infowindow = new google.maps.InfoWindow();
      //extra seperate data ref for client apps
      infowindow.metadata = {
        parent: this,
        parentid: this.infowindowindex,
      };
      this.infowindows[this.infowindowindex] = {
        infowidth: info_args.infopop.infowidth,
        content: info_args.infopop.content,
        fontcolor: info_args.infopop.fontcolor,
        latlng: {lat: lat, lng: lng},
        streetview: info_args.infopop.streetview
      };
      this.infowindowindex++;

      //build for pin click
      google.maps.event.addListener(pin, 'click', function () {
        var infodata = infowindow.metadata.parent.infowindows[infowindow.metadata.parentid];

        //build content
        var infocontent = "<div id='" + infowindow.metadata.parent.name + "infowindow" + (infowindow.metadata.parentid) + "' style='color:" + infodata.fontcolor + ";width:" + infodata.infowidth + "'>";
        infocontent += infodata.content;
        if (infodata.streetview) {
          infocontent += "<div id='" + infowindow.metadata.parent.name + "infowindowsvframe" + (infowindow.metadata.parentid) + "' class='infostreetviewframe' >";
          infocontent += ". . . loading view</div>";
        }
        infocontent += "</div>";
        infowindow.setContent(infocontent);
        infowindow.open(this.map, pin);
        if (infodata.streetview) {
          var service = new google.maps.StreetViewService();
          infowindow.metadata.parent.geo_query({type: "sv_pano_latlng", latlng: infodata.latlng, radius: 50, clientid: infowindow.metadata.parent.name, streetviewframe: infowindow.metadata.parent.name + "infowindowsvframe" + (infowindow.metadata.parentid), callback: "add_streetview_do"});
        }
      });
    }
  }

  /*
   *    'add_streetview'
   *    for flexibility addition of a streetview into a named dom element id
   *
   *  @param object args
   *      @param.args string elemid the element to put the streetview into
   *
   */
  GMap.prototype.add_streetview_do = function (predata, callbackdata) {
    var svelement = document.getElementById(predata.streetviewframe);
    if (callbackdata.status == google.maps.StreetViewStatus.OK) {
      var targetPOVlocation = predata.latlng
      var svLatLng = {lat: callbackdata.results.location.latLng.lat(), lng: callbackdata.results.location.latLng.lng()};

      // var svLatLng = new google.maps.LatLng(callbackdata.results.location.latLng.lat(), callbackdata.results.location.latLng.lng());

      //var svLatLng = callbackdata.results.location.latLng;

      var povyaw = this.getBearing(svLatLng, targetPOVlocation);
      var sv = new google.maps.StreetViewPanorama(svelement);
      var svoptions = {
        position: svLatLng,
        addressControl: false,
        linksControl: false,
        panControl: false,
        zoomControlOptions: {
          style: google.maps.ZoomControlStyle.SMALL
        },
        pov: {
          heading: povyaw,
          pitch: 10,
          zoom: 1
        },
        enableCloseButton: false,
        visible: true
      };
      sv.setOptions(svoptions);
    } else {
      svelement.innerHTML = "no streetview available";
    }
  }

  /*
   *    'getBearing'
   *    calcs bearing from two latlngs
   *
   */
  GMap.prototype.getBearing = function (fromLatLng, targetLatLng) {
    var DEGREE_PER_RADIAN = 57.2957795;
    var RADIAN_PER_DEGREE = 0.017453;

    var dlat = targetLatLng.lat - fromLatLng.lat;
    var dlng = targetLatLng.lng - fromLatLng.lng;
    // We multiply dlng with cos(endLat), since the two points are very closeby,
    // so we assume their cos values are approximately equal.
    var bearing = Math.atan2(dlng * Math.cos(fromLatLng.lat * RADIAN_PER_DEGREE), dlat)
            * DEGREE_PER_RADIAN;

    if (bearing >= 360) {
      bearing -= 360;
    } else if (bearing < 0) {
      bearing += 360;
    }
    return bearing;
  }

  /*
   *    'add_polygon'
   *    adds a polygon to a map using an array of lat lng coords
   *    these are pushed in the order they appear in the locationarray
   *
   *  @param array locationarray - which event/change type triggers update of this element
   *
   */
  GMap.prototype.add_polygon = function (args) {

//construct and store polygon
    var polyobj = model.array_defaults(args, {name: "polygon", polygon: null, infohtml: null, box: null, focuson: false});
    //remove any same named polygon
    if (this.polygons[args.name] != undefined) {
      this.polygons[args.name].polygon.setMap(null);
      this.polygons[args.name] = null;
    }


    var newpolygon = new Array();
    polyobj.box = new google.maps.LatLngBounds();
    for (var l in args.polygon) {
      var point = new google.maps.LatLng(args.polygon[l].lat, args.polygon[l].lng);
      newpolygon.push(point);
      polyobj.box.extend(point);
    }
    polyobj.polygon = new google.maps.Polygon(
            {
              map: this.map,
              paths: newpolygon,
              strokeColor: '#00ff00',
              strokeOpacity: 0.75,
              strokeWeight: 2,
              fillColor: '#00ff00',
              fillOpacity: 0.15
            }
    );
    this.polygons[args.name] = polyobj;
    //set required changes to map
    if (args.infohtml != null) {
// content is forced into div with black font as google default is white text on white background ?!?!?!
      polyobj.info = new google.maps.InfoWindow(
              {
                content: "<div style='color:#000000'>" + args.infohtml + "</div>"
              });
      var selfobj = this;
      google.maps.event.addListener(this.polygons[args.name].polygon, 'click', function (event) {
        var point = event.latLng;
        selfobj.polygons[args.name].info.setPosition(point);
        selfobj.polygons[args.name].info.open(selfobj.map);
      });
    }

    if (polyobj.focuson) {
      this.map.fitBounds(polyobj.box);
    }
  }


  /*****************************************************************/
  /* methods for CLIENT --> GMAP change */
  /*********************************************************S ********/

  /*
   * allows gui to register elements so when changes / events occur in the map gui, its
   * parent gui can be updated.
   *    @param string change_type - which event/change type triggers update of this element
   *    @param string change_return - data required to be returned eg latlng or address etc
   *    @param string callback - the page element identifier to update
   */
  GMap.prototype.register_elem = function (change_type, event_return_cfg) {
    switch (change_type) {
      case "location":
        switch (event_return_cfg.return_type) {
          case "address":
            this.gui_reg.location.address.push(event_return_cfg);
            break;
        }
        break;
    }
  }

  /*****************************************************************/
  /* methods for GMAP --> CLIENT change */
  /*****************************************************************/

  /*
   * checks registered change type to send back to client
   *    @param string change_type - which event/change type triggers update of this element
   *    @param string data_request - data required to be returned
   *    @param string regelem - the parent gui identifier to update5
   *    @param object attr - which attribute to update eg for input, its value, for div its html
   */
  GMap.prototype.update_client_go = function (change_type, data_request) {
    switch (change_type) {
      case "location":
        var loc = this.get_viewport_coords();
        this.geo_query({type: "location", lat: loc.lat, lng: loc.lng});
    }
  }

  /*
   * actions client_update
   *    @param string change_type - which event/change type triggers update of this element
   *    @param string data_request - data required to be returned
   *    @param string regelem - the parent gui identifier to update5
   *    @param object attr - which attribute to update eg for input, its value, for div its html
   */
  GMap.prototype.update_client_do = function (pre_data, callback_data) {
    if (callback_data.status != "ZERO_RESULTS") {
      switch (pre_data.type) {
        case "location":
          var location_data_registrars = this.gui_reg.location;
          for (var loc_type_list in location_data_registrars) {
            switch (loc_type_list) {
              case "address":
                var address = callback_data.results[0].formatted_address;
                for (var r in location_data_registrars[loc_type_list]) {
                  var event_return = location_data_registrars[loc_type_list][r];
                  if (event_return != undefined) {
                    event_return.address = this.address_parse("postcode", address);
                    if (event_return.callback != undefined) {
                      eval(event_return.callback + "(event_return)");
                    }
                  }
                }
                break;
            }
          }
          break;
      }
    }
  }

  /*****************************************************************/
  /* PRIVATE METHODS */
  /*****************************************************************/
  GMap.prototype.address_parse = function (required_part, address) {
    var result = "";
    address = address.split(", ");
    var country = address[address.length - 1];
    switch (country) {
      case "UK":
        switch (required_part) {
          case "postcode":
            result = address[address.length - 2];
            result = result.substr(result.indexOf(" ") + 1);
            break;
        }
        break;
    }
    return result;
  }

  GMap.prototype.loadedCallback = function (callback) {
    this.calledbackonload = false;
    google.maps.event.addListenerOnce(this.map, 'tilesloaded', function () {
      google.maps.event.clearListeners(this.map, 'idle');
      eval(callback + '()');
    });
    google.maps.event.addListenerOnce(this.map, 'idle', function () {
      eval(callback + '()'); //add idle as a catch all
    });
    /*
     google.maps.event.addListenerOnce(this.map, 'idle', function() {
     eval(callback + '()')
     });
     */
  }

  /*
   * zooms map to next level from current depending on dir being '+' or '-'
   */
  GMap.prototype.incrementZoom = function (dir, callback) {
    var newZoom = this.map.getZoom();
    if (dir == '+') {
      newZoom++;
    }
    if (dir == '-') {
      newZoom--;
    }
    this.map.setZoom(newZoom);
    if (callback != undefined) {
      this.loadedCallback(callback);
    }
  }

  /*
   * zooms map to fully zoomed in
   */
  GMap.prototype.zoomMax = function (callback) {
    this.map.setZoom(this.mapoptions.maxzoom);
    if (callback != undefined) {
      this.loadedCallback(callback);
    }
  }

  /*
   * zooms map to fully zoomed out
   */
  GMap.prototype.zoomMin = function (callback) {
    this.map.setZoom(this.mapoptions.minzoom);
    if (callback != undefined) {
      this.loadedCallback(callback);
    }
  }

  /*
   * zooms map to contain the given box as per gmaps southwest / northeast corner specs
   */
  GMap.prototype.boxZoom = function (latfrom, latto, lngfrom, lngto) {
    var bottomleft = {lat: latfrom, lng: lngfrom};
    var topright = {lat: latto, lng: lngto};
    var box = new google.maps.LatLngBounds(bottomleft, topright);
    this.map.fitBounds(box);
  }

  /*
   * forces zoom in to min max params and returns true if it has been constrained
   * additional callback if required for when zoom to constraints has finished
   */
  GMap.prototype.constrainzoom = function (callback) {
    if (this.map.getZoom() > this.mapoptions.maxzoom) {
      this.map.setZoom(this.mapoptions.maxzoom);
    } else if (this.map.getZoom() < this.mapoptions.minzoom) {
      this.map.setZoom(this.mapoptions.minzoom);
    } else {
      return false;
    }
    if (callback != undefined) {
      this.loadedCallback(callback);
    }
    return true;
  }

  /*add extras to generic map object*/
  google.maps.Map.prototype.clearMarkers = function () {
    for (var i = 0; i < this.markers.length; i++) {
      this.markers[i].setMap(null);
    }
    this.markers = new Array();
  };
  /*
   * places an existing div by id as a map control
   */
  GMap.prototype.addcontrol = function (divid, posn) {
    if (posn == undefined) {
      posn = google.maps.ControlPosition.TOP_LEFT;
    }
    this.map.controls[posn].push(document.getElementById(divid));
  }
  /* translate normal functions to internal map object */
  /* trigger setup */
  this.__construct(mapId, options);
}
Datadimension
  • 872
  • 1
  • 12
  • 31