1

I am working with postgis 2.0 and I would like to calculate the maximum minimum distance from a point set (multipoint) to a polygon. It seems that neither st_distance nor st_maxdistance can meet my requirement. I know I can use st_dumppoints to change the point set to a point table and then calculate the maximum distance from the point table to the polygon, but I am still wondering whether there is some function like st_maxmindist(multipt,polygon) that can calculate the distance directly.

An example here:

geom 1: MULTIPOINT(139.64743 35.641438,139.647644 35.641396)
geom 2: POLYGON((139.6478008 35.6414487,139.6476882 35.6414682,139.6476906 35.6414786,139.6476412 35.6414874,139.6476386 35.6414768,139.6475749 35.6414879,139.6475559 35.6414234,139.64754 35.6414262,139.6475316 35.6413962,139.6475252 35.6413974,139.6475284 35.6414107,139.6474595 35.6414227,139.6474448 35.6413664,139.6475132 35.6413531,139.6475152 35.6413585,139.6475365 35.6413545,139.6475387 35.6413621,139.647766 35.6413201,139.6478008 35.6414487))

select st_distance(st_wkttosql('MULTIPOINT(139.64743 35.641438,139.647644 35.641396)'),
  st_wkttosql('POLYGON((139.6478008 35.6414487,139.6476882 35.6414682,139.6476906 35.6414786,139.6476412 35.6414874,139.6476386 35.6414768,139.6475749 35.6414879,139.6475559 35.6414234,139.64754 35.6414262,139.6475316 35.6413962,139.6475252 35.6413974,139.6475284 35.6414107,139.6474595 35.6414227,139.6474448 35.6413664,139.6475132 35.6413531,139.6475152 35.6413585,139.6475365 35.6413545,139.6475387 35.6413621,139.647766 35.6413201,139.6478008 35.6414487))'))

returns: 0

select st_maxdistance(st_wkttosql('MULTIPOINT(139.64743 35.641438,139.647644 35.641396)'),
  st_wkttosql('POLYGON((139.6478008 35.6414487,139.6476882 35.6414682,139.6476906 35.6414786,139.6476412 35.6414874,139.6476386 35.6414768,139.6475749 35.6414879,139.6475559 35.6414234,139.64754 35.6414262,139.6475316 35.6413962,139.6475252 35.6413974,139.6475284 35.6414107,139.6474595 35.6414227,139.6474448 35.6413664,139.6475132 35.6413531,139.6475152 35.6413585,139.6475365 35.6413545,139.6475387 35.6413621,139.647766 35.6413201,139.6478008 35.6414487))')
  );
returns 0.0003709543502758528

select st_distance((st_dumppoints(st_wkttosql('MULTIPOINT(139.64743 35.641438,139.647644 35.641396)'))).geom,
  st_wkttosql('POLYGON((139.6478008 35.6414487,139.6476882 35.6414682,139.6476906 35.6414786,139.6476412 35.6414874,139.6476386 35.6414768,139.6475749 35.6414879,139.6475559 35.6414234,139.64754 35.6414262,139.6475316 35.6413962,139.6475252 35.6413974,139.6475284 35.6414107,139.6474595 35.6414227,139.6474448 35.6413664,139.6475132 35.6413531,139.6475152 35.6413585,139.6475365 35.6413545,139.6475387 35.6413621,139.647766 35.6413201,139.6478008 35.6414487))')
  ) order by st_distance desc limit 1

returns: 0.00003323161144144182 (what I want is this result)

p.s. I think this distance is close to a simplification of Haussdorf distance, but directly using Haussdorf distance here cannot get the result:

select st_hausdorffdistance(st_wkttosql('MULTIPOINT(139.64743 35.641438,139.647644 35.641396)'),
  st_wkttosql('POLYGON((139.6478008 35.6414487,139.6476882 35.6414682,139.6476906 35.6414786,139.6476412 35.6414874,139.6476386 35.6414768,139.6475749 35.6414879,139.6475559 35.6414234,139.64754 35.6414262,139.6475316 35.6413962,139.6475252 35.6413974,139.6475284 35.6414107,139.6474595 35.6414227,139.6474448 35.6413664,139.6475132 35.6413531,139.6475152 35.6413585,139.6475365 35.6413545,139.6475387 35.6413621,139.647766 35.6413201,139.6478008 35.6414487))'))

returns: 0.00016541925521245188

  • 1
    both functions should do exactly what you need. please add the query you are using. if you can't pinpoint the problem, update your question with example data, too. – ThingumaBob Aug 15 at 13:12
  • Thank you for your reply, sorry for not explaining it clearly, I have added an example in my question. – natsuapo Aug 15 at 13:37
  • 1
    Your question seems to be "find closest distance to the polygon from any member of a multipoint geometry that is not inside the polygon" and I think that the ST_DumpPoints method is just right for you. – user30184 Aug 15 at 13:57
  • I see, but is there an easy function to do that? I am afraid using ST_DumpPoints for joining two tables would be a little complicated. – natsuapo Aug 15 at 14:01
1

You are correct that none of ST_Distance, ST_MaxDistance or ST_HausdorffDistance will meet your requirement. ST_HausdorffDistance is closest, but the problem with it is that it is symmetric, which means that a very large polygon will dominate the result. What you really need is the oriented Hausdorff Distance. JTS has an implementation of this, but unfortunately PostGIS does not expose the GEOS equivalent.

So the only option is to use the ST_Dump/ORDER BY method. It should be possible to do this over multiple rows by using a subquery.

0

Perhaps I understood the question somehow wrong but for me the functions seem fit your requirements.

select st_distance(
st_geomfromtext(
'MULTIPOINT (( -80 20 ), ( -40 0 ))'),
st_geomfromtext(
'POLYGON (( 20 0, 60 40, 80 -20, 20 0 ))'))

Result:60

select st_maxdistance(
st_geomfromtext(
'MULTIPOINT (( -80 20 ), ( -40 0 ))'),
st_geomfromtext(
'POLYGON (( 20 0, 60 40, 80 -20, 20 0 ))'))

Result:164.924225024706

Image showing the geometries and minimum-maximum distances

enter image description here

Your geometries look like this

enter image description here

Minimum distance is zero because one part of the multipoint is inside the polygon. What distance are you actually trying to find?

  • Thank you for your answer, sorry for not explaining it clearly, I have added an example in my question. – natsuapo Aug 15 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.