Search code examples
c++geometryopenstreetmapgeos

Find geometry's interior point closest to its centroid


I'm extracting the names of bodies of water from the OpenStreetMap database and getting their label long/lat based on the centroid of their geometry using the Geos library:

geos::geom::Geometry* geometry = BuildInternalGeometry();
geos::geom::Coordinate centroidCoord;

bool result = geometry->getCentroid(centroidCoord);

However, several of the water bodies have irregular shapes that result in the centroid's location falling far outside of the water polygon, making it look out of place when viewed on a map. Is there a procedure I could use to find the interior point of a geometry that falls closest to its centroid?

I've found the Geos library's getInteriorPoint method, but from what I can tell if returns a random point guaranteed to be within the geometry but not necessarily near the centroid.


Solution

  • While Jeffrey's answer didn't quite answer the question (the Geos library does not appear to support polygon sections), it did give me an idea, well... 2 ideas for how to locate an interior point close to a polygon's centroid.

    The first idea (the easier, less accurate one) involves iterating over the geometry's vertices and using the vertex that is closest to the external centroid as the new centroid:

    auto coords = geometry->getCoordinates();
                        
    for (auto i = 0; i < coords.get()->getSize(); i++)
    {
        double dist = coords.get()->getAt(i).distance(coordPoint);
    
        if (dist < nearest)
        {
            nearest = dist;
            closestCoord = coords.get()->getAt(i);
        }
    }
    
    return closestCoord;
    

    However, the new centroid coordinate will always lie on the edge of the polygon, and not inside of it.

    In order to get something that lies within the geometry, the delaunay triangulation class that comes with Geos can be used to generate internal triangle polygons. The centroids of these resulting polygons can be queried and the triangle centroid that is closest to the external centroid can be used as the centroid point that lies within the geometry.