[ Index ] |
PHP Cross Reference of phpwcms V1.4.3 _r380 (23.11.09) |
[Summary view] [Print] [Text view]
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ß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&v=2.x&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),'"') + \")\" + '\" /' + '><' + '/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),'"') + \")\") + '\" /' + '><' + '/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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 30 05:55:15 2009 | Cross-referenced by PHPXref 0.7 |