35

I'm trying to develop an application by using Google Maps API v3. What I'm trying to do is; first let the user draw a polygon on a Google Map and get his/her polygon's coordinates and save them into a database. I will then show the user saved coordinates.

I don't know how to let users draw polygon on a Google Map with API v3 and then get the coordinates. If I can get those coordinates, it's easy to save them into a database.

http://gmaps-samples.googlecode.com/svn/trunk/poly/mymapstoolbar.html is nearly the exact example but it uses API v2 and doesn't give coordinates. I want to use API v3 and be able to get all coordinates.

Is there any examples of drawing polygon and getting its coordinates with API v3?

shanabus
  • 12,989
  • 6
  • 52
  • 78
Burak Erdem
  • 19,630
  • 7
  • 36
  • 56
  • Latest samples from the gmaps-samples-v3 is now on Github https://github.com/googlemaps/js-samples – Burneh Jul 11 '17 at 17:51

10 Answers10

17

If all you need is the coordinates here is a drawing tool I like to use - move the polygon or re-shape it and the coordinates will display right below the map: jsFiddle here.

Also, here is a Codepen

JS

var bermudaTriangle;
function initialize() {
    var myLatLng = new google.maps.LatLng(33.5190755, -111.9253654);
    var mapOptions = {
        zoom: 12,
        center: myLatLng,
        mapTypeId: google.maps.MapTypeId.RoadMap
    };

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


    var triangleCoords = [
        new google.maps.LatLng(33.5362475, -111.9267386),
        new google.maps.LatLng(33.5104882, -111.9627875),
        new google.maps.LatLng(33.5004686, -111.9027061)

    ];

    // Construct the polygon
    bermudaTriangle = new google.maps.Polygon({
        paths: triangleCoords,
        draggable: true,
        editable: true,
        strokeColor: '#FF0000',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#FF0000',
        fillOpacity: 0.35
    });

    bermudaTriangle.setMap(map);
    google.maps.event.addListener(bermudaTriangle, "dragend", getPolygonCoords);
    google.maps.event.addListener(bermudaTriangle.getPath(), "insert_at", getPolygonCoords);
    google.maps.event.addListener(bermudaTriangle.getPath(), "remove_at", getPolygonCoords);
    google.maps.event.addListener(bermudaTriangle.getPath(), "set_at", getPolygonCoords);
}

function getPolygonCoords() {
    var len = bermudaTriangle.getPath().getLength();
    var htmlStr = "";
    for (var i = 0; i < len; i++) {
        htmlStr += bermudaTriangle.getPath().getAt(i).toUrlValue(5) + "<br>";
    }
    document.getElementById('info').innerHTML = htmlStr;
}

HTML

<body onload="initialize()">
    <h3>Drag or re-shape for coordinates to display below</h3>
    <div id="map-canvas">
    </div>
    <div id="info">
    </div>
</body>

CSS

#map-canvas {
    width: auto;
    height: 350px;
}
#info {
    position: absolute;
    font-family: arial, sans-serif;
    font-size: 18px;
    font-weight: bold;
}
jhawes
  • 2,354
  • 3
  • 24
  • 34
  • 1
    Can I get the poligon boundaries? Not position but boundaries. I want to get the boundaries and make a db search of the coordinates inside the boundaries. – JuanFernandoz May 21 '15 at 04:01
  • How can we get co-ordinates for a given area or latitude and longitude to draw polygon @jhawes – saikiran Sep 28 '15 at 18:08
16

It's cleaner/safer to use the getters provided by google instead of accessing the properties like some did

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(polygon) {
    var coordinatesArray = polygon.overlay.getPath().getArray();
});
ylos
  • 522
  • 1
  • 6
  • 16
13

Well, unfortunately it seems that one cannot place custom markers and draw (and obtain coordinates) directly from maps.google.com if one is anonymous/not logged in (as it was possible some years ago, if I recall correctly). Still, thanks to the answers here, I managed to make a combination of examples that has both the Google Places search, and allows drawing via the drawing library, and dumps coordinates upon making a selection of any type of shape (including coordinates for polygon) that can be copypasted; the code is here:

This is how it looks like:

test.png

(The Places markers are handled separately, and can be deleted via the DEL "button" by the search input form element; "curpos" shows the current center [position] and zoom level of the map viewport).

sdaau
  • 36,975
  • 46
  • 198
  • 278
  • Thanks a lot for the code sample, I used it to incorporate this functionality into an Angular2 application (https://github.com/IAMtheIAM/angular2-webpack2-dotnet-starter) and it works perfectly, using Ng2-Map directives (https://github.com/ng2-ui/map) – TetraDev Mar 30 '17 at 15:55
  • any chance to get user inside which square ? using mysql query i have many restaurants predefined delivery area – Kodr.F Jan 21 '18 at 09:18
  • Is it a cause for concern that there is a warning "This page can't load Google Maps correctly."? It seems to work fine. – zabop Jan 30 '22 at 10:46
13

here you have the example above using API V3

http://nettique.free.fr/gmap/toolbar.html

Royce
  • 192
  • 3
  • 5
    nice example, but how can we get the code that generates it? – marimaf May 16 '12 at 03:17
  • Apparently, the code is in [lib/mapToolbar.js](http://nettique.free.fr/gmap/lib/mapToolbar.js), but also, seems to be broken now: if I place a marker, I get "placemark_1 (NaN, NaN)" – sdaau Jul 01 '15 at 01:36
  • It is always a good practice to copy something helpful from the link and then place a reference. Now, the maps on the link are not working correctly. – Jamshaid K. Jan 02 '20 at 05:39
4

Since Google updates sometimes the name of fixed object properties, the best practice is to use GMaps V3 methods to get coordinates event.overlay.getPath().getArray() and to get lat latlng.lat() and lng latlng.lng().

So, I just wanted to improve this answer a bit exemplifying with polygon and POSTGIS insert case scenario:

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
    var str_input ='POLYGON((';
    if (event.type == google.maps.drawing.OverlayType.POLYGON) {
      console.log('polygon path array', event.overlay.getPath().getArray());
      $.each(event.overlay.getPath().getArray(), function(key, latlng){
        var lat = latlng.lat();
        var lon = latlng.lng();
        console.log(lat, lon); 
        str_input += lat +' '+ lon +',';
      });
    }
    str_input = str_input.substr(0,str_input.length-1) + '))';
    console.log('the str_input will be:', str_input);

    // YOU CAN THEN USE THE str_inputs AS IN THIS EXAMPLE OF POSTGIS POLYGON INSERT
    // INSERT INTO your_table (the_geom, name) VALUES (ST_GeomFromText(str_input, 4326), 'Test')

  });
chuycepeda
  • 334
  • 2
  • 6
3

to accomplish what you want, you must getPaths from the polygon. Paths will be an array of LatLng points. you get the elements of the array and split the LatLng pairs with the methods .lat and .lng in the function below, i have a redundant array corresponding to a polyline that marks the perimeter around the polygon.

saving is another story. you can then opt for many methods. you may save your list of points as a csv formatted string and export that to a file (easiest solution, by far). i highly recommend GPS TXT formats, like the ones (there are 2) readable by GPS TRACKMAKER (great free version software). if you are competent to save them to a database, that is a great solution (i do both, for redundancy).

function areaPerimeterParse(areaPerimeterPath) {
    var flag1stLoop = true;
    var areaPerimeterPathArray = areaPerimeterPath.getPath();
    var markerListParsedTXT = "Datum,WGS84,WGS84,0,0,0,0,0\r\n";

    var counter01 = 0;
    var jSpy = "";
    for (var j = 0;j<areaPerimeterPathArray.length;j++) {
        counter01++;
        jSpy += j+"  ";
        if (flag1stLoop) {
            markerListParsedTXT += 'TP,D,'+[ areaPerimeterPathArray.getAt(j).lat(), areaPerimeterPathArray.getAt(j).lng()].join(',')+',00/00/00,00:00:00,1'+'\r\n';
            flag1stLoop = false;
        } else {
            markerListParsedTXT += 'TP,D,'+[ areaPerimeterPathArray.getAt(j).lat(), areaPerimeterPathArray.getAt(j).lng()].join(',')+',00/00/00,00:00:00,0'+'\r\n';
        }

    }
    // last point repeats first point
    markerListParsedTXT += 'TP,D,'+[ areaPerimeterPathArray.getAt(0).lat(), areaPerimeterPathArray.getAt(0).lng()].join(',')+',00/00/00,00:00:00,0'+'\r\n';
    return markerListParsedTXT;
}

attention, the line that ends with ",1" (as opposed to ",0") starts a new polygon (this format allows you to save multiple polygons in the same file). i find TXT more human readable than the XML based formats GPX and KML.

tony gil
  • 9,424
  • 6
  • 76
  • 100
2

The other answers show you to create the polygons, but not how to get the coordinates...

I'm not sure the best way to do it, but heres one way.. It seems like there should be a method to get the paths from the polygon, but I can't find one, and getPath() doesn't seem to work for me. So here's a manual approach that worked for me..

Once you've finished drawing your polygon, and pass in your polygon to the overlay complete function, you can find the coordinates in the polygon.overlay.latLngs.b[0].b

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(polygon) {
        $.each(polygon.overlay.latLngs.b[0].b, function(key, latlng){
            var lat = latlng.d;
            var lon = latlng.e;
            console.log(lat, lon); //do something with the coordinates
        });
});

note, i'm using jquery to loop over the list of coordinates, but you can do loop however.

Gisheri
  • 1,645
  • 2
  • 18
  • 27
1

Adding to Gisheri's answer

Following code worked for me

 var drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: google.maps.drawing.OverlayType.MARKER,
    drawingControl: true,
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_CENTER,
      drawingModes: [
        google.maps.drawing.OverlayType.POLYGON
      ]
    },
    markerOptions: {
      icon: 'images/beachflag.png'
    },
    circleOptions: {
      fillColor: '#ffff00',
      fillOpacity: 1,
      strokeWeight: 5,
      clickable: false,
      editable: true,
      zIndex: 1
    }

  });

  google.maps.event.addListener(drawingManager, 'overlaycomplete', function(polygon) {
      //console.log(polygon.overlay.latLngs.j[0].j);return false;
        $.each(polygon.overlay.latLngs.j[0].j, function(key, LatLongsObject){
            var LatLongs    =   LatLongsObject;

            var lat = LatLongs.k;
            var lon = LatLongs.B;
           console.log("Lat is: "+lat+" Long is: "+lon); //do something with the coordinates

        });
Irfan Younus
  • 174
  • 2
  • 6
0

Cleaned up what chuycepeda has and put it into a textarea to send back in a form.

google.maps.event.addListener(drawingManager, 'overlaycomplete', function (event) {
    var str_input = '{';
    if (event.type == google.maps.drawing.OverlayType.POLYGON) {
        $.each(event.overlay.getPath().getArray(), function (key, latlng) {
            var lat = latlng.lat();
            var lon = latlng.lng();
            str_input += lat + ', ' + lon + ',';
        });
    }
    str_input = str_input.substr(0, str_input.length - 1) + '}';

    $('textarea#Geofence').val(str_input);
});
WebLuke
  • 156
  • 1
  • 5
0

try this

In your controller use

> $scope.onMapOverlayCompleted = onMapOverlayCompleted;
> 
>  function onMapOverlayCompleted(e) {
> 
>                 e.overlay.getPath().getArray().forEach(function (position) {
>                     console.log('lat', position.lat());
>                     console.log('lng', position.lng());
>                 });
> 
>  }

**In Your html page , include drawning manaer** 


    <ng-map id="geofence-map" zoom="8" center="current" default-style="true" class="map-layout map-area"
                        tilt="45"
                        heading="90">

                    <drawing-manager
                            on-overlaycomplete="onMapOverlayCompleted()"
                            drawing-control-options="{position: 'TOP_CENTER',drawingModes:['polygon','circle']}"
                            drawingControl="true"
                            drawingMode="null"
                            markerOptions="{icon:'www.example.com/icon'}"
                            rectangleOptions="{fillColor:'#B43115'}"
                            circleOptions="{fillColor: '#F05635',fillOpacity: 0.50,strokeWeight: 5,clickable: false,zIndex: 1,editable: true}">
                    </drawing-manager>
    </ng-map>
Om Prakash Sharma
  • 1,682
  • 22
  • 13