phpDocumentor GoogleMapAPI
[ class tree: GoogleMapAPI ] [ index: GoogleMapAPI ] [ all elements ]

Source for file GoogleMap.php

Documentation is available at GoogleMap.php

  1. <?php
  2. /*
  3.  * Project:     GoogleMapAPI V3: a PHP library inteface to the Google Map API v3
  4.  * File:        GoogleMapV3.php
  5.  * 
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  *
  20.  * ORIGINAL INFO
  21.  * link http://www.phpinsider.com/php/code/GoogleMapAPI/
  22.  * copyright 2005 New Digital Group, Inc.
  23.  * author Monte Ohrt <monte at ohrt dot com>
  24.  * package GoogleMapAPI
  25.  * version 2.5
  26.  * 
  27.  * REVISION NOTIFICATION
  28.  * NOTE: This is a modified version of the original listed above.  This version
  29.  * maintains all original GNU software licenses.
  30.  */
  31. /**
  32.  * @link http://code.google.com/p/php-google-map-api/
  33.  * @copyright 2010 Brad wedell
  34.  * @author Brad Wedell
  35.  * @package GoogleMapAPI (version 3)
  36.  * @version 3.0beta
  37. */
  38. /*
  39.  * To view the full CHANGELOG, visit 
  40.  * http://code.google.com/p/php-google-map-api/wiki/ChangeLog3
  41. /*
  42. For database caching, you will want to use this schema:
  43.  
  44. CREATE TABLE GEOCODES (
  45.   address varchar(255) NOT NULL default '',
  46.   lon float default NULL,
  47.   lat float default NULL,
  48.   PRIMARY KEY  (address)
  49. );
  50.  
  51. */
  52.  
  53. /**
  54.  * PHP Google Maps API class
  55.  * @package GoogleMapAPI
  56.  * @version 3.0beta
  57.  */
  58. class GoogleMapAPI {
  59.  
  60.     /**
  61.      * PEAR::DB DSN for geocode caching. example:
  62.      * $dsn = 'mysql://user:pass@localhost/dbname';
  63.      *
  64.      * @var string 
  65.      */
  66.     var $dsn = null;
  67.     
  68.     /**
  69.      * current map id, set when you instantiate
  70.      * the GoogleMapAPI object.
  71.      *
  72.      * @var string 
  73.      */
  74.     var $map_id = null;
  75.     
  76.     /**
  77.      * determines whether or not to display the map and associated JS on the page
  78.      * this is used if you just want to display a streetview with no map
  79.      */
  80.     var $display_map = true;
  81.  
  82.     /**
  83.      * sidebar <div> used along with this map.
  84.      *
  85.      * @var string 
  86.      */
  87.     var $sidebar_id = null;    
  88.     
  89.     /**
  90.      * Whether to use new V3 mobile functionality
  91.      *
  92.      * @var bool 
  93.      */
  94.     var $mobile=false;
  95.     
  96.     /**
  97.      * DEPRECATED: Google now has geocoding service.
  98.      * NOTE: Note even sure if this still works
  99.      * GoogleMapAPI used to use the Yahoo geocode lookup API.
  100.      * This is the application ID for YOUR application.
  101.      * This is set upon instantiating the GoogleMapAPI object.
  102.      * (http://developer.yahoo.net/faq/index.html#appid)
  103.      *
  104.      * @var string 
  105.      */
  106.     var $app_id = null;
  107.  
  108.     /**
  109.      * use onLoad() to load the map javascript.
  110.      * if enabled, be sure to include on your webpage:
  111.      * <?=$mapobj->printOnLoad?> or manually create an onload function
  112.      * that calls the map's onload function using $this->printOnLoadFunction
  113.      *
  114.      * @var bool 
  115.      * @default true
  116.      */
  117.     var $onload = true;
  118.     
  119.     /**
  120.      * map center latitude (horizontal)
  121.      * calculated automatically as markers
  122.      * are added to the map.
  123.      *
  124.      * @var float 
  125.      */
  126.     var $center_lat = null;
  127.  
  128.     /**
  129.      * map center longitude (vertical)
  130.      * calculated automatically as markers
  131.      * are added to the map.
  132.      *
  133.      * @var float 
  134.      */
  135.     var $center_lon = null;
  136.     
  137.     /**
  138.      * enables map controls (zoom/move/center)
  139.      *
  140.      * @var bool 
  141.      */
  142.     var $map_controls = true;
  143.  
  144.     /**
  145.      * determines the map control type
  146.      * small -> show move/center controls
  147.      * large -> show move/center/zoom controls
  148.      *
  149.      * @var string 
  150.      */
  151.     var $control_size = 'large';
  152.     
  153.     /**
  154.      * enables map type controls (map/satellite/hybrid/terrain)
  155.      *
  156.      * @var bool 
  157.      */
  158.     var $type_controls = true;
  159.     
  160.     /**
  161.      * determines unit system to use for directions, blank = default
  162.      * @var string (METRIC, IMPERIAL)
  163.      */
  164.     var $directions_unit_system = '';
  165.     
  166.     /**
  167.      * sets default option for type controls(DEFAULT, HORIZONTAL_BAR, DROPDOWN_MENU)
  168.      *
  169.      * @var string 
  170.      */
  171.      var $type_controls_style = "DEFAULT";
  172.  
  173.     /**
  174.      * default map type google.maps.MapTypeId.(ROADMAP, SATELLITE, HYBRID, TERRAIN)
  175.      *
  176.      * @var string 
  177.      */
  178.     var $map_type = 'HYBRID';
  179.     
  180.     /**
  181.      * enables scale map control
  182.      *
  183.      * @var bool 
  184.      */
  185.     var $scale_control = true;
  186.     /**
  187.       * class variable to control scrollwheel
  188.       * @var bool 
  189.       */
  190.     var $scrollwheel = true
  191.     
  192.     /**
  193.      * enables overview map control
  194.      *
  195.      * @var bool 
  196.      */
  197.     var $overview_control = false;
  198.     
  199.     /**
  200.      * enables Google Adsense Adsmanager on page, not currently supported in beta
  201.      *
  202.      * @var bool 
  203.      */
  204.     var $ads_manager = false;
  205.     
  206.     /**
  207.      * Google Adsense Publisher ID
  208.      *
  209.      * @var string 
  210.      */
  211.     var $ads_pub_id = "";  
  212.     
  213.     /**
  214.      * Google Adsense Channel ID
  215.      *
  216.      * @var string 
  217.      */
  218.     var $ads_channel = "";
  219.     
  220.     /**
  221.      * The Max number of Adsmanager ads to show on a map
  222.      *
  223.      * @var int 
  224.      */
  225.     var $ads_max = 10;
  226.     
  227.     /**
  228.      * enables/disables local search on page
  229.      *
  230.      * @var bool 
  231.      */
  232.     var $local_search = false;
  233.     
  234.     /**
  235.      * enables local search ads on page NOTE: will only display ads if local_search == true, otherwise just use ad_manager and settings.
  236.      *
  237.      * @var bool 
  238.      */
  239.     var $local_search_ads = false;
  240.     
  241.     /**
  242.      * enables/disables walking directions option
  243.      *
  244.      * @var bool 
  245.      */
  246.     var $walking_directions = false;
  247.     
  248.     /**
  249.      * enables/disables biking directions on directions
  250.      *
  251.      * @var bool 
  252.      */
  253.     var $biking_directions = false;
  254.     
  255.     /**
  256.      * enables/disables avoid highways on directions
  257.      *
  258.      * @var bool 
  259.      */
  260.     var $avoid_highways = false;
  261.     
  262.     /**
  263.      * determines if avoid tollways is used in directions
  264.      *
  265.      * @var bool 
  266.      */
  267.     var $avoid_tollways = false;    
  268.      
  269.     /**
  270.      * determines the default zoom level
  271.      *
  272.      * @var int 
  273.      */
  274.     var $zoom = 16;
  275.  
  276.     /**
  277.      * determines the map width
  278.      *
  279.      * @var string 
  280.      */
  281.     var $width = '500px';
  282.     
  283.     /**
  284.      * determines the map height
  285.      *
  286.      * @var string 
  287.      */
  288.     var $height = '500px';
  289.  
  290.     /**
  291.      * message that pops up when the browser is incompatible with Google Maps.
  292.      * set to empty string to disable.
  293.      *
  294.      * @var string 
  295.      */
  296.     var $browser_alert = 'Sorry, the Google Maps API is not compatible with this browser.';
  297.     
  298.     /**
  299.      * message that appears when javascript is disabled.
  300.      * set to empty string to disable.
  301.      *
  302.      * @var string 
  303.      */
  304.     var $js_alert = '<b>Javascript must be enabled in order to use Google Maps.</b>';
  305.  
  306.     /**
  307.      * determines if sidebar is enabled
  308.      *
  309.      * @var bool 
  310.      */
  311.     var $sidebar = true;    
  312.  
  313.     /**
  314.      * determines if to/from directions are included inside info window
  315.      * 
  316.      * @var bool 
  317.      * @deprecated
  318.      */
  319.     var $directions = true;
  320.  
  321.     /**
  322.      * determines if map markers bring up an info window
  323.      *
  324.      * @var bool 
  325.      */
  326.     var $info_window = true;    
  327.     
  328.     /**
  329.      * determines if info window appears with a click or mouseover
  330.      *
  331.      * @var string click/mouseover
  332.      */
  333.     var $window_trigger = 'click';    
  334.     
  335.     /**
  336.      * determines whether or not to use the MarkerClusterer plugin
  337.      */
  338.      var $marker_clusterer = false;
  339.      
  340.      /**
  341.      * set default marker clusterer *webserver* file location
  342.      */
  343.      var $marker_clusterer_location = "/MarkerClusterer-1.0/markerclusterer_compiled.js";
  344.      
  345.      /**
  346.      * set default marker clusterer options
  347.      */
  348.      var $marker_clusterer_options = array(
  349.          "maxZoom"=>"null",
  350.         "gridSize"=>"null",
  351.         "styles"=>"null"
  352.      );
  353.     
  354.     /**
  355.      * determines if traffic overlay is displayed on map
  356.      *
  357.      * @var bool 
  358.      */
  359.     var $traffic_overlay = false;
  360.     
  361.     /**
  362.      * determines if biking overlay is displayed on map
  363.      *
  364.      * @var bool 
  365.      */
  366.     var $biking_overlay = false;   
  367.     
  368.     /**
  369.      * determines whether or not to display street view controls
  370.      */
  371.     var $street_view_controls = false;
  372.     
  373.     /**
  374.      * ID of the container that will hold a street view if streetview controls = true.
  375.      */
  376.     var $street_view_dom_id = "";
  377.     
  378.     /**
  379.      * what server geocode lookups come from
  380.      *
  381.      * available: YAHOO  Yahoo! API. US geocode lookups only.
  382.      *            GOOGLE Google Maps. This can do international lookups,
  383.      *                   but not an official API service so no guarantees.
  384.      *            Note: GOOGLE is the default lookup service, please read
  385.      *                  the Yahoo! terms of service before using their API.
  386.      *
  387.      * @var string service name
  388.      */
  389.     var $lookup_service = 'GOOGLE';
  390.     var $lookup_server = array('GOOGLE' => 'maps.google.com''YAHOO' => 'api.local.yahoo.com');
  391.     
  392.     /**
  393.      * 
  394.      * @var array 
  395.      * @deprecated
  396.      */
  397.     var $driving_dir_text = array(
  398.             'dir_to' => 'Start address: (include addr, city st/region)',
  399.             'to_button_value' => 'Get Directions',
  400.             'to_button_type' => 'submit',
  401.             'dir_from' => 'End address: (include addr, city st/region)',
  402.             'from_button_value' => 'Get Directions',
  403.             'from_button_type' => 'submit',
  404.             'dir_text' => 'Directions: ',
  405.             'dir_tohere' => 'To here',
  406.             'dir_fromhere' => 'From here'
  407.             );             
  408.                
  409.     
  410.     /**
  411.      * version number
  412.      *
  413.      * @var string 
  414.      */
  415.     var $_version = '3.0beta';
  416.  
  417.     /**
  418.      * list of added markers
  419.      *
  420.      * @var array 
  421.      */
  422.     var $_markers = array();
  423.     
  424.     /**
  425.      * maximum longitude of all markers
  426.      * 
  427.      * @var float 
  428.      */
  429.     var $_max_lon = -1000000;
  430.     
  431.     /**
  432.      * minimum longitude of all markers
  433.      *
  434.      * @var float 
  435.      */
  436.     var $_min_lon = 1000000;
  437.     
  438.     /**
  439.      * max latitude
  440.      *
  441.      * @var float 
  442.      */
  443.     var $_max_lat = -1000000;
  444.     
  445.     /**
  446.      * min latitude
  447.      *
  448.      * @var float 
  449.      */
  450.     var $_min_lat = 1000000;
  451.     
  452.     /**
  453.      * determines if we should zoom to minimum level (above this->zoom value) that will encompass all markers
  454.      *
  455.      * @var bool 
  456.      */
  457.     var $zoom_encompass = true;
  458.  
  459.     /**
  460.      * factor by which to fudge the boundaries so that when we zoom encompass, the markers aren't too close to the edge
  461.      *
  462.      * @var float 
  463.      */
  464.     var $bounds_fudge = 0.01;
  465.  
  466.     /**
  467.      * use the first suggestion by a google lookup if exact match not found
  468.      *
  469.      * @var float 
  470.      */
  471.     var $use_suggest = false;
  472.  
  473.     
  474.     /**
  475.      * list of added polylines
  476.      *
  477.      * @var array 
  478.      */
  479.     var $_polylines = array();
  480.     
  481.     /**
  482.      * list of polylines that should have an elevation profile rendered.
  483.      */
  484.     var $_elevation_polylines = array();
  485.     
  486.     /**
  487.      * determines whether or not to display a marker on the "line" when
  488.      * mousing over the elevation chart
  489.      */
  490.     var $elevation_markers = true;
  491.     
  492.     /**
  493.      * determines whether or not to display an elevation chart
  494.      * for directions that are added to the map.
  495.      */
  496.     var $elevation_directions = false;
  497.         
  498.     /**
  499.      * icon info array
  500.      *
  501.      * @var array 
  502.      * @deprecated
  503.      * @version 2.5
  504.      */
  505.     var $_icons = array();  
  506.        
  507.     /**
  508.      * marker icon info array
  509.      *
  510.      * @var array 
  511.      * @version 3.0
  512.      */
  513.     var $_marker_icons = array();
  514.     
  515.     /**
  516.      * Default icon image location.
  517.      *
  518.      * @var string 
  519.      */
  520.     var $default_icon = "";
  521.     
  522.     /**
  523.      * Default icon shadow image location.
  524.      *
  525.      * @var string 
  526.      */
  527.     var $default_icon_shadow = "";
  528.     
  529.     /**
  530.      * list of added overlays
  531.      *
  532.      * @var array 
  533.      */
  534.     var $_overlays = array();
  535.     
  536.     /**
  537.      * list of added kml overlays
  538.      */
  539.     var $_kml_overlays = array();
  540.         
  541.  
  542.     /**
  543.      * database cache table name
  544.      *
  545.      * @var string 
  546.      */
  547.     var $_db_cache_table = 'GEOCODES';
  548.     
  549.     /**
  550.      * Class variable that will store generated header code for JS to display directions
  551.      *
  552.      * @var string 
  553.      */
  554.     var $_directions_header = '';
  555.     
  556.     /**
  557.      * Class variable that will store information to render directions
  558.      */
  559.     var $_directions = array();
  560.     
  561.     /**
  562.      * Class variable to store whether or not to display JS functions in the header
  563.      */
  564.     var $_display_js_functions = true;
  565.     
  566.     /**
  567.      * Class variable that will store flag to minify js - this can be overwritten after object is instantiated.  Include JSMin.php if
  568.      * you want to use JS Minification.
  569.      *
  570.      * @var bool 
  571.      */
  572.      var $_minify_js = true;
  573.         
  574.     /**
  575.      * class constructor
  576.      *
  577.      * @param string $map_id the DOM element ID for the map
  578.      * @param string $app_id YOUR Yahoo App ID
  579.      */
  580.     function GoogleMapAPI($map_id 'map'$app_id 'MyMapApp'{
  581.         $this->map_id = $map_id;
  582.         $this->sidebar_id = 'sidebar_' $map_id;
  583.         $this->app_id = $app_id;
  584.     }
  585.     
  586.     /**
  587.      * function to enable map display
  588.      */
  589.     function enableMapDisplay(){
  590.         $this->display_map = true;
  591.     }
  592.     
  593.     /**
  594.      * function to disable map display (used to display street view only)
  595.      */
  596.     function disableMapDisplay(){
  597.         $this->display_map = true;
  598.     }
  599.     
  600.     /**
  601.      * sets the PEAR::DB dsn
  602.      *
  603.      * @param string $dsn Takes the form of "mysql://user:pass@localhost/db_name"
  604.      */
  605.     function setDSN($dsn{
  606.         $this->dsn = $dsn;   
  607.     }
  608.     
  609.     /**
  610.      * sets the width of the map
  611.      *
  612.      * @param string $width 
  613.      * @return string|falseWidth or false if not a valid value
  614.      */
  615.     function setWidth($width{
  616.         if(!preg_match('!^(\d+)(.*)$!',$width,$_match))
  617.             return false;
  618.  
  619.         $_width $_match[1];
  620.         $_type $_match[2];
  621.         if($_type == '%')
  622.             $this->width = $_width '%';
  623.         else
  624.             $this->width = $_width 'px';
  625.         
  626.         return true;
  627.     }
  628.  
  629.     /**
  630.      * sets the height of the map
  631.      *
  632.      * @param string $height 
  633.      * @return string|falseHeight or false if not a valid value
  634.      */
  635.     function setHeight($height{
  636.         if(!preg_match('!^(\d+)(.*)$!',$height,$_match))
  637.             return false;
  638.  
  639.         $_height $_match[1];
  640.         $_type $_match[2];
  641.         if($_type == '%')
  642.             $this->height = $_height '%';
  643.         else
  644.             $this->height = $_height 'px';
  645.         
  646.         return true;
  647.     }  
  648.           
  649.  
  650.     /**
  651.      * sets the default map zoom level
  652.      *
  653.      * @param string $level Initial zoom level value
  654.      */
  655.     function setZoomLevel($level{
  656.         $this->zoom = (int) $level;
  657.     }    
  658.             
  659.     /**
  660.      * enables the map controls (zoom/move)
  661.      *
  662.      */
  663.     function enableMapControls({
  664.         $this->map_controls = true;
  665.     }
  666.  
  667.     /**
  668.      * disables the map controls (zoom/move)
  669.      *
  670.      */
  671.     function disableMapControls({
  672.         $this->map_controls = false;
  673.     
  674.     
  675.     /**
  676.      * sets the map control size (large/small)
  677.      *
  678.      * @param string $size Large/Small
  679.      */
  680.     function setControlSize($size{
  681.         if(in_array($size,array('large','small')))
  682.             $this->control_size = $size;
  683.     }            
  684.  
  685.     /**
  686.      * disable mouse scrollwheel on Map
  687.      */
  688.     function disableScrollWheel(){
  689.         $this->scrollwheel = false;
  690.     
  691.  
  692.      /**
  693.      * enables the type controls (map/satellite/hybrid)
  694.      *
  695.      */
  696.     function enableLocalSearch({
  697.         $this->local_search = true;
  698.     }
  699.  
  700.     /**
  701.      * disables the type controls (map/satellite/hybrid)
  702.      *
  703.      */
  704.     function disableLocalSearch({
  705.         $this->local_search = false;
  706.     }
  707.     
  708.     /**
  709.      * enables the type controls (map/satellite/hybrid)
  710.      *
  711.      */
  712.     function enableLocalSearchAds({
  713.         $this->local_search_ads = true;
  714.     }
  715.  
  716.     /**
  717.      * disables the type controls (map/satellite/hybrid)
  718.      *
  719.      */
  720.     function disableLocalSearchAds({
  721.         $this->local_search_ads = false;
  722.     }
  723.     
  724.     /**
  725.      * enables walking directions
  726.      * 
  727.      */
  728.     function enableWalkingDirections({
  729.         $this->walking_directions = true;
  730.     }
  731.  
  732.     /**
  733.      * disables walking directions
  734.      * 
  735.      */
  736.     function disableWalkingDirections({
  737.         $this->walking_directions = false;
  738.     }
  739.     
  740.     /**
  741.      * enables biking directions
  742.      * 
  743.      */
  744.     function enableBikingDirections({
  745.         $this->biking_directions = true;
  746.     }
  747.  
  748.     /**
  749.      * disables biking directions
  750.      * 
  751.      */
  752.     function disableBikingDirections({
  753.         $this->biking_directions = false;
  754.     }
  755.     
  756.     /**
  757.      * enables avoid highways in directions
  758.      * 
  759.      */
  760.     function enableAvoidHighways({
  761.         $this->avoid_highways = true;
  762.     }
  763.  
  764.     /**
  765.      * disables avoid highways in directions
  766.      * 
  767.      */
  768.     function disableAvoidHighways({
  769.         $this->avoid_highways = false;
  770.     }
  771.     
  772.     /**
  773.      * enables avoid tolls in directions
  774.      * 
  775.      */
  776.     function enableAvoidTolls({
  777.         $this->avoid_tolls true;
  778.     }
  779.  
  780.     /**
  781.      * disables avoid tolls in directions
  782.      * 
  783.      */
  784.     function disableAvoidTolls({
  785.         $this->avoid_tolls false;
  786.     }
  787.     
  788.     /**
  789.      * Add directions route to the map and adds text directions container with id=$dom_id
  790.      *
  791.      * @param string $start_address 
  792.      * @param string $dest_address 
  793.      * @param string $dom_id DOM Element ID for directions container.
  794.      * @param bool $add_markers Add a marker at start and dest locations.
  795.      */
  796.     function addDirections($start_address='',$dest_address='',$dom_id=''$add_markers=true$elevation_samples=256$elevation_width=""$elevation_height=""$elevation_dom_id=''){
  797.         if($elevation_dom_id=="")
  798.             $elevation_dom_id "elevation".$dom_id;
  799.         
  800.         if($start_address != '' && $dest_address != '' && $dom_id != ''){
  801.             $this->_directions[$dom_idarray(
  802.                 "dom_id"=>$dom_id,
  803.                 "start"=>$start_address,
  804.                 "dest"=>$dest_address,
  805.                 "markers"=>true,
  806.                 "elevation_samples"=>$elevation_samples,
  807.                 "width"=>($elevation_width!=""?$elevation_width:str_replace("px","",$this->width)),
  808.                 "height"=>($elevation_height!=""?$elevation_height:str_replace("px","",$this->height)/2),
  809.                 "elevation_dom_id"=>$elevation_dom_id
  810.             );            
  811.             if($add_markers==true){
  812.                 $this->addMarkerByAddress($start_address,$start_address$start_address);
  813.                 $this->addMarkerByAddress($dest_address,$dest_address$dest_address);
  814.             
  815.         }
  816.     }
  817.         
  818.     /**
  819.      * enables the type controls (map/satellite/hybrid)
  820.      *
  821.      */
  822.     function enableTypeControls({
  823.         $this->type_controls = true;
  824.     }
  825.  
  826.     /**
  827.      * disables the type controls (map/satellite/hybrid)
  828.      *
  829.      */
  830.     function disableTypeControls({
  831.         $this->type_controls = false;
  832.     }
  833.     
  834.     /**
  835.      * sets map control style
  836.      */
  837.     function setTypeControlsStyle($type){
  838.         switch($type){
  839.             case "dropdown":
  840.                 $this->type_controls_style = "DROPDOWN_MENU";
  841.                 break;
  842.             case "horizontal":
  843.                 $this->type_controls_style = "HORIZONTAL_BAR";
  844.                 break;
  845.             default:
  846.                 $this->type_controls_style = "DEFAULT";
  847.                 break;
  848.         }
  849.     }
  850.     
  851.     /**
  852.      * set default map type (map/satellite/hybrid)
  853.      *
  854.      * @param string $type New V3 Map Types, only include ending word (HYBRID,SATELLITE,TERRAIN,ROADMAP)
  855.      */
  856.     function setMapType($type{
  857.         switch($type{
  858.             case 'hybrid':
  859.                 $this->map_type = 'HYBRID';
  860.                 break;
  861.             case 'satellite':
  862.                 $this->map_type = 'SATELLITE';
  863.                 break;
  864.             case 'terrain':
  865.                 $this->map_type = 'TERRAIN';
  866.                 break;
  867.             case 'map':
  868.             default:
  869.                 $this->map_type = 'ROADMAP';
  870.                 break;
  871.         }       
  872.     }       
  873.         
  874.     /**
  875.      * enables onload
  876.      *
  877.      */
  878.     function enableOnLoad({
  879.         $this->onload = true;
  880.     }
  881.  
  882.     /**
  883.      * disables onload
  884.      *
  885.      */
  886.     function disableOnLoad({
  887.         $this->onload = false;
  888.     }
  889.     
  890.     /**
  891.      * enables sidebar
  892.      *
  893.      */
  894.     function enableSidebar({
  895.         $this->sidebar = true;
  896.     }
  897.  
  898.     /**
  899.      * disables sidebar
  900.      *
  901.      */
  902.     function disableSidebar({
  903.         $this->sidebar = false;
  904.     }    
  905.  
  906.     /**
  907.      * enables map directions inside info window
  908.      *
  909.      */
  910.     function enableDirections({
  911.         $this->directions = true;
  912.     }
  913.  
  914.     /**
  915.      * disables map directions inside info window
  916.      *
  917.      */
  918.     function disableDirections({
  919.         $this->directions = false;
  920.     }    
  921.         
  922.     /**
  923.      * set browser alert message for incompatible browsers
  924.      *
  925.      * @param string $message 
  926.      */
  927.     function setBrowserAlert($message{
  928.         $this->browser_alert = $message;
  929.     }
  930.  
  931.     /**
  932.      * set <noscript> message when javascript is disabled
  933.      *
  934.      * @param string $message 
  935.      */
  936.     function setJSAlert($message{
  937.         $this->js_alert = $message;
  938.     }
  939.     
  940.     /**
  941.      * enable traffic overlay
  942.      */
  943.     function enableTrafficOverlay({
  944.         $this->traffic_overlaytrue;
  945.     }
  946.     
  947.     /**
  948.      * disable traffic overlay (default)
  949.      */
  950.     function disableTrafficOverlay({
  951.         $this->traffic_overlayfalse;
  952.     }
  953.     
  954.     /**
  955.      * enable biking overlay
  956.      */
  957.     function enableBikingOverlay({
  958.         $this->biking_overlaytrue;
  959.     }
  960.     
  961.     /**
  962.      * disable biking overlay (default)
  963.      */
  964.     function disableBikingOverlay({
  965.         $this->biking_overlayfalse;
  966.     }
  967.     
  968.     /**
  969.      * enable biking overlay
  970.      */
  971.     function enableStreetViewControls({
  972.         $this->street_view_controlstrue;
  973.     }
  974.     
  975.     /**
  976.      * disable biking overlay (default)
  977.      */
  978.     function disableStreetViewControls({
  979.         $this->street_view_controlsfalse;
  980.     }
  981.     
  982.     /**
  983.      * attach a dom id object as a streetview container to the map
  984.      * NOTE: Only one container can be attached to a map.
  985.      **/
  986.  
  987.     function attachStreetViewContainer($dom_id){
  988.         $this->street_view_dom_id = $dom_id;
  989.     }
  990.     
  991.     /**
  992.      * enable Google Adsense admanager on Map (not supported in V3 API)
  993.      */
  994.     function enableAds(){
  995.         $this->ads_manager = true
  996.     }
  997.     
  998.     /**
  999.      * disable Google Adsense admanager on Map (not supported in V3 API)
  1000.      */
  1001.     function disableAds(){
  1002.         $this->ads_manager = false
  1003.     }
  1004.     
  1005.  
  1006.     /**
  1007.      * enable map marker info windows
  1008.      */
  1009.     function enableInfoWindow({
  1010.         $this->info_window = true;
  1011.     }
  1012.     
  1013.     /**
  1014.      * disable map marker info windows
  1015.      */
  1016.     function disableInfoWindow({
  1017.         $this->info_window = false;
  1018.     }
  1019.     
  1020.     /**
  1021.      * enable elevation marker to be displayed
  1022.      */
  1023.      function enableElevationMarker(){
  1024.          $this->elevation_markers = true;
  1025.      }
  1026.      
  1027.      /**
  1028.      * disable elevation marker
  1029.      */
  1030.      function disableElevationMarker(){
  1031.          $this->elevation_markers = false;
  1032.      }
  1033.      
  1034.      /**
  1035.      * enable elevation to be displayed for directions
  1036.      */
  1037.      function enableElevationDirections(){
  1038.          $this->elevation_directions = true;
  1039.      }
  1040.      
  1041.      /**
  1042.      * disable elevation to be displayed for directions
  1043.      */
  1044.      function disableElevationDirections(){
  1045.          $this->elevation_directions = false;
  1046.      }
  1047.     
  1048.     /**
  1049.      * enable map marker clustering
  1050.      */
  1051.     function enableClustering({
  1052.         $this->marker_clusterer = true;
  1053.     }
  1054.     
  1055.     /**
  1056.      * disable map marker clustering
  1057.      */
  1058.     function disableClustering({
  1059.         $this->marker_clusterer = false;
  1060.     }
  1061.     
  1062.     /**
  1063.      * set clustering options
  1064.      */
  1065.     function setClusterOptions($zoom="null"$gridsize="null"$styles="null"){
  1066.         $this->marker_clusterer_options["maxZoom"]=$zoom;
  1067.         $this->marker_clusterer_options["gridSize"]=$gridsize;
  1068.         $this->marker_clusterer_options["styles"]=$styles;
  1069.     }   
  1070.  
  1071.     /**
  1072.      * Set clustering library file location
  1073.      */
  1074.     function setClusterLocation($file){
  1075.         $this->marker_clusterer_location=$file;
  1076.     }
  1077.     
  1078.     /**
  1079.      * set the info window trigger action
  1080.      *
  1081.      * @param string $message click/mouseover
  1082.      */
  1083.     function setInfoWindowTrigger($type{
  1084.         switch($type{
  1085.             case 'mouseover':
  1086.                 $this->window_trigger = 'mouseover';
  1087.                 break;
  1088.             default:
  1089.                 $this->window_trigger = 'click';
  1090.                 break;
  1091.             }
  1092.     }
  1093.  
  1094.     /**
  1095.      * enable zoom to encompass makers
  1096.      */
  1097.     function enableZoomEncompass({
  1098.         $this->zoom_encompass = true;
  1099.     }
  1100.     
  1101.     /**
  1102.      * disable zoom to encompass makers
  1103.      */
  1104.     function disableZoomEncompass({
  1105.         $this->zoom_encompass = false;
  1106.     }
  1107.  
  1108.     /**
  1109.      * set the boundary fudge factor
  1110.      * @param float 
  1111.      */
  1112.     function setBoundsFudge($val{
  1113.         $this->bounds_fudge = $val;
  1114.     }
  1115.     
  1116.     /**
  1117.      * enables the scale map control
  1118.      *
  1119.      */
  1120.     function enableScaleControl({
  1121.         $this->scale_control = true;
  1122.     }
  1123.  
  1124.     /**
  1125.      * disables the scale map control
  1126.      *
  1127.      */
  1128.     function disableScaleControl({
  1129.         $this->scale_control = false;
  1130.     }    
  1131.             
  1132.     /**
  1133.      * enables the overview map control
  1134.      *
  1135.      */
  1136.     function enableOverviewControl({
  1137.         $this->overview_control = true;
  1138.     }
  1139.  
  1140.     /**
  1141.      * disables the overview map control
  1142.      *
  1143.      */
  1144.     function disableOverviewControl({
  1145.         $this->overview_control = false;
  1146.      }    
  1147.     
  1148.     
  1149.     /**
  1150.      * set the lookup service to use for geocode lookups
  1151.      * default is YAHOO, you can also use GOOGLE.
  1152.      * NOTE: GOOGLE can to intl lookups, but is not an
  1153.      * official API, so use at your own risk.
  1154.      *
  1155.      * @param string $service 
  1156.      * @deprecated
  1157.      */
  1158.     function setLookupService($service{
  1159.         switch($service{
  1160.             case 'GOOGLE':
  1161.                 $this->lookup_service = 'GOOGLE';
  1162.                 break;
  1163.             case 'YAHOO':
  1164.             default:
  1165.                 $this->lookup_service = 'YAHOO';
  1166.                 break;
  1167.         }       
  1168.     }
  1169.     
  1170.         
  1171.     /**
  1172.      * adds a map marker by address - DEPRECATION WARNING: Tabs are no longer supported in V3, if this changes this can be easily updated.
  1173.      * 
  1174.      * @param string $address the map address to mark (street/city/state/zip)
  1175.      * @param string $title the title display in the sidebar
  1176.      * @param string $html the HTML block to display in the info bubble (if empty, title is used)
  1177.      * @param string $tooltip Tooltip to display (deprecated?)
  1178.      * @param string $icon_filename Web file location (eg http://somesite/someicon.gif) to use for icon
  1179.      * @param string $icon_shadow_filename Web file location (eg http://somesite/someicon.gif) to use for icon shadow
  1180.      * @return int|bool
  1181.      */
  1182.     function addMarkerByAddress($address,$title '',$html '',$tooltip ''$icon_filename ''$icon_shadow_filename=''{
  1183.         if(($_geocode $this->getGeocode($address)) === false)
  1184.             return false;
  1185.         return $this->addMarkerByCoords($_geocode['lon'],$_geocode['lat'],$title,$html,$tooltip$icon_filename$icon_shadow_filename);
  1186.     }
  1187.  
  1188.     /**
  1189.      * adds a map marker by lat/lng coordinates - DEPRECATION WARNING: Tabs are no longer supported in V3, if this changes this can be easily updated.
  1190.      * 
  1191.      * @param string $lon the map longitude (horizontal)
  1192.      * @param string $lat the map latitude (vertical)
  1193.      * @param string $title the title display in the sidebar
  1194.      * @param string $html the HTML block to display in the info bubble (if empty, title is used)
  1195.      * @param string $tooltip Tooltip to display (deprecated?)
  1196.      * @param string $icon_filename Web file location (eg http://somesite/someicon.gif) to use for icon
  1197.      * @param string $icon_shadow_filename Web file location (eg http://somesite/someicon.gif) to use for icon shadow
  1198.      * @return int|bool
  1199.      */
  1200.     function addMarkerByCoords($lon,$lat,$title '',$html '',$tooltip ''$icon_filename ''$icon_shadow_filename=''{
  1201.         $_marker['lon'$lon;
  1202.         $_marker['lat'$lat;
  1203.         $_marker['html'(is_array($html|| strlen($html0$html $title;
  1204.         $_marker['title'$title;
  1205.         $_marker['tooltip'$tooltip;
  1206.         
  1207.         if($icon_filename!=""){
  1208.             $_marker['icon_key'$this->setMarkerIconKey($icon_filename$icon_shadow_filename);
  1209.             if($icon_shadow_filename!=""){
  1210.                $_marker['shadow_icon']=1;
  1211.             }   
  1212.         }else if$this->default_icon != ''){
  1213.             $_marker['icon_key'$this->setMarkerIconKey($this->default_icon$this->default_icon_shadow);
  1214.             if($this->default_icon_shadow!=""){
  1215.                $_marker['shadow_icon']=1;
  1216.             }
  1217.         }        
  1218.         $this->_markers[$_marker;
  1219.         $this->adjustCenterCoords($_marker['lon'],$_marker['lat']);
  1220.         // return index of marker
  1221.         return count($this->_markers1;
  1222.     }
  1223.     
  1224.     /**
  1225.      * adds a DOM object ID to specified marker to open the marker's info window.
  1226.      *   Does nothing if the info windows is disabled.
  1227.      * @param string $marker_id ID of the marker to associate to
  1228.      * @param string $dom_id ID of the DOM object to use to open marker info window
  1229.      * @return bool true/false status
  1230.      */
  1231.     function addMarkerOpener($marker_id$dom_id){
  1232.         if($this->info_window === false || !isset($this->_markers[$marker_id]))
  1233.            return false;
  1234.         if(!isset($this->_markers[$marker_id]["openers"]))
  1235.            $this->_markers[$marker_id]["openers"array();
  1236.         $this->_markers[$marker_id]["openers"][$dom_id;           
  1237.     }
  1238.     
  1239.     /**
  1240.      * adds polyline by passed array
  1241.      * if color, weight and opacity are not defined, use the google maps defaults
  1242.      * @param array $polyline_array array of lat/long coords
  1243.      * @param string $id An array id to use to append coordinates to a line
  1244.      * @param string $color the color of the line (format: #000000)
  1245.      * @param string $weight the weight of the line in pixels
  1246.      * @param string $opacity the line opacity (percentage)
  1247.      * @return bool|intArray id of newly added point or false
  1248.      */
  1249.     function addPolylineByCoordsArray($polyline_array,$id=false,$color='',$weight=0,$opacity=0){
  1250.         if(!is_array($polyline_array|| sizeof($polyline_array2)
  1251.            return false;
  1252.         $_prev_coords "";
  1253.         $_next_coords "";
  1254.         
  1255.         foreach($polyline_array as $_coords){
  1256.             $_prev_coords $_next_coords;
  1257.             $_next_coords $_coords;
  1258.             
  1259.             if($_prev_coords !== ""){
  1260.               $_lt1=$_prev_coords["lat"];
  1261.               $_ln1=$_prev_coords["long"];
  1262.               $_lt2=$_next_coords["lat"];
  1263.               $_ln2=$_next_coords["long"];
  1264.               $id $this->addPolyLineByCoords($_ln1$_lt1$_ln2$_lt2$id$color$weight$opacity);
  1265.             }
  1266.         }
  1267.         return $id;
  1268.     }
  1269.     
  1270.     /**
  1271.      * adds polyline by passed array
  1272.      * if color, weight and opacity are not defined, use the google maps defaults
  1273.      * @param array $polyline_array array of addresses
  1274.      * @param string $id An array id to use to append coordinates to a line
  1275.      * @param string $color the color of the line (format: #000000)
  1276.      * @param string $weight the weight of the line in pixels
  1277.      * @param string $opacity the line opacity (percentage)
  1278.      * @return bool|intArray id of newly added point or false
  1279.      */
  1280.     function addPolylineByAddressArray($polyline_array,$id=false,$color='',$weight=0,$opacity=0){
  1281.         if(!is_array($polyline_array|| sizeof($polyline_array2)
  1282.            return false;
  1283.         $_prev_address "";
  1284.         $_next_address "";
  1285.         
  1286.         foreach($polyline_array as $_address){
  1287.             $_prev_address $_next_address;
  1288.             $_next_address $_address;
  1289.             
  1290.             if($_prev_address !== ""){
  1291.               $id $this->addPolyLineByAddress($_prev_address$_next_address$id$color$weight$opacity);
  1292.             }
  1293.         }
  1294.         return $id;
  1295.     }
  1296.  
  1297.     /**
  1298.      * adds a map polyline by address
  1299.      * if color, weight and opacity are not defined, use the google maps defaults
  1300.      * 
  1301.      * @param string $address1 the map address to draw from
  1302.      * @param string $address2 the map address to draw to
  1303.      * @param string $id An array id to use to append coordinates to a line
  1304.      * @param string $color the color of the line (format: #000000)
  1305.      * @param string $weight the weight of the line in pixels
  1306.      * @param string $opacity the line opacity (percentage)
  1307.      * @return bool|intArray id of newly added point or false
  1308.      */
  1309.     function addPolyLineByAddress($address1,$address2,$id=false,$color='',$weight=0,$opacity=0{
  1310.         if(($_geocode1 $this->getGeocode($address1)) === false)
  1311.             return false;
  1312.         if(($_geocode2 $this->getGeocode($address2)) === false)
  1313.             return false;
  1314.         return $this->addPolyLineByCoords($_geocode1['lon'],$_geocode1['lat'],$_geocode2['lon'],$_geocode2['lat'],$id,$color,$weight,$opacity);
  1315.     }
  1316.  
  1317.     /**
  1318.      * adds a map polyline by map coordinates
  1319.      * if color, weight and opacity are not defined, use the google maps defaults
  1320.      * 
  1321.      * @param string $lon1 the map longitude to draw from
  1322.      * @param string $lat1 the map latitude to draw from
  1323.      * @param string $lon2 the map longitude to draw to
  1324.      * @param string $lat2 the map latitude to draw to
  1325.      * @param string $id An array id to use to append coordinates to a line
  1326.      * @param string $color the color of the line (format: #000000)
  1327.      * @param string $weight the weight of the line in pixels
  1328.      * @param string $opacity the line opacity (percentage)
  1329.      * @return string $id id of the created/updated polyline array
  1330.      */
  1331.     function addPolyLineByCoords($lon1,$lat1,$lon2,$lat2,$id=false,$color='',$weight=0,$opacity=0{
  1332.         if($id !== false && isset($this->_polylines[$id]&& is_array($this->_polylines[$id])){
  1333.             $_polyline $this->_polylines[$id];
  1334.         }else{
  1335.             //only set color,weight,and opacity if new polyline
  1336.             $_polyline array(
  1337.                 "color"=>$color,
  1338.                 "weight"=>$weight,
  1339.                 "opacity"=>$opacity
  1340.             );
  1341.         }
  1342.         if(!isset($_polyline['coords']|| !is_array($_polyline['coords'])){
  1343.             $_polyline['coords'array(
  1344.                 "0"=> array("lat"=>$lat1"long"=>$lon1),
  1345.                 "1"=> array("lat"=>$lat2"long"=>$lon2)
  1346.             );
  1347.         }else{
  1348.             $last_index sizeof($_polyline['coords'])-1;
  1349.             //check if lat1/lon1 point is already on polyline
  1350.             if($_polyline['coords'][$last_index]["lat"!= $lat1 || $_polyline['coords'][$last_index]["long"]  != $lon1){
  1351.                 $_polyline['coords'][array("lat"=>$lat1"long"=>$lon1);
  1352.             }
  1353.             $_polyline['coords'][array("lat"=>$lat2"long"=>$lon2);
  1354.         }
  1355.         if($id === false){
  1356.             $this->_polylines[$_polyline;
  1357.             $id count($this->_polylines1;
  1358.         }else{
  1359.             $this->_polylines[$id$_polyline;
  1360.         }
  1361.         $this->adjustCenterCoords($lon1,$lat1);
  1362.         $this->adjustCenterCoords($lon2,$lat2);
  1363.         // return index of polyline
  1364.         return $id;
  1365.     }
  1366.     
  1367.     /**
  1368.      * function to add an elevation profile for a polyline to the page
  1369.      */
  1370.      function addPolylineElevation($polyline_id$elevation_dom_id$samples=256$width=""$height=""$focus_color="#00ff00"){
  1371.         if(isset($this->_polylines[$polyline_id])){
  1372.             $this->_elevation_polylines[$polyline_idarray(
  1373.                 "dom_id"=>$elevation_dom_id,
  1374.                 "samples"=>$samples,
  1375.                 "width"=>($width!=""?$width:str_replace("px","",$this->width)),
  1376.                 "height"=>($height!=""?$height:str_replace("px","",$this->height)/2),
  1377.                 "focus_color"=>$focus_color
  1378.             );
  1379.         }
  1380.      }
  1381.     
  1382.     /**
  1383.      * function to add an overlay to the map.
  1384.      */
  1385.      function addOverlay($bds_lat1$bds_lon1$bds_lat2$bds_lon2$img_src$opacity 100){
  1386.          $_overlay array(
  1387.             "bounds" => array(
  1388.                 "ne"=>array(
  1389.                     "lat"=>$bds_lat1,
  1390.                     "long"=>$bds_lon1
  1391.                 ),
  1392.                 "sw"=>array(
  1393.                     "lat"=>$bds_lat2,
  1394.                     "long"=>$bds_lon2
  1395.                 )
  1396.             ),
  1397.             "img" => $img_src,
  1398.             "opacity" => $opacity/10
  1399.          );
  1400.          $this->adjustCenterCoords($bds_lon1,$bds_lat1);
  1401.          $this->adjustCenterCoords($bds_lon2,$bds_lat2);
  1402.          $this->_overlays[$_overlay;
  1403.          return count($this->_overlays)-1;
  1404.      }
  1405.      
  1406.      /**
  1407.       * function to add a KML overlay to the map.
  1408.       *  *Note that this expects a filename and file parsing/processing is done
  1409.       *  on the client side
  1410.       */
  1411.      function addKMLOverlay($file){
  1412.        $this->_kml_overlays[$file;
  1413.        return count($this->_kml_overlays)-1;
  1414.      }
  1415.         
  1416.     /**
  1417.      * adjust map center coordinates by the given lat/lon point
  1418.      * 
  1419.      * @param string $lon the map latitude (horizontal)
  1420.      * @param string $lat the map latitude (vertical)
  1421.      */
  1422.     function adjustCenterCoords($lon,$lat{
  1423.         if(strlen((string)$lon== || strlen((string)$lat== 0)
  1424.             return false;
  1425.         $this->_max_lon = (float) max($lon$this->_max_lon);
  1426.         $this->_min_lon = (float) min($lon$this->_min_lon);
  1427.         $this->_max_lat = (float) max($lat$this->_max_lat);
  1428.         $this->_min_lat = (float) min($lat$this->_min_lat);
  1429.         $this->center_lon = (float) ($this->_min_lon + $this->_max_lon2;
  1430.         $this->center_lat = (float) ($this->_min_lat + $this->_max_lat2;
  1431.         return true;
  1432.     }
  1433.  
  1434.     /**
  1435.      * set map center coordinates to lat/lon point
  1436.      * 
  1437.      * @param string $lon the map latitude (horizontal)
  1438.      * @param string $lat the map latitude (vertical)
  1439.      */
  1440.     function setCenterCoords($lon,$lat{
  1441.         $this->center_lat = (float) $lat;
  1442.         $this->center_lon = (float) $lon;
  1443.     }    
  1444.  
  1445.     /**
  1446.      * generate an array of params for a new marker icon image
  1447.      * iconShadowImage is optional
  1448.      * If anchor coords are not supplied, we use the center point of the image by default.
  1449.      * Can be called statically. For private use by addMarkerIcon() and setMarkerIcon() and addIcon()
  1450.      *
  1451.      * @param string $iconImage URL to icon image
  1452.      * @param string $iconShadowImage URL to shadow image
  1453.      * @param string $iconAnchorX X coordinate for icon anchor point
  1454.      * @param string $iconAnchorY Y coordinate for icon anchor point
  1455.      * @param string $infoWindowAnchorX X coordinate for info window anchor point
  1456.      * @param string $infoWindowAnchorY Y coordinate for info window anchor point
  1457.      * @return array Array with information about newly /previously created icon.
  1458.      */
  1459.     function createMarkerIcon($iconImage,$iconShadowImage '',$iconAnchorX 'x',$iconAnchorY 'x',$infoWindowAnchorX 'x',$infoWindowAnchorY 'x'{
  1460.         $_icon_image_path strpos($iconImage,'http'=== $iconImage $_SERVER['DOCUMENT_ROOT'$iconImage;
  1461.         if(!($_image_info @getimagesize($_icon_image_path))) {
  1462.             die('GoogleMapAPI:createMarkerIcon: Error reading image: ' $iconImage);   
  1463.         }
  1464.         if($iconShadowImage{
  1465.             $_shadow_image_path strpos($iconShadowImage,'http'=== $iconShadowImage $_SERVER['DOCUMENT_ROOT'$iconShadowImage;
  1466.             if(!($_shadow_info @getimagesize($_shadow_image_path))) {
  1467.                 die('GoogleMapAPI:createMarkerIcon: Error reading shadow image: ' $iconShadowImage);
  1468.             }
  1469.         }
  1470.         
  1471.         if($iconAnchorX === 'x'{
  1472.             $iconAnchorX = (int) ($_image_info[02);
  1473.         }
  1474.         if($iconAnchorY === 'x'{
  1475.             $iconAnchorY = (int) ($_image_info[12);
  1476.         }
  1477.         if($infoWindowAnchorX === 'x'{
  1478.             $infoWindowAnchorX = (int) ($_image_info[02);
  1479.         }
  1480.         if($infoWindowAnchorY === 'x'{
  1481.             $infoWindowAnchorY = (int) ($_image_info[12);
  1482.         }
  1483.                         
  1484.         $icon_info array(
  1485.                 'image' => $iconImage,
  1486.                 'iconWidth' => $_image_info[0],
  1487.                 'iconHeight' => $_image_info[1],
  1488.                 'iconAnchorX' => $iconAnchorX,
  1489.                 'iconAnchorY' => $iconAnchorY,
  1490.                 'infoWindowAnchorX' => $infoWindowAnchorX,
  1491.                 'infoWindowAnchorY' => $infoWindowAnchorY
  1492.                 );
  1493.         if($iconShadowImage{
  1494.             $icon_info array_merge($icon_infoarray('shadow' => $iconShadowImage,
  1495.                                                        'shadowWidth' => $_shadow_info[0],
  1496.                                                        'shadowHeight' => $_shadow_info[1]));
  1497.         }
  1498.         return $icon_info;
  1499.     }
  1500.     
  1501.     /**
  1502.      * set the default marker icon for ALL markers on the map
  1503.      * NOTE: This MUST be set prior to adding markers in order for the defaults
  1504.      * to be set correctly.
  1505.      * @param string $iconImage URL to icon image
  1506.      * @param string $iconShadowImage URL to shadow image
  1507.      * @param string $iconAnchorX X coordinate for icon anchor point
  1508.      * @param string $iconAnchorY Y coordinate for icon anchor point
  1509.      * @param string $infoWindowAnchorX X coordinate for info window anchor point
  1510.      * @param string $infoWindowAnchorY Y coordinate for info window anchor point
  1511.      * @return string A marker icon key.
  1512.      */
  1513.     function setMarkerIcon($iconImage,$iconShadowImage '',$iconAnchorX 'x',$iconAnchorY 'x',$infoWindowAnchorX 'x',$infoWindowAnchorY 'x'{
  1514.         $this->default_icon = $iconImage;
  1515.         $this->default_icon_shadow = $iconShadowImage;
  1516.         return $this->setMarkerIconKey($iconImage,$iconShadowImage,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY);       
  1517.     }
  1518.     
  1519.     /**
  1520.      * function to check if icon is in  class "marker_iconset", if it is,
  1521.      * returns the key, if not, creates a new array indice and returns the key
  1522.      * @param string $iconImage URL to icon image
  1523.      * @param string $iconShadowImage URL to shadow image
  1524.      * @param string $iconAnchorX X coordinate for icon anchor point
  1525.      * @param string $iconAnchorY Y coordinate for icon anchor point
  1526.      * @param string $infoWindowAnchorX X coordinate for info window anchor point
  1527.      * @param string $infoWindowAnchorY Y coordinate for info window anchor point
  1528.      * @return string A marker icon key.
  1529.      */
  1530.     function setMarkerIconKey($iconImage,$iconShadow='',$iconAnchorX 'x',$iconAnchorY 'x',$infoWindowAnchorX 'x',$infoWindowAnchorY 'x'){
  1531.         $_iconKey $this->getIconKey($iconImage,$iconShadow);
  1532.         if(isset($this->_marker_icons[$_iconKey])){
  1533.             return $_iconKey;
  1534.         }else{
  1535.             return $this->addIcon($iconImage,$iconShadow,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY);
  1536.         }
  1537.     }
  1538.     
  1539.     /**
  1540.      * function to get icon key
  1541.      * @param string $iconImage URL to marker icon image
  1542.      * @param string $iconShadow URL to marker icon shadow image
  1543.      * @return string Returns formatted icon key from icon or icon+shadow image name pairs
  1544.      */
  1545.     function getIconKey($iconImage,$iconShadow=""){
  1546.         return str_replace(array("/",":","."),"",$iconImage.$iconShadow);
  1547.     }
  1548.  
  1549.     /**
  1550.      * add an icon to "iconset"
  1551.      * @param string $iconImage URL to marker icon image
  1552.      * @param string $iconShadow URL to marker icon shadow image
  1553.      * @param string $iconAnchorX X coordinate for icon anchor point
  1554.      * @param string $iconAnchorY Y coordinate for icon anchor point
  1555.      * @param string $infoWindowAnchorX X coordinate for info window anchor point
  1556.      * @param string $infoWindowAnchorY Y coordinate for info window anchor point
  1557.      * @return string Returns the icon's key.
  1558.      */
  1559.     function addIcon($iconImage,$iconShadowImage '',$iconAnchorX 'x',$iconAnchorY 'x',$infoWindowAnchorX 'x',$infoWindowAnchorY 'x'{
  1560.         $_iconKey $this->getIconKey($iconImage$iconShadowImage);
  1561.         $this->_marker_icons[$_iconKey$this->createMarkerIcon($iconImage,$iconShadowImage,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY);
  1562.         return $_iconKey;
  1563.     }
  1564.     
  1565.     /**
  1566.      * updates a marker's icon key.
  1567.      * NOTE: To be used in lieu of addMarkerIcon, now use addIcon + updateMarkerIconKey for explicit icon association
  1568.      * @param string $markerKey Marker key to define which marker's icon to update
  1569.      * @param string $iconKey Icon key to define which icon to use.
  1570.      */
  1571.     function updateMarkerIconKey($markerKey$iconKey){
  1572.         if(isset($this->_markers[$markerKey])){
  1573.             $this->_markers[$markerKey]['icon_key'$iconKey;
  1574.         }
  1575.     }    
  1576.  
  1577.     /**
  1578.      * print map header javascript (goes between <head></head>)
  1579.      * 
  1580.      */
  1581.     function printHeaderJS({
  1582.         echo $this->getHeaderJS();
  1583.     }
  1584.     
  1585.     /**
  1586.      * return map header javascript (goes between <head></head>)
  1587.      * 
  1588.      */
  1589.     function getHeaderJS({
  1590.         $_headerJS "";
  1591.         if$this->mobile == true){
  1592.             $_headerJS .= "
  1593.                <meta name='viewport' content='initial-scale=1.0, user-scalable=no' />
  1594.             ";
  1595.         }
  1596.         if(!empty($this->_elevation_polylines)||(!empty($this->_directions)&&$this->elevation_directions)){
  1597.             $_headerJS .= "<script type='text/javascript' src='http://www.google.com/jsapi'></script>";
  1598.             $_headerJS .= "
  1599.             <script type='text/javascript'>
  1600.                 // Load the Visualization API and the piechart package.
  1601.                 google.load('visualization', '1', {packages: ['columnchart']});
  1602.             </script>";
  1603.         }
  1604.         $_headerJS .= "<script type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=".(($this->mobile==true)?"true":"false")."'></script>";
  1605.         if($this->marker_clusterer){
  1606.             $_headerJS .= "<script type='text/javascript' src='".$this->marker_clusterer_location."' ></script>";
  1607.         }        
  1608.         if($this->local_search){/*TODO: Load Local Search API V3 when available*/}   
  1609.         return $_headerJS;
  1610.     }    
  1611.     
  1612.    /**
  1613.     * prints onLoad() without having to manipulate body tag.
  1614.     * call this after the print map like so...
  1615.     *      $map->printMap();
  1616.     *      $map->printOnLoad();
  1617.     */
  1618.     function printOnLoad({
  1619.         echo $this->getOnLoad();
  1620.     }
  1621.     
  1622.     /**
  1623.      * print onLoad function name
  1624.      */
  1625.     function printOnLoadFunction(){
  1626.         echo $this->getOnLoadFunction();
  1627.     }
  1628.  
  1629.     /**
  1630.      * return js to set onload function
  1631.      */
  1632.     function getOnLoad({
  1633.         return '<script language="javascript" type="text/javascript" charset="utf-8">window.onload=onLoad'.$this->map_id.';</script>';                       
  1634.     }
  1635.     
  1636.     /**
  1637.      * return js to set onload function
  1638.      */
  1639.     function getOnLoadFunction({
  1640.         return 'onLoad'.$this->map_id;                       
  1641.     }   
  1642.  
  1643.     /**
  1644.      * print map javascript (put just before </body>, or in <header> if using onLoad())
  1645.      * 
  1646.      */
  1647.     function printMapJS({
  1648.         echo $this->getMapJS();
  1649.     }    
  1650.  
  1651.     /**
  1652.      * return map javascript
  1653.      * 
  1654.      */
  1655.     function getMapJS({
  1656.         $_script "";
  1657.         $_key $this->map_id;
  1658.         $_output '<script type="text/javascript" charset="utf-8">' "\n";
  1659.         $_output .= '//<![CDATA[' "\n";
  1660.         $_output .= "/*************************************************\n";
  1661.         $_output .= " * Created with GoogleMapAPI" $this->_version . "\n";
  1662.         $_output .= " * Author: Brad Wedell <brad AT mycnl DOT com>\n";
  1663.         $_output .= " * Link http://code.google.com/p/php-google-map-api/\n";
  1664.         $_output .= " * Copyright 2010 Brad Wedell\n";
  1665.         $_output .= " * Original Author: Monte Ohrt <monte AT ohrt DOT com>\n";
  1666.         $_output .= " * Original Copyright 2005-2006 New Digital Group\n";
  1667.         $_output .= " * Originial Link http://www.phpinsider.com/php/code/GoogleMapAPI/\n";
  1668.         $_output .= " *************************************************/\n";
  1669.         if($this->street_view_dom_id!=""){
  1670.             $_script .= "
  1671.                 var panorama".$this->street_view_dom_id."$_key = '';
  1672.             ";
  1673.             if(!empty($this->_markers)){
  1674.                 $_script .= "
  1675.                     var panorama".$this->street_view_dom_id."markers$_key = [];
  1676.                 ";
  1677.             }
  1678.         }
  1679.         
  1680.         if(!empty($this->_markers)){
  1681.             $_script .= "
  1682.                 var markers$_key  = [];
  1683.             ";
  1684.             if($this->sidebar{        
  1685.                 $_script .= "
  1686.                     var sidebar_html$_key  = '';
  1687.                     var marker_html$_key  = [];
  1688.                 ";
  1689.             }
  1690.         }
  1691.         if($this->marker_clusterer){
  1692.             $_script .= "
  1693.               var markerClusterer$_key = null;
  1694.             ";
  1695.         }        
  1696.         if($this->directions{        
  1697.             $_script .= "
  1698.                 var to_htmls$_key  = [];
  1699.                 var from_htmls$_key  = [];
  1700.             ";
  1701.         }
  1702.         if(!empty($this->_directions)){
  1703.             $_script .= "
  1704.                 var directions$_key = [];
  1705.             ";
  1706.         }
  1707.         //Polylines
  1708.         if(!empty($this->_polylines)){
  1709.             $_script .= "
  1710.                 var polylines$_key = [];
  1711.                 var polylineCoords$_key = [];
  1712.             ";
  1713.             if(!empty($this->_elevation_polylines)){
  1714.                 $_script .= "
  1715.                     var elevationPolylines$_key = [];
  1716.                 ";
  1717.             }
  1718.         }
  1719.         //Elevation stuff
  1720.         if(!empty($this->_elevation_polylines)||(!empty($this->_directions)&&$this->elevation_directions)){
  1721.             $_script .= "
  1722.                 var elevationCharts$_key = [];                
  1723.             ";
  1724.         }
  1725.         //Overlays
  1726.         if(!empty($this->_overlays)){
  1727.             $_script .= "
  1728.                 var overlays$_key = [];
  1729.             ";
  1730.         }
  1731.         //KML Overlays
  1732.         if(!empty($this->_kml_overlays)){
  1733.             $_script .= "
  1734.                 var kml_overlays$_key = [];
  1735.             ";
  1736.         }
  1737.         //New Icons
  1738.         if(!empty($this->_marker_icons)){
  1739.             $_script .= "var icon$_key  = []; \n";
  1740.             foreach($this->_marker_icons as $icon_key=>$icon_info){
  1741.                 //no need to check icon key here since that's already done with setters
  1742.                 $_script .= "
  1743.                   icon".$_key."['$icon_key'] = {};
  1744.                   icon".$_key."['$icon_key'].image =  new google.maps.MarkerImage('".$icon_info["image"]."',
  1745.                       // The size
  1746.                       new google.maps.Size(".$icon_info['iconWidth'].", ".$icon_info['iconHeight']."),
  1747.                       // The origin(sprite)
  1748.                       new google.maps.Point(0,0),
  1749.                       // The anchor
  1750.                       new google.maps.Point(".$icon_info['iconAnchorX'].", ".$icon_info['iconAnchorY'].")
  1751.                   );
  1752.                 ";
  1753.                 if(isset($icon_info['shadow']&& $icon_info['shadow']!=""){
  1754.                   $_script .= "
  1755.                     icon".$_key."['$icon_key'].shadow = new google.maps.MarkerImage('".$icon_info["shadow"]."',
  1756.                       // The size
  1757.                       new google.maps.Size(".$icon_info['shadowWidth'].", ".$icon_info['shadowHeight']."),
  1758.                       // The origin(sprite)
  1759.                       new google.maps.Point(0,0),
  1760.                       // The anchor
  1761.                       new google.maps.Point(".$icon_info['iconAnchorX'].", ".$icon_info['iconAnchorY'].")
  1762.                     );
  1763.                   ";
  1764.                 }
  1765.             }
  1766.         }
  1767.                            
  1768.         $_script .= "var map$_key = null;\n";
  1769.         
  1770.         //start setting script var
  1771.         if($this->onload{
  1772.            $_script .= 'function onLoad'.$this->map_id.'() {' "\n";   
  1773.         
  1774.                 
  1775.         if(!empty($this->browser_alert)) {
  1776.             //TODO:Update with new browser catch - GBrowserIsCompatible is deprecated
  1777.             //$_output .= 'if (GBrowserIsCompatible()) {' . "\n";
  1778.         }
  1779.         
  1780.         /*
  1781.          *TODO:Update with local search bar once implemented in V3 api 
  1782.         $strMapOptions = "";
  1783.         if($this->local_search){
  1784.             $_output .= "
  1785.                 mapOptions.googleBarOptions= {
  1786.                     style : 'new'
  1787.                     ".(($this->local_search_ads)?",
  1788.                     adsOptions: {
  1789.                         client: '".$this->ads_pub_id."',
  1790.                         channel: '".$this->ads_channel."',
  1791.                         language: 'en'
  1792.                     ":"")."
  1793.                 };
  1794.             ";            
  1795.             $strMapOptions .= ", mapOptions";
  1796.         }
  1797.         */
  1798.         
  1799.         if($this->display_map){
  1800.             $_script .= sprintf('var mapObj%s = document.getElementById("%s");'$_key$this->map_id"\n";
  1801.             $_script .= "if (mapObj$_key != 'undefined' && mapObj$_key != null) {\n";
  1802.             
  1803.             $_script .= "
  1804.                 var mapOptions$_key = {
  1805.                     scrollwheel: "($this->scrollwheel?"true":"false"",
  1806.                     zoom: ".$this->zoom.",
  1807.                     mapTypeId: google.maps.MapTypeId.".$this->map_type.",
  1808.                     mapTypeControl: ".($this->type_controls?"true":"false").",
  1809.                     mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.".$this->type_controls_style."}
  1810.                 };
  1811.             ";
  1812.             if(isset($this->center_lat&& isset($this->center_lon)) {
  1813.                 // Special care for decimal point in lon and lat, would get lost if "wrong" locale is set; applies to (s)printf only
  1814.                 $_script .= "
  1815.                     mapOptions".$_key.".center = new google.maps.LatLng(
  1816.                         ".number_format($this->center_lat6".""").",
  1817.                         ".number_format($this->center_lon6".""")."
  1818.                     );
  1819.                 ";
  1820.             }   
  1821.             
  1822.             if($this->street_view_controls){
  1823.                 $_script .= "
  1824.                     mapOptions".$_key.".streetViewControl= true;
  1825.     
  1826.                 ";
  1827.             }
  1828.             
  1829.             $_script .= "
  1830.                 map$_key = new google.maps.Map(mapObj$_key,mapOptions$_key);
  1831.             ";
  1832.                 
  1833.             if($this->street_view_dom_id!=""){
  1834.                 $_script .= "
  1835.                     panorama".$this->street_view_dom_id."$_key = new  google.maps.StreetViewPanorama(document.getElementById('".$this->street_view_dom_id."'));
  1836.                     map$_key.setStreetView(panorama".$this->street_view_dom_id."$_key);
  1837.                 ";
  1838.                 
  1839.                 if(!empty($this->_markers)){
  1840.                     
  1841.                     //Add markers to the street view
  1842.                     if($this->street_view_dom_id!=""){
  1843.                         $_script .= $this->getAddMarkersJS($this->map_id$pano=true);
  1844.                     }
  1845.                     //set center to last marker
  1846.                     $last_id count($this->_markers)-1;
  1847.                     
  1848.                     $_script .= "
  1849.                         panorama".$this->street_view_dom_id."$_key.setPosition(new google.maps.LatLng(
  1850.                             ".$this->_markers[$last_id]["lat"].",
  1851.                             ".$this->_markers[$last_id]["lon"]."
  1852.                         ));
  1853.                         panorama".$this->street_view_dom_id."$_key.setVisible(true);
  1854.                     ";
  1855.                 }
  1856.             }
  1857.             
  1858.             if(!empty($this->_directions)){
  1859.                 $_script .= $this->getAddDirectionsJS();
  1860.             }
  1861.             
  1862.             //TODO:add support for Google Earth Overlay once integrated with V3
  1863.             //$_output .= "map.addMapType(G_SATELLITE_3D_MAP);\n";
  1864.             
  1865.             // zoom so that all markers are in the viewport
  1866.             if($this->zoom_encompass && (count($this->_markers|| count($this->_polylines>= || count($this->_overlays>= 1)) {
  1867.                 // increase bounds by fudge factor to keep
  1868.                 // markers away from the edges
  1869.                 $_len_lon $this->_max_lon - $this->_min_lon;
  1870.                 $_len_lat $this->_max_lat - $this->_min_lat;
  1871.                 $this->_min_lon -= $_len_lon $this->bounds_fudge;
  1872.                 $this->_max_lon += $_len_lon $this->bounds_fudge;
  1873.                 $this->_min_lat -= $_len_lat $this->bounds_fudge;
  1874.                 $this->_max_lat += $_len_lat $this->bounds_fudge;
  1875.     
  1876.                 $_script .= "var bds$_key = new google.maps.LatLngBounds(new google.maps.LatLng($this->_min_lat$this->_min_lon), new google.maps.LatLng($this->_max_lat$this->_max_lon));\n";
  1877.                 $_script .= 'map'.$_key.'.fitBounds(bds'.$_key.');' "\n";
  1878.             }
  1879.             
  1880.             /*
  1881.              * TODO: Update controls to use new API v3 methods.(Not a priority, see below)
  1882.              * default V3 functionality caters control display according to the 
  1883.              * device that's accessing the page, as well as the specified width
  1884.              * and height of the map itself.
  1885.             if($this->map_controls) {
  1886.               if($this->control_size == 'large')
  1887.                   $_output .= 'map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10,10)));' . "\n";
  1888.               else
  1889.                   $_output .= 'map.addControl(new GSmallMapControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,60)));' . "\n";
  1890.             }
  1891.             if($this->type_controls) {
  1892.                 $_output .= 'map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,10)));' . "\n";
  1893.             }
  1894.             
  1895.             if($this->scale_control) {
  1896.                 if($this->control_size == 'large'){
  1897.                     $_output .= 'map.addControl(new GScaleControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(35,190)));' . "\n";
  1898.                 }else {
  1899.                     $_output .= 'map.addControl(new GScaleControl(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(190,10)));' . "\n";
  1900.                 }
  1901.             }
  1902.             if($this->overview_control) {
  1903.                 $_output .= 'map.addControl(new GOverviewMapControl());' . "\n";
  1904.             }
  1905.             
  1906.              * TODO: Update with ads_manager stuff once integrated into V3
  1907.             if($this->ads_manager){
  1908.                 $_output .= 'var adsManager = new GAdsManager(map, "'.$this->ads_pub_id.'",{channel:"'.$this->ads_channel.'",maxAdsOnMap:"'.$this->ads_max.'"});
  1909.            adsManager.enable();'."\n";
  1910.             
  1911.             }
  1912.              * TODO: Update with local search once integrated into V3
  1913.             if($this->local_search){
  1914.                 $_output .= "\n
  1915.                     map.enableGoogleBar();
  1916.                 ";
  1917.             }
  1918.             */
  1919.             
  1920.             if($this->traffic_overlay){
  1921.                 $_script .= "
  1922.                     var trafficLayer = new google.maps.TrafficLayer();
  1923.                     trafficLayer.setMap(map$_key);
  1924.                 ";            
  1925.             }
  1926.             
  1927.             if($this->biking_overlay){
  1928.                 $_script .= "
  1929.                     var bikingLayer = new google.maps.BicyclingLayer();
  1930.                     bikingLayer.setMap(map$_key);
  1931.                 ";            
  1932.             }
  1933.             
  1934.             $_script .= $this->getAddMarkersJS();
  1935.             
  1936.             $_script .= $this->getPolylineJS();
  1937.             $_script .= $this->getAddOverlayJS();
  1938.             
  1939.             if($this->_kml_overlays!==""){
  1940.               foreach($this->_kml_overlays as $_kml_key=>$_kml_file){
  1941.                   $_script .= "
  1942.                       kml_overlays$_key[$_kml_key]= new google.maps.KmlLayer('$_kml_file');
  1943.                       kml_overlays$_key[$_kml_key].setMap(map$_key);
  1944.                   ";
  1945.               }
  1946.               $_script .= "
  1947.                   
  1948.               ";
  1949.             }
  1950.  
  1951.              //end JS if mapObj != "undefined" block
  1952.             $_script .= '}' "\n";
  1953.         
  1954.         }//end if $this->display_map==true
  1955.        
  1956.         if(!empty($this->browser_alert)) {
  1957.             //TODO:Update with new browser catch SEE ABOVE
  1958.            // $_output .= '} else {' . "\n";
  1959.            // $_output .= 'alert("' . str_replace('"','\"',$this->browser_alert) . '");' . "\n";
  1960.            // $_output .= '}' . "\n";
  1961.         }                        
  1962.  
  1963.         if($this->onload{
  1964.            $_script .= '}' "\n";
  1965.         }
  1966.         
  1967.         $_script .= $this->getMapFunctions();
  1968.         
  1969.         if($this->_minify_js && class_exists("JSMin")){
  1970.             $_script JSMin::minify($_script);
  1971.         }
  1972.         
  1973.         //Append script to output
  1974.         $_output .= $_script;
  1975.         $_output .= '//]]>' "\n";
  1976.         $_output .= '</script>' "\n";
  1977.         return $_output;
  1978.     }
  1979.     
  1980.     /**
  1981.      * function to render utility functions for use on the page
  1982.      */
  1983.      function getMapFunctions(){
  1984.         $_script "";
  1985.         if($this->_display_js_functions===true){
  1986.             $_script $this->getUtilityFunctions();           
  1987.         }
  1988.         return $_script;
  1989.      }
  1990.      
  1991.      function getUtilityFunctions(){
  1992.          $_script "";
  1993.          if(!empty($this->_markers))
  1994.              $_script .= $this->getCreateMarkerJS();
  1995.          if(!empty($this->_overlays))
  1996.              $_script .= $this->getCreateOverlayJS();
  1997.          if(!empty($this->_elevation_polylines)||(!empty($this->_directions)&&$this->elevation_directions))
  1998.              $_script .= $this->getPlotElevationJS();
  1999.          // Utility functions used to distinguish between tabbed and non-tabbed info windows
  2000.          $_script .= 'function isArray(a) {return isObject(a) && a.constructor == Array;}' "\n";
  2001.          $_script .= 'function isObject(a) {return (a && typeof a == \'object\') || isFunction(a);}' "\n";
  2002.          $_script .= 'function isFunction(a) {return typeof a == \'function\';}' "\n";
  2003.          $_script .= 'function isEmpty(obj) { for(var i in obj) { return false; } return true; }'."\n";     
  2004.          return $_script;
  2005.      }
  2006.  
  2007.     /**
  2008.      * overridable function for generating js to add markers
  2009.      */
  2010.     function getAddMarkersJS($map_id ""$panofalse{
  2011.         //defaults
  2012.         if($map_id == ""){
  2013.             $map_id $this->map_id;
  2014.         }
  2015.         
  2016.         if($pano==false){
  2017.             $_prefix "map";
  2018.         }else{
  2019.             $_prefix "panorama".$this->street_view_dom_id;
  2020.         }
  2021.         $_output '';
  2022.         foreach($this->_markers as $_marker{
  2023.             $iw_html str_replace('"','\"',str_replace(array("\n""\r")""$_marker['html']));
  2024.             $_output .= "var point = new google.maps.LatLng(".$_marker['lat'].",".$_marker['lon'].");\n";
  2025.             $_output .= sprintf('%s.push(createMarker(%s%s, point,"%s","%s", %s, %s, "%s", %s ));',
  2026.                 (($pano==true)?$_prefix:"")."markers".$map_id,
  2027.                 $_prefix,                
  2028.                 $map_id,
  2029.                 str_replace('"','\"',$_marker['title']),
  2030.                 str_replace('/','\/',$iw_html),
  2031.                 (isset($_marker["icon_key"]))?"icon".$map_id."['".$_marker["icon_key"]."'].image":"''",
  2032.                 (isset($_marker["icon_key"])&&isset($_marker["shadow_icon"]))?"icon".$map_id."['".$_marker["icon_key"]."'].shadow":"''",
  2033.                 (($this->sidebar)?$this->sidebar_id:""),
  2034.                 ((isset($_marker["openers"])&&count($_marker["openers"])>0)?json_encode($_marker["openers"]):"''")
  2035.             "\n";
  2036.         }
  2037.         
  2038.         if($this->marker_clusterer && $pano==false){//only do marker clusterer for map, not streetview
  2039.             $_output .= "
  2040.                markerClusterer".$map_id." = new MarkerClusterer(".$_prefix.$map_id.", markers".$map_id.", {
  2041.                   maxZoom: ".$this->marker_clusterer_options["maxZoom"].",
  2042.                   gridSize: ".$this->marker_clusterer_options["gridSize"].",
  2043.                   styles: ".$this->marker_clusterer_options["styles"]."
  2044.                 });
  2045.                     
  2046.             ";
  2047.         }
  2048.         return $_output;
  2049.     }
  2050.  
  2051.     /**
  2052.      * overridable function to generate polyline js - for now can only be used on a map, not a streetview
  2053.      */
  2054.     function getPolylineJS({
  2055.         $_output '';
  2056.         foreach($this->_polylines as $polyline_id =>$_polyline{
  2057.             $_coords_output "";
  2058.             foreach($_polyline["coords"as $_coords){
  2059.                 if($_coords_output != ""){$_coords_output.=",";}
  2060.                 $_coords_output .= "
  2061.                     new google.maps.LatLng(".$_coords["lat"].", ".$_coords["long"].")
  2062.                 ";
  2063.             }
  2064.             $_output .= "
  2065.                polylineCoords".$this->map_id."[$polyline_id] = [".$_coords_output."];        
  2066.                polylines".$this->map_id."[$polyline_id] = new google.maps.Polyline({
  2067.                   path: polylineCoords".$this->map_id."[$polyline_id]
  2068.                   ".(($_polyline['color']!="")?", strokeColor: '".$_polyline['color']."'":"")."
  2069.                   ".(($_polyline['opacity']!=0)?", strokeOpacity: ".$_polyline['opacity']."":"")."
  2070.                   ".(($_polyline['weight']!=0)?", strokeWeight: ".$_polyline['weight']."":"")."
  2071.               });            
  2072.               polylines".$this->map_id."[$polyline_id].setMap(map".$this->map_id.");
  2073.             ";
  2074.             
  2075.             //Elevation profiles
  2076.             if(!empty($this->_elevation_polylines&& isset($this->_elevation_polylines[$polyline_id])){
  2077.                 $elevation_dom_id=$this->_elevation_polylines[$polyline_id]["dom_id"];
  2078.                 $width $this->_elevation_polylines[$polyline_id]["width"];
  2079.                 $height $this->_elevation_polylines[$polyline_id]["height"];
  2080.                 $samples $this->_elevation_polylines[$polyline_id]["samples"];
  2081.                 $focus_color $this->_elevation_polylines[$polyline_id]["focus_color"];
  2082.                 $_output .= "
  2083.                     elevationPolylines".$this->map_id."[$polyline_id] = {
  2084.                         'selector':'$elevation_dom_id',
  2085.                         'chart': new google.visualization.ColumnChart(document.getElementById('$elevation_dom_id')),
  2086.                         'service': new google.maps.ElevationService(),
  2087.                         'width':$width,
  2088.                         'height':$height,
  2089.                         'focusColor':'$focus_color',
  2090.                         'marker':null
  2091.                     };
  2092.                     elevationPolylines".$this->map_id."[$polyline_id]['service'].getElevationAlongPath({
  2093.                         path: polylineCoords".$this->map_id."[$polyline_id],
  2094.                         samples: $samples
  2095.                     }, function(results,status){plotElevation(results,status, elevationPolylines".$this->map_id."[$polyline_id], map".$this->map_id.", elevationCharts".$this->map_id.");});
  2096.                 ";
  2097.             }
  2098.         }
  2099.         return $_output;
  2100.     }
  2101.     
  2102.     /**
  2103.      * function to render proper calls for directions - for now can only be used on a map, not a streetview
  2104.      */
  2105.      function getAddDirectionsJS(){
  2106.         $_output ""
  2107.          
  2108.         foreach($this->_directions as $directions){
  2109.             $dom_id $directions["dom_id"];            
  2110.             $travelModeParams array();
  2111.             $directionsParams "";         
  2112.             if($this->walking_directions==TRUE)
  2113.                 $directionsParams .= ", \n travelMode:google.maps.DirectionsTravelMode.WALKING";
  2114.             else if($this->biking_directions==TRUE)
  2115.                 $directionsParams .= ", \n travelMode:google.maps.DirectionsTravelMode.BICYCLING";
  2116.             else
  2117.                 $directionsParams .= ", \n travelMode:google.maps.DirectionsTravelMode.DRIVING";
  2118.            
  2119.             if($this->avoid_highways==TRUE)
  2120.                $directionsParams .= ", \n avoidHighways: true";
  2121.             if($this->avoid_tollways==TRUE)
  2122.                $directionsParams .= ", \n avoidTolls: true";
  2123.  
  2124.             if($this->directions_unit_system!=''){
  2125.                 if($this->directions_unit_system == 'METRIC'){
  2126.                     $directionsParams .= ", \n unitSystem: google.maps.DirectionsUnitSystem.METRIC";
  2127.                 }else{
  2128.                     $directionsParams .= ", \n unitSystem: google.maps.DirectionsUnitSystem.IMPERIAL";
  2129.                 }
  2130.             }
  2131.             
  2132.             $_output .= "
  2133.                 directions".$this->map_id."['$dom_id'] = {
  2134.                     displayRenderer:new google.maps.DirectionsRenderer(),
  2135.                     directionService:new google.maps.DirectionsService(),
  2136.                     request:{
  2137.                         origin: '".$directions["start"]."',
  2138.                         destination: '".$directions["dest"]."'
  2139.                         $directionsParams
  2140.                     }
  2141.                     ".(($this->elevation_directions)?",        
  2142.                        selector: '".$directions["elevation_dom_id"]."',
  2143.                        chart: new google.visualization.ColumnChart(document.getElementById('".$directions["elevation_dom_id"]."')),
  2144.                        service: new google.maps.ElevationService(),
  2145.                        width:".$directions["width"].",
  2146.                        height:".$directions["height"].",
  2147.                        focusColor:'#00FF00',
  2148.                        marker:null
  2149.                    ":"")."
  2150.                 };
  2151.                 directions".$this->map_id."['$dom_id'].displayRenderer.setMap(map".$this->map_id.");
  2152.                 directions".$this->map_id."['$dom_id'].displayRenderer.setPanel(document.getElementById('$dom_id'));
  2153.                 directions".$this->map_id."['$dom_id'].directionService.route(directions".$this->map_id."['$dom_id'].request, function(response, status) {
  2154.                     if (status == google.maps.DirectionsStatus.OK) {
  2155.                        directions".$this->map_id."['$dom_id'].displayRenderer.setDirections(response);
  2156.                        ".(($this->elevation_directions)?"
  2157.                            directions".$this->map_id."['$dom_id'].service.getElevationAlongPath({
  2158.                                path: response.routes[0].overview_path,
  2159.                                samples: ".$directions["elevation_samples"]."
  2160.                            }, function(results,status){plotElevation(results,status, directions".$this->map_id."['$dom_id'], map".$this->map_id.", elevationCharts".$this->map_id.");});
  2161.                        ":"")."
  2162.                     }
  2163.                 });
  2164.              ";
  2165.          }
  2166.          
  2167.          return $_output;
  2168.      }
  2169.     
  2170.     /**
  2171.      * function to get overlay creation JS.
  2172.      */
  2173.      function getAddOverlayJS(){
  2174.          $_output "";
  2175.          foreach($this->_overlays as $_key=>$_overlay){
  2176.              $_output .= "
  2177.                   var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(".$_overlay["bounds"]["ne"]["lat"].", ".$_overlay["bounds"]["ne"]["long"]."), new google.maps.LatLng(".$_overlay["bounds"]["sw"]["lat"].", ".$_overlay["bounds"]["sw"]["long"]."));
  2178.                  var image = '".$_overlay["img"]."';
  2179.                  overlays".$this->map_id."[$_key] = new CustomOverlay(bounds, image, map".$this->map_id.", ".$_overlay["opacity"].");
  2180.              ";
  2181.          }
  2182.          return $_output;
  2183.      }
  2184.  
  2185.     /**
  2186.      * overridable function to generate the js for the js function for creating a marker.
  2187.      */
  2188.     function getCreateMarkerJS({
  2189.         $_output "
  2190.            function createMarker(map, point, title, html, icon, icon_shadow, sidebar_id, openers){
  2191.                 var marker_options = {
  2192.                     position: point,
  2193.                     map: map,
  2194.                     title: title};  
  2195.                 if(icon!=''){marker_options.icon = icon;}
  2196.                 if(icon_shadow!=''){marker_options.shadow = icon_shadow;}
  2197.                 //create marker
  2198.                 var new_marker = new google.maps.Marker(marker_options);
  2199.                 if(html!=''){
  2200.                     ".(($this->info_window)?"
  2201.                     var infowindow = new google.maps.InfoWindow({content: html});
  2202.                     google.maps.event.addListener(new_marker, '".$this->window_trigger."', function() {
  2203.                       infowindow.open(map,new_marker);
  2204.                     });
  2205.                     if(openers != ''&&!isEmpty(openers)){
  2206.                        for(var i in openers){
  2207.                          var opener = document.getElementById(openers[i]);
  2208.                          opener.on".$this->window_trigger." = function(){infowindow.open(map,new_marker); return false};
  2209.                        }
  2210.                     }
  2211.                     ":"")."
  2212.                     if(sidebar_id != ''){
  2213.                         var sidebar = document.getElementById(sidebar_id);
  2214.                         if(sidebar!=null && sidebar!=undefined && title!=null && title!=''){
  2215.                             var newlink = document.createElement('a');
  2216.                             ".(($this->info_window)?"
  2217.                             newlink.onclick=function(){infowindow.open(map,new_marker); return false};
  2218.                             ":"
  2219.                             newlink.onclick=function(){map.setCenter(point); return false};
  2220.                             ")."
  2221.                             newlink.innerHTML = title;
  2222.                             sidebar.appendChild(newlink);
  2223.                         }
  2224.                     }
  2225.                 }
  2226.                 return new_marker;  
  2227.             }
  2228.         ";
  2229.         return $_output;
  2230.     }
  2231.     
  2232.     /**
  2233.      * Get create overlay js
  2234.      */
  2235.      function getCreateOverlayJS(){
  2236.          $_output "
  2237.              CustomOverlay.prototype = new google.maps.OverlayView();    
  2238.             function CustomOverlay(bounds, image, map, opacity){
  2239.                 this.bounds_ = bounds;
  2240.                 this.image_ = image;
  2241.                 this.map_ = map;
  2242.                 this.div_ = null;
  2243.                 this.opacity = (opacity!='')?opacity:10;
  2244.                 this.setMap(map);
  2245.             }
  2246.             CustomOverlay.prototype.onAdd = function() {
  2247.                 var div = document.createElement('DIV');
  2248.                 div.style.borderStyle = 'none';
  2249.                 div.style.borderWidth = '0px';
  2250.                 div.style.position = 'absolute';
  2251.                 var img = document.createElement('img');
  2252.                 img.src = this.image_;
  2253.                 img.style.width = '100%';
  2254.                 img.style.height = '100%';
  2255.                 img.style.opacity = this.opacity/10;
  2256.                 img.style.filter = 'alpha(opacity='+this.opacity*10+')';    
  2257.                 div.appendChild(img);
  2258.                 this.div_ = div;    
  2259.                 var panes = this.getPanes();
  2260.                 panes.overlayImage.appendChild(div);
  2261.             }
  2262.             CustomOverlay.prototype.draw = function() {
  2263.                 var overlayProjection = this.getProjection();
  2264.                 var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  2265.                 var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
  2266.                 var div = this.div_;
  2267.                 div.style.left = sw.x + 'px';
  2268.                 div.style.top = ne.y + 'px';
  2269.                 div.style.width = (ne.x - sw.x) + 'px';
  2270.                 div.style.height = (sw.y - ne.y) + 'px';
  2271.             }
  2272.             CustomOverlay.prototype.onRemove = function() {
  2273.                 this.div_.parentNode.removeChild(this.div_);
  2274.                 this.div_ = null;
  2275.             }
  2276.          ";         
  2277.          return $_output;
  2278.      }
  2279.      
  2280.      /**
  2281.       * print helper function to draw elevation results as a chart
  2282.       */
  2283.     function getPlotElevationJS(){
  2284.         $_output "
  2285.             function plotElevation(results, status, elevation_data, map, charts_array) {
  2286.                 charts_array[elevation_data.selector] = {
  2287.                     results:results,
  2288.                     data:new google.visualization.DataTable()
  2289.                 };
  2290.                 charts_array[elevation_data.selector].data.addColumn('string', 'Sample');
  2291.                 charts_array[elevation_data.selector].data.addColumn('number', 'Elevation');
  2292.                 for (var i = 0; i < charts_array[elevation_data.selector].results.length; i++) {
  2293.                   charts_array[elevation_data.selector].data.addRow(['', charts_array[elevation_data.selector].results[i].elevation]);
  2294.                 }
  2295.                 document.getElementById(elevation_data.selector).style.display = 'block';
  2296.                 elevation_data.chart.draw(charts_array[elevation_data.selector].data, {
  2297.                   width: elevation_data.width,
  2298.                   height: elevation_data.height,
  2299.                   legend: 'none',
  2300.                   titleY: 'Elevation (m)',
  2301.                   focusBorderColor: elevation_data.focusColor
  2302.                 });
  2303.         ";
  2304.         if($this->elevation_markers){
  2305.             $_output .= $this->getElevationMarkerJS();            
  2306.         }
  2307.         $_output .= "}";
  2308.         return $_output;
  2309.     }      
  2310.     
  2311.     /**
  2312.      * create JS that is inside of JS plot elevation function
  2313.      */
  2314.      function getElevationMarkerJS(){
  2315.          $_output "
  2316.             google.visualization.events.addListener(elevation_data.chart, 'onmouseover', function(e) {
  2317.                 if(elevation_data.marker==null){
  2318.                     elevation_data.marker = new google.maps.Marker({
  2319.                       position: charts_array[elevation_data.selector].results[e.row].location,
  2320.                       map: map,
  2321.                       icon: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png'
  2322.                     });
  2323.                 }else{
  2324.                     elevation_data.marker.setPosition(charts_array[elevation_data.selector].results[e.row].location);
  2325.                 }
  2326.                 map.setCenter(charts_array[elevation_data.selector].results[e.row].location);
  2327.             });
  2328.             document.getElementById(elevation_data.selector).onmouseout = function(){
  2329.                 elevation_data.marker = clearElevationMarker(elevation_data.marker);
  2330.             };
  2331.             function clearElevationMarker(marker){
  2332.               if(marker!=null){
  2333.                   marker.setMap(null);
  2334.                   return null;
  2335.               }
  2336.             }
  2337.         ";
  2338.         return $_output;
  2339.      }
  2340.      
  2341.  
  2342.     /**
  2343.      * print map (put at location map will appear)
  2344.      * 
  2345.      */
  2346.     function printMap({
  2347.         echo $this->getMap();
  2348.     }
  2349.  
  2350.     /**
  2351.      * return map
  2352.      * 
  2353.      */
  2354.     function getMap({
  2355.         $_output '<script type="text/javascript" charset="utf-8">' "\n" '//<![CDATA[' "\n";
  2356.         //$_output .= 'if (GBrowserIsCompatible()) {' . "\n";
  2357.         if(strlen($this->width&& strlen($this->height0{
  2358.             $_output .= sprintf('document.write(\'<div id="%s" style="width: %s; height: %s; position:relative;"><\/div>\');',$this->map_id,$this->width,$this->height"\n";
  2359.         else {
  2360.             $_output .= sprintf('document.write(\'<div id="%s" style="position:relative;"><\/div>\');',$this->map_id"\n";     
  2361.         }
  2362.         //$_output .= '}';
  2363.  
  2364.         //if(!empty($this->js_alert)) {
  2365.         //    $_output .= ' else {' . "\n";
  2366.         //    $_output .= sprintf('document.write(\'%s\');', str_replace('/','\/',$this->js_alert)) . "\n";
  2367.         //    $_output .= '}' . "\n";
  2368.         //}
  2369.  
  2370.         $_output .= '//]]>' "\n" '</script>' "\n";
  2371.  
  2372.         if(!empty($this->js_alert)) {
  2373.             $_output .= '<noscript>' $this->js_alert . '</noscript>' "\n";
  2374.         }
  2375.  
  2376.         return $_output;
  2377.     }
  2378.  
  2379.     
  2380.     /**
  2381.      * print sidebar (put at location sidebar will appear)
  2382.      * 
  2383.      */
  2384.     function printSidebar({
  2385.         echo $this->getSidebar();
  2386.     }    
  2387.  
  2388.     /**
  2389.      * return sidebar html
  2390.      * 
  2391.      */
  2392.     function getSidebar({
  2393.         return sprintf('<div id="%s" class="'.$this->sidebar_id.'"></div>',$this->sidebar_id"\n";
  2394.     }    
  2395.             
  2396.     /**
  2397.      * get the geocode lat/lon points from given address
  2398.      * look in cache first, otherwise get from Yahoo
  2399.      * 
  2400.      * @param string $address 
  2401.      * @return array GeoCode information
  2402.      */
  2403.     function getGeocode($address{
  2404.         if(empty($address))
  2405.             return false;
  2406.         $_geocode false;  
  2407.         if(($_geocode $this->getCache($address)) === false{
  2408.             if(($_geocode $this->geoGetCoords($address)) !== false{
  2409.                 $this->putCache($address$_geocode['lon']$_geocode['lat']);
  2410.             }
  2411.         }
  2412.         return $_geocode;
  2413.     }
  2414.    
  2415.     /**
  2416.      * get the geocode lat/lon points from cache for given address
  2417.      * 
  2418.      * @param string $address 
  2419.      * @return bool|arrayFalse if no cache, array of data if has cache
  2420.      */
  2421.     function getCache($address{
  2422.         if(!isset($this->dsn))
  2423.             return false;
  2424.         
  2425.         $_ret array();
  2426.         
  2427.         // PEAR DB
  2428.         require_once('DB.php');          
  2429.         $_db =DB::connect($this->dsn);
  2430.         if (PEAR::isError($_db)) {
  2431.             die($_db->getMessage());
  2432.         }
  2433.         $_res =$_db->query("SELECT lon,lat FROM {$this->_db_cache_table} where address = ?", $address);
  2434.         if (PEAR::isError($_res)) {
  2435.             die($_res->getMessage());
  2436.         }
  2437.         if($_row = $_res->fetchRow()) {            
  2438.             $_ret['lon'] = $_row[0];
  2439.             $_ret['lat'] = $_row[1];
  2440.         }
  2441.         
  2442.         $_db->disconnect();
  2443.         
  2444.         return !empty($_ret$_ret false;
  2445.     }
  2446.     
  2447.     /**
  2448.      * put the geocode lat/lon points into cache for given address
  2449.      * 
  2450.      * @param string $address
  2451.      * @param string $lon the map latitude (horizontal)
  2452.      * @param string $lat the map latitude (vertical)
  2453.      * @return bool Status of put cache request
  2454.      */
  2455.     function putCache($address, $lon, $lat) {
  2456.         if(!isset($this->dsn|| (strlen($address== || strlen($lon== || strlen($lat== 0))
  2457.            return false;
  2458.         // PEAR DB
  2459.         require_once('DB.php');         
  2460.         $_db =DB::connect($this->dsn);
  2461.         if (PEAR::isError($_db)) {
  2462.             die($_db->getMessage());
  2463.         }
  2464.         $_res =& $_db->query('insert into '.$this->_db_cache_table.' values (?, ?, ?)'array($address$lon$lat));
  2465.         if (PEAR::isError($_res)) {
  2466.             die($_res->getMessage());
  2467.         }
  2468.         $_db->disconnect();
  2469.         return true;        
  2470.     }
  2471.    
  2472.     /**
  2473.      * get geocode lat/lon points for given address from Yahoo
  2474.      * 
  2475.      * @param string $address
  2476.      * @return bool|array false if can't be geocoded, array or geocdoes if successful
  2477.      */
  2478.     function geoGetCoords($address,$depth=0) {
  2479.         switch($this->lookup_service{
  2480.             case 'GOOGLE':
  2481.                 $_url = sprintf('http://%s/maps/api/geocode/json?sensor=%s&address=%s',$this->lookup_server['GOOGLE']$this->mobile==true?"true":"false"rawurlencode($address));
  2482.                 $_result false;
  2483.                 if($_result $this->fetchURL($_url)) {
  2484.                     $_result_parts = json_decode($_result);
  2485.                     if($_result_parts->status!="OK"){
  2486.                         return false;
  2487.                     }
  2488.                     $_coords['lat'] = $_result_parts->results[0]->geometry->location->lat;
  2489.                     $_coords['lon'$_result_parts->results[0]->geometry->location->lng;
  2490.                 }
  2491.                 break;
  2492.             case 'YAHOO':
  2493.             default:        
  2494.                 $_url = 'http://%s/MapsService/V1/geocode';
  2495.                 $_url .= sprintf('?appid=%s&location=%s',$this->lookup_server['YAHOO'],$this->app_id,rawurlencode($address));
  2496.                 $_result false;
  2497.                 if($_result $this->fetchURL($_url)) {
  2498.                     preg_match('!<Latitude>(.*)</Latitude><Longitude>(.*)</Longitude>!U', $_result, $_match);
  2499.                     $_coords['lon'] = $_match[2];
  2500.                     $_coords['lat'] = $_match[1];
  2501.                 }
  2502.                 break;
  2503.         }         
  2504.         return $_coords;       
  2505.     }
  2506.     
  2507.     /**
  2508.      * get full geocode information for given address from Google
  2509.      * NOTE: This does not use the getCache function as there is 
  2510.      * a lot of data in a full geocode response to cache.
  2511.      * 
  2512.      * @param string $address
  2513.      * @return bool|array false if can't be geocoded, array or geocdoes if successful
  2514.      */
  2515.     function geoGetCoordsFull($address,$depth=0) {
  2516.         switch($this->lookup_service{
  2517.             case 'GOOGLE':
  2518.                 $_url = sprintf('http://%s/maps/api/geocode/json?sensor=%s&address=%s',$this->lookup_server['GOOGLE']$this->mobile==true?"true":"false"rawurlencode($address));
  2519.                 $_result false;
  2520.                 if($_result $this->fetchURL($_url)) {
  2521.                     return json_decode($_result);
  2522.                 }
  2523.                 break;
  2524.             case 'YAHOO':
  2525.             default:        
  2526.                 $_url = 'http://%s/MapsService/V1/geocode';
  2527.                 $_url .= sprintf('?appid=%s&location=%s',$this->lookup_server['YAHOO'],$this->app_id,rawurlencode($address));
  2528.                 $_result false;
  2529.                 if($_result $this->fetchURL($_url)) {
  2530.                     return $_match;
  2531.                 }
  2532.                 break;
  2533.         }         
  2534.     }    
  2535.  
  2536.     /**
  2537.      * fetch a URL. Override this method to change the way URLs are fetched.
  2538.      * 
  2539.      * @param string $url
  2540.      */
  2541.     function fetchURL($url) {
  2542.  
  2543.         return file_get_contents($url);
  2544.  
  2545.     }
  2546.  
  2547.     /**
  2548.      * get distance between to geocoords using great circle distance formula
  2549.      * 
  2550.      * @param float $lat1
  2551.      * @param float $lat2
  2552.      * @param float $lon1
  2553.      * @param float $lon2
  2554.      * @param float $unit   M=miles, K=kilometers, N=nautical miles, I=inches, F=feet
  2555.      * @return float
  2556.      */
  2557.     function geoGetDistance($lat1,$lon1,$lat2,$lon2,$unit='M') {
  2558.         
  2559.       // calculate miles
  2560.       $M =  69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)))); 
  2561.  
  2562.       switch(strtoupper($unit))
  2563.       {
  2564.         case 'K':
  2565.           // kilometers
  2566.           return $M * 1.609344;
  2567.           break;
  2568.         case 'N':
  2569.           // nautical miles
  2570.           return $M * 0.868976242;
  2571.           break;
  2572.         case 'F':
  2573.           // feet
  2574.           return $M * 5280;
  2575.           break;            
  2576.         case 'I':
  2577.           // inches
  2578.           return $M * 63360;
  2579.           break;            
  2580.         case 'M':
  2581.         default:
  2582.           // miles
  2583.           return $M;
  2584.           break;
  2585.       }
  2586.       
  2587.     }    
  2588.     
  2589. }
  2590.  

Documentation generated on Fri, 15 Apr 2011 20:39:48 +0000 by phpDocumentor 1.4.3