PostGIS fun - union some greenways
So I think to myself: Self, why don’t you stick the nearest 5 greenways in your park information? Great question self. After I tried it, I remembered (a) I had tried this before and (b) I didn’t get what I wanted.
1 | SELECT |
| trail_name | trail_surf |
|---|---|
| “Little Sugar Creek Greenway” | “Packed Gravel” |
| “Little Sugar Creek Greenway” | “Asphalt” |
| “Little Sugar Creek Greenway” | “Asphalt” |
| “Little Sugar Creek Greenway” | “Wood” |
| “Little Sugar Creek Greenway” | “Asphalt” |
Yeah, not great. It turns out the greenways are segmented in to 782 lines. For a good reason - the greenway suface is changing - but mostly it’s just trying to piss me off. I’d like to get the neareast 5 different greenways. I’d also like to retain the trail surface information for the barefoot running weirdos (no judgment). In other words, I want to group by the trail name and aggregate the geometry and surface types.
A little DuckDuckGoing and a few dozen SQL error messages later:
1 | SELECT |
| trail_name | trail_surf | geom |
|---|---|---|
| “Antiquity Greenway” | “Asphalt, Concrete” | geom |
| “Barton Creek Greenway” | “Concrete” | geom |
| “Briar Creek Greenway” | “Asphalt, Concrete, Packed Gravel, Wood” | geom |
| “Caldwell Station Creek Greenway” | “Asphalt, Concrete, Wood” | geom |
| “Campbell Creek Greenway” | “Asphalt, Concrete, Packed Gravel, Wood” | geom |
| “Charlotte City Greenway” | “Concrete” | geom |
| … | … | … |
782 records to 29! Breaking it down:
- Aggregate the trail surface values via string_agg, using the distinct clause to eliminate duplicates.
- Use ST_Union to stitch the lines together. The
::explicit bit sticks the correct information in thegeometry_columnsview (QGIS was displeased if I didn’t add this). - With the other two columns being aggregate functions, GROUP BY can be used on the trail names.
If greenways was a gigantic table, I’d dump the results into its own table for performance. But since it’s tiny, using it as a view doesn’t entail a painful performance hit (~160ms). I called the view greenways_union because naming things is hard. Now when I get the 5 closest greenways:
1 | SELECT |
| trail_name | trail_surf |
|---|---|
| “Little Sugar Creek Greenway” | “Asphalt, Concrete, Packed Gravel, Wood” |
| “McMullen Creek Greenway” | “Asphalt, Packed Gravel, Wood” |
| “Briar Creek Greenway” | “Asphalt, Concrete, Packed Gravel, Wood” |
| “Lower McAlpine Creek Greenway” | “Asphalt, Concrete, Wood” |
| “Four Mile Creek Greenway” | “Asphalt, Concrete, Packed Gravel, Wood” |
Did I mention I love Postgres and PostGIS? I love Postgres and PostGIS.