PostGIS cheat sheet

From Wildsong
Jump to navigationJump to search

Table join

I have attributes for taxlots in a separate table. (It came in a DBF file and I loaded it with "shp2pgsql -n") I want to join it so that I only see a single spatial table instead of having to do the join in QGIS or ArcMap.

CREATE VIEW taxlot_rprop
  SELECT *
  FROM taxlot as t LEFT JOIN rprop as r ON t.maptaxlot=r.maptaxlot;

This exposes every attribute in an ugly way. Normally I'd pare it down and normalize it for example

CREATE VIEW or_co_lincoln.taxlot_rprop AS
  SELECT t.gid as gid, t.the_geom as the_geom, t.maptaxlot, r.siteaddnam as situs, r.primaccnum as rpropid
  FROM or_co_lincoln.taxlot as t LEFT JOIN rprop as r ON t.maptaxlot = r.maptaxlot;


Dissolve

I want one multipolygon per state. Note that I can use the MIN function for both the numeric gid field and the text name field.

CREATE VIEW ca_gold.states AS
  SELECT MIN(gid) AS gid, MIN(state) AS name, ST_Multi(ST_Union(ST_Transform(geom,2226)))
  FROM us_national_atlas.states GROUP BY statesp010;

Spatial joins

Update an attribute with a value from a second table

I want to copy the name of a community from 'community' table to 'address_point' table.

The table looks like this. My schema is called "ca_gold".

CREATE TABLE ca_gold.address_points (
  gid SERIAL PRIMARY KEY,
  layer INT,
  streetnum INT4,
  streetname VARCHAR(100),
  displayname VARCHAR(100),
  unit VARCHAR(30),
  geom GEOMETRY
);

The points get copied from some other tables, using INSERT. Not showing that here...

I create a spatial index on the table to speed up the spatial query.

CREATE INDEX address_points_geom_gist ON ca_gold.address_points USING GIST(geom);

Probably totally unnecessary steps:

VACUUM ANALYZE VERBOSE ca_gold.address_points;
VACUUM ANALYZE VERBOSE ca_gold.community;

Now the fun part, add a column to hold the new attribute...

ALTER TABLE ca_gold.address_points ADD COLUMN community VARCHAR(50);

...and do the update. This updates table address_points with the 'name' value from the polygon layer, where the name is the name of the polygon that the point falls into. I found ST_Intersects to be marginally faster than ST_Contains/ST_Within. YMMV.

UPDATE ca_gold.address_points 
 SET community = sa.name FROM ca_gold.community AS sa
 WHERE ST_Intersects(ca_gold.address_points.geom, sa.geom);

-- sanity checks SELECT count(gid) FROM ca_gold.address_points; select distinct(fire_district) from ca_gold.address_points; select distinct(community) from ca_gold.address_points;

Missing PG_GEOMETRY column

This happens when you use ArcGIS to create a new feature class in a PostGIS database. They do a bad job and create broken feature classes in PostGSI. After you fix them you will discover the PostGIS database is still read-only.