Listening to `set_at` event using the ui-gmap-polygon
Asked Answered
S

2

6

I'm currently using the DrawingManager to allow users to draw shapes on the map. Once a shape is drawn, I set up a listener on the polygon's path so I can react after the path has been changed:

var polygonPath = event.overlay.getPath();
google.maps.event.addListener(polygonPath, 'set_at', function () { 
    // my code...
});

This works great when a user adds a new shape using the drawing tool. However, if I already have polygons in my database that I am displaying with the ui-gmap-polygon AngularJS directive (from the angular-google-maps project), how can I listen to the set_at event since this event is not on the polygon, but is instead, on the polygon's path (MVCArray)?

The only place I was able to find a reference to set_at in the source code of the angular-google-maps project was in the array-sync.coffee file, but it doesn't look like it is being exposed.

If I can't listen to the set_at event directly using the directive, I would hope there is an event that gets triggered when the directive creates the polygon so that I can then get the polygon's path and then add a listener to that, just like the code above.

I have put together a JSFiddle with the basic structure, along with the events object. It currently handles the polygon's mouseover and mouseout, but not the set_at event.

Spongioblast answered 20/3, 2015 at 21:43 Comment(4)
What's the goal? Are you using setAt() to build your polygons?Impeccable
I have an array of polygons which I populate from the server. I then use ng-repeat on ui-gmap-polygon and set the path attribute so the directive can create the polygons. I need to listen to the set_at event so I can know when the user modifies the polygon so I can react with some custom code.Spongioblast
Please, provide: mcve.Thionate
I have linked to a basic example, using the angular directive.Spongioblast
S
2

Give a try with the below approach.

directive('uiGmapPolygon', function ($timeout) {
  return {
    restrict: 'E',
    link: function (scope, element, attrs) {

      // Make sure that the polygon is rendered before accessing it. 
      // next two lines will do the trick.
      $timeout(function () {
        // I know that properties with $$ are not good to use, but can't get away without using $$childHead
        scope.$$childHead.control.promise.then(function () {
          // get the polygons
          var polygons = scope.$$childHead.control.polygons;
          // iterate over the polygons
          polygons.forEach(function (polygon) {
            // get google.maps.Polygon instance bound to the polygon
            var gObject = polygon.gObject;

            // get the Paths of the Polygon
            var paths = gObject.getPaths();
            // register the events.
            paths.forEach(function (path) {
              google.maps.event.addListener(path, 'insert_at', function () {
                console.log('insert_at event');
              });

              google.maps.event.addListener(path, 'remove_at', function () {
                  console.log('remove_at event');
              });

              google.maps.event.addListener(path, 'set_at', function () {
                  console.log('set_at event');
              });
            })
          })
        })
      });
    }
  }
})

Working Plnkr

Sultana answered 24/3, 2015 at 13:39 Comment(2)
I really like your approch. However, since this directive has the same name as the directive from the AngularJS UI Google Maps project, does it override the functionality? Would it work best with a different name and instead of having it restricted to an element, restrict it to an attribute so I can just add it to the ui-gmap-polygon element?Spongioblast
Having the same name will not do any harm. The one written in angular gmaps will be processed first then this. We can override any of the directives provided by angular as well. Do let me know if this solution works for you.Sultana
I
1

You need to set your event listeners on the polygon path(s).

You can use the forEach() method of the MVCArray to indentify each path of your polygon.

function initialize() {

    var mapOptions = {
        zoom: 4,
        center: new google.maps.LatLng(40, 9),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

    var polygon = new google.maps.Polygon({
        editable: true,
        strokeOpacity: 0,
        strokeWeight: 0,
        fillColor: '#00FF00',
        fillOpacity: .6,
        paths: [
        new google.maps.LatLng(39, 4),
        new google.maps.LatLng(34, 24),
        new google.maps.LatLng(43, 24),
        new google.maps.LatLng(39, 4)],
        map: map
    });

    // Get paths from polygon and set event listeners for each path separately
    polygon.getPaths().forEach(function (path, index) {

        google.maps.event.addListener(path, 'insert_at', function () {
            console.log('insert_at event');
        });

        google.maps.event.addListener(path, 'remove_at', function () {
            console.log('remove_at event');
        });

        google.maps.event.addListener(path, 'set_at', function () {
            console.log('set_at event');
        });
    });
}

initialize();

JSFiddle demo

Impeccable answered 23/3, 2015 at 8:21 Comment(2)
Thank you, but I am not creating the polygons myself, they are being created with the ui-gmap-polygon AngularJS directive, from angular-google-maps.Spongioblast
I'm using Angular Google maps too, but the technic shown by MrUpsidown works.Francinafrancine

© 2022 - 2024 — McMap. All rights reserved.