Search code examples
leafletlatitude-longitudepolymer-1.0web-componentobservers

Polymer 1.0 / leaflet-map 1.0 Map not consistently returning to given point on button click


I am trying to implement a map using Polymer 1.0 and leaflet-map 1.0, which has a button that when clicked should pan the map to center on the current geolocation.

The map ('mymap') and 'geoButton' are elements on the same level in main index page. I have something that sort of works, but inconsistently.

The map is set up as so (for now the initial center is hard-coded):

        <leaflet-map id="mymap"  latitude="40.707149800" longitude="-74.002101900"   zoom="14">

          <leaflet-geolocation id="locator"  enable-high-accuracy latitude="{{latitude}}" longitude="{{longitude}}" watch="true">
          </leaflet-geolocation>
       ...

In the geoButton element, I assign the locator lat and long to the map lat and long when the button is clicked:

    mymap.latitude = locator.latitude;
    mymap.longitude = locator.longitude;

In leaflet-core.html (which has the properties and events carried over from Leaflet.js) both the latitude and longitude properties have an observer method '_viewChanged':

    _viewChanged: function(newValue, oldValue) {

        if (this.map) {

        this.async(function() {

                this.map.setView(L.latLng(this.latitude, this.longitude), this.zoom);

                console.log("new lat? " +this.latitude );
                console.log("new long? " +this.longitude );

            });

        }

    }

The problem is that the map does not always reset to the new center. If I pan the map far away from the initial point then click the geoButton, it will re-center (a 'viewreset' event is called). Also, the map will reset to the correct center if I drag the map at all after clicking the geoButton.

If I remove the async function in the observer method, and call 'this.map.setView' directly, the map will actually re-center to the geolocated point correctly. But in this case, if I pan the map, it will 'bounce' back to the geolocated latitude (the longitude will remain wherever I pan the map). I think this is because '_viewChanged' is called twice, but the second time the latitude has not changed from the first call.

Can I perhaps force some kind of reset or refresh on the map in the observer method before call this.map/.setView (which is what seems to happen when I drag the map after calling that method)? Or, is there something else I am missing here?

After some more testing, I notice that if I comment out:

 // mymap.latitude = locator.latitude;

then the map will zoom to the correct (geolocated) longitude, but will remain at whatever latitude the map was set to before the button click...the same is true if I comment out the longitude line instead; then the map pans to the correct (geolocated) latitude and to the current longitude. In other words, I can correctly pass one updated property, but not two...both use the same observer method.


Solution

  • I found a solution. The key was to add a function to the leaflet-core element so that I could pass the new latitude and longitude at the same time, then call that method in the event handler for the button:

    (in leaflet-core.html)

         setToPoint: function(newLat, newLong){
            if (this.map) {
                this.async(function() {
                  this.map.setView(L.latLng(newLat, newLong), this.zoom, {pan: {animate: true}});
                  this.map.invalidateSize();
                });
    
            }
    
         },
    

    (in geobutton element - tap callback)

    mymap.setToPoint(locator.latitude, locator.longitude);