1

I have created random points in a polygon and further created a square buffer around them. Now, I want to generate smaller polygons by keeping 100m distance on one side and keeping 200m distance on the other side of the existing polygons. How is it possible in QGIS 3 or PyQGIS? I suppose 'Geometry by Expression' tool can be useful but not able to frame the expression.

1
  • Can you add a screenshot how it should look? From your description, I can't imagine. And: what are "square buffers" - how do you create them?
    – Babel
    Commented Sep 30, 2021 at 20:05

1 Answer 1

2

Not sure if you want to store/create the geometry or if it is just for display. Using geometry generator, you can combine two buffers the one on the exterior side and the other on the interior. The expression should be the same if using "Geometry by Expression".

To do that, you can use something like below in the expression. Caution: screenshots display the original border for demonstration purpose but the polygon buffer is continuous

with_variable('buffer_out', 100,
  with_variable('buffer_in', -200,
    with_variable('exterior_ring', exterior_ring($geometry), /* convert to linestring */
      with_variable('sub_line', /* Get a portion of line from last endpoints to first ones*/
        array_foreach(
          array_filter(
            array_foreach(
              generate_series(-2, 2), 
              @element
            ),
            @element != 0
          ),
          point_n(@exterior_ring, @element)
        ),
        /* Combined both geom*/
        union(
          /* Combined inside/outside buffer using single_sided_buffer*/
          union(
            single_sided_buffer(@exterior_ring, @buffer_out, 8, 2),
            single_sided_buffer(@exterior_ring, @buffer_in, 8, 2)
          ),
          /* Do the same, inside/outside buffer but for substring */
          union(
            single_sided_buffer(make_line(@sub_line), @buffer_out, 8, 2),
            single_sided_buffer(make_line(@sub_line), @buffer_in, 8, 2)
          )
        )
      )
    )
  )
)

enter image description here

I've done a first attempt with the following but the buffer was not generated for the start/end point, hence the approach with "sub-line"

with_variable('buffer_out', 100,
  with_variable('buffer_in', -200,
    with_variable('exterior_ring', exterior_ring($geometry), /* convert to linestring */
      with_variable('sub_line', /* Get a portion of line from last endpoints to first ones*/
        array_foreach(
          array_filter(
            array_foreach(
              generate_series(-2, 2), 
              @element
            ),
            @element != 0
          ),
          point_n(@exterior_ring, @element)
        ),
          /* Combined inside/outside buffer using single_sided_buffer*/
          union(
            single_sided_buffer(@exterior_ring, @buffer_out, 8, 2),
            single_sided_buffer(@exterior_ring, @buffer_in, 8, 2)
          )
      )
    )
  )
)

enter image description here

Your Answer

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

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