From 2b5b8dda56ddb5e996799e07465608130d57ef94 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 14:49:21 +0200 Subject: [PATCH 01/22] Add checkbox for user geolocation location --- extension.json | 14 ++++ resources/GoogleMaps/mylocation.css | 6 ++ resources/GoogleMaps/mylocation.js | 103 ++++++++++++++++++++++++++++ src/GoogleMapsService.php | 2 +- src/Map/MapHtmlBuilder.php | 16 ++++- 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 resources/GoogleMaps/mylocation.css create mode 100644 resources/GoogleMaps/mylocation.js diff --git a/extension.json b/extension.json index d298bc4bb..cb9518515 100644 --- a/extension.json +++ b/extension.json @@ -307,6 +307,20 @@ "targets": [ "desktop", "mobile" ] }, + "ext.maps.mylocation": { + "dependencies": [ + "ext.maps.googlemaps3", + "ext.sm.common" + ], + "scripts": [ + "GoogleMaps/mylocation.js" + ], + "styles": [ + "GoogleMaps/mylocation.css" + ], + "targets": [ "desktop", "mobile" ] + }, + "ext.maps.wikitext.editor": { "dependencies": [ "jquery.ui", diff --git a/resources/GoogleMaps/mylocation.css b/resources/GoogleMaps/mylocation.css new file mode 100644 index 000000000..a8f5581e3 --- /dev/null +++ b/resources/GoogleMaps/mylocation.css @@ -0,0 +1,6 @@ +.my-location-marker { + width: 1rem; + height: 1rem; + background-color: rgba(0,0,255,0.5); + border-radius: 50%; +} diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js new file mode 100644 index 000000000..aa01ebf8f --- /dev/null +++ b/resources/GoogleMaps/mylocation.js @@ -0,0 +1,103 @@ +let markerElement; +let myLocationWatchId; +let myLocationMarker; + +(function( $ ) { + $( document ).ready( async function() { + // Request needed libraries. + const { AdvancedMarkerElement } = await google.maps.importLibrary("marker"); + markerElement = AdvancedMarkerElement; + + // todo: find a way to remove setTimeout. + if( typeof google === 'undefined' ) { + return; + } + $( window.mapsGoogleList ).each( function( index, map ) { + /*if( !map.options.ajaxquery || !map.options.ajaxcoordproperty ) { + return; + }*/ + + console.log(map); + + // Control for toggling the live location function + let myLocationToggleEl = document.querySelector( '#mylocation' ); + if ( myLocationToggleEl ) { + addEventListener( 'change', (event) => { + if ( event.target.checked ) { + console.log('activateMyLocation', map); + activateMyLocation( map.map ); + } else { + deactivateMyLocation(); + } + } ); + } + } ); + } ); +})( window.jQuery ); + +function handleLocationError( browserHasGeolocation, pos ) { + console.log( browserHasGeolocation ? + 'Error: The Geolocation service failed.' : + 'Error: Your browser doesn\'t support geolocation.' ); +} + +function drawMyLocation( position, map ) { + var pos = { + lat: position.coords.latitude, + lng: position.coords.longitude + }; + + // Center the map on the user's location + console.log('center map', map); + map.setCenter( pos ); + + // Add a marker at the user's location + const locationMarker = document.createElement( 'div' ); + locationMarker.className = 'my-location-marker'; + + if ( ! myLocationMarker ) { + // TODO: Radius based on accuracy + myLocationMarker = new markerElement( { + map, + position: pos, + content: locationMarker, + } ); + } else { + myLocationMarker.position = pos; + } +} + +function activateMyLocation( map ) { + // Check if geolocation is supported + if ( navigator.geolocation ) { + myLocationWatchId = navigator.geolocation.watchPosition( + function( position ) { + drawMyLocation( position, map ) + }, + // Error handling + function() { + handleLocationError( true, map.getCenter() ); + }, + // Geolocation options + { + enableHighAccuracy: false, + timeout: 5000, + maximumAge: 0, + } + ); + } else { + // Browser doesn't support geolocation + handleLocationError( false, map.getCenter() ); + } +} + +function deactivateMyLocation() { + // Check if geolocation is supported + if ( navigator.geolocation ) { + navigator.geolocation.clearWatch( myLocationWatchId ); + } + + // Remove marker from the map and remove + myLocationMarker.setMap( null ); + myLocationMarker = null; +} diff --git a/src/GoogleMapsService.php b/src/GoogleMapsService.php index 8ba39c3fe..29ab5e6c3 100644 --- a/src/GoogleMapsService.php +++ b/src/GoogleMapsService.php @@ -273,7 +273,7 @@ public function newMapId(): string { } public function getResourceModules( array $params ): array { - return [ 'ext.maps.googlemaps3', 'ext.maps.googlemaps3ajax' ]; + return [ 'ext.maps.googlemaps3', 'ext.maps.googlemaps3ajax', 'ext.maps.mylocation' ]; } public static function getApiScript( $langCode, array $urlArgs = [] ) { diff --git a/src/Map/MapHtmlBuilder.php b/src/Map/MapHtmlBuilder.php index 7ce117cf6..de7503b13 100644 --- a/src/Map/MapHtmlBuilder.php +++ b/src/Map/MapHtmlBuilder.php @@ -18,7 +18,21 @@ public function getMapHTML( array $json, string $mapId, string $serviceName ): s $json['width'] = (string)$json['width'] . 'px'; } - return Html::rawElement( + return + Html::rawElement( + 'label', + [], + Html::element( + 'input', + [ + 'id' => 'mylocation', + 'type' => 'checkbox', + 'autocomplete' => 'off' + ], + '' + ) . ' My Location' + ) + . Html::rawElement( 'div', [ 'id' => $mapId, From 05cb4febc9b6e84689c604e8e76b261d91e3f6f2 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 15:37:43 +0200 Subject: [PATCH 02/22] Move control into map, multiple map support --- resources/GoogleMaps/jquery.googlemap.js | 5 + resources/GoogleMaps/mylocation.js | 113 ++++++++++++++--------- src/Map/MapHtmlBuilder.php | 16 +--- 3 files changed, 77 insertions(+), 57 deletions(-) diff --git a/resources/GoogleMaps/jquery.googlemap.js b/resources/GoogleMaps/jquery.googlemap.js index 422c3de79..12e246264 100644 --- a/resources/GoogleMaps/jquery.googlemap.js +++ b/resources/GoogleMaps/jquery.googlemap.js @@ -731,6 +731,11 @@ if(options.fullscreen){ this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(new FullscreenControl(this.map)); } + + // - My Location + //if(options.fullscreen){ + this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(new window.MyLocationControl(this.map)); + //} }; this.setup = function () { diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index aa01ebf8f..afb0c92e8 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -1,40 +1,58 @@ let markerElement; -let myLocationWatchId; -let myLocationMarker; (function( $ ) { $( document ).ready( async function() { // Request needed libraries. const { AdvancedMarkerElement } = await google.maps.importLibrary("marker"); markerElement = AdvancedMarkerElement; - - // todo: find a way to remove setTimeout. - if( typeof google === 'undefined' ) { - return; - } - $( window.mapsGoogleList ).each( function( index, map ) { - /*if( !map.options.ajaxquery || !map.options.ajaxcoordproperty ) { - return; - }*/ - - console.log(map); - - // Control for toggling the live location function - let myLocationToggleEl = document.querySelector( '#mylocation' ); - if ( myLocationToggleEl ) { - addEventListener( 'change', (event) => { - if ( event.target.checked ) { - console.log('activateMyLocation', map); - activateMyLocation( map.map ); - } else { - deactivateMyLocation(); - } - } ); - } - } ); } ); })( window.jQuery ); +// Control for toggling the user location function +function MyLocationControl( map ) { + var controlDiv = document.createElement('div'); + controlDiv.style.padding = '5px'; + controlDiv.index = 1; + + var controlUI = document.createElement('div'); + controlUI.style.backgroundColor = 'white'; + controlUI.style.borderStyle = 'solid'; + controlUI.style.borderColor = 'rgba(0, 0, 0, 0.14902)'; + controlUI.style.borderWidth = '1px'; + controlUI.style.borderRadius = '2px'; + controlUI.style.cursor = 'pointer'; + controlUI.style.textAlign = 'center'; + controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px'; + controlUI.style.backgroundClip = 'padding-box'; + controlUI.title = mw.msg('maps-fullscreen-button-tooltip'); + controlDiv.appendChild(controlUI); + + var controlText = document.createElement('div'); + controlText.style.fontFamily = 'Roboto, Arial, sans-serif'; + controlText.style.fontSize = '11px'; + controlText.style.fontWeight = '400'; + controlText.style.color = 'rgb(86, 86, 86)'; + controlText.style.padding = '1px 6px'; + controlText.innerHTML = 'Toggle my location'; // TODO: Translation + controlUI.appendChild(controlText); + + google.maps.event.addDomListener( controlUI, 'click', function() { + var mapDiv = $( map.getDiv() ); + + if ( mapDiv.data( 'followMyLocation' ) != null ) { + mapDiv.removeData( 'followMyLocation' ); + deactivateMyLocation( map ); + } else { + mapDiv.data( 'followMyLocation', 'on' ); + activateMyLocation( map ); + } + } ); + + return controlDiv; +} + +window.MyLocationControl = MyLocationControl; + function handleLocationError( browserHasGeolocation, pos ) { console.log( browserHasGeolocation ? 'Error: The Geolocation service failed.' : @@ -48,29 +66,33 @@ function drawMyLocation( position, map ) { }; // Center the map on the user's location - console.log('center map', map); map.setCenter( pos ); - // Add a marker at the user's location - const locationMarker = document.createElement( 'div' ); - locationMarker.className = 'my-location-marker'; + var mapDiv = $( map.getDiv() ); + + if ( typeof mapDiv.data( 'myLocationMarker' ) === 'undefined' ) { + // Add a marker at the user's location + const locationMarkerEl = document.createElement( 'div' ); + locationMarkerEl.className = 'my-location-marker'; - if ( ! myLocationMarker ) { // TODO: Radius based on accuracy - myLocationMarker = new markerElement( { + let myLocationMarker = new markerElement( { map, position: pos, - content: locationMarker, + content: locationMarkerEl, } ); + mapDiv.data( 'myLocationMarker', myLocationMarker ); } else { - myLocationMarker.position = pos; - } + mapDiv.data( 'myLocationMarker' ).position = pos; + } } function activateMyLocation( map ) { + mapDiv = $( map.getDiv() ); + // Check if geolocation is supported if ( navigator.geolocation ) { - myLocationWatchId = navigator.geolocation.watchPosition( + let myLocationWatchId = navigator.geolocation.watchPosition( function( position ) { drawMyLocation( position, map ) }, @@ -85,19 +107,26 @@ function activateMyLocation( map ) { maximumAge: 0, } ); + mapDiv.data( 'myLocationWatchId', myLocationWatchId ); } else { // Browser doesn't support geolocation handleLocationError( false, map.getCenter() ); } } -function deactivateMyLocation() { +function deactivateMyLocation( map ) { + mapDiv = $( map.getDiv() ); + // Check if geolocation is supported if ( navigator.geolocation ) { - navigator.geolocation.clearWatch( myLocationWatchId ); + // Stop tracking location + navigator.geolocation.clearWatch( mapDiv.data( 'myLocationWatchId' ) ); + mapDiv.removeData( 'myLocationWatchId' ); } - // Remove marker from the map and remove - myLocationMarker.setMap( null ); - myLocationMarker = null; + // Remove marker from the map + if ( typeof mapDiv.data( 'myLocationMarker' ) !== 'undefined' ) { + mapDiv.data( 'myLocationMarker' ).setMap( null ); + mapDiv.removeData( 'myLocationMarker' ); + } } diff --git a/src/Map/MapHtmlBuilder.php b/src/Map/MapHtmlBuilder.php index de7503b13..7ce117cf6 100644 --- a/src/Map/MapHtmlBuilder.php +++ b/src/Map/MapHtmlBuilder.php @@ -18,21 +18,7 @@ public function getMapHTML( array $json, string $mapId, string $serviceName ): s $json['width'] = (string)$json['width'] . 'px'; } - return - Html::rawElement( - 'label', - [], - Html::element( - 'input', - [ - 'id' => 'mylocation', - 'type' => 'checkbox', - 'autocomplete' => 'off' - ], - '' - ) . ' My Location' - ) - . Html::rawElement( + return Html::rawElement( 'div', [ 'id' => $mapId, From f66e856328fa5efae548c26f36c33df44099c4e1 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 15:45:38 +0200 Subject: [PATCH 03/22] Add mylocation parameter --- resources/GoogleMaps/jquery.googlemap.js | 4 ++-- src/GoogleMapsService.php | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/resources/GoogleMaps/jquery.googlemap.js b/resources/GoogleMaps/jquery.googlemap.js index 12e246264..c50c28489 100644 --- a/resources/GoogleMaps/jquery.googlemap.js +++ b/resources/GoogleMaps/jquery.googlemap.js @@ -733,9 +733,9 @@ } // - My Location - //if(options.fullscreen){ + if(options.mylocation){ this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(new window.MyLocationControl(this.map)); - //} + } }; this.setup = function () { diff --git a/src/GoogleMapsService.php b/src/GoogleMapsService.php index 29ab5e6c3..55d19ad0b 100644 --- a/src/GoogleMapsService.php +++ b/src/GoogleMapsService.php @@ -247,6 +247,13 @@ function( string $fileName ) { 'message' => 'maps-par-enable-fullscreen', ]; + $params['mylocation'] = [ + 'aliases' => [ 'enablemylocation' ], + 'type' => 'boolean', + 'default' => false, + 'message' => 'maps-par-enable-mylocation', + ]; + $params['scrollwheelzoom'] = [ 'aliases' => [ 'scrollzoom' ], 'type' => 'boolean', From 5a2ce9bf50ce8d8f743ad1d85341dc0cda07d8b9 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 16:13:55 +0200 Subject: [PATCH 04/22] Draw circle for my location, replacing marker --- extension.json | 3 --- resources/GoogleMaps/mylocation.css | 6 ------ resources/GoogleMaps/mylocation.js | 33 ++++++++++++----------------- 3 files changed, 13 insertions(+), 29 deletions(-) delete mode 100644 resources/GoogleMaps/mylocation.css diff --git a/extension.json b/extension.json index cb9518515..a1bbb4233 100644 --- a/extension.json +++ b/extension.json @@ -315,9 +315,6 @@ "scripts": [ "GoogleMaps/mylocation.js" ], - "styles": [ - "GoogleMaps/mylocation.css" - ], "targets": [ "desktop", "mobile" ] }, diff --git a/resources/GoogleMaps/mylocation.css b/resources/GoogleMaps/mylocation.css deleted file mode 100644 index a8f5581e3..000000000 --- a/resources/GoogleMaps/mylocation.css +++ /dev/null @@ -1,6 +0,0 @@ -.my-location-marker { - width: 1rem; - height: 1rem; - background-color: rgba(0,0,255,0.5); - border-radius: 50%; -} diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index afb0c92e8..27929c4c9 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -1,13 +1,3 @@ -let markerElement; - -(function( $ ) { - $( document ).ready( async function() { - // Request needed libraries. - const { AdvancedMarkerElement } = await google.maps.importLibrary("marker"); - markerElement = AdvancedMarkerElement; - } ); -})( window.jQuery ); - // Control for toggling the user location function function MyLocationControl( map ) { var controlDiv = document.createElement('div'); @@ -24,7 +14,7 @@ function MyLocationControl( map ) { controlUI.style.textAlign = 'center'; controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px'; controlUI.style.backgroundClip = 'padding-box'; - controlUI.title = mw.msg('maps-fullscreen-button-tooltip'); + controlUI.title = mw.msg('maps-fullscreen-button-tooltip'); // TODO controlDiv.appendChild(controlUI); var controlText = document.createElement('div'); @@ -50,7 +40,6 @@ function MyLocationControl( map ) { return controlDiv; } - window.MyLocationControl = MyLocationControl; function handleLocationError( browserHasGeolocation, pos ) { @@ -71,16 +60,20 @@ function drawMyLocation( position, map ) { var mapDiv = $( map.getDiv() ); if ( typeof mapDiv.data( 'myLocationMarker' ) === 'undefined' ) { - // Add a marker at the user's location - const locationMarkerEl = document.createElement( 'div' ); - locationMarkerEl.className = 'my-location-marker'; - - // TODO: Radius based on accuracy - let myLocationMarker = new markerElement( { + let radius = position.coords.accuracy * 0.5; + + // Add a circle at the user's location + let myLocationMarker = new google.maps.Circle( { + strokeColor: "#0000FF", + strokeOpacity: 0.5, + strokeWeight: 2, + fillColor: "#0000FF", + fillOpacity: 0.35, map, - position: pos, - content: locationMarkerEl, + center: pos, + radius: radius, } ); + mapDiv.data( 'myLocationMarker', myLocationMarker ); } else { mapDiv.data( 'myLocationMarker' ).position = pos; From 9aa0b2603c09ff609748112a7bb685da8da83656 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 16:18:13 +0200 Subject: [PATCH 05/22] Update my location accuracy on every update --- resources/GoogleMaps/mylocation.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 27929c4c9..8604c6a2e 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -27,7 +27,7 @@ function MyLocationControl( map ) { controlUI.appendChild(controlText); google.maps.event.addDomListener( controlUI, 'click', function() { - var mapDiv = $( map.getDiv() ); + let mapDiv = $( map.getDiv() ); if ( mapDiv.data( 'followMyLocation' ) != null ) { mapDiv.removeData( 'followMyLocation' ); @@ -49,19 +49,18 @@ function handleLocationError( browserHasGeolocation, pos ) { } function drawMyLocation( position, map ) { - var pos = { + let pos = { lat: position.coords.latitude, lng: position.coords.longitude }; + let radius = position.coords.accuracy * 0.5; // Center the map on the user's location map.setCenter( pos ); - var mapDiv = $( map.getDiv() ); + let mapDiv = $( map.getDiv() ); if ( typeof mapDiv.data( 'myLocationMarker' ) === 'undefined' ) { - let radius = position.coords.accuracy * 0.5; - // Add a circle at the user's location let myLocationMarker = new google.maps.Circle( { strokeColor: "#0000FF", @@ -76,7 +75,9 @@ function drawMyLocation( position, map ) { mapDiv.data( 'myLocationMarker', myLocationMarker ); } else { + // Update circle position and radius mapDiv.data( 'myLocationMarker' ).position = pos; + mapDiv.data( 'myLocationMarker' ).setRadius( radius ); } } @@ -87,7 +88,7 @@ function activateMyLocation( map ) { if ( navigator.geolocation ) { let myLocationWatchId = navigator.geolocation.watchPosition( function( position ) { - drawMyLocation( position, map ) + drawMyLocation( position, map ); }, // Error handling function() { From 283bac7a229f60ef458edda9412c480d5d88ed41 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 16:20:05 +0200 Subject: [PATCH 06/22] Fix my location circle position update --- resources/GoogleMaps/mylocation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 8604c6a2e..445072b1d 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -76,7 +76,7 @@ function drawMyLocation( position, map ) { mapDiv.data( 'myLocationMarker', myLocationMarker ); } else { // Update circle position and radius - mapDiv.data( 'myLocationMarker' ).position = pos; + mapDiv.data( 'myLocationMarker' ).setCenter( pos ); mapDiv.data( 'myLocationMarker' ).setRadius( radius ); } } From c830a35a3582182c5e0bd5f29d1f78659f52984a Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 16:29:21 +0200 Subject: [PATCH 07/22] Fix map centering every time my location updates --- resources/GoogleMaps/mylocation.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 445072b1d..11884e230 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -55,9 +55,6 @@ function drawMyLocation( position, map ) { }; let radius = position.coords.accuracy * 0.5; - // Center the map on the user's location - map.setCenter( pos ); - let mapDiv = $( map.getDiv() ); if ( typeof mapDiv.data( 'myLocationMarker' ) === 'undefined' ) { @@ -73,6 +70,9 @@ function drawMyLocation( position, map ) { radius: radius, } ); + // Center the map on the user's location + map.setCenter( pos ); + mapDiv.data( 'myLocationMarker', myLocationMarker ); } else { // Update circle position and radius From 1acbedd355a37325b5967f1922ea13a68f779a04 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 16 Sep 2024 16:59:22 +0200 Subject: [PATCH 08/22] Use icon for my location toggle --- .../GoogleMaps/img/mylocation-sprite-2x.png | Bin 0 -> 1582 bytes resources/GoogleMaps/jquery.googlemap.js | 2 +- resources/GoogleMaps/mylocation.js | 22 +++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 resources/GoogleMaps/img/mylocation-sprite-2x.png diff --git a/resources/GoogleMaps/img/mylocation-sprite-2x.png b/resources/GoogleMaps/img/mylocation-sprite-2x.png new file mode 100644 index 0000000000000000000000000000000000000000..546b97a245d9bd4964a726de96352c8b0619fbb8 GIT binary patch literal 1582 zcmaKteNYou5WqwEQZfV!PJ%Jw*by>{$S4JjIZ9P5Mko=jLPq?eAoYtct6U&s6iPFw z0VGOvj7NuR1*Jig5m1tffQhG=AXO8$q*Y8M&fj6=Y54hewHN&`(t1_B1lP5R(i8dx|%`4MPOMUr(@7s;q8Dv zTOCtn6-PF&Fer6F?lL#G`rSr1M*4y{in)GjIs8R(ZOK!BP6ucaKm!M7t87C^gv)w8 zM{VsNy-9i3bfY6zsoS=oFUNfMe|CJbm+?y4{)b3?)`E8u?roq@NRR)-hD)bb8JlEd z)F-T@4&EGCn~_d$HMV5@$F-#m&yC4-#N=~Jdym2Kf64tyI)c%-lr|L@K^M46zQq zge5Iyqm+e38LS8_WJ}b613@x@^k~m;Q34)?6#)o9C0eZZMLDd?t|Qil(vM`A;DYA9 zCa`_GV+%QdV-*jjr(Qoc1`pb@0`?r8zWPfWgX^qR#$33oeKDGITG*Gej&RCp(j_W? zq}PGyLw`eNo@@bidmYp*1Jtbm)Gc+74vl)C5M2A2Po=-H?`5@#%-<5$`So=xcOy!? zPm)L^k}vy^`T%4Y|L#Vi*0m_B$G(bz+;9CgU~l}Uj}Ai`()i+l?1qW74R!lc*Fay+ z{BtLa>%O`;sV5s83`gMl$Ac#Cdsc=WxBggaywY2|h!=SM%>IzJxUzJpj#l1}z-o~^;2ZOYPyLdHQBA(K4y#zlPIUu{t#I0G}$%4MgIIpG~~I1ro0% zR`MuTgu?mi>hV%&%`T6rC8(eJ@&gf=}JNN5_Z;SNmlkGFzR<&)P-wA@Tf` zXquml@bF$S$MgU?es;epD?JTF^cX}$;(>@LAfnGFYU~kjk8vz76Cbnj)Q*@(w@3YJ zMUj9rw^%x)5+NG)-rwq8w9iR8h=zeunN#FlA- Date: Wed, 18 Sep 2024 09:45:11 +0200 Subject: [PATCH 09/22] Add translation string --- extension.json | 1 + i18n/en.json | 1 + resources/GoogleMaps/mylocation.js | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/extension.json b/extension.json index a1bbb4233..6ee526d84 100644 --- a/extension.json +++ b/extension.json @@ -256,6 +256,7 @@ "maps-searchmarkers-text", "maps-fullscreen-button", "maps-fullscreen-button-tooltip", + "maps-mylocation-button-tooltip", "maps-kml-parsing-failed" ], "targets": [ "desktop", "mobile" ] diff --git a/i18n/en.json b/i18n/en.json index fa7b345ea..ede2c24bd 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -81,6 +81,7 @@ "maps-displaymap-par-geojson": "URL of a file or name of the page containing GeoJSON data", "maps-fullscreen-button": "Toggle fullscreen", "maps-fullscreen-button-tooltip": "View the map as fullscreen or embedded.", + "maps-mylocation-button-tooltip": "Show my location on the map.", "validation-error-invalid-location": "Parameter \"$1\" must be a valid location.", "validation-error-invalid-locations": "Parameter \"$1\" must be one or more valid locations.", "validation-error-invalid-width": "Parameter \"$1\" must be a valid width.", diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 7d67c62e5..12e079e05 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -15,7 +15,7 @@ function MyLocationControl( map ) { controlUI.style.textAlign = 'center'; controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px'; controlUI.style.backgroundClip = 'padding-box'; - controlUI.title = 'Toggle my location'; // TODO: Translation + controlUI.title = mw.msg('maps-mylocation-button-tooltip'); controlDiv.appendChild(controlUI); var controlText = document.createElement('div'); From ae0d7e6e59d6e1b8e7e8246407ec606192eb1df6 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Wed, 18 Sep 2024 10:43:56 +0200 Subject: [PATCH 10/22] Add marker to user location --- resources/GoogleMaps/mylocation.js | 47 +++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 12e079e05..d1e5138ec 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -64,26 +64,47 @@ function drawMyLocation( position, map ) { let mapDiv = $( map.getDiv() ); if ( typeof mapDiv.data( 'myLocationMarker' ) === 'undefined' ) { - // Add a circle at the user's location - let myLocationMarker = new google.maps.Circle( { - strokeColor: "#0000FF", - strokeOpacity: 0.5, - strokeWeight: 2, - fillColor: "#0000FF", - fillOpacity: 0.35, + // Add a circle to visualize geolocation accuracy + let myLocationCircle = new google.maps.Circle( { + strokeWeight: 0, + fillColor: "#5383EC", + fillOpacity: 0.2, map, center: pos, radius: radius, } ); + // Add a marker at the user's location + const svgMarker = { + path: "M 11, 11 m 10, 0 a 10,10 0 1,0 -20,0 a 10,10 0 1,0 20,0", + fillColor: "#5383EC", + fillOpacity: 1, + strokeWeight: 2, + strokeColor: "white", + anchor: new google.maps.Point( 11, 11 ), + scale: 0.75, + }; + + let myLocationMarker = new google.maps.Marker( { + position: pos, + icon: svgMarker, + map: map, + } ); + // Center the map on the user's location map.setCenter( pos ); + // Zoom in + map.setZoom( 16 ); + + // Store for later access mapDiv.data( 'myLocationMarker', myLocationMarker ); + mapDiv.data( 'myLocationCircle', myLocationCircle ); } else { - // Update circle position and radius - mapDiv.data( 'myLocationMarker' ).setCenter( pos ); - mapDiv.data( 'myLocationMarker' ).setRadius( radius ); + // Update position and radius + mapDiv.data( 'myLocationMarker' ).position = pos; + mapDiv.data( 'myLocationCircle' ).setCenter( pos ); + mapDiv.data( 'myLocationCircle' ).setRadius( radius ); } } @@ -129,4 +150,10 @@ function deactivateMyLocation( map ) { mapDiv.data( 'myLocationMarker' ).setMap( null ); mapDiv.removeData( 'myLocationMarker' ); } + + // Remove circle from the map + if ( typeof mapDiv.data( 'myLocationCircle' ) !== 'undefined' ) { + mapDiv.data( 'myLocationCircle' ).setMap( null ); + mapDiv.removeData( 'myLocationCircle' ); + } } From 61b19889c8e3772b5e1b795af73dce1ee780fd1c Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Wed, 18 Sep 2024 11:32:33 +0200 Subject: [PATCH 11/22] Follow user on map per default, stop following on drag --- resources/GoogleMaps/mylocation.js | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index d1e5138ec..b36d652f9 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -30,6 +30,7 @@ function MyLocationControl( map ) { controlText.style.width = '18px'; controlUI.appendChild(controlText); + // Handle toggle button click google.maps.event.addDomListener( controlUI, 'click', function() { let mapDiv = $( map.getDiv() ); @@ -38,12 +39,22 @@ function MyLocationControl( map ) { controlText.style.backgroundPosition = '0 0'; deactivateMyLocation( map ); } else { - mapDiv.data( 'followMyLocation', 'on' ); + mapDiv.data( 'followMyLocation', 'locked' ); controlText.style.backgroundPosition = '-144px 0'; activateMyLocation( map ); } } ); + // Handle dragged map + google.maps.event.addDomListener( map, 'dragend', function() { + let mapDiv = $( map.getDiv() ); + + // Continue tracking location, without centering on user + if ( mapDiv.data( 'followMyLocation' ) != null ) { + mapDiv.data( 'followMyLocation', 'passive' ); + } + } ); + return controlDiv; } window.MyLocationControl = MyLocationControl; @@ -91,10 +102,7 @@ function drawMyLocation( position, map ) { map: map, } ); - // Center the map on the user's location - map.setCenter( pos ); - - // Zoom in + // Zoom into user's location map.setZoom( 16 ); // Store for later access @@ -102,10 +110,15 @@ function drawMyLocation( position, map ) { mapDiv.data( 'myLocationCircle', myLocationCircle ); } else { // Update position and radius - mapDiv.data( 'myLocationMarker' ).position = pos; + mapDiv.data( 'myLocationMarker' ).setPosition( pos ); mapDiv.data( 'myLocationCircle' ).setCenter( pos ); mapDiv.data( 'myLocationCircle' ).setRadius( radius ); } + + if ( mapDiv.data( 'followMyLocation' ) === 'locked' ) { + // Center the map on the user's location + map.setCenter( pos ); + } } function activateMyLocation( map ) { @@ -123,7 +136,7 @@ function activateMyLocation( map ) { }, // Geolocation options { - enableHighAccuracy: false, + enableHighAccuracy: true, timeout: 5000, maximumAge: 0, } From 666cb8ad9c4cbef15873732e4bc6165ea4b719d8 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Wed, 18 Sep 2024 11:36:51 +0200 Subject: [PATCH 12/22] Fix AJAX markers not updating on re-center --- resources/GoogleMaps/googlemaps3ajax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/GoogleMaps/googlemaps3ajax.js b/resources/GoogleMaps/googlemaps3ajax.js index aa86319ed..c7b2d7d17 100644 --- a/resources/GoogleMaps/googlemaps3ajax.js +++ b/resources/GoogleMaps/googlemaps3ajax.js @@ -9,7 +9,7 @@ (function( $, sm ) { var ajaxRequest = null; - var mapEvents = ['dragend', 'zoom_changed']; + var mapEvents = ['dragend', 'bounds_changed']; $( document ).ready( function() { // todo: find a way to remove setTimeout. From 06e974f1292762c0fdfb352292142235026b4262 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Wed, 18 Sep 2024 11:52:59 +0200 Subject: [PATCH 13/22] Add translation string --- i18n/en.json | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/en.json b/i18n/en.json index ede2c24bd..eeb4429ee 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -126,6 +126,7 @@ "maps-par-height": "Allows setting the height of the map. By default pixels will be assumed as unit, but you can explicitly specify one of these units: px, ex, em.", "maps-par-centre": "The location on which the map should be centered", "maps-par-enable-fullscreen": "Enable fullscreen button", + "maps-par-enable-mylocation": "Enable the geolocation button", "maps-par-kml": "KML files to load onto the map.", "maps-par-markercluster": "Allows merging of multiple nearby markers into one marker", "maps-googlemaps3-incompatbrowser": "Your browser is not compatible with Google Maps v3.", From 1fac8cb73a5e1d81495b87635a5a5db7558a3d4c Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Fri, 20 Sep 2024 13:46:25 +0200 Subject: [PATCH 14/22] Store my location setting in localStorage, global for all maps --- resources/GoogleMaps/mylocation.js | 76 ++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index b36d652f9..ca410ad7d 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -1,3 +1,50 @@ +(function( $ ) { + +function setFollowMyLocation( value ) { + localStorage.setItem( "mapsFollowMyLocation", value ); +} + +function getFollowMyLocation() { + return localStorage.getItem( "mapsFollowMyLocation" ); +} + +function isFollowMyLocationSet() { + return getFollowMyLocation() && getFollowMyLocation() != null; +} + +function clearFollowMyLocation() { + localStorage.removeItem( "mapsFollowMyLocation" ); +} + +function updateMapsFollowMyLocation() { + $( window.mapsGoogleList ).each( function( index, map ) { + if ( ! map.options.mylocation ) { + return; + } + + let mapDiv = $( map.map.getDiv() ); + + if( isFollowMyLocationSet() ) { + mapDiv.data( 'myLocationIconUI' ).style.backgroundPosition = '-144px 0'; + activateMyLocation( map.map ); + } else { + mapDiv.data( 'myLocationIconUI' ).style.backgroundPosition = '0 0'; + deactivateMyLocation( map.map ); + } + } ); +} + +$( document ).ready( function() { + // todo: find a way to remove setTimeout. + setTimeout( function() { + if( typeof google === 'undefined' ) { + return; + } + + updateMapsFollowMyLocation(); + }, 500 ); +} ); + // Control for toggling the user location function function MyLocationControl( map ) { var controlDiv = document.createElement('div'); @@ -30,28 +77,27 @@ function MyLocationControl( map ) { controlText.style.width = '18px'; controlUI.appendChild(controlText); + let mapDiv = $( map.getDiv() ); + + // Store UI for updating it later + mapDiv.data( 'myLocationIconUI', controlText ); + // Handle toggle button click google.maps.event.addDomListener( controlUI, 'click', function() { - let mapDiv = $( map.getDiv() ); - - if ( mapDiv.data( 'followMyLocation' ) != null ) { - mapDiv.removeData( 'followMyLocation' ); - controlText.style.backgroundPosition = '0 0'; - deactivateMyLocation( map ); + if ( isFollowMyLocationSet() ) { + clearFollowMyLocation(); } else { - mapDiv.data( 'followMyLocation', 'locked' ); - controlText.style.backgroundPosition = '-144px 0'; - activateMyLocation( map ); + setFollowMyLocation( 'locked' ); } + + updateMapsFollowMyLocation(); } ); // Handle dragged map google.maps.event.addDomListener( map, 'dragend', function() { - let mapDiv = $( map.getDiv() ); - // Continue tracking location, without centering on user - if ( mapDiv.data( 'followMyLocation' ) != null ) { - mapDiv.data( 'followMyLocation', 'passive' ); + if ( isFollowMyLocationSet() ) { + setFollowMyLocation( 'passive' ); } } ); @@ -115,7 +161,7 @@ function drawMyLocation( position, map ) { mapDiv.data( 'myLocationCircle' ).setRadius( radius ); } - if ( mapDiv.data( 'followMyLocation' ) === 'locked' ) { + if ( getFollowMyLocation() === 'locked' ) { // Center the map on the user's location map.setCenter( pos ); } @@ -170,3 +216,5 @@ function deactivateMyLocation( map ) { mapDiv.removeData( 'myLocationCircle' ); } } + +})( window.jQuery ); From e2e47efeac6005a90919156e99a4c342c4fcf24c Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Fri, 20 Sep 2024 13:46:34 +0200 Subject: [PATCH 15/22] Temp: Disabled locked location, disable zoom into location --- resources/GoogleMaps/mylocation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index ca410ad7d..2038ba1d8 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -87,7 +87,7 @@ function MyLocationControl( map ) { if ( isFollowMyLocationSet() ) { clearFollowMyLocation(); } else { - setFollowMyLocation( 'locked' ); + setFollowMyLocation( 'passive' /*'locked'*/ ); } updateMapsFollowMyLocation(); @@ -149,7 +149,7 @@ function drawMyLocation( position, map ) { } ); // Zoom into user's location - map.setZoom( 16 ); + //map.setZoom( 16 ); // Store for later access mapDiv.data( 'myLocationMarker', myLocationMarker ); From d1f7b91bb0e62d57e90d75387c024a6987b0457e Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Fri, 20 Sep 2024 16:08:48 +0200 Subject: [PATCH 16/22] Center on location on button press --- resources/GoogleMaps/mylocation.js | 39 ++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 2038ba1d8..cd09d43a4 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -16,7 +16,7 @@ function clearFollowMyLocation() { localStorage.removeItem( "mapsFollowMyLocation" ); } -function updateMapsFollowMyLocation() { +function updateMapsFollowMyLocation( centerOnMyLocation = false ) { $( window.mapsGoogleList ).each( function( index, map ) { if ( ! map.options.mylocation ) { return; @@ -26,7 +26,7 @@ function updateMapsFollowMyLocation() { if( isFollowMyLocationSet() ) { mapDiv.data( 'myLocationIconUI' ).style.backgroundPosition = '-144px 0'; - activateMyLocation( map.map ); + activateMyLocation( map.map, centerOnMyLocation ); } else { mapDiv.data( 'myLocationIconUI' ).style.backgroundPosition = '0 0'; deactivateMyLocation( map.map ); @@ -90,7 +90,7 @@ function MyLocationControl( map ) { setFollowMyLocation( 'passive' /*'locked'*/ ); } - updateMapsFollowMyLocation(); + updateMapsFollowMyLocation( true ); } ); // Handle dragged map @@ -167,11 +167,35 @@ function drawMyLocation( position, map ) { } } -function activateMyLocation( map ) { +function activateMyLocation( map, centerOnMyLocation ) { mapDiv = $( map.getDiv() ); + let geolocationOptions = { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0, + }; + // Check if geolocation is supported if ( navigator.geolocation ) { + if ( centerOnMyLocation ) { + // Center map only once + navigator.geolocation.getCurrentPosition( + function( position ) { + let pos = { + lat: position.coords.latitude, + lng: position.coords.longitude + }; + map.setCenter( pos ); + }, + // Error handling + function() { + handleLocationError( true, map.getCenter() ); + }, + geolocationOptions + ); + } + let myLocationWatchId = navigator.geolocation.watchPosition( function( position ) { drawMyLocation( position, map ); @@ -180,12 +204,7 @@ function activateMyLocation( map ) { function() { handleLocationError( true, map.getCenter() ); }, - // Geolocation options - { - enableHighAccuracy: true, - timeout: 5000, - maximumAge: 0, - } + geolocationOptions ); mapDiv.data( 'myLocationWatchId', myLocationWatchId ); } else { From 766ff52c7fc733fa8859b1ac58753716b0a3907d Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 23 Sep 2024 17:03:53 +0200 Subject: [PATCH 17/22] Store follow my location option per map, add mylocationfollow parameter --- i18n/en.json | 1 + resources/GoogleMaps/jquery.googlemap.js | 2 +- resources/GoogleMaps/mylocation.js | 65 ++++++++++++++++-------- src/GoogleMapsService.php | 7 +++ 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/i18n/en.json b/i18n/en.json index eeb4429ee..f23827ccd 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -127,6 +127,7 @@ "maps-par-centre": "The location on which the map should be centered", "maps-par-enable-fullscreen": "Enable fullscreen button", "maps-par-enable-mylocation": "Enable the geolocation button", + "maps-par-enable-mylocation-follow": "Continously center map on user location", "maps-par-kml": "KML files to load onto the map.", "maps-par-markercluster": "Allows merging of multiple nearby markers into one marker", "maps-googlemaps3-incompatbrowser": "Your browser is not compatible with Google Maps v3.", diff --git a/resources/GoogleMaps/jquery.googlemap.js b/resources/GoogleMaps/jquery.googlemap.js index dce7d9185..571b9540b 100644 --- a/resources/GoogleMaps/jquery.googlemap.js +++ b/resources/GoogleMaps/jquery.googlemap.js @@ -734,7 +734,7 @@ // - My Location if(options.mylocation){ - this.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(new window.MyLocationControl(this.map)); + this.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(new window.MyLocationControl(this.map, options.mylocationfollow)); } }; diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index cd09d43a4..6c178fe46 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -1,22 +1,42 @@ (function( $ ) { -function setFollowMyLocation( value ) { - localStorage.setItem( "mapsFollowMyLocation", value ); +/* Track user location with marker on map */ + +function activateTrackMyLocation() { + localStorage.setItem( 'mapsTrackMyLocation', 'yes' ); +} + +function getTrackMyLocation() { + return localStorage.getItem( 'mapsTrackMyLocation' ); } -function getFollowMyLocation() { - return localStorage.getItem( "mapsFollowMyLocation" ); +function isTrackMyLocationSet() { + return getTrackMyLocation() && getTrackMyLocation() === 'yes'; } -function isFollowMyLocationSet() { - return getFollowMyLocation() && getFollowMyLocation() != null; +function clearTrackMyLocation() { + localStorage.removeItem( 'mapsTrackMyLocation' ); +} + +/* Follow: Center map on user location */ + +function activateFollowMyLocation( mapDiv ) { + mapDiv.data( 'followMyLocation', 'locked' ); } -function clearFollowMyLocation() { - localStorage.removeItem( "mapsFollowMyLocation" ); +function getFollowMyLocation( mapDiv ) { + return mapDiv.data( 'followMyLocation' ); } -function updateMapsFollowMyLocation( centerOnMyLocation = false ) { +function isFollowMyLocationSet( mapDiv ) { + return getFollowMyLocation( mapDiv ) && getFollowMyLocation( mapDiv ) === 'locked'; +} + +function clearFollowMyLocation( mapDiv ) { + mapDiv.removeData( 'followMyLocation' ); +} + +function updateMapsTrackMyLocation( centerOnMyLocation = false ) { $( window.mapsGoogleList ).each( function( index, map ) { if ( ! map.options.mylocation ) { return; @@ -24,7 +44,7 @@ function updateMapsFollowMyLocation( centerOnMyLocation = false ) { let mapDiv = $( map.map.getDiv() ); - if( isFollowMyLocationSet() ) { + if( isTrackMyLocationSet() ) { mapDiv.data( 'myLocationIconUI' ).style.backgroundPosition = '-144px 0'; activateMyLocation( map.map, centerOnMyLocation ); } else { @@ -41,12 +61,12 @@ $( document ).ready( function() { return; } - updateMapsFollowMyLocation(); + updateMapsTrackMyLocation( false ); }, 500 ); } ); // Control for toggling the user location function -function MyLocationControl( map ) { +function MyLocationControl( map, followMyLocation ) { var controlDiv = document.createElement('div'); controlDiv.style.padding = '10px 10px 0px 10px'; controlDiv.index = 1; @@ -84,20 +104,24 @@ function MyLocationControl( map ) { // Handle toggle button click google.maps.event.addDomListener( controlUI, 'click', function() { - if ( isFollowMyLocationSet() ) { - clearFollowMyLocation(); + if ( isTrackMyLocationSet() ) { + clearTrackMyLocation(); } else { - setFollowMyLocation( 'passive' /*'locked'*/ ); + if ( followMyLocation ) { + activateFollowMyLocation( mapDiv ); + } + + activateTrackMyLocation(); } - updateMapsFollowMyLocation( true ); + updateMapsTrackMyLocation( true ); } ); // Handle dragged map google.maps.event.addDomListener( map, 'dragend', function() { - // Continue tracking location, without centering on user - if ( isFollowMyLocationSet() ) { - setFollowMyLocation( 'passive' ); + // Stop centering on user location + if ( isFollowMyLocationSet( mapDiv ) ) { + clearFollowMyLocation( mapDiv ); } } ); @@ -161,7 +185,7 @@ function drawMyLocation( position, map ) { mapDiv.data( 'myLocationCircle' ).setRadius( radius ); } - if ( getFollowMyLocation() === 'locked' ) { + if ( isFollowMyLocationSet( mapDiv ) ) { // Center the map on the user's location map.setCenter( pos ); } @@ -196,6 +220,7 @@ function activateMyLocation( map, centerOnMyLocation ) { ); } + // Continously track user location let myLocationWatchId = navigator.geolocation.watchPosition( function( position ) { drawMyLocation( position, map ); diff --git a/src/GoogleMapsService.php b/src/GoogleMapsService.php index 55d19ad0b..33ee7f9bf 100644 --- a/src/GoogleMapsService.php +++ b/src/GoogleMapsService.php @@ -254,6 +254,13 @@ function( string $fileName ) { 'message' => 'maps-par-enable-mylocation', ]; + $params['mylocationfollow'] = [ + 'aliases' => [ 'enablemylocationfollow' ], + 'type' => 'boolean', + 'default' => false, + 'message' => 'maps-par-enable-mylocation-follow', + ]; + $params['scrollwheelzoom'] = [ 'aliases' => [ 'scrollzoom' ], 'type' => 'boolean', From 3734f2011c74c9540fd7664ff7bc8ad058c61938 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 23 Sep 2024 17:32:30 +0200 Subject: [PATCH 18/22] Cleanup --- i18n/en.json | 2 +- resources/GoogleMaps/mylocation.js | 6 +++--- src/GoogleMapsService.php | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/i18n/en.json b/i18n/en.json index f23827ccd..3e3a5ffba 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -127,7 +127,7 @@ "maps-par-centre": "The location on which the map should be centered", "maps-par-enable-fullscreen": "Enable fullscreen button", "maps-par-enable-mylocation": "Enable the geolocation button", - "maps-par-enable-mylocation-follow": "Continously center map on user location", + "maps-par-enable-mylocationfollow": "Continously center map on user location", "maps-par-kml": "KML files to load onto the map.", "maps-par-markercluster": "Allows merging of multiple nearby markers into one marker", "maps-googlemaps3-incompatbrowser": "Your browser is not compatible with Google Maps v3.", diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index 6c178fe46..e6bcc5382 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -1,6 +1,6 @@ (function( $ ) { -/* Track user location with marker on map */ +/* Track user's location with marker on map */ function activateTrackMyLocation() { localStorage.setItem( 'mapsTrackMyLocation', 'yes' ); @@ -18,7 +18,7 @@ function clearTrackMyLocation() { localStorage.removeItem( 'mapsTrackMyLocation' ); } -/* Follow: Center map on user location */ +/* Follow: Center map on user's location */ function activateFollowMyLocation( mapDiv ) { mapDiv.data( 'followMyLocation', 'locked' ); @@ -220,7 +220,7 @@ function activateMyLocation( map, centerOnMyLocation ) { ); } - // Continously track user location + // Continously track user's location let myLocationWatchId = navigator.geolocation.watchPosition( function( position ) { drawMyLocation( position, map ); diff --git a/src/GoogleMapsService.php b/src/GoogleMapsService.php index 33ee7f9bf..38b1d4843 100644 --- a/src/GoogleMapsService.php +++ b/src/GoogleMapsService.php @@ -248,14 +248,12 @@ function( string $fileName ) { ]; $params['mylocation'] = [ - 'aliases' => [ 'enablemylocation' ], 'type' => 'boolean', 'default' => false, 'message' => 'maps-par-enable-mylocation', ]; $params['mylocationfollow'] = [ - 'aliases' => [ 'enablemylocationfollow' ], 'type' => 'boolean', 'default' => false, 'message' => 'maps-par-enable-mylocation-follow', From ff79662c87ccc6d41a119ebad8fe84faf0b0ead8 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 23 Sep 2024 17:33:57 +0200 Subject: [PATCH 19/22] Add my location zoom parameter --- resources/GoogleMaps/jquery.googlemap.js | 2 +- resources/GoogleMaps/mylocation.js | 19 +++++++++++-------- src/GoogleMapsService.php | 8 +++++++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/resources/GoogleMaps/jquery.googlemap.js b/resources/GoogleMaps/jquery.googlemap.js index 571b9540b..1c42e5099 100644 --- a/resources/GoogleMaps/jquery.googlemap.js +++ b/resources/GoogleMaps/jquery.googlemap.js @@ -734,7 +734,7 @@ // - My Location if(options.mylocation){ - this.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(new window.MyLocationControl(this.map, options.mylocationfollow)); + this.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(new window.MyLocationControl(this.map, options.mylocationfollow, options.mylocationzoom)); } }; diff --git a/resources/GoogleMaps/mylocation.js b/resources/GoogleMaps/mylocation.js index e6bcc5382..3eb91699d 100644 --- a/resources/GoogleMaps/mylocation.js +++ b/resources/GoogleMaps/mylocation.js @@ -66,7 +66,7 @@ $( document ).ready( function() { } ); // Control for toggling the user location function -function MyLocationControl( map, followMyLocation ) { +function MyLocationControl( map, followMyLocation, zoom ) { var controlDiv = document.createElement('div'); controlDiv.style.padding = '10px 10px 0px 10px'; controlDiv.index = 1; @@ -99,8 +99,9 @@ function MyLocationControl( map, followMyLocation ) { let mapDiv = $( map.getDiv() ); - // Store UI for updating it later + // Store for later access mapDiv.data( 'myLocationIconUI', controlText ); + mapDiv.data( 'myLocationZoom', zoom === -1 ? false : zoom ); // Handle toggle button click google.maps.event.addDomListener( controlUI, 'click', function() { @@ -119,7 +120,7 @@ function MyLocationControl( map, followMyLocation ) { // Handle dragged map google.maps.event.addDomListener( map, 'dragend', function() { - // Stop centering on user location + // Stop centering on user's location if ( isFollowMyLocationSet( mapDiv ) ) { clearFollowMyLocation( mapDiv ); } @@ -172,9 +173,6 @@ function drawMyLocation( position, map ) { map: map, } ); - // Zoom into user's location - //map.setZoom( 16 ); - // Store for later access mapDiv.data( 'myLocationMarker', myLocationMarker ); mapDiv.data( 'myLocationCircle', myLocationCircle ); @@ -192,7 +190,7 @@ function drawMyLocation( position, map ) { } function activateMyLocation( map, centerOnMyLocation ) { - mapDiv = $( map.getDiv() ); + let mapDiv = $( map.getDiv() ); let geolocationOptions = { enableHighAccuracy: true, @@ -211,6 +209,11 @@ function activateMyLocation( map, centerOnMyLocation ) { lng: position.coords.longitude }; map.setCenter( pos ); + + // Zoom into user's location + if ( mapDiv.data( 'myLocationZoom' ) !== false ) { + map.setZoom( mapDiv.data( 'myLocationZoom' ) ); + } }, // Error handling function() { @@ -239,7 +242,7 @@ function activateMyLocation( map, centerOnMyLocation ) { } function deactivateMyLocation( map ) { - mapDiv = $( map.getDiv() ); + let mapDiv = $( map.getDiv() ); // Check if geolocation is supported if ( navigator.geolocation ) { diff --git a/src/GoogleMapsService.php b/src/GoogleMapsService.php index 38b1d4843..c1b2fb412 100644 --- a/src/GoogleMapsService.php +++ b/src/GoogleMapsService.php @@ -256,7 +256,13 @@ function( string $fileName ) { $params['mylocationfollow'] = [ 'type' => 'boolean', 'default' => false, - 'message' => 'maps-par-enable-mylocation-follow', + 'message' => 'maps-par-enable-mylocationfollow', + ]; + + $params['mylocationzoom'] = [ + 'type' => 'integer', + 'default' => -1, + 'message' => 'maps-par-mylocationzoom', ]; $params['scrollwheelzoom'] = [ From bd567d9fce8501b89c49c04a493d0da0453bf56f Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 23 Sep 2024 17:38:14 +0200 Subject: [PATCH 20/22] Add to existing module --- extension.json | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/extension.json b/extension.json index 6ee526d84..480f2e5dc 100644 --- a/extension.json +++ b/extension.json @@ -248,7 +248,8 @@ "ext.maps.googlemaps3": { "scripts": [ "GoogleMaps/jquery.googlemap.js", - "GoogleMaps/ext.maps.googlemaps3.js" + "GoogleMaps/ext.maps.googlemaps3.js", + "GoogleMaps/mylocation.js" ], "messages": [ "maps-googlemaps3-incompatbrowser", @@ -308,17 +309,6 @@ "targets": [ "desktop", "mobile" ] }, - "ext.maps.mylocation": { - "dependencies": [ - "ext.maps.googlemaps3", - "ext.sm.common" - ], - "scripts": [ - "GoogleMaps/mylocation.js" - ], - "targets": [ "desktop", "mobile" ] - }, - "ext.maps.wikitext.editor": { "dependencies": [ "jquery.ui", From 2b5850474ffcb22439c025cd74259009ae920a42 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 23 Sep 2024 17:39:13 +0200 Subject: [PATCH 21/22] Add to existing module --- src/GoogleMapsService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GoogleMapsService.php b/src/GoogleMapsService.php index c1b2fb412..22f6ee8b0 100644 --- a/src/GoogleMapsService.php +++ b/src/GoogleMapsService.php @@ -291,7 +291,7 @@ public function newMapId(): string { } public function getResourceModules( array $params ): array { - return [ 'ext.maps.googlemaps3', 'ext.maps.googlemaps3ajax', 'ext.maps.mylocation' ]; + return [ 'ext.maps.googlemaps3', 'ext.maps.googlemaps3ajax' ]; } public static function getApiScript( $langCode, array $urlArgs = [] ) { From 6bc5a19d075d346b9383f8918b8390ec13ec5e88 Mon Sep 17 00:00:00 2001 From: Stefan Grassberger Date: Mon, 23 Sep 2024 17:43:19 +0200 Subject: [PATCH 22/22] Add translation string --- i18n/en.json | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/en.json b/i18n/en.json index 3e3a5ffba..dc434e968 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -127,6 +127,7 @@ "maps-par-centre": "The location on which the map should be centered", "maps-par-enable-fullscreen": "Enable fullscreen button", "maps-par-enable-mylocation": "Enable the geolocation button", + "maps-par-mylocationzoom": "The zoom level to go to when user location is turned on", "maps-par-enable-mylocationfollow": "Continously center map on user location", "maps-par-kml": "KML files to load onto the map.", "maps-par-markercluster": "Allows merging of multiple nearby markers into one marker",