-- The city engineer needs to know the total area of the city's lot area
-- not covered by buildings. In fact, she wants the sum of the lot area
-- after the building area has been removed.

CREATE TABLE buildingfootprints (building_id  integer,
                                 lot_id       integer,
                                 footprint    ST_Multipolygon);

CREATE TABLE lots (lot_id  integer,
                   lot     ST_Multipolygon);


INSERT INTO buildingfootprints VALUES(
   506, 1010,
   ST_MPolyFromText('multipolygon (((7.0 45.0,15.0 45.0,15.0 51.0,18.0 51.0,18.0 54.0,8.0 54.0,8.0 51.0,7.0 51.0,7.0 45.0)))',1000)
);

INSERT INTO buildingfootprints VALUES(
   543, 2930,
   ST_MPolyFromText('multipolygon (((26.0 55.0,38.0 55.0,38.0 48.0,34.0 48.0,34.0 50.0,26.0 50.0,26.0 55.0)))',1000)
);

INSERT INTO buildingfootprints VALUES(
   1208, 203,
   ST_MPolyFromText('multipolygon (((8.0 37.0,12.0 37.0,12.0 33.0,17.0 33.0,17.0 22.0,8.0 22.0,8.0 37.0)))',1000)
);

INSERT INTO buildingfootprints VALUES(
   178, 5192,
   ST_MPolyFromText('multipolygon (((26.0 33.0,38.0 33.0,38.0 24.0,33.0 24.0,33.0 27.0,26.0 27.0,26.0 33.0)))',1000)
);

INSERT INTO lots VALUES(
   1010,
   ST_MPolyFromText('multipolygon (((2 57,21.5 57,21.5 38,2 38,2 57)))',1000)
);

INSERT INTO lots VALUES(
   2930,
   ST_MPolyFromText('multipolygon (((21.5 57,40 57,40 38,21.5 38,21.5 57)))',1000)
);

INSERT INTO lots VALUES(
   5192,
   ST_MPolyFromText('multipolygon (((21.5 38,40 38,40 20,21.5 20,21.5 38)))',1000)
);

INSERT INTO lots VALUES(
   203,
   ST_MPolyFromText('multipolygon (((2 20,2 38,21.5 38,21.5 20,2 20)))',1000)
);

-- The city engineer equijoins the buildingfootprints and lots
-- table on the lot_id and takes the sum of the area of the difference
-- of the lots less the building footprints.

SELECT SUM(ST_Area(ST_Difference(lot,footprint)::ST_MultiPolygon))
   FROM buildingfootprints bf, lots
   WHERE bf.lot_id = lots.lot_id;
