2

I would like to extend/ alter a mapbox geolocation control with some features, e.g.:

  1. I would like to flyTo instead of jumpTo the current location
  2. I would like to add some behavior (e.g. prevent dragging) when the geocontrol button is toggled on.

How do I do that? I tried making a wrapper but then I get some problems:

  • the color of button should turn blue when toggled on but that does not work anymore
  • I do not know how to add features to the clicking of the button.

I have a fiddle showing how I tried to make a wrapper. As you can see the flyTo works.

mapboxgl.accessToken = 'pk.eyJ1IjoidG1jdyIsImEiOiJIZmRUQjRBIn0.lRARalfaGHnPdRcc-7QZYQ'


var map = new mapboxgl.Map({
  container: 'map', // container id
  style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
  center: [-74.50, 40], // starting position
  zoom: 9 // starting zoom
})


class GeolocateControlWrapper extends mapboxgl.GeolocateControl {
  constructor() {
    super()
  }
  _onSuccess(position) {
    this._map.flyTo({
      center: [position.coords.longitude, position.coords.latitude],
      zoom: 17,
      bearing: 0,
      pitch: 0
    })

    this.fire('geolocate', position)
    this._finish()
  }
}

map.addControl(new GeolocateControlWrapper({
  positionOptions: {
    enableHighAccuracy: true,
    timeout: 300
  },
  watchPosition: true
}), 'top-left')

EDIT, update: I am still having trouble with part 2 of my question. I managed to get the fiddle with 'a wrapper' working though, see this. However in my 'real-life' environment I get following error when clicking the geocontrol button:

Uncaught TypeError: Cannot read property 'extend' of undefined
    at GeolocateControlWrapper._onClickGeolocate (eval at <anonymous> (0.b708727….js:485), <anonymous>:192:48)
_onClickGeolocate @ Maplayout.vue?f994:154
VM2654:1 Uncaught SyntaxError: Unexpected identifier

which references this line:

mapboxgl.util.extend(defaultGeoPositionOptions, this.options && this.options.positionOptions || {})

Any idea why?

EDIT, update: Got it working using following code:

class GeolocateControlWrapper extends mapboxgl.GeolocateControl {
        _onSuccess (position) {
          this._map.flyTo({
            center: [position.coords.longitude, position.coords.latitude],
            zoom: 17,
            bearing: 0,
            pitch: 0
          })

          this.fire('geolocate', position)
          this._finish()
        }

        _setupUI (supported) {
          super._setupUI(supported)
          if (supported === false) return
          this._geolocateButton.className += ' needsclick'
        }

        _onClickGeolocate () {
          super._onClickGeolocate()
          // toggle watching the device location
          if (this.options.watchPosition) {
            if (this._geolocationWatchID !== undefined) { // clear watchPosition
              console.log('looks good in if....')
            }
            else {
              // enable watchPosition
              console.log('looks good in else....')
            }
          }
        }
      }
musicformellons
  • 12,283
  • 4
  • 51
  • 86

1 Answers1

2

I start with your first problem:

  • the color of button should turn blue when toggled on but that does not work anymore

The color changes when options.watchPosition is set to true and the button works as a toggle button. Otherwise, a button click just updates your location on the map, but is not toggling anything. You set that option, but your constructor does not pass the options object up to its parent class. So either omit the constructor completly or do pass the options:

class GeolocateControlWrapper extends mapboxgl.GeolocateControl {
  constructor(options) {
    super(options)
  }

Now to your second question:

  • I do not know how to add features to the clicking of the button. I would like to add some behavior (e.g. prevent dragging) when the geocontrol button is toggled on.

Toggling of watchPosition is done in _onClickGeolocate(). Adding this._map.dragPan.disable() and this._map.dragPan.enable() should prevent/allow the user from dragging the map. But I sit at my computer and so I didn't test if the map still follows your position as it changes.

sgelb
  • 575
  • 4
  • 9
  • Regarding answer on second question; So I add the _onClickGeolocate method entirely into my wrapper and then add the this._map.dragPan.disable() to that, right? How do I go about the references to other mapbox modules as the method uses it extend module: ```const positionOptions = util.extend(defaultGeoPositionOptions, this.options && this.options.positionOptions || {})``` – musicformellons Mar 02 '17 at 05:59
  • I tried adding the util module with ```let mapboxUtil = require('../../../node_modules/mapbox-gl/js/util/util')``` but I get ```./~/mapbox-gl/js/util/util.js Module parse failed: /home/usr/t1/node_modules/mapbox-gl/js/util/util.js Unexpected token (15:35) You may need an appropriate loader to handle this file type. | * @private | */ | exports.easeCubicInOut = function(t: number): number { | if (t <= 0) return 0; | if (t >= 1) return 1; @ ./~/babel-loader/lib!./~/vue-loader/lib/selector.js? ``` – musicformellons Mar 02 '17 at 07:31
  • @musicformellons: Try `const util = require('mapbox-gl/js/util/util');` – sgelb Mar 02 '17 at 23:35
  • 1
    I don't know your setup. But I can tell you that i could run `util.clamp()` after importing `util` like above via browserify. And btw, did I answer your first question? – sgelb Mar 03 '17 at 08:55
  • Yeah, first question was answered. – musicformellons Mar 03 '17 at 21:33
  • I updated my question. Maybe you can give it another shot... Thx! – musicformellons Mar 15 '17 at 15:16
  • Thanks to your suggestions I got it working, see edited question. – musicformellons Mar 16 '17 at 16:05