[ Index ]

PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10)

title

Body

[close]

/include/inc_ext/GoogleMapsAPI/ -> phpwcmsGoogleMapAPI.class.php (source)

   1  <?php
   2  
   3  /**
   4  * Project:     GoogleMapAPI: a PHP library inteface to the Google Map API
   5  * File:        GoogleMapAPI.class.php
   6  *
   7  * This library is free software; you can redistribute it and/or
   8  * modify it under the terms of the GNU Lesser General Public
   9  * License as published by the Free Software Foundation; either
  10  * version 2.1 of the License, or (at your option) any later version.
  11  *
  12  * This library is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15  * Lesser General Public License for more details.
  16  *
  17  * You should have received a copy of the GNU Lesser General Public
  18  * License along with this library; if not, write to the Free Software
  19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20  *
  21  *
  22  * @link http://www.phpinsider.com/php/code/GoogleMapAPI/
  23  * @link http://www.phpwcms.de/
  24  * @copyright 2005 New Digital Group, Inc.
  25  * @author Monte Ohrt <monte at ohrt dot com>
  26  * @author Oliver Georgi <oliver at phpwcms dot de>
  27  * @package GoogleMapAPI
  28  * @version 2.5
  29  */
  30  
  31  /* $Id: GoogleMapAPI.class.php,v 1.63 2007/08/03 16:29:40 mohrt Exp $ */
  32  
  33  /*
  34  
  35  ************
  36  Enhanced by Oliver Georgi, 2009-06-29 for use with phpwcms Content Management System
  37  ************
  38  
  39  For best results with GoogleMaps, use XHTML compliant web pages with this header:
  40  
  41  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  42  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  43  
  44  For database caching, you will want to use this schema:
  45  
  46  CREATE TABLE `phpwcms_geocodes` (
  47    `address` varchar(255) NOT NULL,
  48    `lon` double DEFAULT NULL,
  49    `lat` double DEFAULT NULL,
  50    PRIMARY KEY (`address`),
  51    KEY `lon` (`lon`),
  52    KEY `lat` (`lat`)
  53  ) ENGINE=MyISAM;
  54  
  55  
  56  */
  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      * YOUR GooglMap API KEY for your site.
  70      * (http://maps.google.com/apis/maps/signup.html)
  71      *
  72      * @var string
  73      */
  74      var $api_key = '';
  75  
  76      /**
  77      * current map id, set when you instantiate
  78      * the GoogleMapAPI object.
  79      *
  80      * @var string
  81      */
  82      var $map_id = null;
  83  
  84      /**
  85      * sidebar <div> used along with this map.
  86      *
  87      * @var string
  88      */
  89      var $sidebar_id = null;
  90  
  91      /**
  92      * GoogleMapAPI uses the Yahoo geocode lookup API.
  93      * This is the application ID for YOUR application.
  94      * This is set upon instantiating the GoogleMapAPI object.
  95      * (http://developer.yahoo.net/faq/index.html#appid)
  96      *
  97      * @var string
  98      */
  99      var $app_id = null;
 100  
 101      /**
 102      * use onLoad() to load the map javascript.
 103      * if enabled, be sure to include on your webpage:
 104      * <html onload="onLoad()">
 105      *
 106      * @var string
 107      */
 108      var $onload = true;
 109  
 110      /**
 111      * map center latitude (horizontal)
 112      * calculated automatically as markers
 113      * are added to the map.
 114      *
 115      * @var float
 116      */
 117      var $center_lat = null;
 118  
 119      /**
 120      * map center longitude (vertical)
 121      * calculated automatically as markers
 122      * are added to the map.
 123      *
 124      * @var float
 125      */
 126      var $center_lon = null;
 127  
 128      /**
 129      * enables map controls (zoom/move/center)
 130      *
 131      * @var boolean
 132      */
 133      var $map_controls = true;
 134  
 135      /**
 136      * determines the map control type
 137      * small -> show move/center controls
 138      * large -> show move/center/zoom controls
 139      *
 140      * @var string
 141      */
 142      var $control_size = 'large';
 143  
 144      /**
 145      * enables map type controls (map/satellite/hybrid)
 146      *
 147      * @var boolean
 148      */
 149      var $type_controls = true;
 150  
 151      /**
 152      * default map type (G_NORMAL_MAP/G_SATELLITE_MAP/G_HYBRID_MAP)
 153      *
 154      * @var boolean
 155      */
 156      var $map_type = 'G_NORMAL_MAP';
 157  
 158      /**
 159      * enables scale map control
 160      *
 161      * @var boolean
 162      */
 163      var $scale_control = true;
 164  
 165      /**
 166      * enables overview map control
 167      *
 168      * @var boolean
 169      */
 170      var $overview_control = false;
 171  
 172      /**
 173      * determines the default zoom level
 174      *
 175      * @var integer
 176      */
 177      var $zoom = 16;
 178  
 179      /**
 180      * determines the map width
 181      *
 182      * @var integer
 183      */
 184      var $width = '500px';
 185  
 186      /**
 187      * determines the map height
 188      *
 189      * @var integer
 190      */
 191      var $height = '500px';
 192  
 193      /**
 194      * message that pops up when the browser is incompatible with Google Maps.
 195      * set to empty string to disable.
 196      *
 197      * @var integer
 198      */
 199      var $browser_alert = 'Sorry, the Google Maps API is not compatible with this browser.';
 200  
 201      /**
 202      * message that appears when javascript is disabled.
 203      * set to empty string to disable.
 204      *
 205      * @var string
 206      */
 207      var $js_alert = '<b>Javascript must be enabled in order to use Google Maps.</b>';
 208  
 209      /**
 210      * determines if sidebar is enabled
 211      *
 212      * @var boolean
 213      */
 214      var $sidebar = true;
 215  
 216      /**
 217      * determines if list of point should given
 218      *
 219      * @var boolean
 220      */
 221      var $pointlist = false;
 222  
 223      /**
 224      * determines if to/from directions are included inside info window
 225      *
 226      * @var boolean
 227      */
 228      var $directions = true;
 229  
 230      /**
 231      * determines if map markers bring up an info window
 232      *
 233      * @var boolean
 234      */
 235      var $info_window = true;
 236  
 237      /**
 238      * determines if info window appears with a click or mouseover
 239      *
 240      * @var string click/mouseover
 241      */
 242      var $window_trigger = 'click';
 243  
 244      /**
 245      * what server geocode lookups come from
 246      *
 247      * available: YAHOO  Yahoo! API. US geocode lookups only.
 248      *             GOOGLE Google Maps. This can do international lookups,
 249      *                    but not an official API service so no guarantees.
 250      *             Note: GOOGLE is the default lookup service, please read
 251      *                   the Yahoo! terms of service before using their API.
 252      *
 253      * @var string service name
 254      */
 255      var $lookup_service = 'GOOGLE';
 256      var $lookup_server = array( 'GOOGLE' => 'maps.google.de', 'YAHOO' => 'api.local.yahoo.com' );
 257  
 258      var $driving_dir_text = array( 'dir_to' => 'Startadresse: (Stra&szlig;e, PLZ Stadt, Land)',
 259          'to_button_value' => 'Los!',
 260          'to_button_type' => 'submit',
 261          'dir_from' => 'Zieladresse: (Straße, PLZ Stadt, Land)',
 262          'from_button_value' => 'Los!',
 263          'from_button_type' => 'submit',
 264          'dir_text' => 'Route berechnen: ',
 265          'dir_tohere' => 'Hierher',
 266          'dir_fromhere' => 'Von hier'
 267          );
 268  
 269      /**
 270      * version number
 271      *
 272      * @var string
 273      */
 274      var $_version = '2.5';
 275  
 276      /**
 277      * list of added markers
 278      *
 279      * @var array
 280      */
 281      var $_markers = array();
 282  
 283      /**
 284      * maximum longitude of all markers
 285      *
 286      * @var float
 287      */
 288      var $_max_lon = -1000000;
 289  
 290      /**
 291      * minimum longitude of all markers
 292      *
 293      * @var float
 294      */
 295      var $_min_lon = 1000000;
 296  
 297      /**
 298      * max latitude
 299      *
 300      * @var float
 301      */
 302      var $_max_lat = -1000000;
 303  
 304      /**
 305      * min latitude
 306      *
 307      * @var float
 308      */
 309      var $_min_lat = 1000000;
 310  
 311      /**
 312      * determines if we should zoom to minimum level (above this->zoom value) that will encompass all markers
 313      *
 314      * @var boolean
 315      */
 316      var $zoom_encompass = true;
 317      
 318      /**
 319      * determines if we can zoom using a mouse's scroll wheel.
 320      *
 321      * @var boolean
 322      */
 323      var $zoom_wheel = false;
 324  
 325      /**
 326      * factor by which to fudge the boundaries so that when we zoom encompass, the markers aren't too close to the edge
 327      *
 328      * @var float
 329      */
 330      var $bounds_fudge = 0.01;
 331  
 332      /**
 333      * use the first suggestion by a google lookup if exact match not found
 334      *
 335      * @var float
 336      */
 337      var $use_suggest = false;
 338  
 339      /**
 340      * list of added polylines
 341      *
 342      * @var array
 343      */
 344      var $_polylines = array();
 345  
 346      /**
 347      * icon info array
 348      *
 349      * @var array
 350      */
 351      var $_icons = array();
 352      
 353      /**
 354      * icon cache array
 355      *
 356      * @var array
 357      */
 358      var $_icon_cache = array();
 359  
 360      /**
 361      * database cache table name
 362      *
 363      * @var string
 364      */
 365      var $_db_cache_table = 'phpwcms_geocodes';
 366      
 367      /**
 368      * JSON class path
 369      *
 370      * @var string
 371      */
 372      var $class_json_path = 'JSON.php';
 373      var $use_json = false;
 374      
 375      /**
 376      * geocode placemarks returned by getGeocode
 377      * it's helpful to check this too and show
 378      * alternative addresses returned by Google Maps
 379      *
 380      * @var array
 381      */
 382      var $Geocode_Placemark = array();
 383      
 384      
 385      /**
 386      * debug enable
 387      *
 388      * @var bool
 389      */
 390      var $_debug = false;
 391      
 392      /**
 393      * debug log path/file
 394      *
 395      * @var string
 396      */
 397      var $_debug_file = '';
 398      
 399      /**
 400      * use MooTools to access element by ID
 401      *
 402      * @var bool
 403      */
 404      var $_mootools = FALSE;
 405      
 406  
 407      /**
 408      * class constructor
 409      *
 410      * @param string $map_id the id for this map
 411      * @param string $app_id YOUR Yahoo App ID
 412      */
 413  	function GoogleMapAPI( $map_id = 'map', $app_id = 'MyMapApp' )
 414      {
 415          $this->map_id = $map_id;
 416          $this->sidebar_id = 'sidebar_' . $map_id;
 417          $this->app_id = $app_id;
 418          $this->document_root = $_SERVER['DOCUMENT_ROOT'];
 419          $this->_debug_file = empty($this->_debug_file) ? PHPWCMS_TEMP.'maps_url.log' : $this->_debug_file;
 420      }
 421      
 422  	function initMap($map_id = 'map', $app_id = 'MyMapApp')
 423      {
 424          $this->map_id = $map_id;
 425          $this->sidebar_id = 'sidebar_' . $map_id;
 426          $this->app_id = $app_id;
 427      }
 428  
 429      /**
 430      * sets the PEAR::DB dsn
 431      *
 432      * @param string $dsn
 433      */
 434  	function setDSN( $dsn )
 435      {
 436          $this->dsn = $dsn;
 437      }
 438  
 439  	function enableMooTools()
 440      {
 441          $this->_mootools = TRUE;
 442      }
 443      
 444  	function disableMooTools()
 445      {
 446          $this->_mootools = FALSE;
 447      }
 448      
 449  	function useJson($path=NULL) {
 450          if($path != NULL) {
 451              $this->class_json_path = $path;
 452          }
 453          if( require_once( $this->class_json_path ) ) {
 454              $this->use_json = true;
 455          } else {
 456              $this->use_json = false;
 457          }
 458      }
 459      
 460  	function useCSV() {
 461          $this->use_json = false;
 462      }
 463  
 464      /**
 465      * return the element by ID JavaScript String
 466      *
 467      * @param string $dsn
 468      */
 469  	function getElementById()
 470      {
 471          return $this->_mootools ? '$' : 'document.getElementById';
 472      }
 473  
 474      /**
 475      * sets YOUR Google Map API key
 476      *
 477      * @param string $key
 478      */
 479  	function setAPIKey( $key )
 480      {
 481          $this->api_key = $key;
 482      }
 483  
 484      /**
 485      * sets the width of the map
 486      *
 487      * @param string $width
 488      */
 489  	function setWidth( $width )
 490      {
 491          if ( !preg_match( '!^(\d+)(.*)$!', $width, $_match ) )
 492              return false;
 493  
 494          $_width = $_match[1];
 495          $_type = $_match[2];
 496          if ( $_type == '%' )
 497              $this->width = $_width . '%';
 498          else
 499              $this->width = $_width . 'px';
 500  
 501          return true;
 502      }
 503  
 504      /**
 505      * sets the height of the map
 506      *
 507      * @param string $height
 508      */
 509  	function setHeight( $height )
 510      {
 511          if ( !preg_match( '!^(\d+)(.*)$!', $height, $_match ) )
 512              return false;
 513  
 514          $_height = $_match[1];
 515          $_type = $_match[2];
 516          if ( $_type == '%' )
 517              $this->height = $_height . '%';
 518          else
 519              $this->height = $_height . 'px';
 520  
 521          return true;
 522      }
 523  
 524      /**
 525      * sets the default map zoom level
 526      *
 527      * @param string $level
 528      */
 529  	function setZoomLevel( $level )
 530      {
 531          $this->zoom = ( int ) $level;
 532      }
 533  
 534      /**
 535      * enables the map controls (zoom/move)
 536      */
 537  	function enableMapControls()
 538      {
 539          $this->map_controls = true;
 540      }
 541  
 542      /**
 543      * disables the map controls (zoom/move)
 544      */
 545  	function disableMapControls()
 546      {
 547          $this->map_controls = false;
 548      }
 549  
 550      /**
 551      * sets the map control size (large/small)
 552      *
 553      * @param string $size
 554      */
 555  	function setControlSize( $size )
 556      {
 557          if ( in_array( $size, array( 'large', 'small', 'medium' ) ) )
 558              $this->control_size = $size;
 559      }
 560  
 561      /**
 562      * enables the type controls (map/satellite/hybrid)
 563      */
 564  	function enableTypeControls()
 565      {
 566          $this->type_controls = true;
 567      }
 568  
 569      /**
 570      * disables the type controls (map/satellite/hybrid)
 571      */
 572  	function disableTypeControls()
 573      {
 574          $this->type_controls = false;
 575      }
 576  
 577      /**
 578      * set default map type (map/satellite/hybrid)
 579      */
 580  	function setMapType( $type )
 581      {
 582          switch ( $type )
 583          {
 584              case 'hybrid':            $this->map_type = 'G_HYBRID_MAP';            break;
 585              case 'satellite':        $this->map_type = 'G_SATELLITE_MAP';        break;
 586              case 'physical':        $this->map_type = 'G_PHYSICAL_MAP';            break;
 587              case 'moon_elevation':    $this->map_type = 'G_MOON_ELEVATION_MAP';    break;
 588              case 'moon':            $this->map_type = 'G_MOON_VISIBLE_MAP';        break;
 589              case 'mars_elevation':    $this->map_type = 'G_MARS_ELEVATION_MAP';    break;
 590              case 'mars':            $this->map_type = 'G_MARS_VISIBLE_MAP';        break;
 591              case 'mars_infrared':    $this->map_type = 'G_MARS_INFRARED_MAP';    break;
 592              case 'nightsky':        $this->map_type = 'G_SKY_VISIBLE_MAP';        break;
 593              
 594              case 'map':
 595              case 'normal':
 596              default:            $this->map_type = 'G_NORMAL_MAP';        break;
 597          }
 598      }
 599  
 600      /**
 601      * enables onload
 602      */
 603  	function enableOnLoad()
 604      {
 605          $this->onload = true;
 606      }
 607  
 608      /**
 609      * disables onload
 610      */
 611  	function disableOnLoad()
 612      {
 613          $this->onload = false;
 614      }
 615  
 616      /**
 617      * enables sidebar
 618      */
 619  	function enableSidebar()
 620      {
 621          $this->sidebar = true;
 622      }
 623  
 624      /**
 625      * disables sidebar
 626      */
 627  	function disableSidebar()
 628      {
 629          $this->sidebar = false;
 630      }
 631  
 632      /**
 633      * enables pointlist
 634      */
 635  	function enablePointlist()
 636      {
 637          $this->pointlist = true;
 638      }
 639  
 640      /**
 641      * disables sidebar
 642      */
 643  	function disablePointlist()
 644      {
 645          $this->pointlist = false;
 646      }
 647  
 648      /**
 649      * enables map directions inside info window
 650      */
 651  	function enableDirections()
 652      {
 653          $this->directions = true;
 654      }
 655  
 656      /**
 657      * disables map directions inside info window
 658      */
 659  	function disableDirections()
 660      {
 661          $this->directions = false;
 662      }
 663  
 664      /**
 665      * set browser alert message for incompatible browsers
 666      *
 667      * @params $message string
 668      */
 669  	function setBrowserAlert( $message )
 670      {
 671          $this->browser_alert = $message;
 672      }
 673  
 674      /**
 675      * set <noscript> message when javascript is disabled
 676      *
 677      * @params $message string
 678      */
 679  	function setJSAlert( $message )
 680      {
 681          $this->js_alert = $message;
 682      }
 683  
 684      /**
 685      * enable map marker info windows
 686      */
 687  	function enableInfoWindow()
 688      {
 689          $this->info_window = true;
 690      }
 691  
 692      /**
 693      * disable map marker info windows
 694      */
 695  	function disableInfoWindow()
 696      {
 697          $this->info_window = false;
 698      }
 699  
 700      /**
 701      * set the info window trigger action
 702      *
 703      * @params $message string click/mouseover
 704      */
 705  	function setInfoWindowTrigger( $type )
 706      {
 707          switch ( $type )
 708          {
 709              case 'mouseover':
 710                  $this->window_trigger = 'mouseover';
 711                  break;
 712              default:
 713                  $this->window_trigger = 'click';
 714                  break;
 715          }
 716      }
 717  
 718      /**
 719      * enable zoom to encompass makers
 720      */
 721  	function enableZoomEncompass()
 722      {
 723          $this->zoom_encompass = true;
 724      }
 725  
 726      /**
 727      * disable zoom to encompass makers
 728      */
 729  	function disableZoomEncompass()
 730      {
 731          $this->zoom_encompass = false;
 732      }
 733  
 734      /**
 735      * enable zoom using a mouse's scroll wheel.
 736      */
 737  	function enableZoomWheel()
 738      {
 739          $this->zoom_wheel = true;
 740      }
 741  
 742      /**
 743      * disable zoom using a mouse's scroll wheel.
 744      */
 745  	function disableZoomWheel()
 746      {
 747          $this->zoom_wheel = false;
 748      }
 749  
 750      /**
 751      * set the boundary fudge factor
 752      */
 753  	function setBoundsFudge( $val )
 754      {
 755          $this->bounds_fudge = $val;
 756      }
 757  
 758      /**
 759      * enables the scale map control
 760      */
 761  	function enableScaleControl()
 762      {
 763          $this->scale_control = true;
 764      }
 765  
 766      /**
 767      * disables the scale map control
 768      */
 769  	function disableScaleControl()
 770      {
 771          $this->scale_control = false;
 772      }
 773  
 774      /**
 775      * enables the overview map control
 776      */
 777  	function enableOverviewControl()
 778      {
 779          $this->overview_control = true;
 780      }
 781  
 782      /**
 783      * disables the overview map control
 784      */
 785  	function disableOverviewControl()
 786      {
 787          $this->overview_control = false;
 788      }
 789  
 790      /**
 791      * set the lookup service to use for geocode lookups
 792      * default is YAHOO, you can also use GOOGLE.
 793      * NOTE: GOOGLE can to intl lookups, but is not an
 794      * official API, so use at your own risk.
 795      */
 796  	function setLookupService( $service )
 797      {
 798          switch ( $service )
 799          {
 800              case 'GOOGLE':
 801                  $this->lookup_service = 'GOOGLE';
 802                  break;
 803              case 'YAHOO':
 804              default:
 805                  $this->lookup_service = 'YAHOO';
 806                  break;
 807          }
 808      }
 809  
 810      /**
 811      * adds a map marker by address
 812      *
 813      * @param string $address the map address to mark (street/city/state/zip)
 814      * @param string $title the title display in the sidebar
 815      * @param string $html the HTML block to display in the info bubble (if empty, title is used)
 816      */
 817  	function addMarkerByAddress( $address, $title = '', $html = '', $tooltip = '' )
 818      {
 819          $_geocode = $this->getGeocode( $address );
 820          if ( $_geocode === false ) {
 821              return false;
 822          }
 823          return $this->addMarkerByCoords( $_geocode['lon'], $_geocode['lat'], $title, $html, $tooltip );
 824      }
 825  
 826      /**
 827      * adds a map marker by geocode
 828      *
 829      * @param string $lon the map longitude (horizontal)
 830      * @param string $lat the map latitude (vertical)
 831      * @param string $title the title display in the sidebar
 832      * @param string $html |array $html
 833      *      string: the HTML block to display in the info bubble (if empty, title is used)
 834      *      array: The title => content pairs for a tabbed info bubble
 835      */
 836      // TODO make it so you can specify which tab you want the directions to appear in (add another arg)
 837  	function addMarkerByCoords( $lon, $lat, $title = '', $html = '', $tooltip = '' )
 838      {
 839          $_marker['lon'] = $lon;
 840          $_marker['lat'] = $lat;
 841          $_marker['html'] = ( is_array( $html ) || strlen( $html ) > 0 ) ? $html : $title;
 842          $_marker['title'] = $title;
 843          $_marker['tooltip'] = $tooltip;
 844          $this->_markers[] = $_marker;
 845          $this->adjustCenterCoords( $_marker['lon'], $_marker['lat'] );
 846          // return index of marker
 847          return count( $this->_markers ) - 1;
 848      }
 849  
 850      /**
 851      * adds a map polyline by address
 852      * if color, weight and opacity are not defined, use the google maps defaults
 853      *
 854      * @param string $address1 the map address to draw from
 855      * @param string $address2 the map address to draw to
 856      * @param string $color the color of the line (format: #000000)
 857      * @param string $weight the weight of the line in pixels
 858      * @param string $opacity the line opacity (percentage)
 859      */
 860  	function addPolyLineByAddress( $address1, $address2, $color = '', $weight = 0, $opacity = 0 )
 861      {
 862          if ( ( $_geocode1 = $this->getGeocode( $address1 ) ) === false )
 863              return false;
 864          if ( ( $_geocode2 = $this->getGeocode( $address2 ) ) === false )
 865              return false;
 866          return $this->addPolyLineByCoords( $_geocode1['lon'], $_geocode1['lat'], $_geocode2['lon'], $_geocode2['lat'], $color, $weight, $opacity );
 867      }
 868  
 869      /**
 870      * adds a map polyline by map coordinates
 871      * if color, weight and opacity are not defined, use the google maps defaults
 872      *
 873      * @param string $lon1 the map longitude to draw from
 874      * @param string $lat1 the map latitude to draw from
 875      * @param string $lon2 the map longitude to draw to
 876      * @param string $lat2 the map latitude to draw to
 877      * @param string $color the color of the line (format: #000000)
 878      * @param string $weight the weight of the line in pixels
 879      * @param string $opacity the line opacity (percentage)
 880      */
 881  	function addPolyLineByCoords( $lon1, $lat1, $lon2, $lat2, $color = '', $weight = 0, $opacity = 0 )
 882      {
 883          $_polyline['lon1'] = $lon1;
 884          $_polyline['lat1'] = $lat1;
 885          $_polyline['lon2'] = $lon2;
 886          $_polyline['lat2'] = $lat2;
 887          $_polyline['color'] = $color;
 888          $_polyline['weight'] = $weight;
 889          $_polyline['opacity'] = $opacity;
 890          $this->_polylines[] = $_polyline;
 891          $this->adjustCenterCoords( $_polyline['lon1'], $_polyline['lat1'] );
 892          $this->adjustCenterCoords( $_polyline['lon2'], $_polyline['lat2'] );
 893          // return index of polyline
 894          return count( $this->_polylines ) - 1;
 895      }
 896  
 897      /**
 898      * adjust map center coordinates by the given lat/lon point
 899      *
 900      * @param string $lon the map latitude (horizontal)
 901      * @param string $lat the map latitude (vertical)
 902      */
 903  	function adjustCenterCoords( $lon, $lat )
 904      {
 905          if ( strlen( ( string )$lon ) == 0 || strlen( ( string )$lat ) == 0 )
 906              return false;
 907          $this->_max_lon = ( float ) max( $lon, $this->_max_lon );
 908          $this->_min_lon = ( float ) min( $lon, $this->_min_lon );
 909          $this->_max_lat = ( float ) max( $lat, $this->_max_lat );
 910          $this->_min_lat = ( float ) min( $lat, $this->_min_lat );
 911  
 912          $this->center_lon = ( float ) ( $this->_min_lon + $this->_max_lon ) / 2;
 913          $this->center_lat = ( float ) ( $this->_min_lat + $this->_max_lat ) / 2;
 914          return true;
 915      }
 916  
 917      /**
 918      * set map center coordinates to lat/lon point
 919      *
 920      * @param string $lon the map latitude (horizontal)
 921      * @param string $lat the map latitude (vertical)
 922      */
 923  	function setCenterCoords( $lon, $lat )
 924      {
 925          $this->center_lat = ( float ) $lat;
 926          $this->center_lon = ( float ) $lon;
 927      }
 928  
 929      /**
 930      * generate an array of params for a new marker icon image
 931      * iconShadowImage is optional
 932      * If anchor coords are not supplied, we use the center point of the image by default.
 933      * Can be called statically. For private use by addMarkerIcon() and setMarkerIcon()
 934      * Uses icon cache to speed up marker image handling
 935      *
 936      * @param string $iconImage URL to icon image
 937      * @param string $iconShadowImage URL to shadow image
 938      * @param string $iconAnchorX X coordinate for icon anchor point
 939      * @param string $iconAnchorY Y coordinate for icon anchor point
 940      * @param string $infoWindowAnchorX X coordinate for info window anchor point
 941      * @param string $infoWindowAnchorY Y coordinate for info window anchor point
 942      */
 943  	function createMarkerIcon( $iconImage, $iconShadowImage = '', $iconAnchorX = 'x', $iconAnchorY = 'x', $infoWindowAnchorX = 'x', $infoWindowAnchorY = 'x' )
 944      {
 945          $_icon_image_path    = strpos( $iconImage, 'http' ) === 0 ? $iconImage : $this->document_root . $iconImage;
 946          $_icon_cache_key    = md5($_icon_image_path . $iconShadowImage . $iconAnchorX . $iconAnchorY . $infoWindowAnchorX . $infoWindowAnchorY);
 947          if(isset($this->_icon_cache[ $_icon_cache_key ]))
 948          {
 949              return $this->_icon_cache[ $_icon_cache_key ];
 950          }        
 951          if ( !( $_image_info = @getimagesize( $_icon_image_path ) ) )
 952          {
 953              return FALSE;
 954              //die( 'GoogleMapAPI:createMarkerIcon: Error reading image: ' . $iconImage );
 955          }
 956          if ( $iconShadowImage )
 957          {
 958              $_shadow_image_path = strpos( $iconShadowImage, 'http' ) === 0 ? $iconShadowImage : $this->document_root . $iconShadowImage;
 959              if ( !( $_shadow_info = @getimagesize( $_shadow_image_path ) ) )
 960              {
 961                  return FALSE;
 962                  die( 'GoogleMapAPI:createMarkerIcon: Error reading image: ' . $iconShadowImage );
 963              }
 964          }
 965  
 966          if ( $iconAnchorX === 'x' )
 967          {
 968              $iconAnchorX = ( int ) ( $_image_info[0] / 2 );
 969          }
 970          if ( $iconAnchorY === 'x' )
 971          {
 972              $iconAnchorY = ( int ) ( $_image_info[1] / 2 );
 973          }
 974          if ( $infoWindowAnchorX === 'x' )
 975          {
 976              $infoWindowAnchorX = ( int ) ( $_image_info[0] / 2 );
 977          }
 978          if ( $infoWindowAnchorY === 'x' )
 979          {
 980              $infoWindowAnchorY = ( int ) ( $_image_info[1] / 2 );
 981          }
 982  
 983          $icon_info = array( 'image' => $iconImage,
 984              'iconWidth' => $_image_info[0],
 985              'iconHeight' => $_image_info[1],
 986              'iconAnchorX' => $iconAnchorX,
 987              'iconAnchorY' => $iconAnchorY,
 988              'infoWindowAnchorX' => $infoWindowAnchorX,
 989              'infoWindowAnchorY' => $infoWindowAnchorY
 990              );
 991          if ( $iconShadowImage )
 992          {
 993              $icon_info = array_merge( $icon_info, array( 'shadow' => $iconShadowImage,
 994                      'shadowWidth' => $_shadow_info[0],
 995                      'shadowHeight' => $_shadow_info[1] ) );
 996          }
 997          
 998          $this->_icon_cache[ $_icon_cache_key ] = $icon_info;
 999          
1000          return $icon_info;
1001      }
1002  
1003      /**
1004      * set the marker icon for ALL markers on the map
1005      */
1006  	function setMarkerIcon( $iconImage, $iconShadowImage = '', $iconAnchorX = 'x', $iconAnchorY = 'x', $infoWindowAnchorX = 'x', $infoWindowAnchorY = 'x' )
1007      {
1008          $result = $this->createMarkerIcon( $iconImage, $iconShadowImage, $iconAnchorX, $iconAnchorY, $infoWindowAnchorX, $infoWindowAnchorY );
1009          if($result !== FALSE) {
1010              $this->_icons = array( $result );
1011          }
1012      }
1013  
1014      /**
1015      * add an icon to go with the correspondingly added marker
1016      */
1017  	function addMarkerIcon( $iconImage, $iconShadowImage = '', $iconAnchorX = 'x', $iconAnchorY = 'x', $infoWindowAnchorX = 'x', $infoWindowAnchorY = 'x' )
1018      {
1019          $result = $this->createMarkerIcon( $iconImage, $iconShadowImage, $iconAnchorX, $iconAnchorY, $infoWindowAnchorX, $infoWindowAnchorY );
1020          if($result !== FALSE) {
1021              $this->_icons[] = $result;
1022          }
1023          return count( $this->_icons ) - 1;
1024      }
1025  
1026      /**
1027      * print map header javascript (goes between <head></head>)
1028      */
1029  	function printHeaderJS()
1030      {
1031          echo $this->getHeaderJS();
1032      }
1033  
1034      /**
1035      * return map header javascript (goes between <head></head>)
1036      */
1037  	function getHeaderJS()
1038      {
1039          return sprintf( '<script src="http://maps.google.de/maps?file=api&amp;v=2.x&amp;key=%s" type="text/javascript" charset="utf-8"></script>', $this->api_key );
1040      }
1041  
1042      /**
1043      * prints onLoad() without having to manipulate body tag.
1044      * call this after the print map like so...
1045      *       $map->printMap();
1046      *       $map->printOnLoad();
1047      */
1048  	function printOnLoad()
1049      {
1050          echo $this->getOnLoad();
1051      }
1052  
1053      /**
1054      * return js to set onload function
1055      */
1056  	function getOnLoad()
1057      {
1058          return '<script language="javascript" type="text/javascript" charset="utf-8">window.onload=onLoad;</script>';
1059      }
1060  
1061      /**
1062      * print map javascript (put just before </body>, or in <header> if using onLoad())
1063      */
1064  	function printMapJS()
1065      {
1066          echo $this->getMapJS();
1067      }
1068  
1069      /**
1070      * return map javascript
1071      */
1072  	function getMapJS()
1073      {
1074          $_output = '<script type="text/javascript">' . "\n";
1075          $_output .= '//<![CDATA[' . "\n";
1076          $_output .= "/*************************************************\n";
1077          $_output .= " * Created with GoogleMapAPI " . $this->_version . "\n";
1078          $_output .= " * Author: Monte Ohrt <monte AT ohrt DOT com>\n";
1079          $_output .= " * Copyright 2005-2006 New Digital Group\n";
1080          $_output .= " * http://www.phpinsider.com/php/code/GoogleMapAPI/\n";
1081          $_output .= " *************************************************/\n";
1082  
1083          $_output .= 'var points = [];' . "\n";
1084          $_output .= 'var markers = [];' . "\n";
1085          $_output .= 'var counter = 0;' . "\n";
1086          if ( $this->sidebar )
1087          {
1088              $_output .= 'var sidebar_html = "";' . "\n";
1089              $_output .= 'var marker_html = [];' . "\n";
1090          }
1091  
1092          if ( $this->pointlist )
1093          {
1094              $_output .= 'var pointlist_html = "";' . "\n";
1095              if ( !$this->sidebar )
1096              {
1097                  $_output .= 'var marker_html = [];' . "\n";
1098              }
1099          }
1100  
1101          if ( $this->directions )
1102          {
1103              $_output .= 'var to_htmls = [];' . "\n";
1104              $_output .= 'var from_htmls = [];' . "\n";
1105          }
1106  
1107          if ( !empty( $this->_icons ) )
1108          {
1109              // define temporary icon storage
1110              $exist_icn = array();
1111              $_output .= 'var icon = [];' . "\n";
1112              for( $i = 0, $j = count( $this->_icons ); $i < $j; $i++ )
1113              {
1114                  $info = $this->_icons[$i];
1115                  // hash the icon data to see if we've already got this one; if so, save some javascript
1116                  $icon_key = md5( serialize( $info ) );
1117                  if ( !isset( $exist_icn[$icon_key] ) ) {
1118                      $_output .= "icon[$i] = new GIcon();\n";
1119                      $_output .= sprintf( 'icon[%s].image = "%s";', $i, $info['image'] ) . "\n";
1120                      if ( $info['shadow'] )
1121                      {
1122                          $_output .= sprintf( 'icon[%s].shadow = "%s";', $i, $info['shadow'] ) . "\n";
1123                          $_output .= sprintf( 'icon[%s].shadowSize = new GSize(%s,%s);', $i, $info['shadowWidth'], $info['shadowHeight'] ) . "\n";
1124                      }
1125                      $_output .= sprintf( 'icon[%s].iconSize = new GSize(%s,%s);', $i, $info['iconWidth'], $info['iconHeight'] ) . "\n";
1126                      $_output .= sprintf( 'icon[%s].iconAnchor = new GPoint(%s,%s);', $i, $info['iconAnchorX'], $info['iconAnchorY'] ) . "\n";
1127                      $_output .= sprintf( 'icon[%s].infoWindowAnchor = new GPoint(%s,%s);', $i, $info['infoWindowAnchorX'], $info['infoWindowAnchorY'] ) . "\n";
1128                      
1129                      // save current icon
1130                      $exist_icn[$icon_key] = $i;
1131                      
1132                  } else {
1133                      $_output .= 'icon['.$i.'] = icon[' . $exist_icn[ $icon_key] . "];\n";
1134                  }
1135              }
1136          }
1137  
1138          $_output .= 'var map = null;' . "\n";
1139  
1140          if ( $this->onload )
1141          {
1142              $_output .= 'function onLoad() {' . "\n";
1143          }
1144  
1145          if ( !empty( $this->browser_alert ) )
1146          {
1147              $_output .= 'if (GBrowserIsCompatible()) {' . "\n";
1148          }
1149  
1150          $_output .= sprintf( 'var mapObj = '.$this->getElementById().'("%s");', $this->map_id ) . "\n";
1151          $_output .= 'if (mapObj != "undefined" && mapObj != null) {' . "\n";
1152          $_output .= sprintf( 'map = new GMap2( mapObj );', $this->map_id ) . "\n";
1153          if ( isset( $this->center_lat ) && isset( $this->center_lon ) )
1154          {
1155              // Special care for decimal point in lon and lat, would get lost if "wrong" locale is set; applies to (s)printf only
1156              $_output .= sprintf( 'map.setCenter(new GLatLng(%s, %s), %d, %s);', number_format( $this->center_lat, 6, ".", "" ), number_format( $this->center_lon, 6, ".", "" ), $this->zoom, $this->map_type ) . "\n";
1157          }
1158          // zoom so that all markers are in the viewport
1159          if ( $this->zoom_encompass && count( $this->_markers ) > 1 )
1160          {
1161              // increase bounds by fudge factor to keep
1162              // markers away from the edges
1163              $_len_lon = $this->_max_lon - $this->_min_lon;
1164              $_len_lat = $this->_max_lat - $this->_min_lat;
1165              $this->_min_lon -= $_len_lon * $this->bounds_fudge;
1166              $this->_max_lon += $_len_lon * $this->bounds_fudge;
1167              $this->_min_lat -= $_len_lat * $this->bounds_fudge;
1168              $this->_max_lat += $_len_lat * $this->bounds_fudge;
1169  
1170              $_output .= "var bds = new GLatLngBounds(new GLatLng($this->_min_lat, $this->_min_lon), new GLatLng($this->_max_lat, $this->_max_lon));\n";
1171              $_output .= 'map.setZoom(map.getBoundsZoomLevel(bds));' . "\n";
1172          }
1173          
1174          if( $this->zoom_wheel ) {
1175              $_output .= 'map.enableScrollWheelZoom();' . "\n";
1176          } else {
1177              $_output .= 'map.disableScrollWheelZoom();' . "\n";
1178          }
1179  
1180          if ( $this->map_controls )
1181          {
1182              if ( $this->control_size == 'large' )
1183                  $_output .= 'map.addControl(new GLargeMapControl());' . "\n";
1184              else
1185                  $_output .= 'map.addControl(new GSmallMapControl());' . "\n";
1186          }
1187          if ( $this->type_controls )
1188          {
1189              $_output .= 'map.addControl(new GMapTypeControl());' . "\n";
1190          }
1191  
1192          if ( $this->scale_control )
1193          {
1194              $_output .= 'map.addControl(new GScaleControl());' . "\n";
1195          }
1196  
1197          if ( $this->overview_control )
1198          {
1199              $_output .= 'map.addControl(new GOverviewMapControl());' . "\n";
1200          }
1201  
1202          $_output .= $this->getAddMarkersJS();
1203  
1204          $_output .= $this->getPolylineJS();
1205  
1206          if ( $this->sidebar )
1207          {
1208              $_output .= 'var sidebar_el = ' . $this->getElementById().'("'.$this->sidebar_id.'");' . "\n";
1209              $_output .= 'if(sidebar_el){' . 'sidebar_el.innerHTML = "<"+"ul class=\"gmapSidebar\">"+ sidebar_html +"<"+"\/ul>";}' . "\n";
1210          }
1211  
1212          $_output .= '}' . "\n";
1213  
1214          if ( !empty( $this->browser_alert ) )
1215          {
1216              $_output .= '} else {' . "\n";
1217              $_output .= 'alert("' . str_replace( '"', '\"', $this->browser_alert ) . '");' . "\n";
1218              $_output .= '}' . "\n";
1219          }
1220          
1221          if(isset($this->jump_index))
1222          {
1223              $_output .= 'click_sidebar('.$this->jump_index.');' . "\n";
1224          }
1225  
1226          if ( $this->onload )
1227          {
1228              $_output .= '}' . "\n";
1229          }
1230  
1231          $_output .= $this->getCreateMarkerJS();
1232          // Utility functions used to distinguish between tabbed and non-tabbed info windows
1233          $_output .= 'function isArray(a){return isObject(a) && a.constructor == Array;}' . "\n";
1234          $_output .= 'function isObject(a){return (a && typeof a == \'object\') || isFunction(a);}' . "\n";
1235          $_output .= 'function isFunction(a){return typeof a == \'function\';}' . "\n";
1236  
1237          if ( $this->sidebar || $this->pointlist ) // use it for pointlist too
1238          {
1239              $_output .= 'function click_sidebar(idx) {';
1240              $_output .= 'if(isArray(marker_html[idx])){markers[idx].openInfoWindowTabsHtml(marker_html[idx]);}';
1241              $_output .= 'else{markers[idx].openInfoWindowHtml(marker_html[idx]);}}' . "\n";
1242          }
1243          $_output .= 'function showInfoWindow(idx,html){map.centerAtLatLng(points[idx]);markers[idx].openInfoWindowHtml(html);}' . "\n";
1244          if ( $this->directions )
1245          {
1246              $_output .= 'function tohere(idx){markers[idx].openInfoWindowHtml(to_htmls[idx]);}' . "\n";
1247              $_output .= 'function fromhere(idx){markers[idx].openInfoWindowHtml(from_htmls[idx]);}' . "\n";
1248          }
1249  
1250          if($this->_mootools) {
1251              $_output .= "\nfunction unloadGoogleMaps(){window.addEvent('unload', function(){GUnload();});}\n";
1252              $_output .= "window.addEvent('domready', function(){if($('".$this->map_id."')){onLoad();unloadGoogleMaps();}});\n";
1253          }
1254          $_output .= "\n//]]>\n";
1255          $_output .= "</script>\n";
1256          return $_output;
1257      }
1258  
1259      /**
1260      * overridable function for generating js to add markers
1261      */
1262  	function getAddMarkersJS()
1263      {
1264          $SINGLE_TAB_WIDTH = 88; // constant: width in pixels of each tab heading (set by google)
1265          $i = 0;
1266          $_output = '';
1267          foreach( $this->_markers as $_marker )
1268          {
1269              if ( is_array( $_marker['html'] ) )
1270              {
1271                  // warning: you can't have two tabs with the same header. but why would you want to?
1272                  $ti = 0;
1273                  $num_tabs = count( $_marker['html'] );
1274                  $tab_obs = array();
1275                  foreach( $_marker['html'] as $tab => $info )
1276                  {
1277                      if ( $ti == 0 && $num_tabs > 2 )
1278                      {
1279                          $width_style = sprintf( ' style=\"width: %spx\"', $num_tabs * $SINGLE_TAB_WIDTH );
1280                      }
1281                      else
1282                      {
1283                          $width_style = '';
1284                      }
1285                      $tab = str_replace( '"', '\"', $tab );
1286                      $info = str_replace( '"', '\"', $info );
1287                      $info = str_replace( array( "\n", "\r" ), "", $info );
1288                      $tab_obs[] = sprintf( 'new GInfoWindowTab("%s", "%s")', $tab, '<div id=\"gmapmarker\"' . $width_style . '>' . $info . '</div>' );
1289                      $ti++;
1290                  }
1291                  $iw_html = '[' . join( ',', $tab_obs ) . ']';
1292              }
1293              else
1294              {
1295                  $iw_html = sprintf( '"%s"', str_replace( '"', '\"', '<div id="gmapmarker">' . str_replace( array( "\n", "\r" ), "", $_marker['html'] ) . '</div>' ) );
1296              }
1297              
1298              // make it smaller, save all JS vars and do functions call direct in map.addOverlay
1299              $_p  = 'new GLatLng('.$_marker['lat'].','.$_marker['lon'].')';
1300              $_m  = 'createMarker('.$_p.',"'.str_replace( '"', '\"', $_marker['title'] );
1301              $_m .= '",'.str_replace( '/', '\/', $iw_html ).', '.$i.',"'.str_replace( '"', '\"', $_marker['tooltip'] ).'")';
1302              $_output .= 'map.addOverlay('.$_m.');' . "\n";
1303              $i++;
1304          }
1305          return $_output;
1306      }
1307  
1308      /**
1309      * overridable function to generate polyline js
1310      */
1311  	function getPolylineJS()
1312      {
1313          $_output = '';
1314          foreach( $this->_polylines as $_polyline )
1315          {
1316              $_output .= sprintf( 'var polyline = new GPolyline([new GLatLng(%s,%s),new GLatLng(%s,%s)],"%s",%s,%s);',
1317                  $_polyline['lat1'], $_polyline['lon1'], $_polyline['lat2'], $_polyline['lon2'], $_polyline['color'], $_polyline['weight'], $_polyline['opacity'] / 100.0 ) . "\n";
1318              $_output .= 'map.addOverlay(polyline);' . "\n";
1319          }
1320          return $_output;
1321      }
1322  
1323      /**
1324      * overridable function to generate the js for the js function for creating a marker.
1325      */
1326  	function getCreateMarkerJS()
1327      {
1328          $_output = 'function createMarker(point, title, html, n, tooltip) {' . "\n";
1329          $_output .= 'if(n >= ' . sizeof( $this->_icons ) . ') { n = ' . ( sizeof( $this->_icons ) - 1 ) . "; }\n";
1330          if ( !empty( $this->_icons ) )
1331          {
1332              $_output .= 'var marker = new GMarker(point,{\'icon\': icon[n], \'title\': tooltip});' . "\n";
1333          }
1334          else
1335          {
1336              $_output .= 'var marker = new GMarker(point,{\'title\': tooltip});' . "\n";
1337          }
1338          // TODO: make it so you can specify which tab you want the directions in.
1339          if ( $this->directions )
1340          {
1341              // WARNING: If you are using a tabbed info window AND directions: this uses an UNDOCUMENTED field
1342              // of the GInfoWindowTab object, contentElem. Google may CHANGE this name or other aspects of their
1343              // GInfoWindowTab implementation without warning and BREAK this code.
1344              // NOTE: If you are NOT using a tabbed info window, you'll be fine.
1345              $_output .= 'var tabFlag = isArray(html);' . "\n";
1346              $_output .= 'if(!tabFlag) { html = [{"contentElem": html}]; }' . "\n";
1347              $_output .= sprintf( "to_htmls[counter] = html[0].contentElem + '<form class=\"gmapDir\" id=\"gmapDirTo\" style=\"white-space: nowrap;\" action=\"http://maps.google.de/maps\" method=\"get\" target=\"_blank\">' +
1348                       '<span class=\"gmapDirHead\" id=\"gmapDirHeadTo\">%s<strong>%s<'+'/strong> - <a href=\"javascript:fromhere(' + counter + ')\">%s<' + '/a><' + '/span>' +
1349                       '<p class=\"gmapDirItem\" id=\"gmapDirItemTo\"><label for=\"gmapDirSaddr\" class=\"gmapDirLabel\" id=\"gmapDirLabelTo\">%s<br /' + '><' + '/label>' +
1350                       '<input type=\"text\" size=\"40\" maxlength=\"40\" name=\"saddr\" class=\"gmapTextBox\" id=\"gmapDirSaddr\" value=\"\" /' + '>' +
1351                       '<span class=\"gmapDirBtns\" id=\"gmapDirBtnsTo\"><input value=\"%s\" type=\"%s\" class=\"gmapDirButton\" id=\"gmapDirButtonTo\" /' + '><' + '/span><' + '/p>' +
1352                       '<input type=\"hidden\" name=\"daddr\" value=\"' +
1353                       point.y + ',' + point.x + \"(\" + title.replace(new RegExp(/\"/g),'&quot;') + \")\" + '\" /' + '><' + '/form>';
1354                        from_htmls[counter] = html[0].contentElem + '<form class=\"gmapDir\" id=\"gmapDirFrom\" style=\"white-space: nowrap;\" action=\"http://maps.google.com/maps\" method=\"get\" target=\"_blank\">' +
1355                       '<span class=\"gmapDirHead\" id=\"gmapDirHeadFrom\">%s<a href=\"javascript:tohere(' + counter + ')\">%s<'+'/a> - <strong>%s<' + '/strong><' + '/span>' +
1356                       '<p class=\"gmapDirItem\" id=\"gmapDirItemFrom\"><label for=\"gmapDirSaddr\" class=\"gmapDirLabel\" id=\"gmapDirLabelFrom\">%s<br /' + '><' + '/label>' +
1357                       '<input type=\"text\" size=\"40\" maxlength=\"40\" name=\"daddr\" class=\"gmapTextBox\" id=\"gmapDirSaddr\" value=\"\" /' + '>' +
1358                       '<span class=\"gmapDirBtns\" id=\"gmapDirBtnsFrom\"><input value=\"%s\" type=\"%s\" class=\"gmapDirButton\" id=\"gmapDirButtonFrom\" /' + '><' + '/span><' + '/p>' +
1359                       '<input type=\"hidden\" name=\"saddr\" value=\"' +
1360                       point.y + ',' + point.x + encodeURIComponent(\"(\" + title.replace(new RegExp(/\"/g),'&quot;') + \")\") + '\" /' + '><' + '/form>';
1361                       html[0].contentElem = html[0].contentElem + '<p /' + '><div id=\"gmapDirHead\" class=\"gmapDir\" style=\"white-space: nowrap;\">%s<a href=\"javascript:tohere(' + counter + ')\">%s<' + '/a> - <a href=\"javascript:fromhere(' + counter + ')\">%s<' + '/a><' + '/div>';\n",
1362                  $this->driving_dir_text['dir_text'],
1363                  $this->driving_dir_text['dir_tohere'],
1364                  $this->driving_dir_text['dir_fromhere'],
1365                  $this->driving_dir_text['dir_to'],
1366                  $this->driving_dir_text['to_button_value'],
1367                  $this->driving_dir_text['to_button_type'],
1368                  $this->driving_dir_text['dir_text'],
1369                  $this->driving_dir_text['dir_tohere'],
1370                  $this->driving_dir_text['dir_fromhere'],
1371                  $this->driving_dir_text['dir_from'],
1372                  $this->driving_dir_text['from_button_value'],
1373                  $this->driving_dir_text['from_button_type'],
1374                  $this->driving_dir_text['dir_text'],
1375                  $this->driving_dir_text['dir_tohere'],
1376                  $this->driving_dir_text['dir_fromhere']
1377                  );
1378              $_output .= 'if(!tabFlag) { html = html[0].contentElem; }';
1379          }
1380  
1381          if ( $this->info_window )
1382          {
1383              $_output .= sprintf( 'if(isArray(html)) { GEvent.addListener(marker, "%s", function() { marker.openInfoWindowTabsHtml(html); }); }', $this->window_trigger ) . "\n";
1384              $_output .= sprintf( 'else { GEvent.addListener(marker, "%s", function() { marker.openInfoWindowHtml(html); }); }', $this->window_trigger ) . "\n";
1385          }
1386          $_output .= 'points[counter] = point;' . "\n";
1387          $_output .= 'markers[counter] = marker;' . "\n";
1388          if ( $this->sidebar || $this->pointlist ) // pointlist too
1389          {
1390              $_output .= 'marker_html[counter] = html;' . "\n";
1391              if ( $this->sidebar )
1392              {
1393                  $_output .= "sidebar_html += '<li class=\"gmapSidebarItem\" id=\"gmapSidebarItem_'+ counter +'\"><a href=\"javascript:click_sidebar(' + counter + ')\">' + title + '<\/a><\/li>';" . "\n";
1394              }
1395              if ( $this->pointlist )
1396              {
1397                  $_output .= "pointlist_html += '<option value=\"' + counter + '\">' + title + '<\/option>';" . "\n";
1398              }
1399          }
1400          $_output .= 'counter++;' . "\n";
1401          $_output .= 'return marker;' . "\n";
1402          $_output .= '}' . "\n";
1403          return $_output;
1404      }
1405  
1406      /**
1407      * print map (put at location map will appear)
1408      */
1409  	function printMap()
1410      {
1411          echo $this->getMap();
1412      }
1413  
1414      /**
1415      * return map
1416      */
1417  	function getMap()
1418      {
1419          if($this->_mootools) {
1420              
1421              $js_alert = empty( $this->js_alert ) ? '' : '<span class="' . $this->map_id . '-jsalert">' . $this->js_alert . '</span>';
1422              
1423              if ( strlen( $this->width ) > 0 && strlen( $this->height ) > 0 )
1424              {
1425                  $_output  = sprintf( '<div id="%s" style="width:%s;height:%s">', $this->map_id, $this->width, $this->height );
1426              }
1427              else
1428              {
1429                  $_output  = sprintf( '<div id="%s">', $this->map_id );
1430              }
1431              
1432              $_output .= $js_alert . '</div>';
1433              
1434          } else {
1435          
1436              $_output  = '<script type="text/javascript" charset="utf-8">' . "\n" . '//<![CDATA[' . "\n";
1437              $_output .= 'if (GBrowserIsCompatible()) {' . "\n";
1438              if ( strlen( $this->width ) > 0 && strlen( $this->height ) > 0 )
1439              {
1440                  $_output .= sprintf( 'document.write(\'<div id="%s" style="width:%s;height:%s"><\/div>\');', $this->map_id, $this->width, $this->height ) . "\n";
1441              }
1442              else
1443              {
1444                  $_output .= sprintf( 'document.write(\'<div id="%s"><\/div>\');', $this->map_id ) . "\n";
1445              }
1446              $_output .= '}';
1447      
1448              if ( !empty( $this->browser_alert ) )
1449              {
1450                  $_output .= ' else {' . "\n";
1451                  $_output .= sprintf( 'document.write(\'%s\');', str_replace( '/', '\/', $this->browser_alert ) ) . "\n";
1452                  $_output .= '}' . "\n";
1453              }
1454      
1455              $_output .= '//]]>' . "\n" . '</script>' . "\n";
1456      
1457              if ( !empty( $this->js_alert ) )
1458              {
1459                  $_output .= '<noscript>' . $this->js_alert . '</noscript>' . "\n";
1460              }
1461              
1462          }
1463  
1464          return $_output;
1465      }
1466  
1467      /**
1468      * print sidebar (put at location sidebar will appear)
1469      */
1470  	function printSidebar()
1471      {
1472          echo $this->getSidebar();
1473      }
1474  
1475      /**
1476      * return sidebar html
1477      */
1478  	function getSidebar()
1479      {
1480          return sprintf( '<div id="%s"></div>', $this->sidebar_id ) . "\n";
1481      }
1482  
1483      /**
1484      * get the geocode lat/lon points from given address
1485      * look in cache first, otherwise get from Yahoo
1486      *
1487      * @param string $address
1488      */
1489  	function getGeocode( $address )
1490      {
1491          $this->Geocode_Placemark = array();
1492      
1493          if ( empty( $address ) ) {
1494              return false;
1495          }    
1496  
1497          $_geocode = $this->getCache( $address );
1498  
1499          if ( $_geocode === false )
1500          {
1501              $_geocode = $this->geoGetCoords( $address );
1502              
1503              if ( $_geocode !== false )
1504              {
1505                  if( count($this->Geocode_Placemark) > 1) {
1506                      return false;
1507                  }
1508                  $this->putCache( $address, $_geocode['lon'], $_geocode['lat'] );
1509              }
1510          }
1511  
1512          return $_geocode;
1513      }
1514  
1515      /**
1516      * get the geocode lat/lon points from cache for given address
1517      *
1518      * @param string $address
1519      */
1520  	function getCache( $address )
1521      {
1522          $_ret = array();
1523          $_row = _dbQuery( 'SELECT lon,lat FROM ' . DB_PREPEND . $this->_db_cache_table . " WHERE address = '" . aporeplace( $address ) . "'" );
1524          if ( isset( $_row[0] ) ) {
1525              
1526              $_ret['lon'] = $_row[0]['lon'];
1527              $_ret['lat'] = $_row[0]['lat'];
1528              
1529          } elseif( $_row === false && $this->_db_cache_table ) {
1530              
1531              $sql  = 'CREATE TABLE IF NOT EXISTS `' . DB_PREPEND . $this->_db_cache_table . '` (';
1532              $sql .= ' `address` varchar(255) NOT NULL, ';
1533              $sql .= '`lon` double DEFAULT NULL, ';
1534              $sql .= '`lat` double DEFAULT NULL, ';
1535              $sql .= 'PRIMARY KEY (`address`), ';
1536              $sql .= 'KEY `lon` (`lon`), ';
1537              $sql .= 'KEY `lat` (`lat`) ';
1538              $sql .= ') ENGINE=MyISAM';
1539              
1540              _dbQuery($sql, 'CREATE');
1541              
1542          }
1543          return isset( $_ret['lon'] ) ? $_ret : false;
1544      }
1545  
1546      /**
1547      * put the geocode lat/lon points into cache for given address
1548      *
1549      * @param string $address
1550      * @param string $lon the map latitude (horizontal)
1551      * @param string $lat the map latitude (vertical)
1552      */
1553  	function putCache( $address, $lon, $lat )
1554      {
1555          if ( strlen( $address ) == 0 || strlen( $lon ) == 0 || strlen( $lat ) == 0 ) {
1556              return false;
1557          }
1558          _dbInsert( $this->_db_cache_table, array( 'address' => $address, 'lon' => $lon, 'lat' => $lat ), 'LOW_PRIORITY' );
1559  
1560          return true;
1561      }
1562  
1563      /**
1564      * get geocode lat/lon points for given address from Yahoo
1565      *
1566      * @param string $address
1567      */
1568      function geoGetCoords($address,$depth=0) {
1569          
1570          $_coords = array('lon'=>NULL, 'lat'=>NULL);
1571          
1572          switch($this->lookup_service) {
1573                          
1574              case 'GOOGLE':
1575              
1576                  $_result = false;
1577                  
1578                  // use JSON
1579                  if($this->use_json) {
1580                  
1581                      // changed to JSON, it's more accurate
1582                      $_url = sprintf( 'http://%s/maps/geo?&q=%s&output=json&key=%s', $this->lookup_server['GOOGLE'], rawurlencode( $address ), $this->api_key );
1583                      
1584                      if ( $_result = $this->fetchURL( $_url ) ) {
1585                          
1586                          $json = new Services_JSON();
1587                          $_result_parts = $json->decode( $_result );
1588                          
1589                          if(!isset($_result_parts->Placemark[0]) || !isset($_result_parts->Status->code) || $_result_parts->Status->code != 200) {
1590                              return false;
1591                          }
1592                          
1593                          $_coords['lat']        = $_result_parts->Placemark[0]->Point->coordinates[1];
1594                          $_coords['lon']        = $_result_parts->Placemark[0]->Point->coordinates[0];
1595                          
1596                          $this->Geocode_Placemark = $_result_parts->Placemark;
1597          
1598                      }
1599                  
1600                  // Use CSV
1601                  } else {
1602      
1603                      $_url = sprintf('http://%s/maps/geo?&q=%s&output=csv&key=%s',$this->lookup_server['GOOGLE'],rawurlencode($address),$this->api_key);
1604  
1605                      if($_result = $this->fetchURL($_url)) {
1606      
1607                          $_result_parts = explode(',',$_result);
1608                          if($_result_parts[0] != 200) {
1609                              return false;
1610                          }
1611                          $_coords['lat'] = $_result_parts[2];
1612                          $_coords['lon'] = $_result_parts[3];
1613                      }
1614                      
1615                  }
1616                  
1617                  break;
1618              
1619              case 'YAHOO':
1620              default:
1621                          
1622                  $_url = 'http://%s/MapsService/V1/geocode';
1623                  $_url .= sprintf('?appid=%s&location=%s',$this->lookup_server['YAHOO'],$this->app_id,rawurlencode($address));
1624  
1625                  $_result = false;
1626  
1627                  if($_result = $this->fetchURL($_url)) {
1628  
1629                      preg_match('!<Latitude>(.*)</Latitude><Longitude>(.*)</Longitude>!U', $_result, $_match);
1630  
1631                      $_coords['lon'] = $_match[2];
1632                      $_coords['lat'] = $_match[1];
1633  
1634                  }
1635                  
1636                  break;
1637          }         
1638  
1639          return $_coords;       
1640      }
1641  
1642      /**
1643      * fetch a URL. Override this method to change the way URLs are fetched.
1644      *
1645      * @param string $url
1646      */
1647  	function fetchURL( $url )
1648      {
1649          if($this->_debug && $this->_debug_file) {
1650              @file_put_contents($this->_debug_file, date('Y/m/d H:i:s') . ' - ' . $url . LF, FILE_APPEND);
1651          }
1652          return file_get_contents( $url );
1653      }
1654  
1655      /**
1656      * get distance between to geocoords using great circle distance formula
1657      *
1658      * @param float $lat1
1659      * @param float $lat2
1660      * @param float $lon1
1661      * @param float $lon2
1662      * @param float $unit M=miles, K=kilometers, N=nautical miles, I=inches, F=feet
1663      */
1664  	function geoGetDistance( $lat1, $lon1, $lat2, $lon2, $unit = 'M' )
1665      {
1666          // calculate miles
1667          $M = 69.09 * rad2deg( acos( sin( deg2rad( $lat1 ) ) * sin( deg2rad( $lat2 ) ) + cos( deg2rad( $lat1 ) ) * cos( deg2rad( $lat2 ) ) * cos( deg2rad( $lon1 - $lon2 ) ) ) );
1668  
1669          switch ( strtoupper( $unit ) )
1670          {
1671              case 'K':
1672                  // kilometers
1673                  return $M * 1.609344;
1674                  break;
1675              case 'N':
1676                  // nautical miles
1677                  return $M * 0.868976242;
1678                  break;
1679              case 'F':
1680                  // feet
1681                  return $M * 5280;
1682                  break;
1683              case 'I':
1684                  // inches
1685                  return $M * 63360;
1686                  break;
1687              case 'M':
1688              default:
1689                  // miles
1690                  return $M;
1691                  break;
1692          }
1693      }
1694      
1695      /**
1696      * get distance between two geocoords using great circle distance formula and return in kilometer (KM)
1697      *
1698      * @param float $lat1
1699      * @param float $lat2
1700      * @param float $lon1
1701      * @param float $lon2
1702      */    
1703  	function geoGetDistanceInKM(  $lat1, $lon1, $lat2, $lon2 )
1704      {
1705          $earthRadius = 6371.0;
1706          return acos( ( sin( deg2rad($lat1) ) * sin( deg2rad($lat2) ) ) + ( cos( deg2rad($lat1) ) * cos( deg2rad($lat2) ) * cos( deg2rad($lon1 - $lon2) ) ) ) * $earthRadius;
1707      }
1708  }
1709  
1710  ?>


Generated: Tue Nov 16 22:51:00 2010 Cross-referenced by PHPXref 0.7