Creating Postgis Polygon using ST_ConcaveHull from Geometry Points - postgresql

I have a postgis 2.2 table with 20 columns of type geometry(Point,4326)
I'd like to generate a polygon which covers the outer boundary of the points - it seems like ST_ConcaveHull is a good option, but I can't see how to do it without first converting my points back to text (which seems to be missing the point).
Is st_concavehull the right option, and how do I go about constructing the query?
Thanks!

You first need to collect your points, then pass this collection to ST_ConcaveHull:
ST_ConcaveHull(ST_Collect(geom), 1)
Per the ST_ConcaveHull documentation:
Although it is not an aggregate - you can use it in conjunction with ST_Collect or ST_Union to get the concave hull of a set of points/linestring/polygons ST_ConcaveHull(ST_Collect(somepointfield), 0.80).

Related

Geopoints: From Single Coordinate to Bounds on map

I try to figure out how to come from a single given coordinate (lat/lon) to the nearest bounds which enclose this coordinate on a map e.g. streets or sea.
Here two examples to give you a better understanding of what I mean:
What i tried already or thought about:
Setting up a Nominatim server and search for the given coordinate via the reverse-function to get the bbox and/or the geojson polygon of this coordinate. -> this only works when the given coordinate is within a POI or for example directly on a street.
Writing an algorithm to walk in all 4 or 8 directions (n/e/s/w) and 'stop' when the map layer/surface changes (change = stop for this direction and mark a bounding-point)
Building up an image-recognition system using TensorFlow to detect the different colors and 'draw' the polygon. Worked with TensorFlow a couple of times but this seems to be the most tricky solution to implement (but at my current understanding the most precise one)
Does someone of you have any other ideas to get a solution for this problem? Would appreciate any kind of approaches
Cheers!
If I got your question right, you might wanna first select all polygons in which the given point is inside of using ST_Contains, and then compute the distance to this point using ST_Distance. If you ORDER BY distance and LIMIT to 1 result you'll get the nearest polygon, e.g.
Data Sample
CREATE TABLE t (gid int, geom geometry);
INSERT INTO t VALUES
(1,'POLYGON((-4.47 54.26,-4.44 54.28,-4.41 54.24,-4.46 54.23,-4.47 54.26))'),
(2,'POLYGON((-4.48 54.25,-4.40 54.25,-4.41 54.23,-4.48 54.23,-4.48 54.25))'),
(3,'POLYGON((-4.53 54.23,-4.44 54.29,-4.38 54.22,-4.53 54.23))');
Query
SELECT gid,ST_AsText(geom) FROM t
WHERE ST_Contains(geom,ST_MakePoint(-4.45, 54.25))
ORDER BY ST_Distance(geom,ST_MakePoint(-4.45, 54.25))
LIMIT 1;
gid | st_astext
-----+------------------------------------------------------------------------
1 | POLYGON((-4.47 54.26,-4.44 54.28,-4.41 54.24,-4.46 54.23,-4.47 54.26))
(1 Zeile)

Why ST_Intersection from Postgis returns multilinestring for self-intersecting linestrings?

I am trying on PostgreSQL with the extension Postgis to get the geometry of a gps_trace that intersects a box, then i want to get one linestring for each distinct part of the trace in the box. In the following example with 1 trace and 1 box , that would mean ST_intersection returns me a multilinestring with 2 linestrings inside, so that i can extract each of them with ST_Dump()
The geometries are in epsg 4326, I use the request SELECT ST_Intersection(gps_traces.geom, grid.box)
FROM gps_traces, grid
But as a result, i get a multilestring with 34 geometries inside. After zooming a little, i discovered that when the line self-intersects, it seems to consider and register each part as a separate linestring although at the beginning, the trace was a linestring in one go.
I am extremely surprised of this behavior, and didn't find any documentation on the subject nor topics that talked about it, so i'm asking here how is build the geometry resulting from an intersection and why I get this behavior ?
This is the first time i get to use stackoverflow, so I apologize if some elements are missing

Calculate distance between two coordinates using postgres?

I´ve got a job offer to work with postgres and I have not much idea of it. The guy told me to build a simple data base which automatically calculates the distance to my house from a list of some other places (bars, pharmacies, museums, whatever...) everything given in geocoordinates.
I have already installed postgres, also postgis and create a data base. May you give me some hints about how I should do this task? Is there any tutorial or resource I could use to make this tasks easier? Should I use postgis?
Thank you.
PostGIS will do this easily. Boundless Geo have an excellent PostGIS tutorial. I also recommend you are familiar with Ch3 & 4 of the PostGIS manual.
I strongly advise you to learn & understand the difference between projected and unprojected coordinates if you're going to be working with spatial data. Projected means the coordinates have been taken from a 'round earth' and adjusted or projected onto to a flat map page (with coordinates normally given in feet or metres depending on the properties of the projection used). This enables computationally efficient normal cartesian calculations to be done for distance, area, direction, intersection, contains etc. There are trade offs for using projections- You can't preserve all of area, distance, shape, direction when you project a curved line or surface onto a flat map. Different projections are optimised for different trade-offs. Calculations on projected data are only accurate over a relatively small portion of the earth's surface. There are many map projections available to suit various needs and localities. If you are going to be working with projected data, you need to pick a projection that suits your purposes and location. If you don't understand projections, your queries can easily produce garbage without realising it.
Unprojected data (ie, raw Lat/Lon coordinates which is what you have) involve much more complicated calculations as they are done on the curved surface of the spheroid representing the earth. There are a number of reference coordinate systems that are used to express Lat/Lon, however the most common is "WGS84" (which is what "GPS" coordinates are expressed in).
PostGIS objects (in the form of "simple features" as defined by the OGC) can be stored as either "geometry" types (projected coordinates) or "geography" types (unprojected Lon/Lat in WGS84: note the order, a common source of confusion!). As a bit of a wrinkle, Lon/Lat (order again!) can also be stored as a "pseudo projected" geometry type (typically with a projection SRID of '4326' for WGS84 Lon/Lat).
The method you use to calculate distance will depend on how you choose to store your points ('geometry' or 'geography').
See ST_Distance from the PostGIS docs for excellent examples of measuring distance using both geometry and geography points. Note, if you wish to calculate projected map distances you will need to pick an appropriate map projection and use ST_Transform to project your points to the appropriate spatial reference system (currently in SRID 4326- "GPS" coordinates). For only a few points the difference won't be at all noticeable, but once you start doing lots of more complex spatial queries, the difference can be significant. PostGIS has a lot more functions for geometry types than for geography types which may influence your decision. Also see ST_DistanceSpheroid for another possibility for calculating distance from Lon/Lat coordinates.
To start with, I'd store your points as 'geography' to simplify your experiments. Your distances will then be 'great circle' calcs in metres and you won't have to worry about projections initially.

Geoserver - How do I draw a geodesic line that represents the great circle between two points

I'm using Geoserver version 2.1.1, Postgres 9 and PostGIS 2.0
What I want to achieve should (i think!) be quite straight forward. I want to render on a map a line that represents the Great Circle between two cities on the earths surface.
My database contains the city locations represented as geography points defined as latitude and lonfitude pairs.
I have a layer defining an SQL view in Geoserver which retrieves a linestring (st_makeline) from the two coordinates for the specified cities. I'm having to type cast the geographies to geometries to get this to work.
But when I draw the returned line on a map what i get is a straight line and not the curved line that I am expecting.
Can someone tell me how I should be going about this?
Thanks!
PostGIS offers mainly "constructors" of the base geometries point, linestring and polygone, like ST_MakeLine.
And what yo uwant to do depends also on the coordinate reference system you use when displaying your map layers.
Here's a nice trick about great circles or parts of:
https://gis.stackexchange.com/questions/5204/curved-point-to-point-route-maps
Yours, Stefan
P.S. Here's some related stuff:
Drawing circles on a sphere
And here's some math:
http://www.mathworks.ch/matlabcentral/newsreader/view_thread/277881
I had a similar problem in cartodb (which also uses PostGIS); I wanted to get curved lines from straight lines. Maybe this post can help.

Unions of polygons (ST_UNION for Geography type)

I am looking for a function that will return the intersection of 2 or more polygons (geography type).
I am aware of ST_UNION, ST_COLLECT but it works only for geometry type.
Any tip will be really appreciated
You can cast to geometry and carry out the operation there. You will just have to be careful that your shapes makes sense when evaluated on a cartesian plane. Do they wrap the dateline or poles?
select geography(st_union(a::geometry, b::geometry))
If the shapes have very long edges, then the difference in edge interpolation between the great circle interpolation you want on a sphere and the linear interpolation you get on a plane comes into play, and you have to get fancier to preserve the edge shapes as best you can by working in an appropriate map projection (automatically chosen with the bestsrid function).
select geography(
st_transform(
st_union(
st_transform(a::geometry, _st_bestsrid(a,b)),
st_transform(b::geometry, _st_bestsrid(a,b))
),
4326
))
Enjoy!
The Geography type supports only a small subset of the PostGIS functions. Here you can check them all and see if any of them suits your needs:
http://postgis.refractions.net/docs/ch08.html#PostGIS_GeographyFunctions
Have you considered a ST_Transform into a geometry type nested within the ST_Union or ST_Collect? PostGIS docs (from amercader's link) say they use that function internally for some geography operations.