How the ST_POINTONSURFACE() function works in Mariadb?

The ST_POINTONSURFACE() function is a powerful tool for obtaining a point that lies on the surface of a given geometry, whether it’s a polygon or a linestring.

Posted on

When working with spatial data, sometimes you need a reliable way to get a point that’s guaranteed to lie inside a polygon or on a linestring. That’s exactly what ST_POINTONSURFACE() does—it provides a point that is always “on” the given geometry, whether it’s a polygon, linestring, or other spatial shape.

Unlike functions that return vertices or centroids, ST_POINTONSURFACE() ensures the point is interior (for polygons) or on the line (for linestrings), making it extremely useful for spatial queries that require a representative point within a shape.

The Core Idea Behind ST_POINTONSURFACE()

The function’s name gives a hint—it returns a point that lies on the “surface” of the geometry. For polygons, this means the point is inside (not just on the boundary). For linestrings, it means the point is somewhere along the line.

Why is this useful? Imagine:

  • You need to place a label inside a country’s borders on a map.
  • You want to check if a point is within a complex polygon without calculating centroids.
  • You need a guaranteed point on a road (linestring) for routing applications.

This is where ST_POINTONSURFACE() shines.

Using ST_POINTONSURFACE() with Polygons

Let’s start with a simple polygon—a rectangle:

SET @rectangle = ST_GEOMFROMTEXT('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))');
SELECT ST_ASTEXT(ST_POINTONSURFACE(@rectangle)) AS point_on_surface;

This might return something like POINT(5 5) (the centroid), but it could also return another interior point. The key guarantee is that the point is inside the polygon.

Now, a more complex polygon with a hole:

SET @donut = ST_GEOMFROMTEXT('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 8 2, 8 8, 2 8, 2 2))');
SELECT ST_ASTEXT(ST_POINTONSURFACE(@donut)) AS point_in_donut;

This will return a point inside the outer ring but outside the inner hole—perhaps POINT(1 1) or POINT(9 9).

Applying ST_POINTONSURFACE() to Linestrings

For linestrings, the function returns a point that lies somewhere on the line. Unlike ST_STARTPOINT() or ST_ENDPOINT(), it doesn’t have to be a vertex—just somewhere along the path.

SET @road = ST_GEOMFROMTEXT('LINESTRING(0 0, 2 3, 5 4, 10 10)');
SELECT ST_ASTEXT(ST_POINTONSURFACE(@road)) AS point_on_road;

This could return POINT(2 3) (a vertex) or an interpolated point like POINT(3.5 3.5).

Handling Edge Cases

What if the geometry is a single point?

SET @point = ST_GEOMFROMTEXT('POINT(5 5)');
SELECT ST_ASTEXT(ST_POINTONSURFACE(@point)) AS result;

It simply returns the same point (POINT(5 5)).

What about an empty geometry?

SET @empty = ST_GEOMFROMTEXT('GEOMETRYCOLLECTION EMPTY');
SELECT ST_POINTONSURFACE(@empty) AS result;

This returns NULL, as expected.

Practical Use Cases

1. Finding a Representative Point for a Region

Suppose you have a table of countries:

CREATE TABLE countries (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    border POLYGON
);

You can get a point inside each country for labeling:

SELECT name, ST_POINTONSURFACE(border) AS label_point
FROM countries;

2. Checking If a Point Is Inside a Complex Shape

Instead of calculating centroids (which might fall outside for odd-shaped polygons), you can use:

SELECT ST_CONTAINS(
    @complex_shape,
    ST_POINTONSURFACE(@complex_shape)
) AS is_point_inside;  -- Always returns 1 (true)

3. Snap a Point to the Nearest Road

If you have a GPS coordinate slightly off a road, you can find the nearest road point:

SELECT ST_POINTONSURFACE(@road) AS snapped_point
FROM roads
ORDER BY ST_DISTANCE(@gps_point, @road)
LIMIT 1;

Wrapping Up ST_POINTONSURFACE()

The ST_POINTONSURFACE() function is a powerful tool for spatial analysis when you need a guaranteed point on a geometry. Unlike centroids or vertices, it always provides a valid interior point for polygons or a point along linestrings.

Key takeaways:

  • Works reliably with polygons, linestrings, and points.
  • Returns NULL for empty geometries.
  • Useful for label placement, spatial queries, and snapping points to geometries.

If you need a safe, representative point inside a shape—without worrying about edge cases—ST_POINTONSURFACE() is the function to use.