1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13: $plugin_is_filter = 5 | THEME_PLUGIN;
14: $plugin_description = gettext('Display Google Maps based on <em>latitude</em> and <em>longitude</em> metadata in the images.');
15: $plugin_notice = sprintf(gettext('<strong>Note</strong>: Google does place limits on the use of its <a href="%s"><em>Maps API</em></a>. Please review these to be sure your site is in compliance.'), 'http://googlegeodevelopers.blogspot.com/2011/10/introduction-of-usage-limits-to-maps.html');
16: $plugin_author = 'Stephen Billard (sbillard) & Vincent Bourganel (vincent3569)';
17:
18:
19: $option_interface = 'GoogleMap';
20: if (isset($_zp_gallery_page) && $_zp_gallery_page != 'index.php') {
21: if (getOption('gmap_sessions')) {
22: zp_session_start();
23: }
24: zp_register_filter('theme_head', 'GoogleMap::js');
25: }
26:
27: 28: 29: 30:
31: class GoogleMap {
32:
33: function __construct() {
34: setOptionDefault('gmap_map_roadmap', 1);
35: setOptionDefault('gmap_map_hybrid', 1);
36: setOptionDefault('gmap_map_satellite', 1);
37: setOptionDefault('gmap_map_terrain', 1);
38: setOptionDefault('gmap_starting_map', 'HYBRID');
39: setOptionDefault('gmap_control_type', 'HORIZONTAL_BAR');
40: setOptionDefault('gmap_zoom_size', 'LARGE');
41: setOptionDefault('gmap_cluster_max_zoom', 13);
42: setOptionDefault('gmap_sessions', 1);
43: if (OFFSET_PATH == 2) {
44: setOptionDefault('gmap_display', 'hide');
45: purgeOption('gmap_hide');
46: }
47: setOptionDefault('gmap_display', 'show');
48: if (class_exists('cacheManager')) {
49: cacheManager::deleteThemeCacheSizes('GoogleMap');
50: cacheManager::addThemeCacheSize('GoogleMap', 150, NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL);
51: }
52: }
53:
54: function getOptionsSupported() {
55:
56: $MapTypes = array();
57: if (getOption('gmap_map_hybrid'))
58: $MapTypes[gettext('Hybrid')] = 'HYBRID';
59: if (getOption('gmap_map_roadmap'))
60: $MapTypes[gettext('Map')] = 'ROADMAP';
61: if (getOption('gmap_map_satellite'))
62: $MapTypes[gettext('Satellite')] = 'SATELLITE';
63: if (getOption('gmap_map_terrain'))
64: $MapTypes[gettext('Terrain')] = 'TERRAIN';
65:
66: $defaultMap = getOption('gmap_starting_map');
67: if (array_search($defaultMap, $MapTypes) === false) {
68: $temp = $MapTypes;
69: $defaultMap = array_shift($temp);
70: setOption('gmap_starting_map', $defaultMap);
71: }
72:
73: return array(
74: gettext('Allowed maps') => array('key' => 'gmap_allowed_maps', 'type' => OPTION_TYPE_CHECKBOX_ARRAY,
75: 'order' => 1,
76: 'checkboxes' => array(gettext('Hybrid') => 'gmap_map_hybrid',
77: gettext('Map') => 'gmap_map_roadmap',
78: gettext('Satellite') => 'gmap_map_satellite',
79: gettext('Terrain') => 'gmap_map_terrain'),
80: 'desc' => gettext('Select the map types that are allowed.')),
81: gettext('Initial map display selection') => array('key' => 'gmap_starting_map', 'type' => OPTION_TYPE_SELECTOR,
82: 'order' => 2,
83: 'selections' => $MapTypes,
84: 'desc' => gettext('Select the initial type of map to display.')),
85: gettext('Map display') => array('key' => 'gmap_display', 'type' => OPTION_TYPE_SELECTOR,
86: 'order' => 3,
87: 'selections' => array(gettext('show') => 'show',
88: gettext('hide') => 'hide',
89: gettext('colorbox') => 'colorbox'),
90: 'desc' => gettext('Select <em>hide</em> to initially hide the map. Select <em>colorbox</em> for the map to display in a colorbox. Select <em>show</em> and the map will display when the page loads.')),
91: gettext('Map controls') => array('key' => 'gmap_control_type', 'type' => OPTION_TYPE_RADIO,
92: 'order' => 4,
93: 'buttons' => array(gettext('None') => 'none',
94: gettext('Default') => 'DEFAULT',
95: gettext('Dropdown') => 'DROPDOWN_MENU',
96: gettext('Horizontal') => 'HORIZONTAL_BAR'),
97: 'desc' => gettext('Display options for the Map type control.')),
98: gettext('Zoom controls') => array('key' => 'gmap_zoom_size', 'type' => OPTION_TYPE_RADIO,
99: 'order' => 5,
100: 'buttons' => array(gettext('Small') => 'SMALL',
101: gettext('Default') => 'DEFAULT',
102: gettext('Large') => 'LARGE'),
103: 'desc' => gettext('Display options for the Zoom control.')),
104: gettext('Max zoom level') => array('key' => 'gmap_cluster_max_zoom', 'type' => OPTION_TYPE_TEXTBOX,
105: 'order' => 6,
106: 'desc' => gettext('The max zoom level for clustering pictures on map.')),
107: gettext('Map sessions') => array('key' => 'gmap_sessions', 'type' => OPTION_TYPE_CHECKBOX,
108: 'order' => 9,
109: 'desc' => gettext('If checked GoogleMaps will use sessions to pass map data for the <em>colorbox</em> display option. We recommend this option be selected. It protects against reference forgery security attacks and mitigates problems with data exceeding the allowed by some browsers.')),
110: gettext('API key') => array('key' => 'gmap_api_key', 'type' => OPTION_TYPE_TEXTBOX,
111: 'order' => 10,
112: 'desc' => gettext('Enter your API key. You can get one <a href="https://developers.google.com/maps/documentation/javascript/get-api-key#key">here</a>.'))
113: );
114: }
115:
116: function handleOption($option, $currentValue) {
117:
118: }
119:
120: 121: 122:
123: static function js() {
124:
125: if (!defined('BASEPATH'))
126: define('BASEPATH', true);
127: require_once(dirname(__FILE__) . '/GoogleMap/CodeIgniter-Google-Maps-V3-API/Googlemaps.php');
128: $parameters = array();
129: $url_appendix = '';
130: $loc = getOption('locale');
131: if ( !empty($loc) ) {
132: $parameters[] = 'language=' . substr(getOption('locale'), 0, 2);
133: }
134: $apikey = getOption('gmap_api_key');
135: if ( !empty($apikey) ) {
136: $parameters[] = 'key=' . $apikey;
137: }
138: if ( !empty($parameters) ) {
139: $url_appendix = implode('&', $parameters);
140: }
141: ?>
142: <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?<?php echo $url_appendix; ?>"></script>
143: <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER; ?>/GoogleMap/markerClustererPlus/markerclusterer.js"></script>
144: <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER; ?>/GoogleMap/overlappingMarkerSpiderfier/oms.min.js"></script>
145: <link rel="stylesheet" href="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER; ?>/GoogleMap/googleMap.css" type="text/css" media="screen"/>
146: <?php
147: }
148:
149: }
150:
151:
152: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . COMMON_FOLDER . '/jsMin/JSMin.php');
153:
154: class CI_load {
155:
156: function library($library) {
157:
158: assert($library == 'jsmin');
159: }
160:
161: }
162:
163: class CI_jsmin {
164:
165: function min($js) {
166: return JSMin::minify($js);
167: }
168:
169: }
170:
171: class codeIgniter_kludge {
172:
173: var $load;
174: var $jsmin;
175:
176: function __construct() {
177: $this->load = new CI_load();
178: $this->jsmin = new CI_jsmin();
179: }
180:
181: }
182:
183: function log_message($class, $msg) {
184:
185: }
186:
187: function get_instance() {
188:
189: return new codeIgniter_kludge();
190: }
191:
192: function omsAdditions() {
193:
194: return '';
195: }
196:
197: 198: 199: 200:
201: function getGeoCoord($image) {
202: global $_zp_current_image;
203: $result = false;
204: if (isImageClass($image)) {
205: $_zp_current_image = $image;
206: $exif = $_zp_current_image->getMetaData();
207: if ((!empty($exif['EXIFGPSLatitude'])) && (!empty($exif['EXIFGPSLongitude']))) {
208: $lat_c = explode('.', str_replace(',', '.', $exif['EXIFGPSLatitude']) . '.0');
209: $lat_f = round((float) abs($lat_c[0]) + ($lat_c[1] / pow(10, strlen($lat_c[1]))), 12);
210: if (strtoupper(@$exif['EXIFGPSLatitudeRef']{0}) == 'S') {
211: $lat_f = -$lat_f;
212: }
213:
214: $long_c = explode('.', str_replace(',', '.', $exif['EXIFGPSLongitude']) . '.0');
215: $long_f = round((float) abs($long_c[0]) + ($long_c[1] / pow(10, strlen($long_c[1]))), 12);
216: if (strtoupper(@$exif['EXIFGPSLongitudeRef']{0}) == 'W') {
217: $long_f = -$long_f;
218: }
219:
220: $thumb = '<a href="javascript:image(\'' . $_zp_current_image->albumname . '\',\'' . $_zp_current_image->filename . '\');"><img src="' . getCustomImageURL(150, NULL, NULL, NULL, NULL, NULL, NULL, true) . '" /></a>';
221:
222: $result = array('lat' => $lat_f, 'long' => $long_f, 'title' => $_zp_current_image->getTitle(), 'desc' => $_zp_current_image->getDesc(), 'thumb' => $thumb);
223: }
224: }
225:
226: return $result;
227: }
228:
229: 230: 231: 232: 233:
234: function addGeoCoord($map, $coord) {
235: global $_x, $_y, $_z, $_n;
236: if ($coord) {
237: $marker = array();
238:
239: $title = str_replace('/', '\/', str_replace('"', '\"', str_replace(array("\n", "\r"), "", html_encodeTagged($coord['title']))));
240: $desc = str_replace('/', '\/', str_replace('"', '\"', str_replace(array("\n", "\r"), "", html_encodeTagged($coord['desc']))));
241: $thumb = str_replace('/', '\/', str_replace('"', '\"', str_replace(array("\n", "\r"), "", html_encodeTagged($coord['thumb']))));
242: if ($title <> '') {
243: $title = '<h3 class="map_title">' . $title . '</h3>';
244: }
245: if ($desc <> '') {
246: $desc = '<div class="map_desc">' . $desc . '</div>';
247: }
248: if ($coord['thumb'] <> '') {
249: $thumb = '<p class="map_img">' . $coord['thumb'] . '</p>';
250: }
251:
252: $marker['position'] = number_format($coord['lat'], 12, '.', '') . ", " . number_format($coord['long'], 12, '.', '');
253: $marker['title'] = addslashes($coord['title']);
254: $marker['infowindow_content'] = $title . $thumb . $desc;
255: $map->add_marker($marker);
256: $lat_f = $coord['lat'] * M_PI / 180;
257: $long_f = $coord['long'] * M_PI / 180;
258: $_x = $_x + cos($lat_f) * cos($long_f);
259: $_y = $_y + cos($lat_f) * sin($long_f);
260: $_z = $_z + sin($lat_f);
261: $_n++;
262: }
263: }
264:
265: 266: 267: 268: 269:
270: function getImageGeodata($image, $map) {
271: $coord = getGeoCoord($image);
272: if ($coord) {
273: addGeoCoord($map, $coord);
274: }
275: return $coord;
276: }
277:
278: 279: 280: 281: 282:
283: function getAlbumGeodata($album, $map) {
284: $result = false;
285: $images = $album->getImages(0, 0, null, null, false);
286: foreach ($images as $an_image) {
287: $image = newImage($album, $an_image);
288: $coord = getGeoCoord($image);
289: if ($coord) {
290: $result = true;
291: addGeoCoord($map, $coord);
292: }
293: }
294: return $result;
295: }
296:
297: 298: 299: 300: 301: 302: 303: 304: 305:
306: function printGoogleMap($text = NULL, $id = NULL, $hide = NULL, $obj = NULL, $callback = NULL) {
307: global $_zp_current_album, $_zp_current_image, $_x, $_y, $_z, $_n;
308:
309:
310: if (is_null($obj)) {
311: if (is_null($_zp_current_image)) {
312: $obj = $_zp_current_album;
313: } else {
314: $obj = $_zp_current_image;
315: }
316: }
317: if (is_null($obj)) {
318: return false;
319: }
320: if (is_object($obj)) {
321: $type = $obj->table;
322: $typeid = $obj->getID();
323: } else {
324: $type = $obj;
325: $typeid = '';
326: }
327: if (is_null($text)) {
328: $text = gettext('Google Map');
329: }
330: if (empty($text)) {
331: $hide = 'show';
332: }
333: if (is_null($hide)) {
334: $hide = getOption('gmap_display');
335: }
336: if (!is_string($hide)) {
337: if ($hide) {
338: $hide = 'hide';
339: } else {
340: $hide = 'show';
341: }
342: }
343:
344:
345: $mapControls = getOption('gmap_control_type');
346: if ($mapControls == 'none') {
347: $mapTypeControl = false;
348: } else {
349: $mapTypeControl = true;
350: $map_control_type = $mapControls;
351:
352: $allowedMapTypes = array();
353: if (getOption('gmap_map_hybrid'))
354: $allowedMapTypes[] = 'HYBRID';
355: if (getOption('gmap_map_roadmap'))
356: $allowedMapTypes[] = 'ROADMAP';
357: if (getOption('gmap_map_satellite'))
358: $allowedMapTypes[] = 'SATELLITE';
359: if (getOption('gmap_map_terrain'))
360: $allowedMapTypes[] = 'TERRAIN';
361: }
362:
363: $config['center'] = '0, 0';
364: $config['zoom'] = 'auto';
365: $config['cluster'] = true;
366: $config['zoomControlStyle'] = getOption('gmap_zoom_size');
367: if ($mapTypeControl) {
368: $config['map_type'] = getOption('gmap_starting_map');
369: $config['map_types_available'] = $allowedMapTypes;
370: } else {
371: $config['disableMapTypeControl'] = true;
372: }
373: $config['clusterMaxZoom'] = getOption('gmap_cluster_max_zoom');
374: $config['clusterAverageCenter'] = true;
375: $config['onclick'] = "iw.close();";
376: $config['minifyJS'] = !TEST_RELEASE;
377: $map = new Googlemaps($config);
378:
379:
380: switch ($type) {
381: case 'images':
382: if (getImageGeodata($obj, $map)) {
383: break;
384: } else {
385: $map = NULL;
386: return false;
387: }
388: case 'albums':
389: if (getAlbumGeodata($obj, $map)) {
390: break;
391: } else {
392: $map = NULL;
393: return false;
394: }
395: default:
396: break;
397: }
398:
399: if ($_n == 1)
400: $map->zoom = 13;
401:
402: if ($_n) {
403: $_x = $_x / $_n;
404: $_y = $_y / $_n;
405: $_z = $_z / $_n;
406: $lon = number_format(atan2($_y, $_x) * 180 / M_PI, 12, '.', '');
407: $hyp = sqrt($_x * $_x + $_y * $_y);
408: $lat = number_format(atan2($_z, $hyp) * 180 / M_PI, 12, '.', '');
409: $map->center = $lat . ', ' . $lon;
410: }
411:
412: if (!is_null($callback)) {
413: call_user_func($callback, $map);
414: }
415:
416:
417: if (is_null($id)) {
418: $id = $type . $typeid . '_googlemap';
419: }
420: $id_toggle = $id . '_toggle';
421: $id_data = $id . '_data';
422:
423: switch ($hide) {
424: case 'show':
425: $map->create_map();
426: ?>
427: <script type="text/javascript">
428:
429: <?php
430: echo $map->output_js_contents;
431: echo omsAdditions();
432: ?>
433:
434: function image(album, image) {
435: window.location = '<?php echo WEBPATH ?>/index.php?album=' + album + '&image=' + image;
436: }
437:
438: </script>
439: <div id="<?php echo $id_data; ?>">
440: <?php echo $map->output_html; ?>
441: </div>
442: <?php
443: break;
444: case 'hide':
445: $map->create_map();
446: ?>
447: <script type="text/javascript">
448:
449: <?php
450: echo $map->output_js_contents;
451: echo omsAdditions();
452: ?>
453:
454: function image(album, image) {
455: window.location = '<?php echo WEBPATH ?>/index.php?album=' + album + '&image=' + image;
456: }
457:
458: function toggle_<?php echo $id_data; ?>() {
459: if ($('#<?php echo $id_data; ?>').hasClass('hidden_map')) {
460: $('#<?php echo $id_data; ?>').removeClass('hidden_map');
461: } else {
462: $('#<?php echo $id_data; ?>').addClass('hidden_map');
463: }
464: }
465:
466: </script>
467: <a id="<?php echo $id_toggle; ?>" href="javascript:toggle_<?php echo $id_data; ?>();" title="<?php echo gettext('Display or hide the Google Map.'); ?>">
468: <?php echo $text; ?>
469: </a>
470: <div id="<?php echo $id_data; ?>" class="hidden_map">
471: <?php echo $map->output_html; ?>
472: </div>
473: <?php
474: break;
475: case 'colorbox':
476: if (zp_has_filter('theme_head', 'colorbox::css')) {
477: $map->create_map();
478: $map_data["output_js_contents"] = $map->output_js_contents;
479: $map_data["output_html"] = $map->output_html;
480:
481: if (getOption('gmap_sessions')) {
482: $param = '';
483: $_SESSION['GoogleMapVars'] = $map_data;
484: } else {
485: $serializedData = serialize($map_data);
486: if (function_exists('bzcompress')) {
487: $data = bzcompress($serializedData);
488: } else {
489: $data = gzcompress($serializedData);
490: }
491: $param = '?map_data=' . base64_encode($data);
492: }
493: ?>
494: <a href="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/GoogleMap/Map.php' . $param ?>" title="<?php echo $text; ?>" class="google_map">
495: <?php echo $text; ?>
496: </a>
497: <script type="text/javascript">
498:
499: $(document).ready(function() {
500: $(".google_map").colorbox({
501: iframe: true,
502: innerWidth: $(window).width() * 0.8,
503: innerHeight: $(window).height() * 0.7,
504: close: '<?php echo gettext("close"); ?>',
505: onComplete: function() {
506: parent.resizeColorBoxMap();$(window).resize(resizeColorBoxMap);
507: }
508: });
509: });
510:
511: </script>
512: <?php
513: }
514: break;
515: }
516: }
517: ?>