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.

Andy T
  • 10,223
  • 5
  • 53
  • 95
  • What's the goal? Are you using `setAt()` to build your polygons? – MrUpsidown Mar 21 '15 at 09:18
  • 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. – Andy T Mar 22 '15 at 18:32
  • Please, provide: [mcve](http://stackoverflow.com/help/mcve). – artur grzesiak Mar 23 '15 at 07:53
  • I have linked to a basic example, using the angular directive. – Andy T Mar 23 '15 at 16:14

2 Answers2

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

Vinay K
  • 5,562
  • 1
  • 18
  • 27
  • 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? – Andy T Mar 27 '15 at 16:59
  • 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. – Vinay K Mar 27 '15 at 17:56
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

MrUpsidown
  • 21,592
  • 15
  • 77
  • 131
  • 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`. – Andy T Mar 23 '15 at 16:13
  • I'm using Angular Google maps too, but the technic shown by MrUpsidown works. – Apalabrados Jan 19 '16 at 13:20