diff --git a/README.md b/README.md index e0f4547..4ad1bb7 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ A [Geofield] widget that provides a [Leaflet] map widget with the - Download [Leaflet.widget] and place it in your libraries directory (see [Libraries API]). E.g: sites/all/libraries +- Download [Leaflet.draw] and place it in your libraries directory (see + [Libraries API]). E.g: sites/all/libraries - Requires [Leaflet] to be available. By default the version bundled with [Leaflet.widget] will be used. However if you have [Leaflet module] installed and [Leaflet] located at /leaflet, that version will be @@ -34,6 +36,6 @@ A [Geofield] widget that provides a [Leaflet] map widget with the [GeoPHP]: http://drupal.org/project/geophp [Leaflet module]: http://drupal.org/project/leaflet [Geofield]: http://drupal.org/project/geofield -[Leaflet.draw]: https://github.com/jacobtoye/Leaflet.draw +[Leaflet.draw]: https://github.com/Leaflet/Leaflet.draw [Leaflet.widget]: https://tnightingale.github.com/Leaflet.widget [Libraries API]: http://drupal.org/project/libraries diff --git a/js/widget.js b/js/widget.js index e0a4274..cd7db6d 100644 --- a/js/widget.js +++ b/js/widget.js @@ -1,28 +1,86 @@ (function ($) { - Drupal.leaflet_widget = Drupal.leaflet_widget || {}; + Drupal.leaflet_widget = Drupal.leaflet_widget || {}; - Drupal.behaviors.geofield_widget = { - attach: attach - }; + Drupal.behaviors.geofield_widget = { + attach: function (context, settings) { + $('.leaflet-widget').once().each(function (i, item) { + var id = $(item).attr('id'), + options = settings.leaflet_widget_widget[id]; - function attach(context, settings) { - $('.leaflet-widget').once().each(function(i, item) { - var id = $(item).attr('id'), - options = settings.leaflet_widget_widget[id]; + L.Util.extend(options.map, { + layers: [L.tileLayer(options.map.base_url)] + }); - L.Util.extend(options.map, { - layers: [L.tileLayer(options.map.base_url)], - }); + var map = L.map(id, options.map); + map.widget.enable(); - var map = L.map(id, options.map); - map.widget.enable(); + // Serialize data and set input value on submit. + $(item).parents('form').bind('submit', $.proxy(map.widget.write, map.widget)); - // Serialize data and set input value on submit. - $(item).parents('form').bind('submit', $.proxy(map.widget.write, map.widget)); + Drupal.leaflet_widget[id] = map; - Drupal.leaflet_widget[id] = map; + // Geocoder handling. + $('.field-widget-leaflet-widget-widget a.geocoder-submit', context).bind('click.leaflet_widget_geocoder', function (event) { + event.preventDefault(); + Drupal.behaviors.geofield_widget.geocoder(id); + return false; + }); + $('.field-widget-leaflet-widget-widget :input.geocoder', context).bind('keydown.leaflet_widget_geocoder', function (event) { + // React to Tab, Enter, Esc. + if ($.inArray(event.keyCode, [9, 13, 27]) > -1) { + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + Drupal.behaviors.geofield_widget.geocoder(id); + } }); + }); + }, + + geocoder: function (id) { + var elem = $(':input.geocoder', $('#' + id ).parent()); + var handler = Drupal.settings.leaflet_widget_widget[id].geocoder.handler; + var map = Drupal.leaflet_widget[id]; + var url = location.protocol + '//' + location.host + Drupal.settings.basePath + 'geocoder/service/' + handler+ '?output=json&data=' + Drupal.encodePath(elem.val()); + + var throbber = $('
 
'); + elem.after(throbber); + + $.ajax({ + url: url, + type: 'GET', + dataType: 'json', + success: function (data, textStatus, jqXHR) { + if (textStatus == 'success') { + var latlng = [data.coordinates[1], data.coordinates[0]]; + var add = !map.widget._full; + if (!add) { + if((add = confirm(Drupal.t('The maximum cardinality is reached.\nDo you want to replace last item by the new one?')))) { + map.removeLayer(map.widget.vectors.getLayers()[0]); + add = !map.widget._full; + } + } + if (add) { + map.fire( + 'draw:marker-created', + { marker: new L.Marker(latlng, { icon: map.drawControl.handlers.marker.options.icon }) } + ); + map.fitBounds(map.widget.vectors.getBounds()); + } + } + else { + alert(Drupal.t('No valid geo reference found.')); + } + }, + complete: function() { + // Remove the progress element. + if (throbber) { + $(throbber).remove(); + } + } + }); } + } }(jQuery)); diff --git a/leaflet_widget.install b/leaflet_widget.install new file mode 100644 index 0000000..eccd9fe --- /dev/null +++ b/leaflet_widget.install @@ -0,0 +1,62 @@ + $t('Leaflet Widget JavaScript file'), + 'severity' => REQUIREMENT_ERROR, + 'description' => $t( + 'You need to download the !leaflet_widget_js and extract the entire contents of the archive into the %path directory on your server.', + array( + '!leaflet_widget_js' => l($t('Leaflet Widget JavaScript file'), 'https://tnightingale.github.com/Leaflet.widget'), + '%path' => 'sites/all/libraries', + ) + ), + 'value' => $t('Not Installed'), + ); + } + else { + $requirements['leaflet_widget_js'] = array( + 'title' => $t('Leaflet Widget JavaScript file'), + 'severity' => REQUIREMENT_OK, + 'value' => $t('Installed'), + ); + } + $leaflet_draw = libraries_get_path('Leaflet.draw'); + if (!$leaflet_draw) { + $requirements['leaflet_draw_js'] = array( + 'title' => $t('Leaflet Draw JavaScript file'), + 'severity' => REQUIREMENT_ERROR, + 'description' => $t( + 'You need to download the !leaflet_draw_js and extract the entire contents of the archive into the %path directory on your server.', + array( + '!leaflet_draw_js' => l($t('Leaflet Draw JavaScript file'), 'https://github.com/Leaflet/Leaflet.draw'), + '%path' => 'sites/all/libraries', + ) + ), + 'value' => $t('Not Installed'), + ); + } + else { + $requirements['leaflet_draw_js'] = array( + 'title' => $t('Leaflet Draw JavaScript file'), + 'severity' => REQUIREMENT_OK, + 'value' => $t('Installed'), + ); + } + break; + } + return $requirements; +} diff --git a/leaflet_widget.module b/leaflet_widget.module index b81a7d7..e0fd1d6 100644 --- a/leaflet_widget.module +++ b/leaflet_widget.module @@ -23,6 +23,10 @@ function leaflet_widget_field_widget_info() { 'auto_center' => TRUE, 'zoom' => 10, ), + 'geocoder' => array( + 'enabled' => module_exists('geocoder'), + 'handler' => NULL, + ), ), 'behaviors' => array( 'multiple values' => FIELD_BEHAVIOR_CUSTOM, @@ -77,6 +81,36 @@ function leaflet_widget_field_widget_settings_form($field, $instance) { '#default_value' => $settings['map']['zoom'], '#required' => TRUE, ); + // If the geocode module is available provide the option to use it. + if (module_exists('geocoder')) { + $form['geocoder'] = array( + '#type' => 'fieldset', + '#title' => t('Geocoder settings'), + '#tree' => TRUE, + ); + $form['geocoder']['enabled'] = array( + '#type' => 'checkbox', + '#title' => t('Show geocoder field'), + '#default_value' => !empty($settings['geocoder']['enabled']), + ); + $processors = array(); + foreach (geocoder_handler_info('text') as $item => $info) { + $processors[$item] = $info['title']; + } + $form['geocoder']['handler'] = array( + '#type' => 'select', + '#title' => t('Handler to use'), + '#options' => $processors, + '#required' => TRUE, + '#default_value' => $settings['geocoder']['handler'], + '#states' => array( + 'visible' => array( + ':input[name$="instance[widget][settings][geocoder][enabled]"]' => array('checked' => TRUE), + ), + ), + ); + + } break; } @@ -143,6 +177,20 @@ function leaflet_widget_field_widget_form(&$form, &$form_state, $field, $instanc 'data' => array('leaflet_widget_widget' => array($id => $settings)), ); + // If geocoder is enabled add geocider field. + if (!empty($settings['geocoder']['enabled']) && module_exists('geocoder')) { + $geocoder_handler = geocoder_get_handler($settings['geocoder']['handler']); + $element['geocoder'] = array( + '#type' => 'textfield', + '#title' => t('Geo-Coding'), + '#description' => t('Enter an address and click "Add" to insert it as marker on the map.'), + '#attributes' => array( + 'class' => array('geocoder'), + ), + '#field_suffix' => '' . t('Add') .'', + ); + } + break; } @@ -163,23 +211,18 @@ function leaflet_widget_widget_validate($element, &$form_state) { $geophp = geophp_load(); if (!$geophp) return FALSE; - $geojson = json_decode($element['geom']['#value']); - - $results = array(); - if ($geojson->type === 'FeatureCollection') { - foreach ($geojson->features as $feature) { - $results[] = leaflet_widget_process_geojson($feature); - } - } - else { - $results = array(leaflet_widget_process_geojson($geojson)); - } + $geojson = $element['geom']['#value']; + $results = array(leaflet_widget_process_geojson($geojson)); form_set_value($element, $results, $form_state); } function leaflet_widget_process_geojson($geojson) { $geom = geoPHP::load($geojson, 'json'); + // Avoid throwing a notice if there was a failure. + if (!$geom) { + return array(); + } $type = $geom->geometryType(); $result = array( 'geom' => $geom->out('wkt'), @@ -239,7 +282,7 @@ function leaflet_widget_library() { // If available, use the same Leaflet as Leaflet module. Otherwise use the // one bundled with Leaflet.widget. $leaflet = libraries_get_path('leaflet'); - $leaflet = !empty($leaflet) ? "$leaflet/dist/" : "$leaflet_widget/lib/Leaflet/"; + $leaflet = !empty($leaflet) ? $leaflet : "$leaflet_widget/lib/Leaflet/"; $libraries['Leaflet'] = array( 'title' => 'Leaflet (Leaflet Widget)', 'version' => '0.4.5', @@ -266,11 +309,11 @@ function leaflet_widget_geojson_feature_collection($features, $properties = arra ); } -function leaflet_widget_geojson_feature($wkb, $properties = array()) { +function leaflet_widget_geojson_feature($wkt, $properties = array()) { $geophp = geophp_load(); if (!$geophp) return FALSE; - $geometry = geoPHP::load($wkb, 'wkb'); + $geometry = geoPHP::load($wkt, 'wkt'); return array( 'type' => 'Feature', 'geometry' => json_decode($geometry->out('json')),