1

I'm working in a layer with MultiPolygons and I'm trying to calculate the shortest distance between a MultiPolygon and a point which is contained in that MultiPolygon, using Django and PostGIS.

At first I check which MultiPolygon contains that Point and I store it in a variable:

mpoly = MPoly.objects.filter(geom__contains=location)

Then, I'm trying to calculate the distance between the point and the mpoly object using the psycopg2 interface:

curs.execute("SELECT ST_Distance(ST_GeogFromText(%s), ST_GeogFromText('SRID=4326;Point(24.050, 35.311)')) FROM MPoly" % mpoly)

But it raises the following syntax error:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
   ProgrammingError: syntax error at or near ";"
   LINE 1: SELECT ST_Distance(ST_GeomFromText(SRID=4326;MULTIPOLYGON ((23.567..

I think that the error comes from "mpoly"'s format but why ? If I type in a Python interpreter >> mpoly, it prints: MultiPolygon object at 0x7fc8d5130

  • Look at the docs for ST_GeomFromText. There is no form with a semicolon. Either use the correct form, or wrap geomfromtext in ST_SetSrid call. – John Powell Aug 30 '18 at 11:49
  • I do not agree with you @John Powell, because this source shows that the semicolon is not an issue. I think @Gpetr should try this code with ST_GeogFromText('SRID=4326;POINT(24.050, 35.311)'). I think the issue is about POINT instead of Point. – Taras Aug 30 '18 at 11:58
  • Thank you both of you for your quick responses. I think that the problem is that the system interprets mpoly variable with this format (SRID=4326;MULTIPOLYGON ((23.567...) automatically. Which is not an acceptable format from ST_Distance function but I don't know how to define the format in an acceptable way. – Gpetr Aug 30 '18 at 12:16
  • @Taras, you are correct, I misread it. Apologies. – John Powell Aug 30 '18 at 12:21
  • 1
    I think it is because you need to enclose the text string you are sending to ST_GeogFromText in quotes, so you have SELECT ST_Distance(ST_GeogFromText('%s') or something similar. – John Powell Aug 30 '18 at 12:23
1

a research on the topic of WKT-Geometries and the syntax of st_geogfromtext reveals, that your query should look something like this:

select st_distance(st_geogfromtext('srid=4326;multipolygon (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))'),st_geogfromtext('srid=4326;point(40 20)'));
   st_distance   
-----------------
 892746.97610591

Your mistake was to type point(40 , 20), not point(40 20). Note that the single quotes are obligatory if you use the st_geogfromtext function, whereas case sensitivity is not a deal. Thus, maybe you could also try quoting your %s, as John Powell already indicated.

Furthermore, are you really sure to want to calculate the shortest distance of a point being within a multipolygon? Because, if the multipolygon contains the point, the distance from the point to the multipolygon is 0 by defintion. See for example this query, where a point lies within the boundaries of the multipolygon:

select st_distance(st_geogfromtext('srid=4326;multipolygon (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))'),st_geogfromtext('srid=4326;point(20 12)'));
 st_distance 
-------------
           0

If you really want to have the distance from the point to the boundaries of the multipolygon, you could try to convert the multipolygon to a multilinestring or similar.

  • Many thanks for your helpful answer ! Your answer and the comments above helped me to find the issue. There were two syntax errors. The one is that I had to enclose "mpoly" variable into quotes and the other is that there should not be commas between Point's coordinates (Point(24.050 35.311)). Also you are right that the distance should be 0 because the point is contained to the multipolygon but at first, I have to find from the database which is the polygon that contains the point. Thus I have to use Polygon geometry. – Gpetr Aug 31 '18 at 10:47
  • Also I had to drop "from MPoly" from my command. Finally the command that did the job is: curs.execute("select st_distance(st_geogfromtext('%s'),st_geogfromtext('srid=4326;point(24.050 35.311)'))" % poly.geom) – Gpetr Aug 31 '18 at 10:53
0

After the helpfull answer of @yorkie I'd like to post a complete solution of my issue about calculating of distance between a MultiPolygon object and a Point. The answer covers the case that the MultiPolygon object contains that point.

At first, I converted the MultiPolygon geometry to MultiLineString because if MultiPolygon contains the point the distance will be zero (0.0).

curs.execute("SELECT ST_Boundary('%s')::geometry(MULTILINESTRING,4326)" % poly[0].geom)

After that, I converted the above MultiLineString geometry to Well Known Text.

curs.execute("SELECT ST_AsEWKT('%s')" % curs.fetchone())

and I stored the result in a variable:

t = curs.fetchone()

and finally, I calculated the distance:

curs.execute("select st_distance(st_geogfromtext('%s'),st_geogfromtext('srid=4326;point(24.050 35.311)'))" % t)

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.