/[drupal]/contributions/modules/openlayers/openlayers.module
ViewVC logotype

Contents of /contributions/modules/openlayers/openlayers.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.77 - (show annotations) (download) (as text)
Fri Oct 30 16:25:43 2009 UTC (4 weeks ago) by tmcw
Branch: MAIN
CVS Tags: DRUPAL-6--0-1-ALPHA6, HEAD
Changes since 1.76: +1 -12 lines
File MIME type: text/x-php
Removing a dead behavior from the 0.x branch
1 <?php
2 // $Id: openlayers.module,v 1.76 2009/10/20 22:41:14 tmcw Exp $
3
4 /**
5 * @defgroup openlayers OpenLayers: Provides an API and Modules to interface with OpenLayers
6 *
7 * Provides an API and Modules to interface with OpenLayers. Needs work...
8 */
9
10 /**
11 * @defgroup openlayers_api OpenLayers API: Specific functions that are part of the OpenLayers API
12 *
13 * Provides an API and Modules to interface with OpenLayers. Needs work...
14 */
15
16 /**
17 * @file
18 * Main OpenLayers API File
19 *
20 * This file holds the main Drupal hook functions,
21 * and the openlayers API functions for the openlayers module.
22 *
23 * @ingroup openlayers
24 */
25
26 /**
27 * Implementation of hook_help
28 */
29 function openlayers_help($path, $arg) {
30 switch ($path) {
31 case 'admin/help#openlayers':
32 $output = '<p>'. t('The OpenLayers module is the base module for the OpenLayer suite of modules, and provides the main API.') .'</p>';
33 }
34 return '';
35 }
36
37 /**
38 * Implementation of hook_theme().
39 */
40 function openlayers_theme($existing, $type, $theme, $path) {
41 return array(
42 'openlayers_map' => array(
43 'arguments' => array(
44 'map' => array(),
45 ),
46 'file' => 'includes/openlayers.theme.inc',
47 ),
48 'openlayers_styles' => array(
49 'arguments' => array(
50 'styles' => array(),
51 'map' => array(),
52 ),
53 'file' => 'includes/openlayers.theme.inc',
54 ),
55 );
56 }
57
58 /**
59 * Implementation of hook_ctools_plugin_api().
60 */
61 function openlayers_ctools_plugin_api($module, $api) {
62 if ($module == "openlayers") {
63 switch ($api) {
64 case 'openlayers_presets':
65 return array('version' => 1);
66 case 'openlayers_layers':
67 return array('version' => 1);
68 case 'openlayers_styles':
69 return array('version' => 1);
70 }
71 }
72 }
73
74 /**
75 * Include necessary CSS and JS for OpenLayers.
76 *
77 * @ingroup openlayers_api
78 */
79 function openlayers_include() {
80 // Use a static variable to prevent running URL check code repeatedly.
81 static $once;
82 if (!isset($once)) {
83 $once = TRUE;
84
85 $path = check_plain(variable_get('openlayers_source', 'http://openlayers.org/dev/OpenLayers.js'));
86 // Check for full URL and include it manually if external.
87 if (valid_url($path, TRUE)) {
88 drupal_set_html_head('<script src="'. check_url($path) .'" type="text/javascript"></script>');
89 }
90 else {
91 drupal_add_js($path);
92 }
93 drupal_add_css(drupal_get_path('module', 'openlayers') .'/openlayers.css', 'module');
94 drupal_add_js(drupal_get_path('module', 'openlayers') .'/js/openlayers.js', 'module');
95 drupal_add_js(drupal_get_path('module', 'openlayers') .'/js/openlayers.layers.js', 'module');
96 }
97 }
98
99 /**
100 * Prepare a map for rendering.
101 */
102 function openlayers_build_map($map = array()) {
103 openlayers_include();
104 module_load_include('inc', 'openlayers', 'includes/openlayers.render');
105
106 // If no map is specified, use the default preset.
107 if (empty($map)) {
108 if ($preset = openlayers_preset_load(variable_get('openlayers_default_preset', 'default'))) {
109 $map = $preset->data;
110 }
111 }
112
113 // Assign an ID
114 $map['id'] = !isset($map['id']) ? _openlayers_create_map_id() : $map['id'];
115
116 $map['layers'] = _openlayers_layers_process($map['layers'], $map);
117
118 // Unset Map Arguments
119 unset($map['args']);
120
121 $map['behaviors'] = _openlayers_behaviors_process($map['behaviors'], $map);
122 $map['styles'] = _openlayers_styles_process($map['styles'], $map['layer_styles'], $map);
123
124 // Hook for one last alter
125 drupal_alter('openlayers_map', $map);
126
127 // Check map for errors
128 $map['errors'] = openlayers_error_check_map($map);
129
130 return $map;
131 }
132
133 /**
134 * Render Map
135 *
136 * Given parameters, render an OpenLayers map
137 *
138 * @ingroup openlayers_api
139 * @param $map
140 * Associative array of map paramters
141 *
142 * @return
143 * Boolean if successful
144 */
145 function openlayers_render_map($map = array(), $preset_name = '') {
146 $map = openlayers_build_map($map);
147
148 // Return themed map if no errors found
149 if (empty($map['errors'])) {
150 $js = array('openlayers' => array('maps' => array($map['id'] => $map)));
151 drupal_add_js($js, 'setting');
152 return theme('openlayers_map', $map, $preset_name);
153 }
154 return '';
155 }
156
157 /**
158 * Get all openlayers layers.
159 *
160 * @ingroup openlayers_api
161 * @param $reset
162 * Boolean whether to reset cache or not
163 * @return
164 * array of layer info
165 */
166 function openlayers_layers($reset = TRUE) {
167 ctools_include('export');
168 $layers = ctools_export_load_object('openlayers_layers', 'all', array(), $reset);
169 return $layers;
170 }
171
172 /**
173 * Menu loader for layers.
174 */
175 function openlayers_layer_load($name) {
176 $layers = openlayers_layers();
177 return !empty($layers[$name]) ? $layers[$name] : FALSE;
178 }
179
180 /**
181 * Save layer.
182 */
183 function openlayers_layer_save($layer) {
184 if (!empty($layer->name)) {
185 $exists = db_result(db_query("SELECT name FROM {openlayers_layers} WHERE name = '%s'", $layer->name));
186 return $exists ? drupal_write_record('openlayers_layers', $layer, 'name') : drupal_write_record('openlayers_layers', $layer);
187 }
188 return FALSE;
189 }
190
191 /**
192 * Get all behaviors.
193 *
194 * @ingroup openlayers_api
195 * @param $reset
196 * Boolean whether to reset cache or not.
197 * @return
198 * Array of behavior info.
199 */
200 function openlayers_behaviors($reset = FALSE) {
201 ctools_include('plugins');
202 ctools_include('context');
203 return ctools_get_plugins('openlayers', 'behaviors');
204 }
205
206 /**
207 * Get all openlayers styles.
208 *
209 * @ingroup openlayers_api
210 * @param $reset
211 * Boolean whether to reset cache or not
212 * @return
213 * array of styles info
214 */
215 function openlayers_styles($reset = FALSE) {
216 ctools_include('export');
217 $styles = ctools_export_load_object('openlayers_styles', 'all', array(), $reset);
218 return $styles;
219 }
220
221 /**
222 * Menu loader for styles.
223 */
224 function openlayers_style_load($name) {
225 $styles = openlayers_styles();
226 return !empty($styles[$name]) ? $styles[$name] : FALSE;
227 }
228
229 /**
230 * Save style.
231 */
232 function openlayers_style_save($style) {
233 if (!empty($style->name)) {
234 $exists = db_result(db_query("SELECT name FROM {openlayers_styles} WHERE name = '%s'", $style->name));
235 return $exists ? drupal_write_record('openlayers_styles', $style, 'name') : drupal_write_record('openlayers_styles', $style);
236 }
237 return FALSE;
238 }
239
240 /**
241 *
242 * Get Presets from DB or code, via cache
243 *
244 * @ingroup openlayers_api
245 * @param $reset
246 * Boolean whether to reset or not
247 * @return
248 * Return formatted data
249 */
250 function openlayers_presets($reset = FALSE) {
251 ctools_include('export');
252 $presets = ctools_export_load_object('openlayers_map_presets', 'all', array(), $reset);
253 return $presets;
254 }
255
256 /**
257 * Given a preset name, get full preset object.
258 *
259 * @ingroup openlayers_api
260 * @param $name
261 * Name of preset
262 * @param $reset
263 * Boolean whether to reset cache
264 * @return
265 * Preset object
266 */
267 function openlayers_preset_load($name = '', $reset = FALSE) {
268 ctools_include('export');
269 $presets = ctools_export_load_object('openlayers_map_presets', 'names', array($name), $reset);
270 return !empty($presets[$name]) ? $presets[$name] : FALSE;
271 }
272
273 /**
274 * Save a preset object to the database.
275 *
276 * @ingroup openlayers_api
277 * @param $preset
278 * Array of data for preset
279 * @return
280 * Boolean of whether successful
281 */
282 function openlayers_preset_save($preset) {
283 if (!empty($preset->name)) {
284 $exists = db_result(db_query("SELECT name FROM {openlayers_map_presets} WHERE name = '%s'", $preset->name));
285 return $exists ? drupal_write_record('openlayers_map_presets', $preset, 'name') : drupal_write_record('openlayers_map_presets', $preset);
286 }
287 return FALSE;
288 }
289
290 /**
291 * Get preset options in an array suitable for a FormAPI element.
292 *
293 * @param $reset
294 * Boolean whether to reset or not
295 * @return
296 * Return formatted data
297 */
298 function openlayers_preset_options($reset = FALSE) {
299 $presets = openlayers_presets($reset);
300 $options = array();
301 foreach ($presets as $preset) {
302 $options[$preset->name] = $preset->title;
303 }
304 return $options;
305 }
306
307 /**
308 * Check Map Errors
309 *
310 * Checks map array for incompatibilities or errors.
311 *
312 * @ingroup openlayers_api
313 * @param $map
314 * Map array
315 * @param $log_errors
316 * Boolean whether to log erros
317 * @return
318 * FALSE if passed. Array of descriptive errors if fail
319 */
320 function openlayers_error_check_map($map, $log_errors = TRUE) {
321 // @TODO: Instead of manually specifying projections, we should do a lookup on the projections in a big table to get variables that it should be checked against.
322 // @TODO: For next release, make hook
323 $errors = array();
324
325 // Check layer projections
326 foreach ($map['layers'] as $layer) {
327 if ($layer['projection']) {
328 if (!in_array($map['projection'], $layer['projection'])) {
329 $errors[] = t('The layer %layer_name cannot work with the map projection: EPSG: %map_proj', array(
330 '%layer_name' => $layer['name'],
331 '%map_proj' => $map['projection'],
332 ));
333 }
334 }
335 }
336
337 // TODO: rewrite to use openlayers_get_extent
338 // If we are using a degree based projection, then check to make sure
339 // our bounds are not over 180/90 degrees
340 if ($map['projection'] == '4326' || $map['projection'] == '4269') {
341 if (
342 ($map['options']['maxExtent']['top'] && $map['options']['maxExtent']['top'] > 90) ||
343 ($map['options']['maxExtent']['bottom'] && $map['options']['maxExtent']['bottom'] < -90) ||
344 ($map['options']['maxExtent']['left'] && $map['options']['maxExtent']['left'] < -180) ||
345 ($map['options']['maxExtent']['right'] && $map['options']['maxExtent']['right'] > 180) ||
346 ($map['options']['maxResoluton'] && $map['options']['maxResoluton'] > 180)
347 ) {
348 $errors[] = t("Your Maximum Extents are set greater than 180/90 degrees. Try Maximum Extent of: -180,180,-90,90 and a Maximum Resolution of 1.40625");
349 }
350 }
351
352 // Check if any errors found to log
353 if (count($errors) > 0 && $log_errors) {
354 // Log the Error(s)
355 watchdog('openlayers', implode(', ', $errors), array(), WATCHDOG_ERROR);
356 }
357
358 // Check if errors and return
359 return (count($errors) > 0) ? $errors : FALSE;
360 }
361
362 /**
363 * Implementation of hook_openlayers_layers_handler_info
364 * @return array of relationships between layer types and javascript
365 * layer handlers
366 */
367 function openlayers_openlayers_layers_handler_info($map = array()) {
368 return array(
369 'WMS' => array('layer_handler' => 'WMS'),
370 'TMS' => array('layer_handler' => 'TMS'),
371 'OSM' => array('layer_handler' => 'OSM'),
372 'Vector' => array('layer_handler' => 'Vector'),
373 );
374 }
375
376 /**
377 * Returns standard world-max-extents for common projections.
378 * Layers implementing other projections and subsets of the world should define their
379 * maxExtent in the layer array
380 * @param projection 900913, 4326
381 * @return array of maxExtent in OpenLayers toArray() format
382 */
383 function openlayers_get_extent($projection) {
384 switch($projection) {
385 case '900913':
386 return array(-20037508.34, -20037508.34, 20037508.34, 20037508.34);
387 case '4326':
388 return array(-180, -90, 180, 90);
389 }
390 }
391
392 /**
393 * Returns a default set of resolutions for standard TMS, WMS, etc servers
394 * serving up common projections. Layers supporting less common projections and resolutions
395 * can easily define custom resolutions arrays
396 * @param projection as string specifying which projection this should take, like 900913
397 * @return array of resolutions
398 */
399 function openlayers_get_resolutions($projection, $zoom_start = 0, $zoom_end = FALSE) {
400 switch ($projection) {
401 case '900913':
402 // 16 zoom levels, taken from
403 // openlayers.org TMS map
404 $res = array(
405 156543.0339,
406 78271.51695,
407 39135.758475,
408 19567.8792375,
409 9783.93961875,
410 4891.969809375,
411 2445.9849046875,
412 1222.99245234375,
413 611.496226171875,
414 305.7481130859375,
415 152.87405654296876,
416 76.43702827148438,
417 38.21851413574219,
418 19.109257067871095,
419 9.554628533935547,
420 4.777314266967774,
421 2.388657133483887,
422 1.1943285667419434,
423 0.5971642833709717);
424 break;
425 case '4326':
426 // 16 zoom levels, taken from
427 // openlayers.org default WMS map
428 $res = array(
429 0.703125,
430 0.3515625,
431 0.17578125,
432 0.087890625,
433 0.0439453125,
434 0.02197265625,
435 0.010986328125,
436 0.0054931640625,
437 0.00274658203125,
438 0.001373291015625,
439 0.0006866455078125,
440 0.00034332275390625,
441 0.000171661376953125,
442 0.0000858306884765625,
443 0.00004291534423828125,
444 0.000021457672119140625);
445 break;
446 default:
447 $res = array();
448 break;
449 }
450 $length = ($zoom_end == FALSE) ? null : $zoom_end - $zoom_start;
451 // By default this will not actually clip the array
452 $resolutions = array_slice($res, $zoom_start, $length);
453 return $resolutions;
454 }
455
456 /**
457 * Implementation of hook_openlayers_layers_info.
458 */
459 function openlayers_openlayers_layers_info() {
460 $layers = array();
461
462 $layer = new StdClass();
463 $layer->api_version = 1;
464 $layer->name = 'openlayers_default_wms';
465 $layer->title = t('Default OpenLayers WMS');
466 $layer->description = t('A simple basemap to get you started');
467 $layer->data = array(
468 'projection' => array('4326', '900913', '4269'),
469 'baselayer' => TRUE,
470 'type' => 'WMS',
471 'url' => 'http://labs.metacarta.com/wms/vmap0',
472 'params' => array('layers' => 'basic'),
473 'options' => array(
474 'maxExtent' => openlayers_get_extent('4326'),
475 ),
476 'events' => array(),
477 );
478 $layers[$layer->name] = $layer;
479
480 return $layers;
481 }
482
483 /**
484 * Implementation of hook_openlayers_styles_info
485 */
486 function openlayers_openlayers_styles_info() {
487 $styles = array();
488
489 $style = new stdClass();
490 $style->api_version = 1;
491 $style->name = 'default';
492 $style->title = t('Default style');
493 $style->description = t('Basic default style.');
494 $style->data = array(
495 'pointRadius' => 5,
496 'fillColor' => '#FFCC66',
497 'strokeColor' => '#FF9933',
498 'strokeWidth' => 4,
499 'fillOpacity' => 0.5
500 );
501 $styles[$style->name] = $style;
502
503 $style = new stdClass();
504 $style->api_version = 1;
505 $style->name = 'default_select';
506 $style->title = t('Default select style');
507 $style->description = t('Default style for selected geometries');
508 $style->data = array(
509 'pointRadius' => 5,
510 'fillColor' => '#66CCFF',
511 'strokeColor' => '#3399FF',
512 'strokeWidth' => 4,
513 'fillOpacity' => 0.5
514 );
515 $styles[$style->name] = $style;
516
517 return $styles;
518 }
519
520 /**
521 * Implementation of hook_openlayers_presets.
522 */
523 function openlayers_openlayers_presets() {
524 // Create full preset array
525 $default = new stdClass();
526 $default->api_version = 1;
527 $default->name = 'default';
528 $default->title = t('Default Map');
529 $default->description = t('This is the default map preset that comes with the OpenLayers module.');
530 $default->data = array(
531 'projection' => '4326',
532 'width' => 'auto',
533 'default_layer' => 'openlayers_default_wms',
534 'height' => '300px',
535 'center' => array(
536 'initial' => array(
537 'centerpoint' => '0,0',
538 'zoom' => '1'
539 )
540 ),
541 'options' => array(
542 'displayProjection' => '4326',
543 'maxExtent' => openlayers_get_extent('4326'),
544 ),
545 'behaviors' => array(
546 'openlayers_behavior_panzoombar' => array(),
547 ),
548 'layer_styles' => array(),
549 );
550 return array('default' => $default);
551 }
552
553 /**
554 * We define base classes in the core module.
555 * All other parent classes can be autoloaded through ctools.
556 */
557 class openlayers_behavior implements openlayers_behavior_interface {
558 var $options, $map;
559
560 function __construct($options = array(), $map = array()) {
561 $this->options = $options + $this->options_init();
562 $this->map = $map;
563 }
564
565 function options_init() {
566 return array();
567 }
568
569 function options_form() {
570 return array();
571 }
572
573 function render(&$map) {}
574 }
575
576 /**
577 * Interface for openlayers_behaviors.
578 */
579 interface openlayers_behavior_interface {
580 function __construct($options = array(), $map = array());
581 function options_init();
582 function options_form();
583 function render(&$map);
584 }
585
586 /**
587 * Implementation of hook_openlayers_behaviors().
588 *
589 */
590 function openlayers_openlayers_behaviors() {
591 return array(
592 'openlayers_behavior_attribution' => array(
593 'title' => t('Attribution'),
594 'description' => t('Allows layers to provide attribution to the map if it exists.'),
595 'type' => 'layer',
596 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
597 'file' => 'openlayers_behavior_attribution.inc',
598 'behavior' => array(
599 'class' => 'openlayers_behavior_attribution',
600 'parent' => 'openlayers_behavior',
601 ),
602 ),
603 'openlayers_behavior_keyboarddefaults' => array(
604 'title' => t('Keyboard Defaults'),
605 'description' => t('Provides a the ability to use the keyboard to pan and zoom map.'),
606 'type' => 'layer',
607 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
608 'file' => 'openlayers_behavior_keyboarddefaults.inc',
609 'behavior' => array(
610 'class' => 'openlayers_behavior_keyboarddefaults',
611 'parent' => 'openlayers_behavior',
612 ),
613 ),
614 'openlayers_behavior_layerswitcher' => array(
615 'title' => t('Layer Switcher'),
616 'description' => t('Gives user ability to switch Layers in the map interface.'),
617 'type' => 'map',
618 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
619 'file' => 'openlayers_behavior_layerswitcher.inc',
620 'behavior' => array(
621 'class' => 'openlayers_behavior_layerswitcher',
622 'parent' => 'openlayers_behavior',
623 ),
624 ),
625 'openlayers_behavior_mouseposition' => array(
626 'title' => t('Mouse Position'),
627 'description' => t('Gives a visual indication of the mouse position to the user.'),
628 'type' => 'map',
629 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
630 'file' => 'openlayers_behavior_mouseposition.inc',
631 'behavior' => array(
632 'class' => 'openlayers_behavior_mouseposition',
633 'parent' => 'openlayers_behavior',
634 ),
635 ),
636 'openlayers_behavior_navigation' => array(
637 'title' => t('Navigation'),
638 'description' => t('Gives the user the ability to navigate the map interface.'),
639 'type' => 'map',
640 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
641 'file' => 'openlayers_behavior_navigation.inc',
642 'behavior' => array(
643 'class' => 'openlayers_behavior_navigation',
644 'parent' => 'openlayers_behavior',
645 ),
646 ),
647 'openlayers_behavior_dragpan' => array(
648 'title' => t('DragPan'),
649 'description' => t('Gives user ability to pan in the map interface.'),
650 'type' => 'map',
651 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
652 'file' => 'openlayers_behavior_dragpan.inc',
653 'behavior' => array(
654 'class' => 'openlayers_behavior_dragpan',
655 'parent' => 'openlayers_behavior',
656 ),
657 ),
658 'openlayers_behavior_panzoombar' => array(
659 'title' => t('PanZoomBar'),
660 'description' => t('Gives user ability to pan and zoom in the map interface.'),
661 'type' => 'map',
662 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
663 'file' => 'openlayers_behavior_panzoombar.inc',
664 'behavior' => array(
665 'class' => 'openlayers_behavior_panzoombar',
666 'parent' => 'openlayers_behavior',
667 ),
668 ),
669 'openlayers_behavior_mapformvalues' => array(
670 'title' => t('Map Form Values'),
671 'description' => t('Private method for admin UI'),
672 'type' => 'map',
673 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
674 'file' => 'openlayers_behavior_mapformvalues.inc',
675 'behavior' => array(
676 'class' => 'openlayers_behavior_mapformvalues',
677 'parent' => 'openlayers_behavior',
678 ),
679 ),
680 'openlayers_behavior_boxselect' => array(
681 'title' => t('Boxselect'),
682 'description' => t('Allows the selection and display of a box.'),
683 'type' => 'map',
684 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
685 'file' => 'openlayers_behavior_boxselect.inc',
686 'behavior' => array(
687 'class' => 'openlayers_behavior_boxselect',
688 'parent' => 'openlayers_behavior',
689 ),
690 ),
691 'openlayers_behavior_permalink' => array(
692 'title' => t('Permalink'),
693 'description' => t('Prvides a URL that will link to a specific map position.'),
694 'type' => 'map',
695 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
696 'file' => 'openlayers_behavior_permalink.inc',
697 'behavior' => array(
698 'class' => 'openlayers_behavior_permalink',
699 'parent' => 'openlayers_behavior',
700 ),
701 ),
702 'openlayers_behavior_scaleline' => array(
703 'title' => t('Scale Line'),
704 'description' => t('Provides the user with a line of scale in the map interface.'),
705 'type' => 'map',
706 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
707 'file' => 'openlayers_behavior_scaleline.inc',
708 'behavior' => array(
709 'class' => 'openlayers_behavior_scaleline',
710 'parent' => 'openlayers_behavior',
711 ),
712 ),
713 'openlayers_behavior_zoombox' => array(
714 'title' => t('Zoom Box'),
715 'description' => t('Allows user to draw a box on screen to zoom with Shift + Click.'),
716 'type' => 'map',
717 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
718 'file' => 'openlayers_behavior_zoombox.inc',
719 'behavior' => array(
720 'class' => 'openlayers_behavior_zoombox',
721 'parent' => 'openlayers_behavior',
722 ),
723 ),
724 'openlayers_behavior_zoomtomaxextent' => array(
725 'title' => t('Zoom to Max Extent'),
726 'description' => t('Provides button to zoom to the maximum extent of the map.'),
727 'type' => 'map',
728 'path' => drupal_get_path('module', 'openlayers') .'/includes/behaviors',
729 'file' => 'openlayers_behavior_zoomtomaxextent.inc',
730 'behavior' => array(
731 'class' => 'openlayers_behavior_zoomtomaxextent',
732 'parent' => 'openlayers_behavior',
733 ),
734 ),
735 );
736 }

  ViewVC Help
Powered by ViewVC 1.1.2