Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polygon intersection and containment #193

Open
atombender opened this issue Mar 15, 2021 · 4 comments
Open

Polygon intersection and containment #193

atombender opened this issue Mar 15, 2021 · 4 comments

Comments

@atombender
Copy link

I'm looking for a way to use this library to check, using Cartesian coordinates:

  • If two polygons intersect
  • if a polygon fully contains another polygon

I'm not seeing any exported functions for doing this. Is there any support for it, or should I look somewhere else?

From what I can tell, checking if a point is contained in a polygon can be accomplished this way:

func PolygonContainsPoint(polygon *geom.Polygon, p *geom.Point) bool {
	exterior := polygon.LinearRing(0)
	if !xy.IsPointInRing(geom.XY, p.Coords(), exterior.FlatCoords()) {
		return false
	}

	// Next rings are holes
	num := polygon.NumLinearRings()
	for i := 1; i < num; i++ {
		interior := polygon.LinearRing(i)
		if xy.IsPointInRing(geom.XY, p.Coords(), interior.FlatCoords()) {
			return false
		}
	}

	return true
}

Or? I'm not too familiar with rings or if this is how they're intended to be used. Either way, such a function would be a useful addition to this library, I think.

@twpayne
Copy link
Owner

twpayne commented Mar 16, 2021

Thank you @atombender for opening this issue :)

This library effectively contains three parts: a Go-friendly representation for geometry types, a set of packages to serialize and deserialize those types, and packages (like xy) that perform operations on geometries. The first two are solid, fast, and widely used. The third part, the xy package, is a contributed port of code from the Java Topology Suite. Sadly the xy package has not seen much love in the last few years.

The fix depends on your requirements:

  • If you're looking for a robust available-now implementation of polygon intersection and polygon-contains-polygon then I would recommend using cgo to bind to either of the excellent GEOS or CGAL libraries. The code in these libraries is battle-hardened but the cgo overhead can be significant. go-geom can help you translate geometries into a format (hint: WKB) that these libraries can consume.

  • If you want a pure Go implementation of these algorithms, then I would be very happy to guide you in contributing a PR to go-geom.

@atombender
Copy link
Author

Thanks for responding! After I wrote the comment, I went hunting for bindings to either GEOS or GDAL, and I ended up on this decent maintained fork of an old, abandoned set of bindings to GEOS, which seems like an absolutely solid library.

Your support for WKT/WKB was a life-saver. So now I read GeoSON into go-geom, then convert to GEOS to perform operations like the ones I need. Having to go through WKB is not optimal, but fortunately this is not on a fast path, and it looks like it would be feasible to write a translator if we should need more speed. My only complaint with this solution is the fact that the GEOS library is now a build dependency.

Geometry/geography libs for Go are lacking. I poked through so many pure Go libraries that provide a lot of trivial functionality (such as reading and writing GeoJSON), but fall short when it comes to the actual hard stuff. If you ever feel like sitting down and making the xy package more complete, that would be very cool indeed.

@thomascoquet
Copy link

@twpayne
Copy link
Owner

twpayne commented Sep 14, 2023

Or better, go-geos now provides this functionality in Go using the battle-tested GEOS library. Note that GDAL is for data formats and GEOS is for geometric operations like polygon intersection and containment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants