Description
This is commonly needed in Geographic Information Systems (GIS), there may be other uses too.
Briefly mentioned this to @pzwang and @bryevdv and it was thought to be a good idea.
It's worth noting the GeoJSON spec for this exact problem:
Polygon
http://geojson.org/geojson-spec.html#id4
Coordinates of a Polygon are an array of LinearRing coordinate arrays. The first element in the array represents the exterior ring. Any subsequent elements represent interior rings (or holes).
No holes:
{ "type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
]
}
With holes:
{ "type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
]
}
MultiPolygon
http://geojson.org/geojson-spec.html#id7
Coordinates of a MultiPolygon are an array of Polygon coordinate arrays:
{ "type": "MultiPolygon",
"coordinates": [
[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
]
}
I'd be delighted to try and implement, but need some direction in terms of implementation.
Some thoughts:
I had initially imagined modifying Patch. However, Patch currently supports MultiPolygon's by separating the list of xs or ys with a NaN (https://github.com/bokeh/bokeh/blob/master/bokeh/models/glyphs.py#L604). If we were trying to follow the GeoJSON logic, and maintain easy backward compatibility if seems like we'd need some other type of separator to signify when it was an inner ring, and then the NaN would signify the start of a new Patch.....this feels like it's getting unwieldy.
Another thing to consider is whether GIS is a special case, and it would be more appropriate to accept a list of [lon, lat] coordinates instead of splitting out xs and ys. This would take us away from the ggplot style geom_polygon and much more towards geojson. (Sidenote: the geojson spec allows for a height as well (x, y, z))
Finally, this article http://journal.r-project.org/archive/2012-2/RJournal_2012-2_Murrell2.pdf seems like it might be relevant - it discusses two different types of "holes."
My straw man offer of an implementation is:
- implement Patch/Patches to accept a new separator to signify a hole
- implement GeoPolygon & GeoMultiPolygon Glyphs which accept input that looks much more like GeoJSON but use Patch/Patches under the hood. (This could pave the way for implementing the other the GeoJSON types Point/MultiPoint and Line/MultiLine)