Polygons from two different shapefiles that share common border in QGIS?

Goal: Isolate the small polygons adjacent to the border which divides them into two different larger polygons/areas.


Concept: Either select everything by hand (feasible if this is only a one-time-job and few polygons like in this case), or use the select by location tool to select all areas adjacent to the border. To do so we need to get the line feature of the border first.


Workflow:

  1. Use merge vector layers to combine both/all layers with small polygons. Save this output, since we need it later on.
  2. Run dissolve on the merged data. Set the district name column as an attribute to keep (everything with the same district name is combined to one polygon, but different districts will be kept). This output can be temporary.
  3. Convert polygons to lines with your dissolved data. This will give you the district boundaries. Another temporary output.
  4. Dissolve again, this time the line layer, and this again is a temporary output.
  5. Use multipart to singlepart on your dissolved line layer. This splits the border lines at every intersection. If you need to repeat the process later on, save this output.
  6. In the latest processing output manually select the border which is of interest to you. enter image description here
  7. Use select by location to select every feature in your village-layer which touches the selected line in the line layer with the borders. enter image description here
  8. Save your selected village-polygons to a new file. enter image description here

As you can see, the preparation takes some time, but if done right, it can save you time later on, if you have to repeat the process.


Here I am using Virtual Layer approach because it can save me from following a step-by-step workflow, where the output of the previous has to be used as the input for the next geoalgorithm.


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

Let's assume we have two layers "units_1" (yellow) and "units_2" (green) with its corresponding attribute tables accordingly, see image below (I tried to recreate the upper example).

input

With the following query, it is possible to get the border featuress (villages) on both side of the border.

SELECT u1.*, "unit_1" AS Name
FROM "unit_1" AS u1, "unit_2" AS u2
WHERE st_touches(u1.geometry, u2.geometry)
UNION
SELECT u2.*, "unit_2" AS Name
FROM "unit_1" AS u1, "unit_2" AS u2
WHERE st_touches(u2.geometry, u1.geometry)

The output Virtual Layer with its Attribute table will look as following

output


In case when the "one-vertices-neighbors" have to be ignored use a little bit different query

SELECT u1.*, "unit_1" AS Name
FROM "unit_1" AS u1, "unit_2" AS u2
WHERE st_touches(u1.geometry, u2.geometry) AND st_length(st_intersection(u1.geometry, u2.geometry)) > 0
UNION
SELECT u2.*, "unit_2" AS Name
FROM "unit_1" AS u1, "unit_2" AS u2
WHERE st_touches(u2.geometry, u1.geometry) AND st_length(st_intersection(u2.geometry, u1.geometry)) > 0

Then the new output Virtual Layer with its Attribute table will look as following

output_2

Note: st_touches is gently sensitive therefore, gaps, overlaps, and other geometric inconsistencies have to be cleaned up before applying the query.