[Google Maps API v3] Polygon contains LatLng

2,525 views
Skip to first unread message

Charles

unread,
Apr 20, 2010, 7:11:35 PM4/20/10
to Google Maps JavaScript API v3
Hi, I want to know if it's possible in v3 to know if a polygon
contains a certain coordinate.

I have polygons representing the districts of a city and users enter
their address (which I reverse geocode to get the latlng of where they
live) to know in which district they are. I have no problem with
drawing polygons or getting the coordinates, the only thing missing is
getting to know of the coordinate is in a certain polygon.

I know that in v2 there was a GPolygon.contains method but it seems it
is not in v3. I've searched a lot today and all I found were tutorials
for binding clicks... this is not what I want.

Thanks

--
You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group.
To post to this group, send email to google-map...@googlegroups.com.
To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.

Björn Brala

unread,
Apr 21, 2010, 10:21:13 AM4/21/10
to google-map...@googlegroups.com
You should sjust the Contains function to v3.

The things you need to change is getVertextCount() to (getPath().length im guessing)

And perhaps some of the other methods, but the base should be the same.


/**
*   @desc Check if polygon contains point.
*   @return boolean
**/   
GPolygon.prototype.Contains = function(point) {
    var j=0;
    var oddNodes = false;
    var x = point.lng();
    var y = point.lat();
    for (var i=0; i < this.getVertexCount(); i++) {
      j++;
      if (j == this.getVertexCount()) {j = 0;}
      if (((this.getVertex(i).lat() < y) && (this.getVertex(j).lat() >= y))
      || ((this.getVertex(j).lat() < y) && (this.getVertex(i).lat() >= y))) {
        if ( this.getVertex(i).lng() + (y - this.getVertex(i).lat())
        /  (this.getVertex(j).lat()-this.getVertex(i).lat())
        *  (this.getVertex(j).lng() - this.getVertex(i).lng())<x ) {
          oddNodes = !oddNodes;
        }
      }
    }
    return oddNodes;
};


2010/4/21 Charles <charles...@gmail.com>



--
Bjorn Brala
----------------
www.GeoStart.nl/english/ - Google maps - Swis Webdesign
www.twitter.com/bbrala

Björn Brala

unread,
Apr 21, 2010, 10:23:16 AM4/21/10
to google-map...@googlegroups.com
The group will prabably make the code unreadable. Here's a link:

http://www.geostart.nl/GPolygon.contains.js

2010/4/21 Björn Brala <bbr...@gmail.com>

Martin Revert

unread,
Apr 23, 2010, 9:01:22 AM4/23/10
to Google Maps JavaScript API v3
There's an issue reported about this, but it is in Need More Info
status since february 2010.
It would be nice to have a Polygon.isLatLngInside
Circle.isLatLngInside and Rectangle.isLatLngInside methods in the API
from scratch.

For circles I guess that is more easy and less CPU consuming to
estimate the difference between the total distance of the center and
the point (using Havershine's formula) and the total radius. For
irregular polygons, I think Björn's suggestion is the way to go but if
need use that for many polygons yo could expect severe time delays
when that prototype is invoked.
> > 2010/4/21 Charles <charles.deme...@gmail.com>
>
> > Hi, I want to know if it's possible in v3 to know if a polygon
> >> contains a certain coordinate.
>
> >> I have polygons representing the districts of a city and users enter
> >> their address (which I reverse geocode to get the latlng of where they
> >> live) to know in which district they are.  I have no problem with
> >> drawing polygons or getting the coordinates, the only thing missing is
> >> getting to know of the coordinate is in a certain polygon.
>
> >> I know that in v2 there was a GPolygon.contains method but it seems it
> >> is not in v3. I've searched a lot today and all I found were tutorials
> >> for binding clicks... this is not what I want.
>
> >> Thanks
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Google Maps JavaScript API v3" group.
> >> To post to this group, send email to
> >> google-map...@googlegroups.com.
> >> To unsubscribe from this group, send email to
> >> google-maps-js-a...@googlegroups.com<google-maps-js-api-v3%2Bunsu...@googlegroups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/google-maps-js-api-v3?hl=en.
>
> > --
> > Bjorn Brala
> > ----------------
> >www.GeoStart.nl/english/- Google maps - Swis Webdesign
> >www.twitter.com/bbrala
>
> --
> Bjorn Brala
> ----------------www.GeoStart.nl/english/- Google maps - Swis Webdesignwww.twitter.com/bbrala
>

Björn Brala

unread,
Apr 23, 2010, 9:19:22 AM4/23/10
to google-map...@googlegroups.com
You can speeden up the process a lot if you need to do large comparisions. I keep an array of bounds and only do Contains on polygons from which the bounds are inside. You can also just put that in the method itself

v2 syntax:


/**
*   @desc Check if polygon contains point.
*   @return boolean
**/   
GPolygon.prototype.Contains = function(point) {
    if(!this.getBounds().contains(point)){
        return false;

    }

    var j=0;
    var oddNodes = false;
    var x = point.lng();
    var y = point.lat();
    for (var i=0; i < this.getVertexCount(); i++) {
      j++;
      if (j == this.getVertexCount()) {j = 0;}
      if (((this.getVertex(i).lat() < y) && (this.getVertex(j).lat() >= y))
      || ((this.getVertex(j).lat() < y) && (this.getVertex(i).lat() >= y))) {
        if ( this.getVertex(i).lng() + (y - this.getVertex(i).lat())
        /  (this.getVertex(j).lat()-this.
getVertex(i).lat())
        *  (this.getVertex(j).lng() - this.getVertex(i).lng())<x ) {
          oddNodes = !oddNodes;
        }
      }
    }
    return oddNodes;
};


Comparing to bounds is a maximum of eh, maybe 4 operations so a LOT faster, this would make it a lot faster.

2010/4/23 Martin Revert <martin...@gmail.com>



--
Bjorn Brala
----------------
www.GeoStart.nl/english/ - Google maps - Swis Webdesign
www.twitter.com/bbrala

--

Björn Brala

unread,
Jul 7, 2010, 3:36:07 AM7/7/10
to google-map...@googlegroups.com
Cool, the updated code for v2 by Ucha :)

Here goes updated code for V3

functional - type
you can also implement it via prototype...


 var Contains = function(obj, point) {

   var j=0;
   var oddNodes = false;
   var x = point.lng();
   var y = point.lat();
   for (var i=0; i < obj.getPath().getLength(); i++) {
     j++;
     if (j == obj.getPath().getLength()) {j = 0;}
     if (((obj.getPath().getAt(i).lat(
) < y) &&
(obj.getPath().getAt(j).lat() >= y))
     || ((obj.getPath().getAt(j).lat() < y) &&
(obj.getPath().getAt(i).lat() >= y))) {
       if ( obj.getPath().getAt(i).lng() + (y -
obj.getPath().getAt(i).lat())
       /  (obj.getPath().getAt(j).lat()-obj.getPath().getAt(i).lat())
       *  (obj.getPath().getAt(j).lng() -
obj.getPath().getAt(i).lng())<x ) {

         oddNodes = !oddNodes;
       }
     }
   }
   return oddNodes;
 };


Best


2010/4/23 Björn Brala <bbr...@gmail.com>

Nianwei Liu

unread,
Jul 7, 2010, 6:10:58 AM7/7/10
to Google Maps JavaScript API v3
bjorn,
v3 polygon now supports multiple rings(donut holes etc). the code
ported straight from v2 needs adjustment.
> > 2010/4/23 Martin Revert <martinrev...@gmail.com>
> >> > >> google-maps-js-a...@googlegroups.com<google-maps-js-api-v3%2B unsub...@googlegroups.com>
> >> <google-maps-js-api-v3%2Bunsu...@googlegroups.com<google-maps-js-api-v3 %252Buns...@googlegroups.com>
>
> >> > >> .
> >> > >> For more options, visit this group at
> >> > >>http://groups.google.com/group/google-maps-js-api-v3?hl=en.
>
> >> > > --
> >> > > Bjorn Brala
> >> > > ----------------
> >> > >www.GeoStart.nl/english/-Google maps - Swis Webdesign
> >> > >www.twitter.com/bbrala
>
> >> > --
> >> > Bjorn Brala
> >> > ----------------www.GeoStart.nl/english/-Google maps - Swis
> >> Webdesignwww.twitter.com/bbrala
>
> >> > --
> >> > You received this message because you are subscribed to the Google
> >> Groups "Google Maps JavaScript API v3" group.
> >> > To post to this group, send email to
> >> google-map...@googlegroups.com.
> >> > To unsubscribe from this group, send email to
> >> google-maps-js-a...@googlegroups.com<google-maps-js-api-v3%2B unsub...@googlegroups.com>
> >> .
> >> > For more options, visit this group athttp://
> >> groups.google.com/group/google-maps-js-api-v3?hl=en.
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Google Maps JavaScript API v3" group.
> >> To post to this group, send email to
> >> google-map...@googlegroups.com.
> >> To unsubscribe from this group, send email to
> >> google-maps-js-a...@googlegroups.com<google-maps-js-api-v3%2B unsub...@googlegroups.com>

Björn Brala

unread,
Jul 7, 2010, 6:51:49 AM7/7/10
to google-map...@googlegroups.com
Thats a good point actually, he sent me the mail directly so i thought i'd put the code up to the group. I haven't really gotten into v3 yet, so dont even know the syntax for donut holes.

2010/7/7 Nianwei Liu <nia...@gmail.com>
To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.




--
Bjorn Brala
----------------
www.GeoStart.nl/english/ - Google maps - Swis Webdesign
www.twitter.com/bbrala

Ucha Dzodzuashvili

unread,
Jul 7, 2010, 5:51:17 PM7/7/10
to Google Maps JavaScript API v3
Bjorn

sorry for direct mail... it's my first time with groups...

Clicked something wrong... :)

About donuts - Reverse "!" Condition checking for "donut" paths, would
actually do the job. easy thow... too lazy to post donut-ing code...

I am also damn new not only to v3, but programming in general :D

Ucha
Reply all
Reply to author
Forward
0 new messages