Project

General

Profile

Download (17.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Functions for dealing maps
5
 *
6
 * @copyright
7
 *   (C) 2007-2013 EDIT
8
 *   European Distributed Institute of Taxonomy
9
 *   http://www.e-taxonomy.eu
10
 *
11
 *   The contents of this module are subject to the Mozilla
12
 *   Public License Version 1.1.
13
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
14
 *
15
 * @author
16
 *   - Andreas Kohlbecker <a.kohlbecker@BGBM.org>
17
 */
18

    
19
/**
20
 * Compose an render array for distribution and occurrence
21
 * maps.
22
 *
23
 * The map can either be a plain image or a dynamic open layers map
24
 * depending on the settings
25
 *
26
 * compose_hook() implementation
27
 *
28
 * @param string $occurrence_query
29
 * @param string $distribution_query
30
 * @param string $legend_format_query
31
 * @param array $event_listeners
32
 *   An associative array of with OpenLayers.Map event names as key and corresponding js callbacks.
33
 *   In addition to the event names '#execute' as key is also allowed.
34
 *   Valid events are:
35
 *      - move
36
 *      - moveend
37
 *      - zoomend
38
 *      - changelayer
39
 *      - changebaselayer
40
 *      - #execute:
41
 *            force execution of the given callback after registration of the event handlers
42
 *   see http://dev.openlayers.org/apidocs/files/OpenLayers/Map-js.html#OpenLayers.Map.events for more
43
 *
44
 * @return array
45
 *    A drupal render array
46
 *
47
 * Similar compose function compose_distribution_map()
48
 *
49
 * @ingroup compose
50
 */
51
function compose_map($occurrence_query = NULL, $distribution_query = NULL, $legend_format_query = NULL, array $event_listeners = array()) {
52

    
53
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
54
  if ($map_settings['map_type'] == 1) {
55
    $map_html = get_openlayers_map(
56
        $map_settings['width'],
57
        $map_settings['height'],
58
        $map_settings['bbox'],
59
        $occurrence_query,
60
        $distribution_query,
61
        $legend_format_query,
62
        $map_settings['caption'],
63
        $event_listeners
64
    );
65
  }
66
  else {
67
    $map_html = get_image_map(
68
        $map_settings['width'],
69
        $map_settings['height'],
70
        $map_settings['bbox'],
71
        $occurrence_query,
72
        $distribution_query,
73
        $legend_format_query,
74
        $map_settings['caption']
75
    );
76
  }
77
  return markup_to_render_array($map_html, 0);
78
}
79

    
80
/**
81
 * @param $map_settings
82
 *   The map settings array as retrieved by e.g. get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
83
 * @param array $event_listeners
84
 *   An associative array of with OpenLayers.Map event names as key and corresponding js callbacks.
85
 *   In addition to the event names '#execute' as key is also allowed.
86
 *   Valid events are:
87
 *      - move
88
 *      - moveend
89
 *      - zoomend
90
 *      - changelayer
91
 *      - changebaselayer
92
 *      - #execute:
93
 *            force execution of the given callback after registration of the event handlers
94
 *   see http://dev.openlayers.org/apidocs/files/OpenLayers/Map-js.html#OpenLayers.Map.events for more
95
 */
96
function _add_js_openlayers_map($map_settings, array $event_listeners = array()) {
97

    
98
  _add_js_openlayers();
99

    
100
  $edit_map_service = get_edit_map_service_settings();
101

    
102
  $gmap_api_key = variable_get('gmap_api_key', 'ABQIAAAAFho6eHAcUOTHLmH9IYHAeBRi_j0U6kJrkFvY4-OX2XYmEAa76BTsyMmEq-tn6nFNtD2UdEGvfhvoCQ');
103

    
104
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/map/openlayers_map.js');
105
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/map/openlayers_layers.js');
106

    
107
  $cdm_openlayers_options = array(
108
      'legendPosition'  => '3',
109
      'boundingBox' => $map_settings['bbox'],
110
      'distributionOpacity' => $map_settings['distribution_opacity'],
111
      'legendOpacity' => $map_settings['legend']['opacity'],
112
      'showLayerSwitcher' => $map_settings['openlayers']['show_layer_switcher']  ==  1,
113
      'displayOutsideMaxExtent' => $map_settings['openlayers']['display_outside_max_extent'] == 1,
114
//       'imgPath' => drupal_get_path('module', 'cdm_dataportal') . '/js/map/OpenLayers-2.13.1/img/' // path to the control icons
115
      // if no baseLayerNames or defaultBaseLayerName are not defined
116
      // the defaults in cdm_openlayers.js will be used
117
  );
118

    
119
  // --- setting the base layer options
120
  if (is_array($map_settings['openlayers']['base_layers']) && count($map_settings['openlayers']['base_layers']) > 0) {
121

    
122
    $layer_names = $map_settings['openlayers']['base_layers'];
123

    
124
    if(isset($layer_names['PREFERRED'])){
125
      $cdm_openlayers_options['defaultBaseLayerName'] = $layer_names['PREFERRED'];
126
      unset($layer_names['PREFERRED']);
127
    }
128

    
129
    $cdm_openlayers_options['baseLayerNames'] = array_values($layer_names);
130

    
131
    if (isset($layer_names['gmap']) || isset($layer_names['gsat']) || isset($layer_names['ghyb'])) {
132
      // gmaps version 2 (needs api key)
133
      drupal_add_js('http://maps.google.com/maps?file=api&v=2&key=' . $gmap_api_key . '', array('type' => 'external'));
134
      // gmaps version 3 (does not need api key)
135
  //     drupal_add_js('http://maps.google.com/maps?file=api&v=3&sensor=false', array('type' => 'external'));
136
      drupal_add_js('http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1', array('type' => 'external'));
137
    }
138

    
139
  }
140

    
141
  // --- custom wms base layer
142
  $map_settings['openlayers']['custom_wms_base_layer']['params'] = json_decode($map_settings['openlayers']['custom_wms_base_layer']['params']);
143
  $cdm_openlayers_options['customWMSBaseLayerData'] = $map_settings['openlayers']['custom_wms_base_layer'];
144

    
145
  // --- eventhandlers
146
  $event_listeners_js = '';
147
  $execute_handler = '';
148
  foreach($event_listeners as $event=>$js_callback){
149
    if($event == '#execute'){
150
      $execute_handler = 'map_container.each(function(){' . $js_callback . '();});';
151
    } else {
152
      $event_listeners_js .= ($event_listeners_js ? ",\n": "\n") .'"' . $event . '": ' . $js_callback;
153
    }
154
  }
155

    
156
//   // combine keys and values
157
//   foreach($cdm_openlayers_options as $key=>&$val){
158
//     $val = $key . ": " . $val;
159
//   };
160

    
161
  // window.onload - is executed when the document and images etc is fully loaded
162
  // Query(document).ready - is executed much earlier, when the DOM is loaded
163
  drupal_add_js("
164
          jQuery(document).ready(function() {
165
                window.onload = function () {
166
                  var map_container = jQuery('#openlayers_map').cdm_openlayers_map(
167
                   '" . $edit_map_service['base_uri'] . "',
168
                   '" . $edit_map_service['version'] . "',
169
                   " .  json_encode($cdm_openlayers_options) . "
170
                );
171
                map_container.each(function(){
172
                        this.cdmOpenlayersMap.registerEvents({" . $event_listeners_js . "});
173
                });
174
                " . $execute_handler . "
175
        };
176
      });
177
    ", array('type' => 'inline'));
178

    
179
}
180

    
181

    
182
/**
183
 * @todo Enter description here ...
184
 *
185
 * @param unknown_type $width
186
 * @param unknown_type $bounding_box
187
 * @param unknown_type $occurrenceQuery
188
 * @param unknown_type $distributionQuery
189
 * @param unknown_type $legendFormatQuery
190
 * @param unknown_type $map_caption
191
 * @param array $event_listeners
192
 *   An associative array of with OpenLayers.Map event names as key and corresponding js callbacks.
193
 *   In addition to the event names '#execute' as key is also allowed.
194
 *   Valid events are:
195
 *      - move
196
 *      - moveend
197
 *      - zoomend
198
 *      - changelayer
199
 *      - changebaselayer
200
 *      - #execute:
201
 *            force execution of the given callback after registration of the event handlers
202
 *   see http://dev.openlayers.org/apidocs/files/OpenLayers/Map-js.html#OpenLayers.Map.events for more
203
 *
204
 * @return String
205
 *    rendered html
206
 */
207
function get_openlayers_map($width, $height, $bounding_box = FALSE, $occurrenceQuery = FALSE, $distributionQuery = FALSE, $legendFormatQuery = FALSE, $map_caption = FALSE, array $event_listeners = array()) {
208

    
209
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
210

    
211
  _add_js_openlayers_map($map_settings, $event_listeners);
212

    
213
  $out = '<div id="openlayers">';
214
  $out .= '<div id="openlayers_map" class="smallmap"';
215
  if($width) {
216
    if(!$height){
217
      $height = $width / 2;
218
    }
219
    $out .= ' style="width: ' . $width . 'px; height:' . $height . 'px"';
220
  }
221

    
222
  // Additional query parameters as set in the data portal admin section.
223
  $labels_on = $map_settings['show_labels'];
224

    
225
  $openlayers_map_query_string = '&img=false&ms=' . $width
226
  . ($bounding_box ? '&bbox=' . $bounding_box : '')
227
  . ($labels_on ? '&label=' . $labels_on : '');
228

    
229
  if ($occurrenceQuery) {
230
    // @todo Fix $occurrenceQuery.
231
    //     $occurrenceQuery .= '&bbox=-180,-90,180,90';
232
    $occurrenceQuery .= '&l=v%3Aatbi%2Ce_w_0'; // TODO why are we using v:atbi,e_w_0 as layer ???
233
    // $occurrenceQuery .= '&l=v:e_w_0';
234
    // TODO add to cdm service?
235
    $occurrenceQuery .= '&legend=0';
236

    
237
    $out .= ' occurrenceQuery="' . $occurrenceQuery . '&' . $openlayers_map_query_string . '"';
238
  }
239

    
240
  if ($distributionQuery) {
241
    //HACK for testing (this must be done in js)
242
//     $distributionQuery .= "&layer=em_tiny_jan2003&dest_projection_epsg=7777777";
243
    $out .= ' distributionQuery="' . $distributionQuery . '&' . $openlayers_map_query_string . '"';
244
  }
245

    
246
  if ($legendFormatQuery) {
247
    $out .= ' legendFormatQuery="' . $legendFormatQuery . '"';
248
  }
249

    
250
  $out .= '></div></div>';
251

    
252
  // Showing map caption.
253
  if ($map_caption) {
254
    // FIXME: replace <br> by according css style.
255
    $out .= '<div class="distribution_map_caption">' . $map_caption . '</div>' . '<br />';
256
    $out .= '</div>';
257
  }
258
  return $out;
259
}
260

    
261

    
262
/**
263
 * Composes the render array for a distribution map of the given taxon.
264
 *
265
 * The distribution map can either be a plain image or a dynamic open layers map
266
 * depending on the settings.
267
 *
268
 * compose_hook() implementation
269
 *
270
 * @param $taxon
271
 *   The CDM Taxon instance to create the distribution map for.
272
 * @return array
273
 *    A drupal render array
274
 *
275
 * Similar compose function compose_map()
276
 *
277
 * @ingroup compose
278
 */
279
function compose_distribution_map($taxon, $query_string) {
280

    
281
  $out = '';
282
  $settings = get_edit_map_service_settings();
283

    
284
  $fontStyles = array(
285
      0 => "plane",
286
      1 => "italic",
287
  );
288

    
289
//   // Query cdm server for map service uri parameters.
290
//   $query_string = cdm_ws_get(CDM_WS_GEOSERVICE_DISTRIBUTIONMAP, $taxon->uuid, queryString(cdm_distribution_filter_query()));
291
//   $query_string = $query_string->String;
292
  $out .= "<!-- map_data_parameters:" . print_r($query_string, TRUE) . " -->";
293
  if (!$query_string) {
294
    // The $query_string is empty if there are no distribution areas defined.
295
    return;
296
  }
297

    
298
  /* ------ choose the display mode, either openlayers or static image ------ */
299

    
300
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
301

    
302
  if ($map_settings['map_type'] == 1) {
303

    
304
    /* =========== display distributions using the openlayers map viewer =========== */
305

    
306
    $legendFormatQueryStr = "format=image" . urlencode('/') . "png"
307
      . "&TRANSPARENT=TRUE"
308
      . "&WIDTH=" . $map_settings['legend']['icon_width']
309
      . "&HEIGHT=" . $map_settings['legend']['icon_height']
310
      // TODO why is the layer=topp:tdwg_level_4 parameter needed at all here??
311
      // AK: i think the tdwg_level_4 is used as place holder and will be replaced later on
312
      // => search for "tdwg_level_4" in the code
313
      . "&layer=topp" . urlencode(':') . "tdwg_level_4"
314
      . "&LEGEND_OPTIONS=forceLabels" . urlencode(':') . "on"
315
      . ";fontStyle" . urlencode(':') . $fontStyles[$map_settings['legend']['font_style']]
316
      . ";fontSize" . urlencode(':') .  $map_settings['legend']['font_size']
317
      . "&SLD=";
318

    
319
    $out .= get_openlayers_map(
320
        $map_settings['width'],
321
        $map_settings['height'],
322
        $map_settings['bbox'],
323
        NULL,
324
        $query_string,
325
        $legendFormatQueryStr,
326
        $map_settings['caption']
327
    );
328
  }
329
  else {
330
    $legendFormatQueryStr = '';
331
    $out = get_image_map(
332
        $map_settings['width'],
333
        $map_settings['height'],
334
        $map_settings['bbox'],
335
        NULL,
336
        $query_string,
337
        $legendFormatQueryStr,
338
        $map_settings['caption']
339
    );
340
  }
341
  return markup_to_render_array($out);
342
}
343

    
344

    
345

    
346

    
347
/**
348
 * @todo Enter description here ...
349
 *
350
 * @param unknown_type $width
351
 * @param unknown_type $bounding_box
352
 * @param unknown_type $occurrenceQuery
353
 * @param unknown_type $distributionQuery
354
 * @param unknown_type $legendFormatQuery
355
 * @param unknown_type $map_caption
356
 *
357
* @return String
358
 *    rendered html
359
 */
360
function get_image_map($width, $height= NULL, $bounding_box = FALSE, $occurrenceQuery = FALSE, $distributionQuery = FALSE, $legendFormatQuery = FALSE, $map_caption = FALSE) {
361

    
362
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
363

    
364
  $baselayer_name = $map_settings['image_map']['base_layer'];
365
  if(empty($baselayer_name)){
366
    $baselayer_name = "earth";
367
  }
368

    
369
  $query_string = '&image=true&recalculate=false&ms=' . $width . ($height ? ',' . $height : '')
370
  // Additional query parameters as set in the data portal admin section.
371
  . ($bounding_box ? '&bbox=' . $bounding_box : '')
372
  . ($map_settings['show_labels'] ? '&label=' . $map_settings['show_labels'] : '');
373

    
374
  if ($map_caption) {
375
    $query_string .= '&mlp=3&mc_s=Georgia,15,blue&mc=' . $map_caption;
376
  }
377

    
378
  if (get_edit_map_service_version_number() >= 1.1) {
379

    
380
    // Either occurrence or distribution - combined maps will be possible
381
    // in the future.
382
    if ($occurrenceQuery) {
383
      // @todo Fix $occurrenceQuery.
384
      $occurrenceQuery = str_replace("&image=false", "", $occurrenceQuery);
385
      // $occurrenceQuery .= '&l=v%3Aatbi%2Ce_w_0';
386

    
387
      // Will be replaced below.. HACK!!!
388
      $occurrenceQuery .= '&l=' . $baselayer_name . '&as=';
389

    
390
      $query_string .= "&" . $occurrenceQuery;
391
    }
392
    elseif ($distributionQuery) {
393
      $query_string .= '&l=' . $baselayer_name . "&" .$distributionQuery;
394
    }
395

    
396
    // Apply Plain Image map settings special for version >= 1.1.
397
    /*
398
    example : title=a:Naturalized++non-invasive
399
    &ad=cyprusdivs:bdcode:a:5&as=a:ff9900,,0.1,&l=tdwg4
400
    &ms=500&bbox=32,34,35,36&img=true&legend=1&mlp=3
401
    &mc_s=Georgia,15,blue&mc=&recalculate=false
402

    
403
    http://edit.br.fgov.be/edit_wp5/v1/rest_gen.php?
404
    l=background_gis:b,cyprusdivs&ad=cyprusdivs%3Abdcode%3Aa%3A8%2C4
405
    &as=a%3A339966%2C%2C0.1%2C|b:0000ff,,
406
    &bbox=32%2C34%2C35%2C36&img=true&legend=1&mc=&mc_s=Georgia%2C15%2Cblue
407
    &mlp=3&ms=500&recalculate=false&title=a%3Aindigenous
408
    */
409

    
410
    $map_service_script_name = "rest_gen.php";
411

    
412
    $bgcolor_areaStyleId = "Y";
413
    $baselayer_areaStyleId = "Z";
414
    $bgcolor_layer = '';
415
    $additional_area_styles = array();
416

    
417
    // Background color:
418
    if ($map_settings['image_map']['bg_color'] ) {
419
      $bgcolor_layer = "background_gis:" . $bgcolor_areaStyleId;
420
      $additional_area_styles[] = $bgcolor_areaStyleId . ":" . $map_settings['image_map']['bg_color'] . ",,";
421
    }
422

    
423
    // TODO HACK to replace the default base layer which currently is tdwg4 !!!
424
    // only needed for distribution maps.
425
    if (strpos($query_string, "?l=") !== FALSE) {
426
      $layer_param_token = "?l=";
427
    }
428
    else {
429
      $layer_param_token = "&l=";
430
    }
431
    if (strpos($query_string, "?as=") !== FALSE) {
432
      $areystyle_param_token = "?as=";
433
    }
434
    else {
435
      $areystyle_param_token = "&as=";
436
    }
437
    if ($map_settings['image_map']['base_layer']) {
438
      $query_string = str_replace($layer_param_token .$baselayer_name, "$layer_param_token" . $map_settings['image_map']['base_layer'] . ":" . $baselayer_areaStyleId, $query_string);
439
    }
440
    else {
441
      $query_string = str_replace($layer_param_token . $baselayer_name, $layer_param_token . $baselayer_name . ":" . $baselayer_areaStyleId . ",", $query_string);
442
    }
443

    
444
    if ($bgcolor_layer) {
445
      $query_string = str_replace($layer_param_token, $layer_param_token . $bgcolor_layer . ",", $query_string);
446
    }
447

    
448
    if ($map_settings['image_map']['layer_style']) {
449
      $additional_area_styles[] = $baselayer_areaStyleId . ":" . $map_settings['image_map']['layer_style'];
450
    }
451

    
452
    if(isset($map_settings['projection'])){
453
      $query_string .= "&srs=" . $map_settings['projection'];
454
    }
455

    
456
    if(isset($map_settings['legend']['show']) && $map_settings['legend']['show']){
457
      $query_string .= "&legend=1";
458
    }
459

    
460
    foreach ($additional_area_styles as $as) {
461
      $query_string = str_replace($areystyle_param_token, $areystyle_param_token . $as . "|", $query_string);
462
    }
463

    
464
  }
465
  else {
466
    // Pre 1.1. version of map service.
467
    if ($occurrenceQuery) {
468

    
469
      $map_service_script_name = "point.php";
470

    
471
      // Fix $occurrenceQuery.
472
      $occurrenceQuery = str_replace("&image=false", "", $occurrenceQuery);
473
      // $occurrenceQuery .= '&l=v%3Aatbi%2Ce_w_0';
474
      $occurrenceQuery .= '&l=v:e_w_0';
475
      $query_string .= "&" . $occurrenceQuery;
476
    }
477
    elseif ($distributionQuery) {
478
      $query_string .= "&" . $distributionQuery;
479
      $map_service_script_name = "areas.php";
480
    }
481
  }
482

    
483
  $mapUri = url(get_edit_map_service_full_uri() . '/' . $map_service_script_name . '?' .  $query_string);
484
  $out = '<img class="distribution_map" src="' . $mapUri . '" alt="Map" />';
485
  // Showing map caption.
486
  if ($map_caption) {
487
    // FIXME: replace <br> by according css style.
488
    $out .= '<div class="distribution_map_caption">' . $map_caption . '</div>' . '<br />';
489
    $out .= '</div>';
490
  }
491

    
492
  return $out;
493
}
494

    
495

    
(3-3/7)