PostGIS: ST_Covers fails for extremum point location - postgis

I am using PostGis to save geographical data and then use ST_Covers() function to find if a point or location lies with in a geography or not.
I can save a location with extremum values like:
-90,180;90,180;90,-180;-90,-180;-90,180
These values will tend to cover whole globe (lies along side the poles). I can save such a location and can retrieve it with no worries. However, when I call ST_Covers() on such locations, to find if a location lies within such location, the function fails and gives parse error.
I am using Postgis 1.5.3, upgraded to 2.0.2 but with little luck.
Can anybody please help me if something like this is possible. and how can I call ST_Covers() on such a location without any error.

PostGIS geography will not correctly interpret any edge greater than or equal to 180 degrees. Re-formulate your box with shorter edges and you should get what you desire.

Related

Problem when adding coordinates with geoadd

I'm using redis geosearch function to look for coordinates that were introduced in the database from differents points from my API, the problem is, because of some misunderstanding, some services used geoadd key fromlonlat latitude longitude and others used geoadd key fromlonlat longitude latitude and now my geosearch doesn't return the correct results, always parcially correct results. I would like to know why this happens, since when using redis geoadd function, the longitude and latitude are transformed into 1 geohashed string, shouldn't it work even with inverted types of coordinates? Why does it have to be in this exact same order as the documentation.
Also considering most of the coordinates saved were using geoadd key fromlonlat latitude longitude, should I implement the rest incorrectly to continue the pattern or start using it correctly and deal with the older coordinates?
From the inception of the Geo data structure, the order has always been lon,lat. This is a pain point that many have encountered (including myself). Unfortunately, no you cannot just reverse all of the coordinates and expect the geo data structure to work properly, the command expects the longitude and latitude in the correct order, if they're out of order it won't know how to compile the geo hashes correctly, and there are wide ranges of valid longitudes that are illegal as latitudes (see the geoadd page you linked to)

In Snowflake, can you create a circle polygon from a given centre point and radius?

I have a table containing geometrics points (called [Polygon_Centre]) and distances (called [Desired_Radius]). Anybody know which Snowflake function I could use to create polygon circles from this?
I'm trying to achieve a similar result to the Trade Area tool in Alteryx if anybody is familiar with that.
I was hoping for something like the following (which doesn't work):
ST_MAKEPOLYGON('Circle', [Polygon_Centre], [Desired_Radius])
Does anybody know how to create a circle polygon from a given centre point and radius in Snowflake?
Thanks everybody. I've found and used the following solution:
Calculate 120 points around the circle mathematically
Turn this into an ordered list with ST_COLLECT() (the order is critical and the start and end must match)
Use ST_MAKELINE() to turn these points into a line
Create the circle with ST_MAKEPOLYGON().

Does anyone know of potential problems with st_line_substring in postGIS?

Specifically I'm getting a result that I do not understand. It is possible that my understanding is simply wrong, but I don't think so. So I'm hoping that someone will either say "yes, that's a known problem" or "no, it is working correct and here is why your understanding is wrong".
Here is my example.
To start I have the following geometry of lat/longs.
LINESTRING(-1.32007599 51.06707497,-1.31192207 51.09430508,-1.30926132 51.10206677,-1.30376816 51.11133597,-1.29261017 51.12981493,-1.27510071 51.15906713,-1.27057314 51.16440941,-1.26606703 51.16897072,-1.26235485 51.17439257,-1.26089573 51.17875111,-1.26044512 51.1833917,-1.25793457 51.19727033,-1.25669003 51.20141159,-1.25347137 51.20630532,-1.24845028 51.21110444,-1.23325825 51.22457158,-1.2274003 51.22821321,-1.22038364 51.23103494,-1.20326042 51.23596583,-1.1776185 51.24346193,-1.16356373 51.24968088,-1.13167763 51.26363353,-1.12247229 51.2659966,-1.11629248 51.26682901,-1.10906124 51.26728549,-1.09052181 51.26823871,-1.08522177 51.26885628,-1.07013702 51.27070895,-1.03683472 51.27350122,-1.00917578 51.27572955,-0.98243952 51.2779175,-0.9509182 51.28095094,-0.9267354 51.28305811,-0.90499878 51.28511151,-0.86051702 51.2883055,-0.83661318 51.29023789,-0.7534647 51.29708113,-0.74908733 51.29795323,-0.7400322 51.2988924,-0.71535587 51.30125366,-0.68475723 51.29863749,-0.65746307 51.30220618,-0.63246489 51.30380261,-0.60542822 51.30645873,-0.58150291 51.3103219,-0.57603121 51.31150225,-0.57062387 51.31317883,-0.54195642 51.32475227,-0.4855442 51.34771616,-0.4553318 51.36283147)
This is in a column called "geom" in my table, called "fibre_lines". When I run the following query,
select st_length(geography(geom), false) as full_length,
st_length(geography(st_line_substring(geom, 0, 1)), false) as full_length_2,
st_length(geography(st_line_substring(geom, 0, 0.5)), false) as first_half,
st_length(geography(st_line_substring(geom, 0.5, 1)), false) as second_half
from fibre_lines
where id = 10;
I get the following result...
76399.4939375278 76399.4939375278 41008.9667229201 35390.5272197668
The first two make sense to me, they are simply the length of my line assuming a spherical earth. The first is just using the obvious function while the second is using st_line_substring to get the length of the entire line. These two values agree.
But the last two have me puzzled. I am asking for the length of the first half of the line, then I'm asking for the length of the last half. My expectation was that these would be equal or nearly equal. Instead the first half is about 6km longer than the second half.
If you plot the geometry on the map you will see that the first third of the line is fairly north/south oriented and the remaining two thirds are more east/west. I wouldn't have thought that would make a difference when asking for the length on a spherical earth, but I am happy to be told that I'm wrong (so long as it is also explained why I'm wrong).
For reference the PostGIS I am using is 1.5.8. If this is a bug, upgrading to a newer version is possible, but not trivial, so I would prefer to only do that if it is necessary.
Anyone have ideas?
While Arunas' comments didn't directly answer my question, it did lead me to some research that I think identifies the problem. I'm posting it here in part to get it straight in my own mind and in part in case others are wondering.
It seems the key is the PostGIS distinction between a "geometry" and a "geography". A geometry is a 2D planar geometry that is typically in UTMs and used with a projection of the globe onto a flat surface (which projection is configurable). A geography, on the other hand, is designed to store latitude/longitude information specifically and is used to work either on a sphere or a spheroid. So the essential problem I have is twofold:
Perhaps not obvious from my original post is that I am using a geometry object to store lat/long information rather than UTMs. I cast that to a geography most of the time so that I get the correct answers, but it would be more correct if I actually stored it as a geography object. That would eliminate the need for a number of the casts in my code as well as allow PostGIS to tell me when I am doing something wrong.
While ST_Length will work with either a geometry or a geography, ST_Line_Substring only works with geometries. Hence when I ask it for the halfway point, I am asking it for the halfway point of a flat geometry. This will give me the correct answer for the latitude coordinate, but for the longitude it will have an error term that increases (for most projections) the farther I am from the equator.
I've looked into newer versions of PostGIS and they don't seem to have an ST_Line_Substring or anything similar that will give me the 50% point of a geography, so I will have to do it the "hard" way by using ST_Length to give me all my segment lengths and then adding them up and doing the math needed for my interpolation.
Sorry I can't add comments so will provide it as an answer.
I experienced the same problem and I resolved by transforming my lat-lon geometries to utm geometries into st_line_substring function call. The I as getting sub-geometries with proper length. Of course I had to transform them back to lat-lon afterward.

Issue with OpenStreetMap administration area rendering

I imported latest OpenStreetMap data to local SQLServer db and generated "outer" shape for some administration area. Original area shape is available here:
http://www.openstreetmap.org/relation/2658573
What I received is below:
What I did is I took "outer" way definitions for this shape (mentioned above) in the order defined in the db and constructed POLYGON definition from points belonging to all the ways in the order defined in OpenStreetMap db.
To import data to SQLServer db I used OsmSharp.core nuget package.
The orientation of shape data is clockwise as per info on this page(see Naming and Orientation section)):
http://wiki.openstreetmap.org/wiki/Talk:Relation:multipolygon
My questions are:
Does anybody know why taking direct definitions for "ways"/lines describing some area shape doesn't work as it should?
Should I reject some points from line/way definitions?
Maybe I just missed something else...
Edit 1:
I did quick query to verify info from scai and it looks promising:
NodeNr column shows which point on the way/line definition I should take as the start/endpoint for polygon definition. WayNr shows which consecutive way shares point with which one.
Edit 2:
I tested data related to way definitions already and it looks the main issue is with order of nodes in the way definitions only. All the tested ways used all the nodes belonging to them (no any redundant points were there in case the way could cross some other way in the middle of that way).
Some sample data:
The definition of the way with nr 42 (WayNr = 42) shows that start point of this line (continuation of the way nr 41) is on position 44. It means point/node 44 in the definition of the way 42 has the same gps/coordinates as point on position 30 in the definition of way nr 41.
After taking such "reverted" lines in the correct order I received the shape shown below:
After adding an inner area (exclusion) it looks finally as the original one shape:
The other issue with OpenStreetMap data is it uses right-hand rule to define outer-ring of the shape (clockwise instead of counter-clockwise) so in case of SQLServer we have to use ReorientObject() method on Geography instance. To detect orientation of the shape you can use EnvelopeAngle() method on Geography object for instance.
Edit 3:
I received an answer on OSM forum the order of ways on relation members doesn't matter (we can't rely on it) so ways have to be reordered before any further processing yet...
There are already various similar questions here at stackoverflow and at gis.stackexchange.com.
Relations don't necessarily contain the ways in the correct order. Thus it will be necessary to order the ways yourself. Take a look at the ID of the last node of a way and search for the way who has the same ID for its start node. If you do this for all ways then the resulting geometry should be fine.

How to calculate the geohash of the viewable area/bounding box?

I've recently start working on a personal project involving geo locations, maps (Google Maps V3) etc.
The project is developed in Python and is intended to run on Google App Engine.
I've learned that in order to find markers/position close to a position one can use to geohash algorithm (which is pretty cool).
What I don't understand is this: lets say I have all my locations in the data store (along with a latitude, longitude and a geohash (with high precision) of each location.)
I know that I should use the prefix of the geohash (to match locations within), but how do I calculate a geohash of a bounding box? Considering the bounding box is made up of two points, North-East and South-West, I do not understand how to go about doing this..
In order for me to querying which locations should be returned for the currently visible bounding box, I need the geohash of the visible/viewable bounding box - Now I know I can geohash the center location on the viewable map, but I do not know how many letters to cut off (to reduce precision) to achieve 'a fit' to the actual bounding box. (Or maybe that isn't the way...?)
What do you do when the bounding box container to geohashes? (like in the middle of the viewable area it splits between 'dqcjr0' and 'dqcjqb')
Also, lets assume I have a 5 letter geohash, how can I convert that back into a viewable bounding box? or in other words, how do I know what is 'included' the hash, and what is in adjacent hashes?
Thanks in advance for your help,
Ken.
I used geohash with google app engine data types ie db.GeoPt a lot and I used to keep a geohash which I found was inferior to combine the db.GeoPt with the very good but a bit slow library called geomodel Geomodel can do bounding-box and radius mappings and I suggest that you try with the bounding-box since it is not as expensive as the radius. I can perform a bounding-box query like this:
articles = Article.bounding_box_fetch(Article.all().filter('modified >',
timeline).filter('published =',
True).filter('modified <=',
bookmark).order('-modified'),
bounds,
max_results=PAGESIZE + 1)
So even if I stored geohash for every article, using geomodel was much better in my case. Maybe you already evaluated geomodel and found that it didn't suit your purpose and that you absolutely must use geohashes I suggest that we agree on a common library for the geohash so that our coordinates hash to the same value. I do keep a version of the geohash library I used somewhere but it is probably outdated and the recent articles about geospatial queries also metion geomodel, so if you didn't look at geomodel yet, I really propose you look at the geomodel library to perform your geospatial queries.
Ken
You may want to update your question stating whether or not you're using django / django-nonrel?
I'm just about to try this (currently archived) port of Geomodel to django:
https://bitbucket.org/scotch/django-geomodel/
Kyle suggests that the upcoming Google "full text search" would replace his Geomodel implmentation. Nonetheless, I need it working within the next few days.
(My current conversation re: this topic:
https://groups.google.com/forum/#!topic/django-non-relational/WCxFjkUzw18
)
Jon

Resources