4

I'm very new to QGIS and am just learning the intersect function. I have about 10 polygons that overlap (not perfectly) and one layer of about say 15 points. I want to know with which of the polygons each point intersects. The goal is to eventually have data that looks like:

enter image description here

TRUE/FALSE not needed. Any way to denote yes the point intersects with the polygon or no it does not will suffice.

New contributor
Colton is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • 1
    intersection tool does the job, but its output is so-called long format (pairs of point id and polygon id). To format it to your style (wide format), you will need to work on spreadsheet (e.g. INDEX and MATCH in MS-Excel)... not sure QGIS has such reshaping capability. – Kazuhito Jun 12 at 20:21
  • 1
    Spin up a PostgreSQL with PostGIS and use SQL spatial... short answer, but it's the best way to do this. – DPSSpatial Jun 12 at 22:12
4

Queries shall do the work but they can probably be optimised, e.g. proceeding with a loop. Currently working on those improvements


Tested on QGIS 2.18 and QGIS 3.4

I can suggest using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer...


Option 1. For features in different layers

Let's assume we have the following layers "some_points" and two polygon layers, "Layer_1" (two features) and "Layer_2" (three features) accordingly, see image below.

input_1

With the following query, it is possible to create a variable that is either TRUE or FALSE.

SELECT poi.*,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "Layer_1" AS l1
         WHERE st_intersects(poi.geometry, l1.geometry)
         AND l1.id = 1)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Layer1_1,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "Layer_1" AS l1
         WHERE st_intersects(poi.geometry, l1.geometry)
         AND l1.id = 2)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Layer1_2,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "Layer_2" AS l2
         WHERE st_intersects(poi.geometry, l2.geometry)
         AND l2.id = 1)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Layer2_1,   
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "Layer_2" AS l2
         WHERE st_intersects(poi.geometry, l2.geometry)
         AND l2.id = 2)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Layer2_2,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "Layer_2" AS l2
         WHERE st_intersects(poi.geometry, l2.geometry)
         AND l2.id = 3)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Layer2_3    
FROM "some_points" AS poi

The output Virtual Layer with its Attribute table will look as follows.

output_1


Option 2. For features in one layer

Let's assume we have the following layers "some_points" and "some_polygons", see image below.

input_2

With the following query, it is possible to create a variable that is either TRUE or FALSE.

SELECT poi.*,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "some_polygons" AS pol
         WHERE st_intersects(poi.geometry, pol.geometry)
         AND pol.id = 1)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Polygon1,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "some_polygons" AS pol
         WHERE st_intersects(poi.geometry, pol.geometry)
         AND pol.id = 2)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Polygon2,
(CASE
    WHEN poi.id IN
        (SELECT poi.id
         FROM "some_points" AS poi, "some_polygons" AS pol
         WHERE st_intersects(poi.geometry, pol.geometry)
         AND pol.id = 3)
    THEN 'TRUE'
    ELSE 'FALSE'
    END) AS Polygon3    
FROM "some_points" AS poi

The output Virtual Layer with its Attribute table will look as follows.

output_2

3

I would go with a QGIS/LibreOffice combo (HT Kazuhito):

In QGIS

Use the intersection tool to create a new layer, with repeated features.

Each time a (point) feature of the Input layer is contained in a (polygon) feature of the Overlay layer, a new (point) feature is created in the Output layer.

(Point) features not contained in any (polygon) feature will not be created in the Output layer.

Beware: this can create a lot of features.

enter image description here

In LibreOffice / Excel

  • Import/paste the table associated with the Output layer
  • Create a pivot with a Layout like the one in the next screenshot:

enter image description here

3

You can do this with the join attributes by location (summary) tool.

If your polygons are in multiple layers, merge them into a single layer before proceeding. Use the merge vector layers tool or select, copy and paste the polygons into a single layer.

I'm assuming that your polygon layer has an attribute table field (eg, "name") which contains the polygon names (eg, polygon1, polygon2, etc). If you don't have this column, you can create it with the field calculator using this expression: 'polygon' || @row_number. Or you can use @row_number = 1 in step 1 instead of the expression "name" = 'polygon1'.

  1. Use the Field Calculator to add a new numerical field named after each polygon.

    • The first polygon will have the number 1 in the column "polygon1", and 0 in the columns called "polygon2", "polygon3", etc. Use this expression: "name" = 'polygon1'

    enter image description here

    • For the second column, "polygon2", use this expression: "name" = 'polygon2'
    • Continue in the same fashion until you have a new column for each polygon.

    enter image description here

  2. Use the Join Attributes by Location (Summary) tool, which you can find in the Processing Toolbox.

    • input layer: Points
    • join layer: Polygons
    • geometric predicate: intersects
    • fields to summarize: select all the fields you created in step 1
    • summaries to calculate: select Sum

    enter image description here

    enter image description here

The output is a point layer, with an attribute table that looks like this:

enter image description here

Each point has a 1 in the column representing each polygon that it intersects. Almost every point has a 0 in the columns for polygons that it doesn't intersect.

Points that don't intersect any polygon have in all the columns. If you need all the non-intersecting fields to have 0 (currently some of them are null), update each field with the field calculator.

  • For example, for the field "polygon1" use this expression: if("polygon1" is null, 0, "polygon1") (This expression means: If the current value of the field "polygon1" is null, replace it with 0. Otherwise, keep the current value.)

If you want the 0's and nulls to display as FALSE, and the 1's to display as TRUE, you can set up Value Map field edit widgets in the layer properties.

enter image description here enter image description here

Your Answer

Colton is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.