Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I've just posted this at StackOverflow and someone suggested I try here. Original: http://stackoverflow.com/q/5863859/246265

I'm trying to represent a rectangular area which crosses 180 degrees longitude. For more background see http://stackoverflow.com/q/5737506/246265

Here's my test case:

from django.contrib.gis.geos import Polygon, MultiPolygon
from my_project.my_app.models import Photo

a = Polygon.from_bbox((30, -80, 180, 80))  # the part to the east of 180
b = Polygon.from_bbox((-180, -80, -160, 80))  # a part to the west of 180
c = Polygon.from_bbox((-180, -80, -100, 80))  # a larger part to the west of 180

ok   = MultiPolygon(a,b)
ok2  = MultiPolygon(c)
boom = MultiPolygon(a,c)

# This works
Photo.objects.filter(location__coveredby=ok)[:1]
# This also works so c is ok
Photo.objects.filter(location__coveredby=ok2)[:1]
# This gives "BOOM! Could not generate outside point!"
Photo.objects.filter(location__coveredby=boom)[:1]

# splitting c doesn't help
c1 = Polygon.from_bbox((-180, -80, -140, 80))
c2 = Polygon.from_bbox((-140, -80, -100, 80))
test = MultiPolygon(a,c1,c2)
Photo.objects.filter(location__coveredby=test)[:1]
# BOOM! Could not generate outside point!

By changing the numbers I can make this error come and go. (-180, -80, x, 80) works where x <= -140 for example. For every number there is a threshold like this but I can't find a pattern. For boxes with the same area, some will work and others not. For boxes with the same width some will work and others not.

I can look at the SQL being generated but the areas are represented in binary (EWKB) and I'm not sure how to read it.

Can anyone explain this?

share|improve this question
    
Update: I've just tried specifying srid for my Polygons with the same results. Like so: x0, y0, x1, y1 = -180, -80,-100,80 c = Polygon(((x0, y0), (x0, y1), (x1, y1), (x1, y0), (x0, y0)), srid=4326) –  Jake May 3 '11 at 2:51
    
I've got the problem down to pure SQL. The following causes the error: SELECT * FROM "photo" WHERE ST_CoveredBy("photo"."location", ST_GeomFromEWKT('SRID=4326;MULTIPOLYGON (((30 -80, 30 80, 180 80, 180 -80, 30 -80)), ((-180 -80, -180 80, -100 80, -100 -80, -180 -80)))')) –  Jake May 3 '11 at 3:08

2 Answers 2

Sounds like your using geometry rather than geography tables

In order to load geometry data into a geography table, the geometry first needs to be projected into EPSG:4326 (longitude/latitude), then it needs to be changed into geography. The ST_Transform(geometry,srid) function converts coordinates to geographics and the Geography(geometry) function “casts” them from geometry to geography.

If your data is geographically compact (contained within a state, county or city), use the geometry type with a cartesian projection that makes sense with your data. See the http://spatialreference.org site and type in the name of your region for a selection of possible reference systems.

If, on the other hand, you need to measure distance with a dataset that is geographically dispersed (covering much of the world), use the geography type.

to convert your geometry to geography use the code below

CREATE TABLE yourdata_geog AS
SELECT
  Geography(ST_Transform(the_geom,4326)) AS geog,
  attr1,
  att2
FROM yourdata;

http://workshops.opengeo.org/postgis-intro/geography.html

share|improve this answer
    
Yes, I do need geography. When looking at the table in pgAdmin it shows the column as "location geography(Point,4326)". That means it is a geography column, right? Do I need to change the table somehow? Could it be that my query is trying to use geometry? –  Jake May 3 '11 at 2:40
    
This was recently discussion on the postgis-users mailing list –  Mike T May 3 '11 at 7:50
up vote 1 down vote accepted

I think I've figured this out, please correct me if my assumptions are wrong.

The MultiPolygon(a,c) covers more than half the earth's surface so postGIS thinks I'm referring to the area outside my MultiPolygon, because it's smaller. This area includes the poles, as Mike Toews pointed out, postGIS doesn't like these extreme values.

My solution is to use an SQL OR to join each Polygon, rather than putting them in a MultiPolygon. My area is split up in the first place to allow for searching areas bigger than half the earth's surface.

share|improve this answer
1  
Hmm, I've been looking into this to some degree. It is a bug, as the "BOOM" error message has some source comments to the effect of "this case should never happen". The boundary of [-180, -90, +180, +90] does not trigger this error, but it is exactly as you say, when it is greater than half of the Earth's distance across. The bug hasn't been filed yet, as I'm trying to figure it out. (Technically it is with _st_distance and internal functions) –  Mike T May 6 '11 at 1:02
    
FYI: trac.osgeo.org/postgis/ticket/1046 –  Mike T Jul 15 '11 at 5:34
    
@MikeToews I just ran into this same problem. Looking at the osgeo ticket (link above), I got the impression that it's not a bug but rather an error due to genuinely invalid geometry in the polygon (or multipolygon). If this is the case, then can you suggest a way to deal with it in the following situation? –  pyrogerg May 2 '12 at 18:25
    
@pyrogerg I'm not sure if there is a general suggestion, except to question if you really need a geography type. Keep the geometries less than half of the hemisphere in size, and not at the poles. If you want more specifics, I'd ask it as a new question. Edit: ah yes, I see you asked it! –  Mike T May 2 '12 at 21:16
    
@MikeToews For some reason the site didn't want to let me edit my comment above, after I accidentally submitted it before I could describe the situation. Sorry if my message seemed incomplete. I was thinking a new question was in order anyway. –  pyrogerg May 3 '12 at 4:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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