From 656ddc3089afb3e04b77208291fa61e26de4081b Mon Sep 17 00:00:00 2001 From: David Molineus Date: Tue, 6 Feb 2018 16:32:56 +0100 Subject: [PATCH] Add feature to define the radius in the geocode widget. --- composer.json | 2 +- .../templates/be_widget_leaflet_geocode.html5 | 24 +++-- src/Resources/public/css/backend.css | 12 +++ src/Resources/public/js/geocode.widget.js | 90 +++++++++++++++---- src/Widget/GeocodeWidget.php | 1 + 5 files changed, 106 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index 8873c3d..1b0317c 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "require": { "php": ">=5.6.0", "contao/core-bundle": "^4.4.0", - "netzmacht/contao-leaflet-libraries": "~1.0" + "netzmacht/contao-leaflet-libraries": "~1.3" }, "require-dev": { "contao/manager-plugin": "^2.0", diff --git a/src/Resources/contao/templates/be_widget_leaflet_geocode.html5 b/src/Resources/contao/templates/be_widget_leaflet_geocode.html5 index e299ab8..8e62c01 100644 --- a/src/Resources/contao/templates/be_widget_leaflet_geocode.html5 +++ b/src/Resources/contao/templates/be_widget_leaflet_geocode.html5 @@ -6,6 +6,12 @@ $GLOBALS['TL_CSS'][] = 'bundles/leafletgeocodewidget/css/backend.css'; $GLOBALS['TL_JAVASCRIPT'][] = 'assets/leaflet/libs/leaflet/leaflet.js'; $GLOBALS['TL_JAVASCRIPT'][] = 'assets/leaflet/libs/control-geocoder/Control.Geocoder.js'; + +if ($this->radius) { + $GLOBALS['TL_CSS'][] = 'assets/leaflet/libs/leaflet-pm/leaflet.pm.css'; + $GLOBALS['TL_JAVASCRIPT'][] = 'assets/leaflet/libs/leaflet-pm/leaflet.pm.min.js'; +} + $GLOBALS['TL_JAVASCRIPT'][] = 'bundles/leafletgeocodewidget/js/geocode.widget.js'; ?> @@ -24,10 +30,16 @@ $GLOBALS['TL_JAVASCRIPT'][] = 'bundles/leafletgeocodewidget/js/geocode.widget.js wizard ?> diff --git a/src/Resources/public/css/backend.css b/src/Resources/public/css/backend.css index e09e3f5..8da0ca1 100644 --- a/src/Resources/public/css/backend.css +++ b/src/Resources/public/css/backend.css @@ -2,3 +2,15 @@ width: 325px; display: inline-block; } + +.leaflet-submit-btn { + margin-top: 10px; + display: block; + padding: 7px 12px; + border: 1px solid #aaa; + border-radius: 2px; + box-sizing: border-box; + cursor: pointer; + background: #eee; + transition: background .2s ease; +} diff --git a/src/Resources/public/js/geocode.widget.js b/src/Resources/public/js/geocode.widget.js index d2435a1..b4f2f86 100644 --- a/src/Resources/public/js/geocode.widget.js +++ b/src/Resources/public/js/geocode.widget.js @@ -3,7 +3,7 @@ * * @package netzmacht * @author David Molineus - * @copyright 2016-2017 netzmacht David Molineus. All rights reserved. + * @copyright 2016-2018 netzmacht David Molineus. All rights reserved. * @license LGPL-3.0 https://github.com/netzmacht/contao-leaflet-geocode-widget/blob/master/LICENSE * @filesource */ @@ -14,7 +14,13 @@ var LeafletGeocodeWidget = L.Class.extend({ modalWidth: 800, modalTitle: 'Choose coordinates', searchPositionLabel: 'Search', - applyPositionLabel: 'Apply' + applyPositionLabel: 'Apply', + radius: null, + mapOptions: { + maxZoom: 15, + minZoom: 2 + }, + bboxPadding: [0, 70] }, initialize: function (options) { L.Util.setOptions(this, options); @@ -22,6 +28,10 @@ var LeafletGeocodeWidget = L.Class.extend({ this.element = $(this.options.id); this.toggle = $(this.options.id + '_toggle'); this.toggle.addEvent('click', this._showMap.bind(this)); + + if (this.options.radius) { + this.radius = $(this.options.radius); + } }, _showMap: function () { var content, modal; @@ -50,7 +60,7 @@ var LeafletGeocodeWidget = L.Class.extend({ }); }, _createMap: function (modal) { - var map = L.map('leaflet_geocode_widget_map_' + this.options.id).setView([0, 0], 2); + var map = L.map('leaflet_geocode_widget_map_' + this.options.id, this.options.mapOptions).setView([0, 0], 2); L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' @@ -70,8 +80,12 @@ var LeafletGeocodeWidget = L.Class.extend({ var value = this.element.value.split(/,/); this._createMarker(value, map); - map.setZoom(16); - map.panTo(value); + if (this.radius) { + map.fitBounds(this._geocodeMarker.getBounds()); + } else { + map.setZoom(this.options.mapOptions.maxZoom); + map.panTo(value); + } } return map; @@ -81,12 +95,12 @@ var LeafletGeocodeWidget = L.Class.extend({ var link = document.createElement('button'); var result = event.geocode; - link.set('style', 'margin-left: 10px;'); + link.set('class', 'leaflet-submit-btn'); link.appendText(this.options.applyPositionLabel); link.addEvent('click', function (e) { e.stop(); - this.element.set('value', result.center.lat + ',' + result.center.lng); + this._updateInputs(result.center); modal.hide(); }.bind(this)); @@ -97,19 +111,63 @@ var LeafletGeocodeWidget = L.Class.extend({ map.removeLayer(this._geocodeMarker); } - map.fitBounds(result.bbox, { padding: [0, 70]}); + map.fitBounds(result.bbox, { padding: this.options.bboxPadding}); map.panTo(result.center); this._createMarker(result.center, map); - this._geocodeMarker.bindPopup(container, { - keepInView: true, - autoPanPaddingTopLeft: [0, 70] - }).openPopup(); + + if (!this.radius) { + this._geocodeMarker.bindPopup(container, { + keepInView: true, + autoClose: false, + closeOnClick: false, + autoPanPaddingTopLeft: this.options.bboxPadding + }).openPopup(); + } }, _createMarker: function (position, map) { - this._geocodeMarker = L.marker(position, {draggable: true}).addTo(map); - this._geocodeMarker.on('dragend', function (event) { - this.element.set('value', event.target._latlng.lat + ',' + event.target._latlng.lng); - }.bind(this)); + if (this.radius) { + this._geocodeMarker = L.circle(position, { radius: this.radius.get('value') }); + this._geocodeMarker.addTo(map); + map.fitBounds(this._geocodeMarker.getBounds()); + + this._geocodeMarker.on('pm:markerdragend', function (event) { + var radius = Math.floor(this._geocodeMarker.getRadius()); + + this._updateInputs(event.target._latlng, radius); + this._geocodeMarker.pm._outerMarker.setTooltipContent(this._formatRadius(radius)); + map.fitBounds(this._geocodeMarker.getBounds()); + }.bind(this)); + this._geocodeMarker.pm.enable({dragable: false}); + + this._geocodeMarker.pm._outerMarker.bindTooltip( + this._formatRadius(this._geocodeMarker.getRadius()), + {permanent: true, direction: 'right', offset: [10, 0] } + ); + } else { + this._geocodeMarker = L.marker(position, {draggable: true}).addTo(map); + this._geocodeMarker.on('dragend', function (event) { + this._updateInputs(event.target._latlng); + }.bind(this)); + } + }, + _updateInputs: function (coordinates, radius) { + this.element.set('value', coordinates.lat + ',' + coordinates.lng); + + if (this.radius && typeof(radius) !== 'undefined') { + this.radius.set('value', radius); + } + }, + _formatRadius: function (radius) { + var unit = 'm'; + + radius = Math.floor(radius); + + if (radius > 1000) { + unit = 'km'; + radius = (radius / 1000).toFixed(1); + } + + return radius.toString() + ' ' + unit; } }); diff --git a/src/Widget/GeocodeWidget.php b/src/Widget/GeocodeWidget.php index 798db5b..06a0721 100644 --- a/src/Widget/GeocodeWidget.php +++ b/src/Widget/GeocodeWidget.php @@ -123,6 +123,7 @@ class GeocodeWidget extends \Widget 'attributes' => $this->getAttributes(), 'wizard' => $this->wizard, 'label' => $this->strLabel, + 'radius' => $this->radius ] );