0

I have been spatially joining land use zones to parcels successfully with the following query:

CREATE TABLE new_parcel AS
SELECT DISTINCT ON(t.geom) t.*, m.basezone, m.overlay
FROM parcel AS t
LEFT JOIN zoning AS m
 ON st_intersects(t.geom, m.geom)
 AND st_area(st_intersection(t.geom, m.geom)) / st_area(t.geom) > 0.5

Currently, more than 50% of the parcel's area must be within a single zone for a join to occur.

However, it turns out that some of the parcels overlap 3 or more zones and are not getting joined to the zoning table because less than 50% of their area overlaps. For example, the parcels of dark purple color overlap more than two zones:

enter image description here

How would one modify the query to add extra columns in the resulting table which would include data from all zones overlapped?

The existing code produces a table that has

basezone | overlay

How could one produce

basezone_2|overlay_2|basezone_3|overlay_3|...

and so on for all zones overlapped?

Evan Carroll
7,2592 gold badges34 silver badges67 bronze badges
asked Dec 21, 2016 at 3:34
2
  • Got any sample data? Commented Dec 21, 2016 at 6:19
  • Remove the distinct clause and add sum(ST_Area(ST_Intersection(.... I think, so you would get the sum of all intersected areas for any given t.geom. Commented Dec 21, 2016 at 6:55

1 Answer 1

1

What you're asking for isn't easy because you don't know how many columns to produce until after the query is complete. crosstab from tablefunc will permit some of this, but because you're not providing any sample data it's damn near impossible.

As a mater of the join,

In order to first tell which zones overlap multiple zones with more than 50% of their area, you have to

  1. Calculate all zones that overlap with a join of parcel/zoning,
  2. Calculate the area of the overlap.

Then afterward, you can see if the combined overlap is greater tan 50%.

A join operation works row-wise. There is no concept of a join based on a function of the other table the row. Modifying your query, it would look something like this...

First, you need the

SELECT t.parcel
FROM (
 SELECT p.geom AS parcel,
 m.geom AS zoning,
 st_area(st_intersection(p.geom, m.geom)) AS areaintersection
 FROM parcel AS p
 JOIN zoning AS m
 ON st_intersects(p.geom, m.geom)
) AS t
GROUP BY t.parcel
HAVING sum(areaintersection) / st_area(t.geom) > 0.5;

Now, should be a result set of parcel.geom. From there, you can INNER JOIN back to parcel, and to zoning to get a list that you can feed to crosstab().

answered Dec 21, 2016 at 7:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.