ST_GeographyFromText() function changes the input while storing in DB- PostgreSQL - postgis

I'm working on building a database for a geo referenced application which involves storing of latitude, longitude and altitude. The column to store the same is location and is declared as location geography(PointZ,4326).
I insert the points in the following manner
INSERT INTO SOMETABLE VALUES (ST_GeographyFromText('SRID=4326;POINT("+loc+")'); , where loc is a space seperated string with the latitude , longitude and altitude values (for example 2.098 5.67 3.45).
I did not find any aberration until I inserted a specific geographical point 19.4333 99.1333 2200, which on retrieval becomes 19.433299999999999 80.866699999999994 2200. My concern is about the second coordinate point changing while storing.
Could someone advise me on what's the issue.
I appreciate your help!!
Thanks.

I had figured out what the issue was myself when I tried to understand the specifics of ST_GeographyFromText() It takes in coordinates in this order - [longitude, latitude, altitude] and I had misordered latitude and longitude and as a matter of fact, the maximum value for latitude is 90 and that's the reason the 99.1333 was altered to 80.86669 ( a value less than 90 ).
Thanks!

Related

how to generate a query for bring points in a radius in postgis

My question is how to calculate the radius from a point for all the locations that are in this radius? I am trying but always the query finds locations out site from the radius. This is an example:
the query I am using is:
SELECT *
FROM "Property"
WHERE "Property"."DeletedAt" IS NULL
AND ((ST_DWithin(ST_SetSRID(ST_Point(43.628123412124616, -116.19140625), 4326)::geography, ST_SetSRID(ST_Point("Latitude", "Longitude"), 4326)::geography, 25730.9, true)))
ST_POINT takes longitude then latitude, so you should swap the two parameters. see the doc

PostGIS ST_Expand point by meters and bounding box

I don't think something is right want max and min lat long of the 100 meter buffer.
SELECT ST_Asgeojson(
ST_Expand(
ST_GeomFromEWKT('SRID=4326;POINT(-88.33 36.33)')
,100
)
);
Think it is calculating by 100 degrees of lat and long.
This gis.se question shows what I'm wanting to do. Answer 5 graphically depicts what I'm wanting to do.
I'm trying to get the
coordinates: [
[-80.425, 46.437],
[-71.516, 46.437],
[-71.516, 37.936],
[-80.425, 37.936]`
to add it to the map.
Yes, of course... As in documentation of ST_Expand
Units are in the units of the spatial reference system in use denoted
by the SRID.
EPSG:4326 is in degrees so it's exanding by 100 degrees.
I suggest you use ST_Buffer function with geography datatype:
SELECT ST_Asgeojson(ST_Buffer((ST_GeomFromEWKT('SRID=4326;POINT(-88.33 36.33)'))::geography,100));
And if you need rectangle you have to add ST_Envelope with geography::geometry
SELECT ST_Asgeojson(ST_Envelope(ST_Buffer((ST_GeomFromEWKT('SRID=4326;POINT(-88.33 36.33)'))::geography,100)::geometry));
If you need to use this in select from table you might need to reproject your geometry because cast ::geography needs a LatLon CRS, so it'll look like this:
SELECT ST_Asgeojson(ST_Envelope(ST_Buffer((ST_Transform(x.the_geom,4326)::geography,100)::geometry));

How to find the name of a place from latitude and longitude value

I am analysing app data which contains lat value and lon value of a user visited places. I was able to export the data to tableau and plot it on the map but I want to find the name of place for each pair of lat and lon.
One solution could be, if I get a table of three columns (Lat, Lon, Place) then I can join it with my user data table to find the name of a place at a given Lat and Lon.
My question is, do we have a ready made table with the above three columns which I can import in my SQL-Server? I am interested in places of UK or London. Is there any other approach to achieve it?
You can get this from the Ordinance Survey which should get you lat, long, postcode;
https://www.ordnancesurvey.co.uk/business-and-government/products/code-point-open.html
You'll then need another data source to map the postcode to location name (e.g. town, county etc). See the similar post below;
Where can I find a list of all UK _full_ postcodes including street name and their precise coordinates?
It might take a little fiddling about, and you're always going to have the issue with data being a little out of date but it should be good enough.
I wrote an API wrapper in R for postcodes.io, which is a free UK postcode database. Check the original documentation so that you could create an API wrapper in your language of choice. Wrappers in languages other than R are also available.
If you use R, then type you can get the place names in the following way:
if (!require("devtools")) install.packages("devtools")
devtools::install_github("erzk/PostcodesioR")
library(PostcodesioR)
rev_geo <- reverse_geocoding(0.127, 51.507)
It will return a list with extensive information about the latitude and longitude, e.g. wards, NUTS, administrative district, county, parish, consituency, CCG and many more.
There is also a bulk_reverse_geocoding() function which takes several lat and lon inputs.

Calculate Convex Hull of points from a set of (lat/long) points

I am working on a web app with Google Map that I’d like to display a “coverage area”/’ geographical area” by creating a polygon overlay of a given set of geo coordinates/points.
The “coverage area” can consist of thousands of the geo coordinates (Longitude and Latitude data stored in a table in sql server). Ideally, I’d like to calculate the Convex Hull points from the sql server database (2008 R2) so I can pass the results (points) to the Google Map to create the polygon overlay.
The sample here (http://www.geocodezip.com/v3_map-markers_ConvexHull.asp) is exactly what I am looking for, except that I’d like to get the hull points on the right-panel straight from the SQL server if possible. The reason is that I may have to process thousands of the geo coordinates. I’d rather not to retrieve a huge amount of data from the database and then send to the client using JavaScript to calculate the convex hull points.
Any help will be very much appreciated!!!
Thank you.
You didn't mention what version you're on, but there's a built in ConvexHullAggregate starting in SQL 2012 that should do exactly what you're looking for.
Here's an extension of the example in the linked to documentation that gets the coordinates of the corners of the convex hull. It assumes that you have a table of numbers laying around (a pretty useful thing in my experience).
with cte as (
SELECT City, geography::ConvexHullAggregate(SpatialLocation) AS Hull
FROM Person.Address
WHERE City in ('Ottawa', 'Burnaby')
group by City
)
select City, Number, Edge.Long as Long, Edge.Lat as Lat
from cte
cross apply (
select Number, Hull.STPointN(Number) as Edge
from dbadmin.dbo.Numbers
where Number < Hull.STNumPoints()
) as HullEdges

I tried all ways, but still my area is calculated wrongly in Postgis

I created a very simple polygon in the middle of Germany to demonstrate my problem.
You can visualize it in geojsonlint using the following GeoJSON
{"type":"Polygon","coordinates":[[
[10.439844131469727,51.17460781257472],
[10.430574417114258,51.1753073564544],
[10.429565906524658,51.17179607723465],
[10.438792705535889,51.170706315523866],
[10.439372062683105,51.17267055874809],
[10.43975830078125,51.17439256616884],
[10.439844131469727,51.17460781257472]]]G}
When calculating the surface with online tools (e.g. http://www.daftlogic.com/projects-google-maps-area-calculator-tool.htm, but I tried several),
I get the following numbers (these are based on a similar drawing of the polygon, but not the exact same one, as I couldn't copy it over to these tools):
276583.39 m²
0.28 km²
68.35 acres
27.66 hectares
2977118.86 feet²
0.08 square nautical miles
Now I want to calculate these areas using POSTGIS, but I always get wrong and not matching numbers.
First I started without transformation using the examples given here:
http://postgis.net/docs/ST_Area.html
SELECT ST_Area(the_geom) As sqft, ST_Area(the_geom)*POWER(0.3048,2) As sqm
FROM (SELECT ST_GeomFromText('
POLYGON ((51.17460781257472 10.439844131469727,
51.1753073564544 10.430574417114258,
51.17179607723465 10.429565906524658,
51.170706315523866 10.438792705535889,
51.17267055874809 0.439372062683105,
51.17439256616884 10.43975830078125,
51.17460781257472 10.439844131469727))',4326) ) As foo(the_geom);
--> sqft = 3.52643124351653e-05 and sqm = 3.27616182873666e-06
How can I interprete these numbers?
Then I tried to transform it to WGS 84 / UTM zone 33N 32633
SELECT ST_Area(the_geom) As sqft, ST_Area(the_geom)*POWER(0.3048,2) As sqm
FROM (SELECT ST_Transform(ST_GeomFromText('
POLYGON ((51.174661624019286 10.440187454223633,
51.17067940750161 10.438899993896484,
51.17197097486416 10.429544448852539,
51.17536116708255 10.430488586425781,
51.174661624019286 10.440187454223633))',4326),32633) ) As foo(the_geom);
--> sqft = 662918.939349234 and sqm = 61587.1847391195
But even these numbers don't come close.
The coordinates of the polygon were accidentally loaded as lat,lon instead of lon, lat.
http://postgis.net/2013/08/18/tip_lon_lat
says
In spatial databases spatial coordinates are in x = longitude, and y = latitude
I converted the coordinates into EPSG: 31467, see epsg:31467 which is projected to meters and applies to the area of Germany covered by your geometry.
select st_area(st_transform(st_setsrid(st_geomfromtext('POLYGON((10.439844131469727
51.17460781257472,10.430574417114258 51.1753073564544,10.429565906524658
51.17179607723465,10.438792705535889 51.170706315523866, 10.439372062683105
51.17267055874809, 10.43975830078125 51.17439256616884, 10.439844131469727
51.17460781257472))'),4326),31467));
and got the answer: 274442.27 m2 which is within 0.007% of your original answer.
Measurements are usually more accurate in projected coordinate systems that use a geoid appropriate to that region. If you run this query on the spatial reference system table in Postgis for that projection:
select * from spatial_ref_sys where srid=31467;
you will see some more details, such as the fact that it uses the Bessel 1841 spheroid.
EDIT: your original geojson has coordinates in x/y, but for some reason you flipped them when putting them into Postgis.

Resources