Mas informaciĆ³n al usuario al momento de usar las ubicaciones en el mapa.
[ecomupi.git] / include / maps / GoogleMapAPI.class.php
bloba8b057adf82b2c1bd8fb164a35b92a004b8db8a9
1 <?php
2 error_reporting(E_STRICT | E_ALL);
4 /**
5 * Project: GoogleMapAPI: a PHP library inteface to the Google Map API
6 * File: GoogleMapAPI.class.php
7 *
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
30 * @version 2.5
33 /* $Id: GoogleMapAPI.class.php,v 1.63 2007/08/03 16:29:40 mohrt Exp $ */
35 class GoogleMapAPI {
37 var $dsn = null;
38 var $api_key = '';
39 var $map_id = null;
40 var $sidebar_id = NULL;
41 var $app_id = null;
42 var $onload = true;
43 var $center_lat = null;
44 var $center_lon = null;
45 var $map_controls = true;
46 var $control_size = 'large';
47 var $type_controls = false;
48 var $map_type = 'G_NORMAL_MAP';
49 var $scale_control = false;
50 var $disable_map_drag = false;
51 var $disable_drag = false;
52 var $referencias = false;
53 var $overview_control = false;
54 var $zoom = 17;
55 var $width = '500px';
56 var $height = '500px';
57 var $sidebar = false;
58 var $info_window = true;
59 var $window_trigger = 'click';
60 var $lookup_service = 'GOOGLE';
61 var $lookup_server = array('GOOGLE' => 'maps.google.com', 'YAHOO' => 'api.local.yahoo.com');
62 var $_version = '2.5';
63 var $_markers = array();
64 var $_max_lon = -1000000;
65 var $_min_lon = 1000000;
66 var $_max_lat = -1000000;
67 var $_min_lat = 1000000;
68 var $zoom_encompass = false;
69 var $bounds_fudge = 0.01;
70 var $use_suggest = false;
71 var $_polylines = array();
72 var $_icons = array();
73 var $_db_cache_table = 'GEOCODES';
75 function GoogleMapAPI($map_id = 'map', $app_id = 'MyMapApp') {
76 $this->map_id = $map_id;
77 $this->sidebar_id = 'sidebar_' . $map_id;
78 $this->app_id = $app_id;
81 /**
82 * sets the PEAR::DB dsn
84 * @param string $dsn
86 function setDSN($dsn) {
87 $this->dsn = $dsn;
90 /**
91 * sets YOUR Google Map API key
93 * @param string $key
95 function setAPIKey($key) {
96 $this->api_key = $key;
99 /**
100 * sets the width of the map
102 * @param string $width
104 function setWidth($width) {
105 if(!preg_match('!^(\d+)(.*)$!',$width,$_match))
106 return false;
108 $_width = $_match[1];
109 $_type = $_match[2];
110 if($_type == '%')
111 $this->width = $_width . '%';
112 else
113 $this->width = $_width . 'px';
115 return true;
119 * sets the height of the map
121 * @param string $height
123 function setHeight($height) {
124 if(!preg_match('!^(\d+)(.*)$!',$height,$_match))
125 return false;
127 $_height = $_match[1];
128 $_type = $_match[2];
129 if($_type == '%')
130 $this->height = $_height . '%';
131 else
132 $this->height = $_height . 'px';
134 return true;
138 * sets the default map zoom level
140 * @param string $level
142 function setZoomLevel($level) {
143 $this->zoom = (int) $level;
147 * enables the map controls (zoom/move)
150 function enableMapControls() {
151 $this->map_controls = true;
155 * disables the map controls (zoom/move)
158 function disableMapControls() {
159 $this->map_controls = false;
163 * sets the map control size (large/small)
165 * @param string $size
167 function setControlSize($size) {
168 if(in_array($size,array('large','small')))
169 $this->control_size = $size;
173 * enables the type controls (map/satellite/hybrid)
176 function enableTypeControls() {
177 $this->type_controls = true;
181 * disables the type controls (map/satellite/hybrid)
184 function disableTypeControls() {
185 $this->type_controls = false;
189 * set default map type (map/satellite/hybrid)
192 function setMapType($type) {
193 switch($type) {
194 case 'hybrid':
195 $this->map_type = 'G_HYBRID_MAP';
196 break;
197 case 'satellite':
198 $this->map_type = 'G_SATELLITE_MAP';
199 break;
200 case 'map':
201 default:
202 $this->map_type = 'G_NORMAL_MAP';
203 break;
208 * enables onload
211 function enableOnLoad() {
212 $this->onload = true;
216 * disables onload
219 function disableOnLoad() {
220 $this->onload = false;
224 * enables sidebar
227 function enableSidebar() {
228 $this->sidebar = true;
232 * disables sidebar
235 function disableSidebar() {
236 $this->sidebar = false;
240 * enables map directions inside info window
243 function enableDirections() {
244 $this->directions = true;
248 * disables map directions inside info window
251 function disableDirections() {
252 $this->directions = false;
256 * enable map marker info windows
258 function enableInfoWindow() {
259 $this->info_window = true;
263 * disable map marker info windows
265 function disableInfoWindow() {
266 $this->info_window = false;
270 * set the info window trigger action
272 * @params $message string click/mouseover
274 function setInfoWindowTrigger($type) {
275 switch($type) {
276 case 'mouseover':
277 $this->window_trigger = 'mouseover';
278 break;
279 default:
280 $this->window_trigger = 'click';
281 break;
286 * enable zoom to encompass makers
288 function enableZoomEncompass() {
289 $this->zoom_encompass = true;
293 * disable zoom to encompass makers
295 function disableZoomEncompass() {
296 $this->zoom_encompass = false;
300 * set the boundary fudge factor
302 function setBoundsFudge($val) {
303 $this->bounds_fudge = $val;
307 * enables the scale map control
310 function enableScaleControl() {
311 $this->scale_control = true;
315 * disables the scale map control
318 function disableScaleControl() {
319 $this->scale_control = false;
323 * enables the overview map control
326 function enableOverviewControl() {
327 $this->overview_control = true;
331 * disables the overview map control
334 function disableOverviewControl() {
335 $this->overview_control = false;
340 * set the lookup service to use for geocode lookups
341 * default is YAHOO, you can also use GOOGLE.
342 * NOTE: GOOGLE can to intl lookups, but is not an
343 * official API, so use at your own risk.
346 function setLookupService($service) {
347 switch($service) {
348 case 'GOOGLE':
349 $this->lookup_service = 'GOOGLE';
350 break;
351 case 'YAHOO':
352 default:
353 $this->lookup_service = 'YAHOO';
354 break;
360 * adds a map marker by address
362 * @param string $address the map address to mark (street/city/state/zip)
363 * @param string $title the title display in the sidebar
364 * @param string $html the HTML block to display in the info bubble (if empty, title is used)
366 function addMarkerByAddress($address,$title = '',$html = '',$tooltip = '',$id = '') {
367 if(($_geocode = $this->getGeocode($address)) === false)
368 return false;
369 return $this->addMarkerByCoords($_geocode['lon'],$_geocode['lat'],$title,$html,$tooltip);
373 * adds a map marker by geocode
375 * @param string $lon the map longitude (horizontal)
376 * @param string $lat the map latitude (vertical)
377 * @param string $title the title display in the sidebar
378 * @param string $html|array $html
379 * string: the HTML block to display in the info bubble (if empty, title is used)
380 * array: The title => content pairs for a tabbed info bubble
382 // TODO make it so you can specify which tab you want the directions to appear in (add another arg)
383 function addMarkerByCoords($lon,$lat,$title = '',$html = '',$tooltip = '',$id = '', $html_pedidos = '') {
384 $_marker['lon'] = $lon;
385 $_marker['lat'] = $lat;
386 $_marker['html'] = (is_array($html) || strlen($html) > 0) ? $html : $title;
387 $_marker['title'] = $title;
388 $_marker['tooltip'] = $tooltip;
389 $_marker['id'] = $id;
390 $_marker['html_pedidos'] = $html_pedidos;
392 $this->_markers[] = $_marker;
393 $this->adjustCenterCoords($_marker['lon'],$_marker['lat']);
394 // return index of marker
395 // HACK
396 return count($this->_markers) - 1;
397 // HACK
400 // HACK
401 function deleteMarkers() {
402 unset ($this->_markers);
403 return;
406 * adds a map polyline by address
407 * if color, weight and opacity are not defined, use the google maps defaults
409 * @param string $address1 the map address to draw from
410 * @param string $address2 the map address to draw to
411 * @param string $color the color of the line (format: #000000)
412 * @param string $weight the weight of the line in pixels
413 * @param string $opacity the line opacity (percentage)
415 function addPolyLineByAddress($address1,$address2,$color='',$weight=0,$opacity=0) {
416 if(($_geocode1 = $this->getGeocode($address1)) === false)
417 return false;
418 if(($_geocode2 = $this->getGeocode($address2)) === false)
419 return false;
420 return $this->addPolyLineByCoords($_geocode1['lon'],$_geocode1['lat'],$_geocode2['lon'],$_geocode2['lat'],$color,$weight,$opacity);
424 * adds a map polyline by map coordinates
425 * if color, weight and opacity are not defined, use the google maps defaults
427 * @param string $lon1 the map longitude to draw from
428 * @param string $lat1 the map latitude to draw from
429 * @param string $lon2 the map longitude to draw to
430 * @param string $lat2 the map latitude to draw to
431 * @param string $color the color of the line (format: #000000)
432 * @param string $weight the weight of the line in pixels
433 * @param string $opacity the line opacity (percentage)
435 function addPolyLineByCoords($lon1,$lat1,$lon2,$lat2,$color='',$weight=0,$opacity=0) {
436 $_polyline['lon1'] = $lon1;
437 $_polyline['lat1'] = $lat1;
438 $_polyline['lon2'] = $lon2;
439 $_polyline['lat2'] = $lat2;
440 $_polyline['color'] = $color;
441 $_polyline['weight'] = $weight;
442 $_polyline['opacity'] = $opacity;
443 $this->_polylines[] = $_polyline;
444 $this->adjustCenterCoords($_polyline['lon1'],$_polyline['lat1']);
445 $this->adjustCenterCoords($_polyline['lon2'],$_polyline['lat2']);
446 // return index of polyline
447 return count($this->_polylines) - 1;
451 * adjust map center coordinates by the given lat/lon point
453 * @param string $lon the map latitude (horizontal)
454 * @param string $lat the map latitude (vertical)
456 function adjustCenterCoords($lon,$lat) {
457 if(strlen((string)$lon) == 0 || strlen((string)$lat) == 0)
458 return false;
459 $this->_max_lon = (float) max($lon, $this->_max_lon);
460 $this->_min_lon = (float) min($lon, $this->_min_lon);
461 $this->_max_lat = (float) max($lat, $this->_max_lat);
462 $this->_min_lat = (float) min($lat, $this->_min_lat);
464 $this->center_lon = (float) ($this->_min_lon + $this->_max_lon) / 2;
465 $this->center_lat = (float) ($this->_min_lat + $this->_max_lat) / 2;
466 return true;
470 * set map center coordinates to lat/lon point
472 * @param string $lon the map latitude (horizontal)
473 * @param string $lat the map latitude (vertical)
475 function setCenterCoords($lon,$lat) {
476 $this->center_lat = (float) $lat;
477 $this->center_lon = (float) $lon;
481 * generate an array of params for a new marker icon image
482 * iconShadowImage is optional
483 * If anchor coords are not supplied, we use the center point of the image by default.
484 * Can be called statically. For private use by addMarkerIcon() and setMarkerIcon()
486 * @param string $iconImage URL to icon image
487 * @param string $iconShadowImage URL to shadow image
488 * @param string $iconAnchorX X coordinate for icon anchor point
489 * @param string $iconAnchorY Y coordinate for icon anchor point
490 * @param string $infoWindowAnchorX X coordinate for info window anchor point
491 * @param string $infoWindowAnchorY Y coordinate for info window anchor point
493 function createMarkerIcon($iconImage,$iconShadowImage = '',$iconAnchorX = 'x',$iconAnchorY = 'x',$infoWindowAnchorX = 'x',$infoWindowAnchorY = 'x') {
494 $_icon_image_path = $iconImage;
496 if(!($_image_info = @getimagesize($_icon_image_path))) {
497 die('GoogleMapAPI:createMarkerIcon: Error reading image [1]: ' . $iconImage);
500 if($iconShadowImage) {
501 $_shadow_image_path = $iconShadowImage;
502 if(!($_shadow_info = @getimagesize($_shadow_image_path))) {
503 die('GoogleMapAPI:createMarkerIcon: Error reading image [2]: ' . $iconShadowImage);
508 if($iconAnchorX === 'x') {
509 $iconAnchorX = (int) ($_image_info[0] / 2);
511 if($iconAnchorY === 'x') {
512 $iconAnchorY = (int) ($_image_info[1] / 2);
514 if($infoWindowAnchorX === 'x') {
515 $infoWindowAnchorX = (int) ($_image_info[0] / 2);
517 if($infoWindowAnchorY === 'x') {
518 $infoWindowAnchorY = (int) ($_image_info[1] / 2);
522 $icon_info = array(
523 'image' => $iconImage,
524 'iconWidth' => $_image_info[0],
525 'iconHeight' => $_image_info[1],
526 'iconAnchorX' => $iconAnchorX,
527 'iconAnchorY' => $iconAnchorY,
528 'infoWindowAnchorX' => $infoWindowAnchorX,
529 'infoWindowAnchorY' => $infoWindowAnchorY
533 if($iconShadowImage) {
534 $icon_info = array_merge($icon_info, array('shadow' => $iconShadowImage,
535 'shadowWidth' => '100', $_shadow_info[0],
536 'shadowHeight' => '100', $_shadow_info[1]));
540 return $icon_info;
544 * set the marker icon for ALL markers on the map
546 function setMarkerIcon($iconImage,$iconShadowImage = '',$iconAnchorX = 'x',$iconAnchorY = 'x',$infoWindowAnchorX = 'x',$infoWindowAnchorY = 'x') {
547 $this->_icons = array($this->createMarkerIcon($iconImage,$iconShadowImage,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY));
551 * add an icon to go with the correspondingly added marker
553 function addMarkerIcon($iconImage,$iconShadowImage = '',$iconAnchorX = 'x',$iconAnchorY = 'x',$infoWindowAnchorX = 'x',$infoWindowAnchorY = 'x') {
554 $this->_icons[] = $this->createMarkerIcon($iconImage,$iconShadowImage,$iconAnchorX,$iconAnchorY,$infoWindowAnchorX,$infoWindowAnchorY);
555 return count($this->_icons) - 1;
560 * print map javascript (put just before </body>, or in <header> if using onLoad())
563 function printMapJS() {
564 echo $this->getMapJS();
568 * return map javascript
571 function getMapJS() {
572 $_output = '<script type="text/javascript" charset="utf-8">' . "\n";
573 $_output .= '//<![CDATA[' . "\n";
574 $_output .= "/*************************************************\n";
575 $_output .= " * Created with GoogleMapAPI " . $this->_version . "\n";
576 $_output .= " * Author: Monte Ohrt <monte AT ohrt DOT com>\n";
577 $_output .= " * Copyright 2005-2006 New Digital Group\n";
578 $_output .= " * http://www.phpinsider.com/php/code/GoogleMapAPI/\n";
579 $_output .= " *************************************************/\n";
581 $_output .= 'function fix6ToString(n) { return n.toFixed(6).toString();} ';
582 $_output .= 'var points = [];' . "\n";
583 $_output .= 'var markers = [];' . "\n";
584 $_output .= 'var counter = 0;' . "\n";
585 if($this->sidebar) {
586 $_output .= 'var sidebar_html = "";' . "\n";
587 $_output .= 'var marker_html = [];' . "\n";
590 if(!empty($this->_icons)) {
591 $_output .= 'var icon = [];' . "\n";
592 for($i = 0, $j = count($this->_icons); $i<$j; $i++) {
593 $info = $this->_icons[$i];
595 // hash the icon data to see if we've already got this one; if so, save some javascript
596 $icon_key = md5(serialize($info));
597 if(!isset($exist_icn[$icon_key])) {
599 $_output .= "icon[$i] = new GIcon();\n";
600 $_output .= sprintf('icon[%s].image = "%s";',$i,$info['image']) . "\n";
601 if(isset($info['shadow'])) {
602 $_output .= sprintf('icon[%s].shadow = "%s";',$i,$info['shadow']) . "\n";
603 $_output .= sprintf('icon[%s].shadowSize = new GSize(%s,%s);',$i,$info['shadowWidth'],$info['shadowHeight']) . "\n";
605 $_output .= sprintf('icon[%s].iconSize = new GSize(%s,%s);',$i,$info['iconWidth'],$info['iconHeight']) . "\n";
606 $_output .= sprintf('icon[%s].iconAnchor = new GPoint(%s,%s);',$i,$info['iconAnchorX'],$info['iconAnchorY']) . "\n";
607 $_output .= sprintf('icon[%s].infoWindowAnchor = new GPoint(%s,%s);',$i,$info['infoWindowAnchorX'],$info['infoWindowAnchorY']) . "\n";
608 } else {
609 $_output .= "icon[$i] = icon[$exist_icn[$icon_key]];\n";
614 $_output .= 'var map = null;' . "\n";
616 if($this->onload) {
617 $_output .= 'function onLoad() {' . "\n";
620 $_output .= sprintf('var mapObj = document.getElementById("%s");',$this->map_id) . "\n";
621 $_output .= 'if (mapObj != "undefined" && mapObj != null) {' . "\n";
622 $_output .= sprintf('map = new GMap2(document.getElementById("%s"));',$this->map_id) . "\n";
623 if(isset($this->center_lat) && isset($this->center_lon)) {
624 // Special care for decimal point in lon and lat, would get lost if "wrong" locale is set; applies to (s)printf only
625 $_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";
628 // zoom so that all markers are in the viewport
629 if($this->zoom_encompass && count($this->_markers) > 1) {
630 // increase bounds by fudge factor to keep
631 // markers away from the edges
632 $_len_lon = $this->_max_lon - $this->_min_lon;
633 $_len_lat = $this->_max_lat - $this->_min_lat;
634 $this->_min_lon -= $_len_lon * $this->bounds_fudge;
635 $this->_max_lon += $_len_lon * $this->bounds_fudge;
636 $this->_min_lat -= $_len_lat * $this->bounds_fudge;
637 $this->_max_lat += $_len_lat * $this->bounds_fudge;
639 $_output .= "var bds = new GLatLngBounds(new GLatLng($this->_min_lat, $this->_min_lon), new GLatLng($this->_max_lat, $this->_max_lon));\n";
640 $_output .= 'map.setZoom(map.getBoundsZoomLevel(bds));' . "\n";
643 if($this->map_controls) {
644 if($this->control_size == 'large')
645 $_output .= 'map.addControl(new GLargeMapControl());' . "\n";
646 else
647 $_output .= 'map.addControl(new GSmallMapControl());' . "\n";
648 } else {
649 $_output .= 'map.disableDoubleClickZoom()' . "\n";
652 if($this->type_controls) {
653 $_output .= 'map.addControl(new GMapTypeControl());' . "\n";
656 if($this->scale_control) {
657 $_output .= 'map.addControl(new GScaleControl());' . "\n";
660 if($this->overview_control) {
661 $_output .= 'map.addControl(new GOverviewMapControl());' . "\n";
664 // HACK -> DRAG
665 if($this->disable_map_drag) {
666 $_output .= 'map.disableDragging();'."\n";
669 // HACK -> New Mupi
670 if($this->map_controls) {
671 $_output .= 'function mapSingleRightClick(point, src, overlay)
673 var point = map.fromContainerPixelToLatLng(point);
674 menu(\'<a onclick="menu()">Cerrar este menĆŗ</a><hr /><b>Latidud: </b>\'+fix6ToString( point.lat() )+\'<br /> <b>Longitud: </b>\'+fix6ToString( point.lng() )+\'<hr /><a target="_blank" href="./?accion=gestionar+mupis&crear=1&lat=\'+fix6ToString( point.lat() )+\'&lng=\'+fix6ToString( point.lng() )+\'&calle=\'+$("#combo_calles").val()+\'">Crear Mupi</a><br /><a target="_blank" href="./?accion=gestionar+referencias&crear=1&lat=\'+fix6ToString( point.lat() )+\'&lng=\'+fix6ToString( point.lng() )+\'&calle=\'+$("#combo_calles").val()+\'">Crear Referencia</a>\');
677 $_output .= 'GEvent.addListener(map, "singlerightclick", mapSingleRightClick);' . "\n";
680 $_output .= $this->getAddMarkersJS();
682 $_output .= $this->getPolylineJS();
684 if($this->sidebar) {
685 // HACK HACK
686 //$_output .= sprintf('document.getElementById("%s").innerHTML = "<ul class=\"gmapSidebar\">"+ sidebar_html +"<\/ul>";', $this->sidebar_id) . "\n";
687 $_output .= sprintf('document.getElementById("%s").innerHTML = "<b>Ver Eco Mupis:</b><br /><select id=\"combobox_mupis\" class=\"gmapSidebar\">"+ sidebar_html +"</select>";', 'lista_mupis') . "\n";
688 $_output .= 'click_sidebar($("#combobox_mupis").val())'."\n";
689 $_output .= '$("#combobox_mupis").change(function (){click_sidebar($("#combobox_mupis").val());})'."\n";
692 $_output .= '}' . "\n";
694 if($this->onload) {
695 $_output .= '}' . "\n";
698 $_output .= $this->getCreateMarkerJS();
700 // Utility functions used to distinguish between tabbed and non-tabbed info windows
701 $_output .= 'function isArray(a) {return isObject(a) && a.constructor == Array;}' . "\n";
702 $_output .= 'function isObject(a) {return (a && typeof a == \'object\') || isFunction(a);}' . "\n";
703 $_output .= 'function isFunction(a) {return typeof a == \'function\';}' . "\n";
705 if($this->sidebar) {
706 $_output .= 'function click_sidebar(idx) {' . "\n";
707 //$_output .= ' alert(idx);' . "\n";
708 $_output .= ' if(isArray(marker_html[idx])) { markers[idx].openInfoWindowTabsHtml(marker_html[idx]); }' . "\n";
709 $_output .= ' else { markers[idx].openInfoWindowHtml(marker_html[idx]); }' . "\n";
710 $_output .= ' GEvent.trigger(markers[idx],"'.$this->window_trigger.'");' . "\n";
711 $_output .= '}' . "\n";
714 $_output .= 'function showInfoWindow(idx,html) {' . "\n";
715 $_output .= 'map.centerAtLatLng(points[idx]);' . "\n";
716 $_output .= 'markers[idx].openInfoWindowHtml(html);' . "\n";
717 $_output .= '}' . "\n";
719 $_output .= '//]]>' . "\n";
720 $_output .= '</script>' . "\n";
721 return $_output;
725 * overridable function for generating js to add markers
727 function getAddMarkersJS() {
728 $SINGLE_TAB_WIDTH = 88; // constant: width in pixels of each tab heading (set by google)
729 $i = 0;
730 $_output = '';
731 foreach($this->_markers as $_marker) {
732 if(is_array($_marker['html'])) {
733 // warning: you can't have two tabs with the same header. but why would you want to?
734 $ti = 0;
735 $num_tabs = count($_marker['html']);
736 $tab_obs = array();
737 foreach($_marker['html'] as $tab => $info) {
738 if($ti == 0 && $num_tabs > 2) {
739 $width_style = sprintf(' style=\"width: %spx\"', $num_tabs * $SINGLE_TAB_WIDTH);
740 } else {
741 $width_style = '';
743 $tab = str_replace('"','\"',$tab);
744 $info = str_replace('"','\"',$info);
745 $info = str_replace(array("\n", "\r"), "", $info);
746 $tab_obs[] = sprintf('new GInfoWindowTab("%s", "%s")', $tab, '<div id=\"gmapmarker\"'.$width_style.'>' . $info . '</div>');
747 $ti++;
749 $iw_html = '[' . join(',',$tab_obs) . ']';
750 } else {
751 $iw_html = sprintf('"%s"',str_replace('"','\"','<div id="gmapmarker">' . str_replace(array("\n", "\r"), "", $_marker['html']) . '</div>'));
753 // HACK ID
754 $_output .= sprintf('var point = new GLatLng(%s,%s);',$_marker['lat'],$_marker['lon']) . "\n";
755 $_output .= sprintf('var marker = createMarker(point,"%s",%s, %s,"%s","%s","%s");',
756 str_replace('"','\"',$_marker['title']),
757 str_replace('/','\/',$iw_html),
759 str_replace('"','\"',$_marker['tooltip']),
760 $_marker['id'],
761 $_marker['html_pedidos']) . "\n";
762 //TODO: in above createMarker call, pass the index of the tab in which to put directions, if applicable
763 $_output .= 'map.addOverlay(marker);' . "\n";
764 $i++;
766 return $_output;
770 * overridable function to generate polyline js
772 function getPolylineJS() {
773 $_output = '';
774 foreach($this->_polylines as $_polyline) {
775 $_output .= sprintf('var polyline = new GPolyline([new GLatLng(%s,%s),new GLatLng(%s,%s)],"%s",%s,%s);',
776 $_polyline['lat1'],$_polyline['lon1'],$_polyline['lat2'],$_polyline['lon2'],$_polyline['color'],$_polyline['weight'],$_polyline['opacity'] / 100.0) . "\n";
777 $_output .= 'map.addOverlay(polyline);' . "\n";
779 return $_output;
783 * overridable function to generate the js for the js function for creating a marker.
785 // IMPORTANTE!, acĆ” tiene que ir el hack mayor!.
786 function getCreateMarkerJS() {
787 $_SCRIPT_ = '$("#Mensajes").html("Cargando FotofrafĆ­as del Eco Mupi seleccionado...");$("#datos_mupis").load(\'contenido/mupis+ubicaciones+dinamico.php?accion=mupi&MUPI=\'+id,{},function(){$("#Mensajes").empty();});$("#indicaciones").html("<a href=\'#imagenes\'> | Clic aquĆ­ para ver las imagenes del Mupi Seleccionado</a>")';
788 $_output = '';
789 $_output .= 'function createMarker(point, title, html, n, tooltip, id, html_pedidos) {' . "\n";
790 $_output .= 'if(n >= '. sizeof($this->_icons) .') { n = '. (sizeof($this->_icons) - 1) ."; }\n";
791 if(!empty($this->_icons)) {
792 $tmpBool = $this->disable_drag ? 'false' : 'true';
793 $_output .= 'var marker = new GMarker(point,{\'icon\': icon[n], \'title\': tooltip, \'draggable\': '.$tmpBool.', \'bouncy\': false});' . "\n";
794 } else {
795 $_output .= 'var marker = new GMarker(point,{\'title\': tooltip});' . "\n";
798 // Admin -> Open Info Window + click + Mover + Marcardores
799 // Usuario -> Click
800 if($this->info_window) {
801 $_output .= 'if (id.indexOf(\'REF\') == -1) {' . "\n";
802 $_output .= 'GEvent.addListener(marker, "'.$this->window_trigger.'", function() { '.$_SCRIPT_.'; marker.openInfoWindowHtml(html,{\'maxTitle\': \'EdiciĆ³n de pedidos\', \'maxContent\': html_pedidos}) });' . "\n";
803 $_output .= 'GEvent.addListener(marker, "infowindowclose", function() { $("#datos_mupis").html(""); });' . "\n";
804 $_output .= '} else {' . "\n";
805 $_output .= 'GEvent.addListener(marker, "'.$this->window_trigger.'", function() { '.$_SCRIPT_.'; });' . "\n";
806 $_output .= '}' . "\n";
807 } else {
808 $_output .= 'if (id.indexOf(\'REF\') == -1) {' . "\n";
809 $_output .= 'GEvent.addListener(marker, "'.$this->window_trigger.'", function() { '.$_SCRIPT_.'; });' . "\n";
810 $_output .= '}' . "\n";
812 if (!$this->disable_drag) {
813 $_output .= 'GEvent.addListener(marker, "dragstart", function() { map.closeInfoWindow();});' . "\n";
814 //$_output .= 'GEvent.addListener(marker, "dragend", function() { var point = marker.getPoint(); alert( id + \' \' + fix6ToString( point.lat() ) + \',\' + fix6ToString( point.lng() ) ); $("#datos_mupis").load(\'contenido/mupis+ubicaciones+dinamico.php?accion=drag&id=\'+id+\'&lat=\'+fix6ToString( point.lat() )+\'&lng=\'+fix6ToString( point.lng() )); });' . "\n";
815 $_output .= 'GEvent.addListener(marker, "dragend", function() { var point = marker.getPoint(); $("#datos_mupis").load(\'contenido/mupis+ubicaciones+dinamico.php?accion=drag&id=\'+id+\'&lat=\'+fix6ToString( point.lat() )+\'&lng=\'+fix6ToString( point.lng() )); });' . "\n";
817 $_output .= 'points[counter] = point;' . "\n";
818 $_output .= 'markers[counter] = marker;' . "\n";
819 if($this->sidebar) {
820 $_output .= 'if (id.indexOf(\'REF\') == -1) {' . "\n";
821 $_output .= 'marker_html[counter] = html;' . "\n";
822 $_output .= 'sidebar_html += \'<option class="gmapSidebarItem" id="gmapSidebarItem" value="\'+counter+\'">\' + title + \'</option>\';' . "\n";
823 $_output .= '}' . "\n";
825 $_output .= 'counter++;' . "\n";
826 $_output .= 'return marker;' . "\n";
827 $_output .= '}' . "\n";
828 return $_output;
832 * print map (put at location map will appear)
835 function printMap() {
836 echo $this->getMap();
840 * return map
843 function getMap() {
844 $_output = '';
845 if(strlen($this->width) > 0 && strlen($this->height) > 0) {
846 $_output .= sprintf('<div id="%s" style="width: %s; height: %s"></div>',$this->map_id,$this->width,$this->height) . "\n";
847 } else {
848 $_output .= sprintf('<div id="%s"></div>;',$this->map_id) . "\n";
850 return $_output;
855 * print sidebar (put at location sidebar will appear)
858 function printSidebar() {
859 echo $this->getSidebar();
863 * return sidebar html
866 function getSidebar() {
867 return sprintf('<div id="%s"></div>',$this->sidebar_id) . "\n";
871 * get the geocode lat/lon points from given address
872 * look in cache first, otherwise get from Yahoo
874 * @param string $address
876 function getGeocode($address) {
877 if(empty($address))
878 return false;
880 $_geocode = false;
882 if(($_geocode = $this->getCache($address)) === false) {
883 if(($_geocode = $this->geoGetCoords($address)) !== false) {
884 $this->putCache($address, $_geocode['lon'], $_geocode['lat']);
888 return $_geocode;
892 * get the geocode lat/lon points from cache for given address
894 * @param string $address
896 function getCache($address) {
897 if(!isset($this->dsn))
898 return false;
900 $_ret = array();
902 // PEAR DB
903 require_once('DB.php');
904 $_db =& DB::connect($this->dsn);
905 if (PEAR::isError($_db)) {
906 die($_db->getMessage());
908 $_res =& $_db->query("SELECT lon,lat FROM {$this->_db_cache_table} where address = ?", $address);
909 if (PEAR::isError($_res)) {
910 die($_res->getMessage());
912 if($_row = $_res->fetchRow()) {
913 $_ret['lon'] = $_row[0];
914 $_ret['lat'] = $_row[1];
917 $_db->disconnect();
919 return !empty($_ret) ? $_ret : false;
923 * put the geocode lat/lon points into cache for given address
925 * @param string $address
926 * @param string $lon the map latitude (horizontal)
927 * @param string $lat the map latitude (vertical)
929 function putCache($address, $lon, $lat) {
930 if(!isset($this->dsn) || (strlen($address) == 0 || strlen($lon) == 0 || strlen($lat) == 0))
931 return false;
932 // PEAR DB
933 require_once('DB.php');
934 $_db =& DB::connect($this->dsn);
935 if (PEAR::isError($_db)) {
936 die($_db->getMessage());
939 $_res =& $_db->query('insert into '.$this->_db_cache_table.' values (?, ?, ?)', array($address, $lon, $lat));
940 if (PEAR::isError($_res)) {
941 die($_res->getMessage());
943 $_db->disconnect();
945 return true;
950 * get geocode lat/lon points for given address from Yahoo
952 * @param string $address
954 function geoGetCoords($address,$depth=0) {
956 switch($this->lookup_service) {
958 case 'GOOGLE':
960 $_url = sprintf('http://%s/maps/geo?&q=%s&output=csv&key=%s',$this->lookup_server['GOOGLE'],rawurlencode($address),$this->api_key);
962 $_result = false;
964 if($_result = $this->fetchURL($_url)) {
966 $_result_parts = explode(',',$_result);
967 if($_result_parts[0] != 200)
968 return false;
969 $_coords['lat'] = $_result_parts[2];
970 $_coords['lon'] = $_result_parts[3];
973 break;
975 case 'YAHOO':
976 default:
978 $_url = 'http://%s/MapsService/V1/geocode';
979 $_url .= sprintf('?appid=%s&location=%s',$this->lookup_server['YAHOO'],$this->app_id,rawurlencode($address));
981 $_result = false;
983 if($_result = $this->fetchURL($_url)) {
985 preg_match('!<Latitude>(.*)</Latitude><Longitude>(.*)</Longitude>!U', $_result, $_match);
987 $_coords['lon'] = $_match[2];
988 $_coords['lat'] = $_match[1];
992 break;
995 return $_coords;
1001 * fetch a URL. Override this method to change the way URLs are fetched.
1003 * @param string $url
1005 function fetchURL($url) {
1007 return file_get_contents($url);
1012 * get distance between to geocoords using great circle distance formula
1014 * @param float $lat1
1015 * @param float $lat2
1016 * @param float $lon1
1017 * @param float $lon2
1018 * @param float $unit M=miles, K=kilometers, N=nautical miles, I=inches, F=feet
1020 function geoGetDistance($lat1,$lon1,$lat2,$lon2,$unit='K') {
1022 // calculate miles
1023 $M = 69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));
1025 switch(strtoupper($unit))
1027 case 'K':
1028 // kilometers
1029 return $M * 1.609344;
1030 break;
1031 case 'N':
1032 // nautical miles
1033 return $M * 0.868976242;
1034 break;
1035 case 'F':
1036 // feet
1037 return $M * 5280;
1038 break;
1039 case 'I':
1040 // inches
1041 return $M * 63360;
1042 break;
1043 case 'M':
1044 default:
1045 // miles
1046 return $M;
1047 break;