Unable to draw in Leaflet after update of a marker position using geolocation

926 Views Asked by At

I'm using Leaflet, Leaflet-draw and Cordova Geolocation. When the map is loaded (globe view) it is possible to draw correctly, when locate function is called mapcenter and marker position are update but become impossible to draw. Draw toolbar is visible and clickable but any tool selected doesn't work when I use it, I don't receive any error in logger, it seems that the draw editable layer "disappear"...

Link to Plunker: http://plnkr.co/edit/6DH7o3HyPzbpCJs7szcn?p=preview

This is my code:

angular.module('starter', ['ionic', 'ui-leaflet','ngCordova'])
.controller("MapCtrl", [ "$scope", "leafletData", "$cordovaGeolocation", function($scope, leafletData, $cordovaGeolocation) {
  angular.extend($scope, {
    center: {
      lat: 51.505,
      lng: -0.09,
      zoom: 4
    },
    controls: {
      draw: {}
    },
    markers:{
      tracker: {
          lat: 51.505,
          lng: -0.09,
          message: "You're here!",
          focus: false,
          icon: {},
      }
    },
    layers: {
      baselayers: {
        bingAerial: {
          name: 'Bing Aerial',
          type: 'bing',
          key: 'Aj6XtE1Q1rIvehmjn2Rh1LR2qvMGZ-8vPS9Hn3jCeUiToM77JFnf-kFRzyMELDol',
          layerOptions: {
            type: 'Aerial'
          }
        }
      },

      overlays: {
        draw: {
          name: 'draw',
          type: 'group',
          visible: true,
          layerParams: {
            showOnSelector: false
          }
        }
      }
    }
  });

  // Cordova Geolocation
  $scope.locate = function(){
    console.log(leafletData);
    var posOptions = {timeout: 10000, enableHighAccuracy: false};
    $cordovaGeolocation
    .getCurrentPosition(posOptions)
    .then(function (position) {
      $scope.center.lat = position.coords.latitude
      $scope.center.lng = position.coords.longitude
      $scope.center.zoom = 19
      $scope.markers.tracker.lat = position.coords.latitude
      $scope.markers.tracker.lng = position.coords.longitude
    }, function(err) {
      // error
    });
    setInterval(function(){
      var posOptions = {timeout: 10000, enableHighAccuracy: false};
      $cordovaGeolocation
      .getCurrentPosition(posOptions)
      .then(function (position) {
        $scope.markers.tracker.lat = position.coords.latitude
        $scope.markers.tracker.lng = position.coords.longitude
      }, function(err) {
        // error
      });
    },5000)
  }
  // /Cordova Geolocation


  leafletData.getMap().then(function(map) {
    console.log(leafletData);
    leafletData.getLayers().then(function(baselayers) {
      var drawnItems = baselayers.overlays.draw;
      map.on('draw:created', function (e) {
        var layer = e.layer;
        drawnItems.addLayer(layer);
        console.log(JSON.stringify(layer.toGeoJSON()));
      });
    });
  });
}])

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link rel="manifest" href="manifest.json">

    <!-- un-comment this code to enable service worker
    <script>
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('service-worker.js')
          .then(() => console.log('service worker installed'))
          .catch(err => console.log('Error', err));
      }
    </script>-->

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="lib/ngCordova/dist/ng-cordova.js"></script>
    <script src="cordova.js"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>

    <script src="lib/leaflet/dist/leaflet.js"></script>
    <script src="lib/angular-simple-logger/dist/angular-simple-logger.js"></script>
    <script src="lib/ui-leaflet/dist/ui-leaflet.min.js"></script>
    <script src="https://rawgit.com/elesdoar/ui-leaflet-layers/master/dist/ui-leaflet-layers.min.js"></script>
    <script src="lib/leaflet-draw/dist/leaflet.draw.js"></script>
    <script src="lib/leaflet-plugins/layer/tile/Bing.js"></script>
    <link rel="stylesheet" href="lib/leaflet/dist/leaflet.css" />
    <link rel="stylesheet" href="lib/leaflet-draw/dist/leaflet.draw.css" />

  </head>
  <body ng-app="starter">

    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Ionic Blank Starter</h1>
        <a class="button" ng-click ='locate();'>Locate</a>
      </ion-header-bar>


      <ion-content ng-controller ='MapCtrl'>
        <a class="button" ng-click ='locate();'>Locate</a>
        <leaflet lf-center="center" controls="controls" markers='markers' layers="layers" width="100%" height="400"></leaflet>
      </ion-content>

    </ion-pane>
  </body>
  </html>
1

There are 1 best solutions below

0
On BEST ANSWER

The reason it stops working is because Ionic's own tap system doesn't play nicely with Leaflet's.

The following Ionic documentation has more information:

In some cases, third-party libraries may also be working with touch events which can interfere with the tap system. For example, mapping libraries like Google or Leaflet Maps often implement a touch detection system which conflicts with Ionic’s tap system.

Disable Ionic's tap system on the specific element to make it work:

<leaflet data-tap-disabled="true" ...

Demo: https://plnkr.co/edit/LlhpTGYHNMBUzNo1oSwF?p=preview