# Finding maximum distance point can be from polygon using PostGIS?

I have a hydrography dataset containing navigable waterways: ponds, lakes, rivers, and streams. I need to find the maximum distance ANY location within the state can be from a navigable waterway. I'm familiar with the st_geometry predicates but I'm not sure how to attack this problem.

I do not have a table of predefined point geometries. The ANY location is the set of X,Y real numbers contained within the state.

I have a collection of polygons and lines, all contained within a much larger region (another polygon) and need to find the X,Y of the most remote point and the distance from it to the nearest waterway.

How do I proceed with figuring out the maximum distance any point can lie from any navigable waterway?

The dataset is large and the geographic area covers an entire state. I don't expect an instant answer and this will not be part of an on-the-fly solution. For development purposes, I have a subset of the dataset covering only a few hundred acres with limited hydrographic features

Postgres 9.6.1 / PostGIS 2.3.1

• This sentence is really confusing: "I have a collection of polygons and lines, all contained within a much larger region (another polygon) and need to find the X,Y of the most remote point and the distance from it to the nearest waterway." To clarify: Are you wanting like a raster of your entire state? Can you provide a sample column structure of your desired output? Dec 16, 2016 at 15:16

PostGIS doesn't have any capabilities to provide an exact solution to this this problem, which I've seen described as the obnoxious facility location problem. There's a whole literature devoted to this sort of problem from which you might draw some ideas, though I'd suspect (I don't know) that most work is based on maximizing distance to a set of points, rather than a set of lines and polygons.

If you don't need an exact solution (and I'm not sure one is possible), here's one possible approach:

1. Divide your problem boundary using `ST_Subdivide`, and use the resulting cells to partition your hydrologic network, so that each hydrologic feature is associated with only one cell. This will reduce the cost of overlay operations in subsequent steps.
2. Generate one or more test point(s) in each cell (`ST_GeneratePoints` is an option)
3. In each cell, find the maxmin distance from these the test points to the hydrologic network
4. Buffer the network in all cells by the maximum value obtained in #3, and subtract this area from the cell (`ST_Difference`)
5. Iterate

Note that after #1, all of this can run in parallel.

• I wish I could give +2 for "obnoxious facility location problem". That really made my day :D Dec 16, 2016 at 8:31
• How about making this iteration: buffer the whole line and polygon layers, merge the buffered features and take ST_Difference(survey_area,merged_buffers). When the result gets zero the maximum distance is found. For finding the place decrease the buffer and find the centroid of the polygon that comes from ST_Difference. Dec 19, 2016 at 8:18
• @user30184 I think that would work and is simpler, I'm making the (perhaps premature) optimization to avoid running overlay operations (union, difference) on an entire state's worth of data. Dec 19, 2016 at 13:08

You could try `ST_MaxDistance()`.

From the docs, this function:

Returns the 2-dimensional largest distance between two geometries in projected units.

So to query a whole table of navigable waterways, you'd want something like:

``````SELECT ptid, MAX(maxdist) FROM (
SELECT ptid, ST_MaxDistance(p.geom, l.geom) AS maxdist
FROM points p, waterways l) t1
GROUP BY ptid
``````
• This would give the distance from a point to the farthest-away waterway, no? I believe the poster is asking about the point which is at a maximum distance from the nearest waterway. Dec 16, 2016 at 14:22
• I understood that the distance from a point to the furthest-away waterway was what the poster wanted. They ask for " the maximum distance any point can lie from any navigable waterway." But if @dbaston's interpretation, is right, just replace `MAX(maxdist)` with `MIN(maxdist)`. Dec 16, 2016 at 17:45
• In that case it would return the point that is closest to the farthest body of water, not the point that is farthest from the closest body of water. Dec 19, 2016 at 13:10

I will propose an alternate query form using the `DISTINCT ON` clause, which will ensure one row for every `(p.id)` selecting the waterway with the greatest max distance.

``````SELECT DISTINCT ON (ptid) p.id as point_id, w.id AS waterway_id, ST_MaxDistance(p.geom, w.geom) as max_distance
FROM points p, waterways w
ORDER BY ptid, ST_MaxDistance(p.geom, w.geom) DESC
``````

Don't forget to create a spatial index on each table!

• I believe the poster is asking about the point which is at a maximum distance from the nearest waterway. Dec 16, 2016 at 14:23
• @dbaston having now seen your answer, I see how you have interpreted the question and am inclined to agree with you. I'm waiting for clarification from OP Dec 16, 2016 at 15:19

I would suggest trying converting your vector data to rasters then using the Grass raster tool set with r.Grow.distance

It seems like the example in their documentation is similar to your own problem.

Your may need to confine the growth within your state borders if applicable.

As of PostGIS 3.1 this can be solved using `ST_MaximumInscribedCircle`:

1. Turn lines into polygons by buffering them by a small distance
2. Use `ST_Union` to union all water polygons, producing a single polygonal geometry `water`
3. Use `ST_Difference` to subtract `water` geometry from the outer constraint polygon, producing a polygonal geometry `land`
4. Use `ST_MaximumInscribedCircle(land)` to find the most distance point contained in the land area