polygon inner rings/exclusions/islands

1,573 views
Skip to first unread message

arclyte

unread,
Nov 17, 2009, 3:53:02 PM11/17/09
to Google Maps JavaScript API v3
I've been working on a polygon drawing app and I've gotten the basics
of it down, but now I've gotten myself all mixed up trying to support
polygon exclusions. I swear that I got a proof of concept working at
one point, but now I can't seem to figure out the proper syntax.

I've put up an example of what I'm working on at:

http://arclyte.netdojo.com/geo/edit_poly.php

Some of the functionality is missing or doesn't work in this example,
but it should at least give you an idea of what I'm talking about.
The blue polygon in this example is for zip code 10022. It has a
square exclusion in it that I'm currently loading as a separate
polygon.

Here's the trick... When you click on the colored squares at the
bottom of the page next to the polygon name, it should load the
markers for that particular polygon's points so that you can edit it.
So, I have to have a separate array of those points (I believe)
outside of the polygon description that separates the polygon proper
from its exclusions so I can edit either. But I also want the polygon
to load with those exclusions included into the polygon so that they
will load as a proper "hole".

And the next rabbit I'm trying to pull out of my hat is to actually
inject new "holes" into an already defined polygon so that an
exclusion can be added to it. Any assistance you can give in this
regard would be greatly appreciated. Just a few hints on the
formatting of such a thing would help me out a lot.

I've tried doing something like this, with no luck (untested example
only):

points[0][0] = [[lat1, lng1]...[latn, lngn]];
points[0][1] = [[lat1, lng1]...[latn, lngn]];
path[0] = new google.maps.MVCArray([points[0]]);
poly = new google.maps.Polygon();
poly.setPaths(new google.maps.MVCArray([path[0]]));

That gives me an invalid constructor parameter error, saying path[0]
is an object...

Ben Appleton

unread,
Nov 17, 2009, 6:50:12 PM11/17/09
to google-map...@googlegroups.com
You'll need to convert your [lat1, lng1] pairs to a LatLng.

Example: polygon with hole
(http://gmaps-samples-v3.googlecode.com/svn/trunk/poly/pentagon.html)
var paths = [[
new google.maps.LatLng(38.872886, -77.054720),
new google.maps.LatLng(38.872602, -77.058046),
...
], [
new google.maps.LatLng(38.871684, -77.056780),
new google.maps.LatLng(38.871867, -77.055449),
...
]];

var poly = new google.maps.Polygon({
paths: paths,
strokeWeight: 3,
fillColor: '#55FF55',
fillOpacity: 0.5
});

poly.setMap(map);

To edit the polygon you simply edit the paths array, like:

poly.getPaths().removeAt(1) // Remove the hole

Or insert a new hole:

poly.getPaths().insertAt(1, new MVCArray([ ... some LatLngs ... ]))
> --
>
> 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=.
>
>
>

arclyte

unread,
Nov 18, 2009, 2:17:20 PM11/18/09
to Google Maps JavaScript API v3
Thanks Ben,

I was looking for just that example but couldn't seem to dig it up.
I've cleaned up the code a bit, but I've kept the convention of having
my path and poly variables as arrays so that I can display multiple
polygons at the same time, each having a different stroke/fill color:

path[0] = [[new google.maps.LatLng(38.872886, -77.054720),
new google.maps.LatLng(38.872602, -77.058046),
...]
];

poly[0] = new google.maps.Polygon({
paths: path[0],
fillColor: mapcolor[0]
});

Now I just have to modify the rest of the code to accept this
format... So I'm sure you haven't heard the last of me yet!

- Jim


On Nov 17, 6:50 pm, Ben Appleton <apple...@google.com> wrote:
> You'll need to convert your [lat1, lng1] pairs to a LatLng.
>
> Example: polygon with hole
> (http://gmaps-samples-v3.googlecode.com/svn/trunk/poly/pentagon.html)
>   var paths = [[
>     new google.maps.LatLng(38.872886, -77.054720),
>     new google.maps.LatLng(38.872602, -77.058046),
>     ...
>   ], [
>     new google.maps.LatLng(38.871684, -77.056780),
>     new google.maps.LatLng(38.871867, -77.055449),
>     ...
>   ]];
>
>   var poly = new google.maps.Polygon({
>     paths: paths,
>     strokeWeight: 3,
>     fillColor: '#55FF55',
>     fillOpacity: 0.5
>   });
>
>   poly.setMap(map);
>
> To edit the polygon you simply edit the paths array, like:
>
>   poly.getPaths().removeAt(1)  // Remove the hole
>
> Or insert a new hole:
>
>   poly.getPaths().insertAt(1, new MVCArray([ ... some LatLngs ... ]))
>

Richard Quadling

unread,
May 11, 2011, 11:28:19 AM5/11/11
to google-map...@googlegroups.com
The solution is to use 2 paths, but you have to plot the second path (the inner boundary so to speak) in the opposite direction to the first path.

If you imagine the fill is on the right hand side of the line as it is drawn, drawing clockwise creates a small filled area.

For the inner boundary, you have to draw it the counter clockwise to get the same effect.

Unfortunately, I can see no way of tagging the boundaries so that you know which path is the outer boundary and the inner boundary.

That would be extremely useful when used to build an SQL query using WTK. In WTK, a POLYGON can have 2 paths. An outer and an optional inner. If you want multiple polygons, then you can use a MULTIPOLYGON. See http://en.wikipedia.org/wiki/Well-known_text#Geometric_objects

If you take the example that was provided (the Pentagon one) and edit the second path from ...

  var paths = [[
    new google.maps.LatLng(38.872886, -77.054720),
    new google.maps.LatLng(38.872602, -77.058046),
    new google.maps.LatLng(38.870080, -77.058604),
    new google.maps.LatLng(38.868894, -77.055664),
    new google.maps.LatLng(38.870598, -77.053346)
  ], [
    new google.maps.LatLng(38.871684, -77.056780),
    new google.maps.LatLng(38.871867, -77.055449),
    new google.maps.LatLng(38.870915, -77.054891),
    new google.maps.LatLng(38.870113, -77.055836),
    new google.maps.LatLng(38.870581, -77.057037)
  ]];

to

  var paths = [[
    new google.maps.LatLng(38.872886, -77.054720),
    new google.maps.LatLng(38.872602, -77.058046),
    new google.maps.LatLng(38.870080, -77.058604),
    new google.maps.LatLng(38.868894, -77.055664),
    new google.maps.LatLng(38.870598, -77.053346)
  ], [
    new google.maps.LatLng(38.870581, -77.057037),
    new google.maps.LatLng(38.871684, -77.056780),
    new google.maps.LatLng(38.871867, -77.055449),
    new google.maps.LatLng(38.870915, -77.054891),
    new google.maps.LatLng(38.870113, -77.055836)
  ]];

(The second path is in reverse order to what it should be), you'll see that you end up with 2 filled polygons, one inside the other, but the inner polygon is not acting as an exclusion, just a normal polygon.


Reply all
Reply to author
Forward
0 new messages