OpenStreetMaps and Postgis: wrong latitude and longitude from a geography point - latitude-longitude

I downloaded the file italy.osm and import to postgresql with postgis.
So i try to extract latitude and longitude from the field "way" (geometry) of the table planet_osm_point, using the functions ST_X(), ST_Y() and these are the coordinates that I get as a result by querying a point in center of Milan City.
X: 1025988.29850153
Y: 5709056.87437553
I'm doing something wrong?

The data need to be projected to WGS84:
SELECT ST_Y(ST_Transform(way, 4326)) AS lat, ST_X(ST_Transform(way, 4326)) AS long
FROM planet_osm_point;
Don't install the spatial reference from spatialreference.org (which is srid=94326), as you should already have this when you spatially enabled the database. If srid=4326 wasn't already there, then there was a problem or skipped step when you spatially enabled the database.

Related

Finding Locations Within A Specific Distance using PostGIS data within postgress

I am trying to find all locations within a one mile radius of a specified point. I have longitude and latitude data for each point,
multi polygon geometry (Example :
MULTIPOLYGON(((2147312.63139525 161631.130590368,2147298.94808962 164286.665686698,2147623.79332922 164287.328517173,2149920.27996486 164292.162599235,2149944.29540875 161654.921437815,2147312.63139525 161631.130590368)))
and the_geom data
Example:
0106000020DA08000001000000010300000001000000060000003F8FD150F86140417EF6720BF9BA03412C005B79F16140412A8C5353F50D0441D7CF8BE593624041929CCDA0FA0D044177E3D52310674041E5D3004D210E044134F4CF251C67404106CA1A5FB7BB03413F8FD150F86140417EF6720BF9BA0341
I'm just not sure of the best way to approach finding all distances within one mile.
To query geometries within a given radius you have to use ST_DWithin:
SELECT * FROM t
WHERE
ST_DWithin(
the_geom::geography,
ST_MakePoint(longitude,latitude),1609.344); -- 1609.34 metres = 1 mile;
The geography cast enables you to search using metres as unit, which can be easily converted to miles.
Related post: Getting all Buildings in range of 5 miles from specified coordinates
I wanted to stop by and thank Jim Jones for your help! I wasn't able to end up to get the_geom to work, although this was probably user error. The link you shared did help me to come up with the fix below.
SELECT * FROM t where ST_DWithin('POINT($long $lat)'::geography, ST_MakePoint(longitude,latitude)::GEOGRAPHY, 1609.344);

redis Geo distance (GEODIST) suspect not accurate

I am new to Redis and was trying GEODIST function but found the result was not consistent with the result i got from some website which provide geo distance calculation function.
for example, i tried to points as
GEOADD locations 35.0963009 -80.858142 "A" 35.145314 -80.842567 "B"
and
GEODIST locations A B km
redis gave me 1.9370km but https://www.functions-online.com/geo-distance.html and https://www.geodatasource.com/distance-calculator
was giving me 5.37km
i then used google map to determine which one is more accurate and it turned out redis was wrong.
does anyone know the explanation and how to fix/adjust redis to give a more accurate result? like a ratio?
it turns out GEOADD takes lng, lat, name rather than lat, lng, name.
the first 2 arguments order was reversed.
Though I should read more carefully, the first sentence 'Adds the specified geospatial items (latitude, longitude, name) to the specified key. ' from doc https://redis.io/commands/geoadd was really confusing.

How to create and query table containing lat/long using PostGIS?

How would I create a table that contains a geography point (lat/long) using PostGIS? Then also, what would the format be for inserting into this table (Using SQL/PostgreSQL)?
Would it just the following for table creation:
CREATE TABLE x (geog geography(point, 4326))
If so, what is the point and when would you instead use ST_Point(X,Y)
Should this column have an index?
Note: Many questions previously answered detail how to convert. But I want to create an empty table from scratch that supports storing latitude and longitude.
Yes, the Syntax for Creating a table with Geography is as simple as CREATE TABLE x (geog geography(POINT,4326) );
In this Command, POINT is the type of shape that this table will be storing. Other possibilities are :
LINESTRING
POLYGON
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON
GEOMETRYCOLLECTION
The reason why storing a Geography in a table makes sense in some cases, is that it gives you the ability to run several functions which would give you results as if you are calculating on a Spherical Earth. So for example I could have two points stored as Geography (knowing only lat-long of each), and I could easily find the distance between them in Meters
ST_Point(X,Y) is just a function that takes in two numbers, and then creates a point which has X as the first number and Y as the second number. It need not be a Lat-long pair. Infact this Point has not concept of which Coordinate reference system it is in.
Once you create the table, inserting records in it, is as simple as:
INSERT INTO X (geog) VALUES (ST_GeographyFromText('POINT(2.5559 49.0083)'));
Here You are are creating a Geography point for Paris, with latitude of 49.0083N and longitude of 2.5559 E

postgresql with postgis & polygons

I'm working with postgresql with postgis.
I have few questions:
trying to insert into a table with polygon column using the following syntax:
ST_GeomFromText('POLYGON((long1 lat1, long2 lat2, long3 lat3))')
fails with the following error: function geomfromtext(unknown) does not exist
what is the difference between
CREATE TABLE my_table (my_polys polygon);
and
CREATE TABLE my_table2 (my_polys GEOGRAPHY(POLYGON));
and why does the following:
INSERT INTO my_table (my_polys) VALUES ('
(51.504824, -0.125918),
(51.504930, -0.122743),
(51.504930, -0.110297),
(51.504824, -0.102229),
(51.503435, -0.099311)'
);
work fine with my_table and not with my_table2 (I've changed the table name to my_table2)
what is the maximum number of points a polygon can have?
The geography data type is mostly useful when your geometry might wrap around the date line. If it does not, you are better off using normal geometry data types, as most functions in Postgis are designed to work on planar geometries. If your data are lat/lon, you can explicitly set this when you create your column with:
create table foo geom geometry(POLYGON, 4326);
Explicitly setting the coordinate reference system is useful if you want to convert between one coordinate system and another and helps prevent suprises if you attempt to run an intersection, say, between geometries in different coordinate systems.
It is hard to imagine your insert fragment above working with any table, not only is there a trailing comma, but there is no st_geomfromtext, st_makepolygon or anything else to convert what you have written into any geometry.
I have no idea what the maximum size for a polygon is, although, as Chris has already said, you are likely to have performance issues with polygons of 1gb in size, when you try and do spatial queries on them.
Your polygon size is limited by the max storage size. I believe this is limited to 1gb for a toasted column, though my guess is that you are likely to run into performance issues long before you exceed the maximum number of points.
Polygon is a built in type in PostgreSQL, and PostGIS offers additional types for geometry and geography. As I understand it the built-in-types only work for 2d Euclidean space, while PostGIS offers additional options there.
As for why your query fails, I wonder which version of PostGIS you are running and why st_geomfromtext is calling geomfromtext.

SimpleDB - Location comparative select expression

I have a coordinate, assume any latitude and longitude values.
I have a domain setup on SimpleDB that has many items (simple strings) with attributes of 'Latitude' and 'Longitude'. Now what I want to do is query SimpleDB and see if the current location coordinates are 'x' meters apart from SimpleDB's items' coordinates. 'x' should be 10.
My app uploads an item to SimpleDB with an attribute that contains the latitude and longitude. I detect the users location, get the coordinates and I want to use a select expression to see if the coordinates are 'x' meters apart. So is their a better approach to doing this? Or is this is the best way, if so, how can I do it?
Here is an example of what the select expression may look like, I just have no idea how to use it in this case and what the '%#' values would be filled in by. This whole format could be off, its just my idea.
select * from test-app-simpledb where Latitude >= '%#' AND Latitude <= '%#' AND Longitude >= '%#' AND Longitude <= '%#'
So "test-app-simpledb" is my SimpleDB domain name, Latitude and Longitude are the attributes I compare to the coordinates. They are all converted to string.
So, how can I do location comparative select expressions. Querying if the item's coordinate (latitude and longitude attribute) are 'x' (in this case 10) meters apart.
Any way to do this? Thanks!
In the revised question, it has become clear that the actual question is how to conduct a query against a Amazon SimpleDB database to see if locations in the database are within a certain radius of a location provided by an iOS app.
As you correctly identify, you really want to do this server-side, rather than client-side, if possible. And the particular solutions will be highly dependent upon the particular database technology (SimpleDB in this case).
This question is touched upon in Spatial queries on AWS SimpleDB. I would suggest checking that out for more information.
As a proxy for a proper distance algorithm, you could translate the distance in meters into a ranges of latitudes and longitudes. Thus, you could, in iOS, calculate a minimum and maximum for both latitude and longitude and then pass those along in the WHERE clause to your remote database. Then the server could filter results based upon those criteria. That admittedly gives you a square-shaped region (rather than a circular region that you get by calculating distances properly), but it makes it really easy to quickly limit the result set with no special geolocation logic required on the server. To do this, you could define a region with MKCoordinateRegionMakeWithDistance, and then grab its span.
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(originalCoordinate, 200, 200);
MKCoordinateSpan span = region.span;
That gives you span.latitudeDelta and span.longitudeDelta which you can center around a given location's latitude and longitude to define a square shaped region around a location. To demonstrate that in action, here the center pin is my location at Times Square, and the shaded area is a region (constructed using the above span which is 200m wide and tall), which covers longitudes between 100m east and 100m west of my current location, as well as latitudes 100m north and 100m south of my current location.
This is a way to employ MapKit.framework functions to greatly streamline your SQL queries for remote databases to filter locations based upon geographic distance. If the square region is problematic, you could also further filter the results once they're downloaded to the iOS app using the CLLocation instance method, distanceFromLocation to determine the actual distance. But by limiting the longitudes and latitudes of locations retrieved by the server, you dramatically streamline the server retrieval process while not encumbering it with too much geographic location calculations.
But you really want to have SimpleDB do the full, proper distance calculation, I'll have to leave that to others.
Below, is my original answer. In the original question, I misinterpreted it as being "how do I construct a list of coordinates going in a circle around a particular location?" As made clear by the revised question, that was not the issue at all, but I'll keep my old answer here for historical reference.
Original answer:
If you used Calculate new coordinate x meters and y degree away from one coordinate, the implementation might look like:
NSInteger numberOfPoints = 10;
for (double bearing = 0.0; bearing < 360.0; bearing += (360.0 / numberOfPoints))
{
CLLocationCoordinate2D coordinate = [self coordinateFromCoord:originalCoordinate
atDistanceKm:distanceKm
atBearingDegrees:bearing];
// do whatever you want with this coordinate
}
It seems to work fine. For example, I had an app use this routine to drop 10 pins 100m from me in Times Square: