4

I have four boundary points around a plot area that I measured with an RTK unit, and I need to create a shapefile that has 13 equally-sized plots within those points. I am in the EPSG:32614 projection, so the four point coordinates are:

xcoord ycoord 704388.4936225644, 4332694.122983527 704428.1828445836, 4332696.215448606 704427.2692543723, 4332714.244665029 704387.6004763406, 4332712.4337334875 

I need 13 plots between these points, as illustrated in the picture below. The dimensions should be 3.048m x 18.29m. I have tried the v.mkgrid from the GRASS toolbox, but it doesn't quite line up precisely between the points like I need it to:

enter image description here

How can I make equally-sized grids between these four points?

If you would like the shapefiles for further investigation, they can be downloaded here (total download size: 24 KB).

1
  • 2
    You can try looking at this answer. It addresses how to make subdivisions in a rectangle. The only issue is that your surveyed points assuredly don't describe a perfect rectangle. Maybe you could consider fitting a perfect rectangle using a tool like Oriented minimum bounding box? Commented May 9, 2023 at 15:46

1 Answer 1

3

Use the following expression (see below) with Geometry by expression, making the following adaptations:

  • replace the @id of the points at the bottom/top - right/left (use a label with @id to see which point has which id); See QGIS documentation: @id is the newer syntax to use for the older $id, so in older QGIS versions, you might have to replace @id with $id
  • in line 2 ($id=1), change 1 to any number of the $id of one of the points
  • in line 3, change the number to define the numbor of polygons you want to create and replace
  • replace points with the name of your points layer

Run Multipart to singleparts on the resulting layer to get separate features.

Works even for irregularily shaped polygons: enter image description here

This is the expression to use:

case when @id=1 -- must be a valid @id value of one of the points then with_variable('no',13, -- no. of sub-polygons you want the polygon to divide into with_variable( 'line1', make_line ( geometry (get_feature_by_id ('points', 0)), -- @id of point at bottom left geometry (get_feature_by_id ('points', 1)) -- @id of point at bottom right ), with_variable( 'line2', make_line ( geometry (get_feature_by_id ('points', 3)), -- @id of point at top left geometry (get_feature_by_id ('points', 2)) -- @id of point at top right ), collect_geometries ( array_foreach ( generate_series (1,@no), make_polygon( make_line( end_point( line_substring ( @line1, 0, length(@line1)/@no*(@element-1) ) ), end_point( line_substring ( @line1, 0, length(@line1)/@no*@element ) ), end_point( line_substring ( @line2, 0, length(@line2)/@no*@element ) ), end_point( line_substring ( @line2, 0, length(@line2)/@no*(@element-1) ) ) ))))))) end 

The expression in use, here with Geometry Generator (just for visual purpose, not creating actual geometries): enter image description here


If you have not one set of 4 points, but several ones, you can slightly modify the expression to subdivide all rectangles at once. For this, you have to define an array for each rectangle, listing the points as you can see in the screenshot (find the expression below):

enter image description here

collect_geometries( case when @id=1 -- must be a valid $id value of one of the points then with_variable('no',13, -- no. of sub-polygons you want the polygon to divide into array_foreach( array ( array (0,1,19,18), array (19,18,20,15), array(22,11,23,10), array(20,15,21,14), array(21,14,22,11), array(2,3,17,4), array(17,4,16,5), array(16,5,13,6), array(13,6,12,7), array(12,7,9,8) ), with_variable( 'line1', make_line ( geometry (get_feature_by_id ('points', @element[0])), -- $id of point at bottom left geometry (get_feature_by_id ('points', @element[1])) -- $id of point at bottom right ), with_variable( 'line2', make_line ( geometry (get_feature_by_id ('points', @element[2])), -- $id of point at top left geometry (get_feature_by_id ('points', @element[3])) -- $id of point at top right ), collect_geometries ( array_foreach ( generate_series (1,@no), make_polygon( make_line( end_point( line_substring ( @line1, 0, length(@line1)/@no*(@element-1) ) ), end_point( line_substring ( @line1, 0, length(@line1)/@no*@element ) ), end_point( line_substring ( @line2, 0, length(@line2)/@no*@element ) ), end_point( line_substring ( @line2, 0, length(@line2)/@no*(@element-1) ) ) )))))))) end ) 
4
  • Thank you! Is id the same as fid? I have fid instead of id. Commented May 9, 2023 at 20:04
  • 1
    You can use fid, but then you have to replace $id by fid in the expression. $id is often the same as fid, but fid is a field containing unique values. For Geopackage, you need such a field, whereas for Shapefiles, there's no need for such a field. $id, however, exists for all kind of data and is the (internal) unique numbering of the features. For that reason, I used $id, as it exists in any case, whereas fid does not (or might have different names, as id, uid etc.) Commented May 9, 2023 at 20:08
  • See docs.qgis.org/latest/en/docs/user_manual/expressions/… - this mentions that for newer versions, better use @id instead of the older $id Commented May 9, 2023 at 20:10
  • It still didn't work, sent you a pm. Commented May 9, 2023 at 20:20

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.