2 error_reporting(E_STRICT | E_ALL
);
5 * Project: GoogleMapAPI: a PHP library inteface to the Google Map API
6 * File: GoogleMapAPI.class.php
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * For questions, help, comments, discussion, etc., please join the
23 * Smarty mailing list. Send a blank e-mail to
24 * smarty-general-subscribe@lists.php.net
26 * @link http://www.phpinsider.com/php/code/GoogleMapAPI/
27 * @copyright 2005 New Digital Group, Inc.
28 * @author Monte Ohrt <monte at ohrt dot com>
29 * @package GoogleMapAPI
33 /* $Id: GoogleMapAPI.class.php,v 1.63 2007/08/03 16:29:40 mohrt Exp $ */
37 For best results with GoogleMaps, use XHTML compliant web pages with this header:
39 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
40 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
42 For database caching, you will want to use this schema:
44 CREATE TABLE GEOCODES (
45 address varchar(255) NOT NULL default '',
46 lon float default NULL,
47 lat float default NULL,
56 * PEAR::DB DSN for geocode caching. example:
57 * $dsn = 'mysql://user:pass@localhost/dbname';
64 * YOUR GooglMap API KEY for your site.
65 * (http://maps.google.com/apis/maps/signup.html)
72 * current map id, set when you instantiate
73 * the GoogleMapAPI object.
80 * sidebar <div> used along with this map.
84 var $sidebar_id = NULL;
87 * GoogleMapAPI uses the Yahoo geocode lookup API.
88 * This is the application ID for YOUR application.
89 * This is set upon instantiating the GoogleMapAPI object.
90 * (http://developer.yahoo.net/faq/index.html#appid)
97 * use onLoad() to load the map javascript.
98 * if enabled, be sure to include on your webpage:
99 * <html onload="onLoad()">
106 * map center latitude (horizontal)
107 * calculated automatically as markers
108 * are added to the map.
112 var $center_lat = null;
115 * map center longitude (vertical)
116 * calculated automatically as markers
117 * are added to the map.
121 var $center_lon = null;
124 * enables map controls (zoom/move/center)
128 var $map_controls = true;
131 * determines the map control type
132 * small -> show move/center controls
133 * large -> show move/center/zoom controls
137 var $control_size = 'large';
140 * enables map type controls (map/satellite/hybrid)
144 var $type_controls = true;
147 * default map type (G_NORMAL_MAP/G_SATELLITE_MAP/G_HYBRID_MAP)
151 var $map_type = 'G_NORMAL_MAP';
154 * enables scale map control
158 var $scale_control = true;
163 var $disable_drag = false;
166 * enables overview map control
170 var $overview_control = false;
173 * determines the default zoom level
180 * determines the map width
184 var $width = '500px';
187 * determines the map height
191 var $height = '500px';
194 * message that pops up when the browser is incompatible with Google Maps.
195 * set to empty string to disable.
199 var $browser_alert = 'Sorry, the Google Maps API is not compatible with this browser.';
202 * message that appears when javascript is disabled.
203 * set to empty string to disable.
207 var $js_alert = '<b>Javascript must be enabled in order to use Google Maps.</b>';
210 * determines if sidebar is enabled
217 * determines if to/from directions are included inside info window
221 var $directions = false;
224 * determines if map markers bring up an info window
228 var $info_window = true;
231 * determines if info window appears with a click or mouseover
233 * @var string click/mouseover
235 var $window_trigger = 'click';
238 * what server geocode lookups come from
240 * available: YAHOO Yahoo! API. US geocode lookups only.
241 * GOOGLE Google Maps. This can do international lookups,
242 * but not an official API service so no guarantees.
243 * Note: GOOGLE is the default lookup service, please read
244 * the Yahoo! terms of service before using their API.
246 * @var string service name
248 var $lookup_service = 'GOOGLE';
249 var $lookup_server = array('GOOGLE' => 'maps.google.com', 'YAHOO' => 'api.local.yahoo.com');
256 var $_version = '2.5';
259 * list of added markers
263 var $_markers = array();
266 * maximum longitude of all markers
270 var $_max_lon = -1000000;
273 * minimum longitude of all markers
277 var $_min_lon = 1000000;
284 var $_max_lat = -1000000;
291 var $_min_lat = 1000000;
294 * determines if we should zoom to minimum level (above this->zoom value) that will encompass all markers
298 var $zoom_encompass = true;
301 * factor by which to fudge the boundaries so that when we zoom encompass, the markers aren't too close to the edge
305 var $bounds_fudge = 0.01;
308 * use the first suggestion by a google lookup if exact match not found
312 var $use_suggest = false;
316 * list of added polylines
320 var $_polylines = array();
327 var $_icons = array();
330 * database cache table name
334 var $_db_cache_table = 'GEOCODES';
340 * @param string $map_id the id for this map
341 * @param string $app_id YOUR Yahoo App ID
343 function GoogleMapAPI($map_id = 'map', $app_id = 'MyMapApp') {
344 $this->map_id
= $map_id;
345 $this->sidebar_id
= 'sidebar_' . $map_id;
346 $this->app_id
= $app_id;
350 * sets the PEAR::DB dsn
354 function setDSN($dsn) {
359 * sets YOUR Google Map API key
363 function setAPIKey($key) {
364 $this->api_key
= $key;
368 * sets the width of the map
370 * @param string $width
372 function setWidth($width) {
373 if(!preg_match('!^(\d+)(.*)$!',$width,$_match))
376 $_width = $_match[1];
379 $this->width
= $_width . '%';
381 $this->width
= $_width . 'px';
387 * sets the height of the map
389 * @param string $height
391 function setHeight($height) {
392 if(!preg_match('!^(\d+)(.*)$!',$height,$_match))
395 $_height = $_match[1];
398 $this->height
= $_height . '%';
400 $this->height
= $_height . 'px';
406 * sets the default map zoom level
408 * @param string $level
410 function setZoomLevel($level) {
411 $this->zoom
= (int) $level;
415 * enables the map controls (zoom/move)
418 function enableMapControls() {
419 $this->map_controls
= true;
423 * disables the map controls (zoom/move)
426 function disableMapControls() {
427 $this->map_controls
= false;
431 * sets the map control size (large/small)
433 * @param string $size
435 function setControlSize($size) {
436 if(in_array($size,array('large','small')))
437 $this->control_size
= $size;
441 * enables the type controls (map/satellite/hybrid)
444 function enableTypeControls() {
445 $this->type_controls
= true;
449 * disables the type controls (map/satellite/hybrid)
452 function disableTypeControls() {
453 $this->type_controls
= false;
457 * set default map type (map/satellite/hybrid)
460 function setMapType($type) {
463 $this->map_type
= 'G_HYBRID_MAP';
466 $this->map_type
= 'G_SATELLITE_MAP';
470 $this->map_type
= 'G_NORMAL_MAP';
479 function enableOnLoad() {
480 $this->onload
= true;
487 function disableOnLoad() {
488 $this->onload
= false;
495 function enableSidebar() {
496 $this->sidebar
= true;
503 function disableSidebar() {
504 $this->sidebar
= false;
508 * enables map directions inside info window
511 function enableDirections() {
512 $this->directions
= true;
516 * disables map directions inside info window
519 function disableDirections() {
520 $this->directions
= false;
524 * set browser alert message for incompatible browsers
526 * @params $message string
528 function setBrowserAlert($message) {
529 $this->browser_alert
= $message;
533 * set <noscript> message when javascript is disabled
535 * @params $message string
537 function setJSAlert($message) {
538 $this->js_alert
= $message;
542 * enable map marker info windows
544 function enableInfoWindow() {
545 $this->info_window
= true;
549 * disable map marker info windows
551 function disableInfoWindow() {
552 $this->info_window
= false;
556 * set the info window trigger action
558 * @params $message string click/mouseover
560 function setInfoWindowTrigger($type) {
563 $this->window_trigger
= 'mouseover';
566 $this->window_trigger
= 'click';
572 * enable zoom to encompass makers
574 function enableZoomEncompass() {
575 $this->zoom_encompass
= true;
579 * disable zoom to encompass makers
581 function disableZoomEncompass() {
582 $this->zoom_encompass
= false;
586 * set the boundary fudge factor
588 function setBoundsFudge($val) {
589 $this->bounds_fudge
= $val;
593 * enables the scale map control
596 function enableScaleControl() {
597 $this->scale_control
= true;
601 * disables the scale map control
604 function disableScaleControl() {
605 $this->scale_control
= false;
609 * enables the overview map control
612 function enableOverviewControl() {
613 $this->overview_control
= true;
617 * disables the overview map control
620 function disableOverviewControl() {
621 $this->overview_control
= false;
626 * set the lookup service to use for geocode lookups
627 * default is YAHOO, you can also use GOOGLE.
628 * NOTE: GOOGLE can to intl lookups, but is not an
629 * official API, so use at your own risk.
632 function setLookupService($service) {
635 $this->lookup_service
= 'GOOGLE';
639 $this->lookup_service
= 'YAHOO';
646 * adds a map marker by address
648 * @param string $address the map address to mark (street/city/state/zip)
649 * @param string $title the title display in the sidebar
650 * @param string $html the HTML block to display in the info bubble (if empty, title is used)
652 function addMarkerByAddress($address,$title = '',$html = '',$tooltip = '',$id = '') {
653 if(($_geocode = $this->getGeocode($address)) === false)
655 return $this->addMarkerByCoords($_geocode['lon'],$_geocode['lat'],$title,$html,$tooltip);
659 * adds a map marker by geocode
661 * @param string $lon the map longitude (horizontal)
662 * @param string $lat the map latitude (vertical)
663 * @param string $title the title display in the sidebar
664 * @param string $html|array $html
665 * string: the HTML block to display in the info bubble (if empty, title is used)
666 * array: The title => content pairs for a tabbed info bubble
668 // TODO make it so you can specify which tab you want the directions to appear in (add another arg)
669 function addMarkerByCoords($lon,$lat,$title = '',$html = '',$tooltip = '',$id = '') {
670 $_marker['lon'] = $lon;
671 $_marker['lat'] = $lat;
672 $_marker['html'] = (is_array($html) ||
strlen($html) > 0) ?
$html : $title;
673 $_marker['title'] = $title;
674 $_marker['tooltip'] = $tooltip;
675 $_marker['id'] = $id;
676 $this->_markers
[] = $_marker;
677 $this->adjustCenterCoords($_marker['lon'],$_marker['lat']);
678 // return index of marker
680 return count($this->_markers
) - 1;
685 function deleteMarkers() {
686 unset ($this->_markers
);
690 * adds a map polyline by address
691 * if color, weight and opacity are not defined, use the google maps defaults
693 * @param string $address1 the map address to draw from
694 * @param string $address2 the map address to draw to
695 * @param string $color the color of the line (format: #000000)
696 * @param string $weight the weight of the line in pixels
697 * @param string $opacity the line opacity (percentage)
699 function addPolyLineByAddress($address1,$address2,$color='',$weight=0,$opacity=0) {
700 if(($_geocode1 = $this->getGeocode($address1)) === false)
702 if(($_geocode2 = $this->getGeocode($address2)) === false)
704 return $this->addPolyLineByCoords($_geocode1['lon'],$_geocode1['lat'],$_geocode2['lon'],$_geocode2['lat'],$color,$weight,$opacity);
708 * adds a map polyline by map coordinates
709 * if color, weight and opacity are not defined, use the google maps defaults
711 * @param string $lon1 the map longitude to draw from
712 * @param string $lat1 the map latitude to draw from
713 * @param string $lon2 the map longitude to draw to
714 * @param string $lat2 the map latitude to draw to
715 * @param string $color the color of the line (format: #000000)
716 * @param string $weight the weight of the line in pixels
717 * @param string $opacity the line opacity (percentage)
719 function addPolyLineByCoords($lon1,$lat1,$lon2,$lat2,$color='',$weight=0,$opacity=0) {
720 $_polyline['lon1'] = $lon1;
721 $_polyline['lat1'] = $lat1;
722 $_polyline['lon2'] = $lon2;
723 $_polyline['lat2'] = $lat2;
724 $_polyline['color'] = $color;
725 $_polyline['weight'] = $weight;
726 $_polyline['opacity'] = $opacity;
727 $this->_polylines
[] = $_polyline;
728 $this->adjustCenterCoords($_polyline['lon1'],$_polyline['lat1']);
729 $this->adjustCenterCoords($_polyline['lon2'],$_polyline['lat2']);
730 // return index of polyline
731 return count($this->_polylines
) - 1;
735 * adjust map center coordinates by the given lat/lon point
737 * @param string $lon the map latitude (horizontal)
738 * @param string $lat the map latitude (vertical)
740 function adjustCenterCoords($lon,$lat) {
741 if(strlen((string)$lon) == 0 ||
strlen((string)$lat) == 0)
743 $this->_max_lon
= (float) max($lon, $this->_max_lon
);
744 $this->_min_lon
= (float) min($lon, $this->_min_lon
);
745 $this->_max_lat
= (float) max($lat, $this->_max_lat
);
746 $this->_min_lat
= (float) min($lat, $this->_min_lat
);
748 $this->center_lon
= (float) ($this->_min_lon +
$this->_max_lon
) / 2;
749 $this->center_lat
= (float) ($this->_min_lat +
$this->_max_lat
) / 2;
754 * set map center coordinates to lat/lon point
756 * @param string $lon the map latitude (horizontal)
757 * @param string $lat the map latitude (vertical)
759 function setCenterCoords($lon,$lat) {
760 $this->center_lat
= (float) $lat;
761 $this->center_lon
= (float) $lon;
765 * generate an array of params for a new marker icon image
766 * iconShadowImage is optional
767 * If anchor coords are not supplied, we use the center point of the image by default.
768 * Can be called statically. For private use by addMarkerIcon() and setMarkerIcon()
770 * @param string $iconImage URL to icon image
771 * @param string $iconShadowImage URL to shadow image
772 * @param string $iconAnchorX X coordinate for icon anchor point
773 * @param string $iconAnchorY Y coordinate for icon anchor point
774 * @param string $infoWindowAnchorX X coordinate for info window anchor point
775 * @param string $infoWindowAnchorY Y coordinate for info window anchor point
777 function createMarkerIcon($iconImage,$iconShadowImage = '',$iconAnchorX = 'x',$iconAnchorY = 'x',$infoWindowAnchorX = 'x',$infoWindowAnchorY = 'x') {
778 $_icon_image_path = $iconImage;
780 if(!($_image_info = @getimagesize
($_icon_image_path))) {
781 die('GoogleMapAPI:createMarkerIcon: Error reading image [1]: ' . $iconImage);
784 if($iconShadowImage) {
785 $_shadow_image_path = $iconShadowImage;
786 if(!($_shadow_info = @getimagesize($_shadow_image_path))) {
787 die('GoogleMapAPI:createMarkerIcon: Error reading image [2]: ' . $iconShadowImage);
792 if($iconAnchorX === 'x') {
793 $iconAnchorX = (int) ($_image_info[0] / 2);
795 if($iconAnchorY === 'x') {
796 $iconAnchorY = (int) ($_image_info[1] / 2);
798 if($infoWindowAnchorX === 'x') {
799 $infoWindowAnchorX = (int) ($_image_info[0] / 2);
801 if($infoWindowAnchorY === 'x') {
802 $infoWindowAnchorY = (int) ($_image_info[1] / 2);
807 'image' => $iconImage,
808 'iconWidth' => '50', //$_image_info[0],
809 'iconHeight' => '50', // $_image_info[1],
810 'iconAnchorX' => $iconAnchorX,
811 'iconAnchorY' => $iconAnchorY,
812 'infoWindowAnchorX' => $infoWindowAnchorX,
813 'infoWindowAnchorY' => $infoWindowAnchorY
817 if($iconShadowImage) {
818 $icon_info = array_merge($icon_info, array('shadow' => $iconShadowImage,
819 'shadowWidth' => '100', $_shadow_info[0],
820 'shadowHeight' => '100', $_shadow_info[1]));
828 * set the marker icon for ALL markers on the map
830 function setMarkerIcon($iconImage,$iconShadowImage = '',$iconAnchorX = 'x',$iconAnchorY = 'x',$infoWindowAnchorX = 'x',$infoWindowAnchorY = 'x') {
831 $this->_icons
= array($this->createMarkerIcon($iconImage,$iconShadowImage,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY));
835 * add an icon to go with the correspondingly added marker
837 function addMarkerIcon($iconImage,$iconShadowImage = '',$iconAnchorX = 'x',$iconAnchorY = 'x',$infoWindowAnchorX = 'x',$infoWindowAnchorY = 'x') {
838 $this->_icons
[] = $this->createMarkerIcon($iconImage,$iconShadowImage,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY);
839 return count($this->_icons
) - 1;
844 * print map javascript (put just before </body>, or in <header> if using onLoad())
847 function printMapJS() {
848 echo $this->getMapJS();
852 * return map javascript
855 function getMapJS() {
856 $_output = '<script type="text/javascript" charset="utf-8">' . "\n";
857 $_output .= '//<![CDATA[' . "\n";
858 $_output .= "/*************************************************\n";
859 $_output .= " * Created with GoogleMapAPI " . $this->_version
. "\n";
860 $_output .= " * Author: Monte Ohrt <monte AT ohrt DOT com>\n";
861 $_output .= " * Copyright 2005-2006 New Digital Group\n";
862 $_output .= " * http://www.phpinsider.com/php/code/GoogleMapAPI/\n";
863 $_output .= " *************************************************/\n";
865 $_output .= 'var points = [];' . "\n";
866 $_output .= 'var markers = [];' . "\n";
867 $_output .= 'var counter = 0;' . "\n";
869 $_output .= 'var sidebar_html = "";' . "\n";
870 $_output .= 'var marker_html = [];' . "\n";
873 if($this->directions
) {
874 $_output .= 'var to_htmls = [];' . "\n";
875 $_output .= 'var from_htmls = [];' . "\n";
878 if(!empty($this->_icons
)) {
879 $_output .= 'var icon = [];' . "\n";
880 for($i = 0, $j = count($this->_icons
); $i<$j; $i++
) {
881 $info = $this->_icons
[$i];
883 // hash the icon data to see if we've already got this one; if so, save some javascript
884 $icon_key = md5(serialize($info));
885 if(!isset($exist_icn[$icon_key])) {
887 $_output .= "icon[$i] = new GIcon();\n";
888 $_output .= sprintf('icon[%s].image = "%s";',$i,$info['image']) . "\n";
889 if(isset($info['shadow'])) {
890 $_output .= sprintf('icon[%s].shadow = "%s";',$i,$info['shadow']) . "\n";
891 $_output .= sprintf('icon[%s].shadowSize = new GSize(%s,%s);',$i,$info['shadowWidth'],$info['shadowHeight']) . "\n";
893 $_output .= sprintf('icon[%s].iconSize = new GSize(%s,%s);',$i,$info['iconWidth'],$info['iconHeight']) . "\n";
894 $_output .= sprintf('icon[%s].iconAnchor = new GPoint(%s,%s);',$i,$info['iconAnchorX'],$info['iconAnchorY']) . "\n";
895 $_output .= sprintf('icon[%s].infoWindowAnchor = new GPoint(%s,%s);',$i,$info['infoWindowAnchorX'],$info['infoWindowAnchorY']) . "\n";
897 $_output .= "icon[$i] = icon[$exist_icn[$icon_key]];\n";
902 $_output .= 'var map = null;' . "\n";
905 $_output .= 'function onLoad() {' . "\n";
908 if(!empty($this->browser_alert
)) {
909 $_output .= 'if (GBrowserIsCompatible()) {' . "\n";
912 $_output .= sprintf('var mapObj = document.getElementById("%s");',$this->map_id
) . "\n";
913 $_output .= 'if (mapObj != "undefined" && mapObj != null) {' . "\n";
914 $_output .= sprintf('map = new GMap2(document.getElementById("%s"));',$this->map_id
) . "\n";
915 if(isset($this->center_lat
) && isset($this->center_lon
)) {
916 // Special care for decimal point in lon and lat, would get lost if "wrong" locale is set; applies to (s)printf only
917 $_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";
920 // zoom so that all markers are in the viewport
921 if($this->zoom_encompass
&& count($this->_markers
) > 1) {
922 // increase bounds by fudge factor to keep
923 // markers away from the edges
924 $_len_lon = $this->_max_lon
- $this->_min_lon
;
925 $_len_lat = $this->_max_lat
- $this->_min_lat
;
926 $this->_min_lon
-= $_len_lon * $this->bounds_fudge
;
927 $this->_max_lon +
= $_len_lon * $this->bounds_fudge
;
928 $this->_min_lat
-= $_len_lat * $this->bounds_fudge
;
929 $this->_max_lat +
= $_len_lat * $this->bounds_fudge
;
931 $_output .= "var bds = new GLatLngBounds(new GLatLng($this->_min_lat, $this->_min_lon), new GLatLng($this->_max_lat, $this->_max_lon));\n";
932 $_output .= 'map.setZoom(map.getBoundsZoomLevel(bds));' . "\n";
935 if($this->map_controls
) {
936 if($this->control_size
== 'large')
937 $_output .= 'map.addControl(new GLargeMapControl());' . "\n";
939 $_output .= 'map.addControl(new GSmallMapControl());' . "\n";
941 if($this->type_controls
) {
942 $_output .= 'map.addControl(new GMapTypeControl());' . "\n";
945 if($this->scale_control
) {
946 $_output .= 'map.addControl(new GScaleControl());' . "\n";
949 if($this->overview_control
) {
950 $_output .= 'map.addControl(new GOverviewMapControl());' . "\n";
954 if($this->disable_drag
) {
955 $_output .= 'map.disableDragging();'."\n";
958 $_output .= $this->getAddMarkersJS();
960 $_output .= $this->getPolylineJS();
964 //$_output .= sprintf('document.getElementById("%s").innerHTML = "<ul class=\"gmapSidebar\">"+ sidebar_html +"<\/ul>";', $this->sidebar_id) . "\n";
965 $_output .= sprintf('document.getElementById("%s").innerHTML = "Ver Eco Mupis:<br /><select id=\"combobox_mupis\" class=\"gmapSidebar\">"+ sidebar_html +"</select>";', 'lista_mupis') . "\n";
966 $_output .= 'click_sidebar($("#combobox_mupis").val())'."\n";
967 $_output .= '$("#combobox_mupis").change(function (){click_sidebar($("#combobox_mupis").val());})'."\n";
970 $_output .= '}' . "\n";
972 if(!empty($this->browser_alert
)) {
973 $_output .= '} else {' . "\n";
974 $_output .= 'alert("' . str_replace('"','\"',$this->browser_alert
) . '");' . "\n";
975 $_output .= '}' . "\n";
979 $_output .= '}' . "\n";
982 $_output .= $this->getCreateMarkerJS();
984 // Utility functions used to distinguish between tabbed and non-tabbed info windows
985 $_output .= 'function isArray(a) {return isObject(a) && a.constructor == Array;}' . "\n";
986 $_output .= 'function isObject(a) {return (a && typeof a == \'object\') || isFunction(a);}' . "\n";
987 $_output .= 'function isFunction(a) {return typeof a == \'function\';}' . "\n";
990 $_output .= 'function click_sidebar(idx) {' . "\n";
991 //$_output .= ' alert(idx);' . "\n";
992 $_output .= ' if(isArray(marker_html[idx])) { markers[idx].openInfoWindowTabsHtml(marker_html[idx]); }' . "\n";
993 $_output .= ' else { markers[idx].openInfoWindowHtml(marker_html[idx]); }' . "\n";
994 $_output .= '}' . "\n";
996 $_output .= 'function showInfoWindow(idx,html) {' . "\n";
997 $_output .= 'map.centerAtLatLng(points[idx]);' . "\n";
998 $_output .= 'markers[idx].openInfoWindowHtml(html);' . "\n";
999 $_output .= '}' . "\n";
1000 if($this->directions
) {
1001 $_output .= 'function tohere(idx) {' . "\n";
1002 $_output .= 'markers[idx].openInfoWindowHtml(to_htmls[idx]);' . "\n";
1003 $_output .= '}' . "\n";
1004 $_output .= 'function fromhere(idx) {' . "\n";
1005 $_output .= 'markers[idx].openInfoWindowHtml(from_htmls[idx]);' . "\n";
1006 $_output .= 'map.updateInfoWindow();' . "\n";
1007 $_output .= '}' . "\n";
1010 $_output .= '//]]>' . "\n";
1011 $_output .= '</script>' . "\n";
1016 * overridable function for generating js to add markers
1018 function getAddMarkersJS() {
1019 $SINGLE_TAB_WIDTH = 88; // constant: width in pixels of each tab heading (set by google)
1022 foreach($this->_markers
as $_marker) {
1023 if(is_array($_marker['html'])) {
1024 // warning: you can't have two tabs with the same header. but why would you want to?
1026 $num_tabs = count($_marker['html']);
1028 foreach($_marker['html'] as $tab => $info) {
1029 if($ti == 0 && $num_tabs > 2) {
1030 $width_style = sprintf(' style=\"width: %spx\"', $num_tabs * $SINGLE_TAB_WIDTH);
1034 $tab = str_replace('"','\"',$tab);
1035 $info = str_replace('"','\"',$info);
1036 $info = str_replace(array("\n", "\r"), "", $info);
1037 $tab_obs[] = sprintf('new GInfoWindowTab("%s", "%s")', $tab, '<div id=\"gmapmarker\"'.$width_style.'>' . $info . '</div>');
1040 $iw_html = '[' . join(',',$tab_obs) . ']';
1042 $iw_html = sprintf('"%s"',str_replace('"','\"','<div id="gmapmarker">' . str_replace(array("\n", "\r"), "", $_marker['html']) . '</div>'));
1045 $_output .= sprintf('var point = new GLatLng(%s,%s);',$_marker['lat'],$_marker['lon']) . "\n";
1046 $_output .= sprintf('var marker = createMarker(point,"%s",%s, %s,"%s","%s");',
1047 str_replace('"','\"',$_marker['title']),
1048 str_replace('/','\/',$iw_html),
1050 str_replace('"','\"',$_marker['tooltip']),
1051 $_marker['id']) . "\n";
1052 //TODO: in above createMarker call, pass the index of the tab in which to put directions, if applicable
1053 $_output .= 'map.addOverlay(marker);' . "\n";
1060 * overridable function to generate polyline js
1062 function getPolylineJS() {
1064 foreach($this->_polylines
as $_polyline) {
1065 $_output .= sprintf('var polyline = new GPolyline([new GLatLng(%s,%s),new GLatLng(%s,%s)],"%s",%s,%s);',
1066 $_polyline['lat1'],$_polyline['lon1'],$_polyline['lat2'],$_polyline['lon2'],$_polyline['color'],$_polyline['weight'],$_polyline['opacity'] / 100.0) . "\n";
1067 $_output .= 'map.addOverlay(polyline);' . "\n";
1073 * overridable function to generate the js for the js function for creating a marker.
1075 // IMPORTANTE!, acá tiene que ir el hack mayor!.
1076 function getCreateMarkerJS() {
1077 $_SCRIPT_ = '$("#datos_mupis").load(\'contenido/mupis+ubicaciones+dinamico.php?accion=mupi&MUPI=\'+id);';
1078 $_output = 'function createMarker(point, title, html, n, tooltip, id) {' . "\n";
1079 $_output .= 'if(n >= '. sizeof($this->_icons
) .') { n = '. (sizeof($this->_icons
) - 1) ."; }\n";
1080 if(!empty($this->_icons
)) {
1081 $_output .= 'var marker = new GMarker(point,{\'icon\': icon[n], \'title\': tooltip});' . "\n";
1083 $_output .= 'var marker = new GMarker(point,{\'title\': tooltip});' . "\n";
1085 if($this->directions
) {
1086 $_output .= 'var tabFlag = isArray(html);' . "\n";
1087 $_output .= 'if(!tabFlag) { html = [{"contentElem": html}]; }' . "\n";
1088 $_output .= 'if(!tabFlag) { html = html[0].contentElem; }';
1091 if($this->info_window
) {
1092 $_output .= sprintf('if(isArray(html)) { GEvent.addListener(marker, "%s", function() { marker.openInfoWindowTabsHtml(html); }); }',$this->window_trigger
) . "\n";
1093 $_output .= sprintf('else { GEvent.addListener(marker, "%s", function() { marker.openInfoWindowHtml(html); '.$_SCRIPT_.' }); }',$this->window_trigger
) . "\n";
1095 $_output .= 'points[counter] = point;' . "\n";
1096 $_output .= 'markers[counter] = marker;' . "\n";
1097 if($this->sidebar
) {
1098 $_output .= 'marker_html[counter] = html;' . "\n";
1100 //$_output .= "sidebar_html += '<li class=\"gmapSidebarItem\" id=\"gmapSidebarItem_'+ counter +'\"><a href=\"javascript:click_sidebar(' + counter + ')\">' + title + '<\/a><\/li>';" . "\n";
1101 $_output .= 'sidebar_html += \'<option class="gmapSidebarItem" id="gmapSidebarItem" value="\'+counter+\'">\' + title + \'</option>\';' . "\n";
1103 $_output .= 'counter++;' . "\n";
1104 $_output .= 'return marker;' . "\n";
1105 $_output .= '}' . "\n";
1110 * print map (put at location map will appear)
1113 function printMap() {
1114 echo $this->getMap();
1123 if(strlen($this->width
) > 0 && strlen($this->height
) > 0) {
1124 $_output .= sprintf('<div id="%s" style="width: %s; height: %s"></div>',$this->map_id
,$this->width
,$this->height
) . "\n";
1126 $_output .= sprintf('<div id="%s"></div>;',$this->map_id
) . "\n";
1133 * print sidebar (put at location sidebar will appear)
1136 function printSidebar() {
1137 echo $this->getSidebar();
1141 * return sidebar html
1144 function getSidebar() {
1145 return sprintf('<div id="%s"></div>',$this->sidebar_id
) . "\n";
1149 * get the geocode lat/lon points from given address
1150 * look in cache first, otherwise get from Yahoo
1152 * @param string $address
1154 function getGeocode($address) {
1160 if(($_geocode = $this->getCache($address)) === false) {
1161 if(($_geocode = $this->geoGetCoords($address)) !== false) {
1162 $this->putCache($address, $_geocode['lon'], $_geocode['lat']);
1170 * get the geocode lat/lon points from cache for given address
1172 * @param string $address
1174 function getCache($address) {
1175 if(!isset($this->dsn
))
1181 require_once('DB.php');
1182 $_db =& DB
::connect($this->dsn
);
1183 if (PEAR
::isError($_db)) {
1184 die($_db->getMessage());
1186 $_res =& $_db->query("SELECT lon,lat FROM {$this->_db_cache_table} where address = ?", $address);
1187 if (PEAR
::isError($_res)) {
1188 die($_res->getMessage());
1190 if($_row = $_res->fetchRow()) {
1191 $_ret['lon'] = $_row[0];
1192 $_ret['lat'] = $_row[1];
1197 return !empty($_ret) ?
$_ret : false;
1201 * put the geocode lat/lon points into cache for given address
1203 * @param string $address
1204 * @param string $lon the map latitude (horizontal)
1205 * @param string $lat the map latitude (vertical)
1207 function putCache($address, $lon, $lat) {
1208 if(!isset($this->dsn
) ||
(strlen($address) == 0 ||
strlen($lon) == 0 ||
strlen($lat) == 0))
1211 require_once('DB.php');
1212 $_db =& DB
::connect($this->dsn
);
1213 if (PEAR
::isError($_db)) {
1214 die($_db->getMessage());
1217 $_res =& $_db->query('insert into '.$this->_db_cache_table
.' values (?, ?, ?)', array($address, $lon, $lat));
1218 if (PEAR
::isError($_res)) {
1219 die($_res->getMessage());
1228 * get geocode lat/lon points for given address from Yahoo
1230 * @param string $address
1232 function geoGetCoords($address,$depth=0) {
1234 switch($this->lookup_service
) {
1238 $_url = sprintf('http://%s/maps/geo?&q=%s&output=csv&key=%s',$this->lookup_server
['GOOGLE'],rawurlencode($address),$this->api_key
);
1242 if($_result = $this->fetchURL($_url)) {
1244 $_result_parts = explode(',',$_result);
1245 if($_result_parts[0] != 200)
1247 $_coords['lat'] = $_result_parts[2];
1248 $_coords['lon'] = $_result_parts[3];
1256 $_url = 'http://%s/MapsService/V1/geocode';
1257 $_url .= sprintf('?appid=%s&location=%s',$this->lookup_server
['YAHOO'],$this->app_id
,rawurlencode($address));
1261 if($_result = $this->fetchURL($_url)) {
1263 preg_match('!<Latitude>(.*)</Latitude><Longitude>(.*)</Longitude>!U', $_result, $_match);
1265 $_coords['lon'] = $_match[2];
1266 $_coords['lat'] = $_match[1];
1279 * fetch a URL. Override this method to change the way URLs are fetched.
1281 * @param string $url
1283 function fetchURL($url) {
1285 return file_get_contents($url);
1290 * get distance between to geocoords using great circle distance formula
1292 * @param float $lat1
1293 * @param float $lat2
1294 * @param float $lon1
1295 * @param float $lon2
1296 * @param float $unit M=miles, K=kilometers, N=nautical miles, I=inches, F=feet
1298 function geoGetDistance($lat1,$lon1,$lat2,$lon2,$unit='K') {
1301 $M = 69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +
cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));
1303 switch(strtoupper($unit))
1307 return $M * 1.609344;
1311 return $M * 0.868976242;