12

For a little map project of mine, I need to create quadrilaterals around a polygon feature based on the bisected angles of the vertices of that feature. Here is an example:

enter image description here

Is it possible to automate this procedure, especially regarding having equal distances? I am using QGIS 3.10.

EDIT:

I am interested in the underlying map, as I want to transform the geometry. Basically I want to recreate Daniel Huffman's linear map, but with a GIS rather than a vector program without losing the spatial information (this is part of a totally different question...). I want to draw my own polygon and then derive such a quadrilateral buffer with a unique buffer of 100km towards land and perhaps 10km towards the sea.

6
  • 1
    If its expressible mathematically (which it looks to be) then it can be coded up and implemented. Done in python it can be a QGIS Processing add-on. But how are you defining the length of the quadrilateral side? For example, on the left of the lake, just over half way up, the quadrilateral internal to the lake suddenly gets larger and juts into the lake more - why? Where is that information stored?
    – Spacedman
    Jan 10 '20 at 8:15
  • @Spacedman This is not needed for my solution. For me it would be great to have equal length towards land (e.g. 100km) and a different length towards the water (e.g. 1km)
    – JoeBe
    Jan 10 '20 at 10:53
  • Are you interested in the quadrilaterals themselves or the buffer region formed by them? Do you have any Python programming skill (worth learning) or familiarity with QGIS+Python integration? I think doing it with standard QGIS processing tools would be very tricky (but happy to be proved wrong...).
    – Spacedman
    Jan 10 '20 at 11:56
  • I have Python experience and did one or two little Python processing scripts for QGIS layers. But I never had to create new polygons based on some other polygons.
    – JoeBe
    Jan 10 '20 at 12:11
  • @JoeBe, I have voted to reopen your question. But please, edit your post to include the information provided in your comments. Let other users ask details to you in the comments, and answer them in the body of the question post. Jan 15 '20 at 3:22
3

This can be done by applying the following processing sequence to your polygon:

enter image description here

  1. Buffer the shoreline polygon by the desired buffer length (e.g. 100 km for the land side and -10 km for the lake side) using the miter join style.

    Buffered

  2. Convert the shoreline polygon and the buffered polygon to lines using the Polygons to lines tool.

  3. Split the the lines into individual line segments using Explode lines

    enter image description here

  4. Add corresponding IDs to the line segments using Add autoincremental field

    enter image description here

  5. Join the two sets of line segments using Union

  6. Create a new merged ID column in the joined set

  7. Find the convex hull of the line segment pairs using Minimum bounding geometry, with the merged ID column serving as the grouping class

  1. Repeat with a negative buffer for the inner quadrilaterals.

These steps can be wrapped into a Processing model:

Processing model

<!DOCTYPE model>
<Option type="Map">
  <Option type="Map" name="children">
    <Option type="Map" name="native:addautoincrementalfield_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:addautoincrementalfield"/>
      <Option type="QString" name="component_description" value="Add autoincremental field"/>
      <Option type="double" name="component_pos_x" value="402"/>
      <Option type="double" name="component_pos_y" value="457"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:addautoincrementalfield_1"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="false"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="FIELD_NAME">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value="ID_2"/>
          </Option>
        </Option>
        <Option type="List" name="GROUP_FIELDS">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="StringList" name="static_value">
              <Option type="QString" value=""/>
            </Option>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:explodelines_1"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="SORT_ASCENDING">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="bool" name="static_value" value="true"/>
          </Option>
        </Option>
        <Option type="List" name="SORT_EXPRESSION">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value=""/>
          </Option>
        </Option>
        <Option type="List" name="SORT_NULLS_FIRST">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="bool" name="static_value" value="false"/>
          </Option>
        </Option>
        <Option type="List" name="START">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="0"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:addautoincrementalfield_2">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:addautoincrementalfield"/>
      <Option type="QString" name="component_description" value="Add autoincremental field"/>
      <Option type="double" name="component_pos_x" value="155"/>
      <Option type="double" name="component_pos_y" value="453"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:addautoincrementalfield_2"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="FIELD_NAME">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value="ID_1"/>
          </Option>
        </Option>
        <Option type="List" name="GROUP_FIELDS">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="StringList" name="static_value">
              <Option type="QString" value=""/>
            </Option>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:explodelines_2"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="SORT_ASCENDING">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="bool" name="static_value" value="true"/>
          </Option>
        </Option>
        <Option type="List" name="SORT_EXPRESSION">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value=""/>
          </Option>
        </Option>
        <Option type="List" name="SORT_NULLS_FIRST">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="bool" name="static_value" value="false"/>
          </Option>
        </Option>
        <Option type="List" name="START">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="0"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:buffer_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:buffer"/>
      <Option type="QString" name="component_description" value="Buffer"/>
      <Option type="double" name="component_pos_x" value="395"/>
      <Option type="double" name="component_pos_y" value="148"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:buffer_1"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="DISSOLVE">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="bool" name="static_value" value="false"/>
          </Option>
        </Option>
        <Option type="List" name="DISTANCE">
          <Option type="Map">
            <Option type="QString" name="parameter_name" value="buffer"/>
            <Option type="int" name="source" value="0"/>
          </Option>
        </Option>
        <Option type="List" name="END_CAP_STYLE">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="0"/>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="parameter_name" value="input"/>
            <Option type="int" name="source" value="0"/>
          </Option>
        </Option>
        <Option type="List" name="JOIN_STYLE">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="MITER_LIMIT">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="double" name="static_value" value="2"/>
          </Option>
        </Option>
        <Option type="List" name="SEGMENTS">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="1"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:explodelines_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:explodelines"/>
      <Option type="QString" name="component_description" value="Explode lines"/>
      <Option type="double" name="component_pos_x" value="407"/>
      <Option type="double" name="component_pos_y" value="345"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:explodelines_1"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:polygonstolines_1"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:explodelines_2">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:explodelines"/>
      <Option type="QString" name="component_description" value="Explode lines"/>
      <Option type="double" name="component_pos_x" value="158"/>
      <Option type="double" name="component_pos_y" value="344"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:explodelines_2"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:polygonstolines_2"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:polygonstolines_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:polygonstolines"/>
      <Option type="QString" name="component_description" value="Polygons to lines"/>
      <Option type="double" name="component_pos_x" value="391"/>
      <Option type="double" name="component_pos_y" value="236"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:polygonstolines_1"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:buffer_1"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:polygonstolines_2">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:polygonstolines"/>
      <Option type="QString" name="component_description" value="Polygons to lines"/>
      <Option type="double" name="component_pos_x" value="164"/>
      <Option type="double" name="component_pos_y" value="234"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:polygonstolines_2"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="parameter_name" value="input"/>
            <Option type="int" name="source" value="0"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:union_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="native:union"/>
      <Option type="QString" name="component_description" value="Union"/>
      <Option type="double" name="component_pos_x" value="307"/>
      <Option type="double" name="component_pos_y" value="587"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="native:union_1"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:addautoincrementalfield_1"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="OVERLAY">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:addautoincrementalfield_2"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="OVERLAY_FIELDS_PREFIX">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value=""/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="qgis:fieldcalculator_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="qgis:fieldcalculator"/>
      <Option type="QString" name="component_description" value="Field calculator"/>
      <Option type="double" name="component_pos_x" value="308"/>
      <Option type="double" name="component_pos_y" value="696"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="qgis:fieldcalculator_1"/>
      <Option name="outputs"/>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="FIELD_LENGTH">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="10"/>
          </Option>
        </Option>
        <Option type="List" name="FIELD_NAME">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value="ID"/>
          </Option>
        </Option>
        <Option type="List" name="FIELD_PRECISION">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="3"/>
          </Option>
        </Option>
        <Option type="List" name="FIELD_TYPE">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="FORMULA">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value="if(&quot;ID_1&quot; IS NOT NULL, &quot;ID_1&quot;, &quot;ID_2&quot;)"/>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="native:union_1"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="NEW_FIELD">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="bool" name="static_value" value="true"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="qgis:minimumboundinggeometry_1">
      <Option type="bool" name="active" value="true"/>
      <Option name="alg_config"/>
      <Option type="QString" name="alg_id" value="qgis:minimumboundinggeometry"/>
      <Option type="QString" name="component_description" value="Minimum bounding geometry"/>
      <Option type="double" name="component_pos_x" value="319"/>
      <Option type="double" name="component_pos_y" value="796"/>
      <Option name="dependencies"/>
      <Option type="QString" name="id" value="qgis:minimumboundinggeometry_1"/>
      <Option type="Map" name="outputs">
        <Option type="Map" name="Output">
          <Option type="QString" name="child_id" value="qgis:minimumboundinggeometry_1"/>
          <Option type="QString" name="component_description" value="Output"/>
          <Option type="double" name="component_pos_x" value="536"/>
          <Option type="double" name="component_pos_y" value="868"/>
          <Option type="invalid" name="default_value"/>
          <Option type="bool" name="mandatory" value="false"/>
          <Option type="QString" name="name" value="Output"/>
          <Option type="QString" name="output_name" value="OUTPUT"/>
        </Option>
      </Option>
      <Option type="bool" name="outputs_collapsed" value="true"/>
      <Option type="bool" name="parameters_collapsed" value="true"/>
      <Option type="Map" name="params">
        <Option type="List" name="FIELD">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="QString" name="static_value" value="ID"/>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option type="QString" name="child_id" value="qgis:fieldcalculator_1"/>
            <Option type="QString" name="output_name" value="OUTPUT"/>
            <Option type="int" name="source" value="1"/>
          </Option>
        </Option>
        <Option type="List" name="TYPE">
          <Option type="Map">
            <Option type="int" name="source" value="2"/>
            <Option type="int" name="static_value" value="3"/>
          </Option>
        </Option>
      </Option>
    </Option>
  </Option>
  <Option name="help"/>
  <Option type="QString" name="model_group" value=""/>
  <Option type="QString" name="model_name" value="Quadrilat"/>
  <Option type="Map" name="parameterDefinitions">
    <Option type="Map" name="buffer">
      <Option type="int" name="data_type" value="1"/>
      <Option type="QString" name="default" value="0"/>
      <Option type="QString" name="description" value="Buffer value"/>
      <Option type="int" name="flags" value="0"/>
      <Option type="double" name="max" value="1.7976931348623157e+308"/>
      <Option name="metadata"/>
      <Option type="double" name="min" value="-1.7976931348623157e+308"/>
      <Option type="QString" name="name" value="buffer"/>
      <Option type="QString" name="parameter_type" value="number"/>
    </Option>
    <Option type="Map" name="input">
      <Option type="List" name="data_types">
        <Option type="int" value="2"/>
      </Option>
      <Option type="invalid" name="default"/>
      <Option type="QString" name="description" value="Input"/>
      <Option type="int" name="flags" value="0"/>
      <Option name="metadata"/>
      <Option type="QString" name="name" value="input"/>
      <Option type="QString" name="parameter_type" value="vector"/>
    </Option>
    <Option type="Map" name="qgis:minimumboundinggeometry_1:Output">
      <Option type="bool" name="create_by_default" value="true"/>
      <Option type="int" name="data_type" value="2"/>
      <Option type="invalid" name="default"/>
      <Option type="QString" name="description" value="Output"/>
      <Option type="int" name="flags" value="0"/>
      <Option name="metadata"/>
      <Option type="QString" name="name" value="qgis:minimumboundinggeometry_1:Output"/>
      <Option type="QString" name="parameter_type" value="sink"/>
      <Option type="bool" name="supports_non_file_outputs" value="true"/>
    </Option>
  </Option>
  <Option type="Map" name="parameters">
    <Option type="Map" name="buffer">
      <Option type="QString" name="component_description" value="buffer"/>
      <Option type="double" name="component_pos_x" value="393"/>
      <Option type="double" name="component_pos_y" value="49"/>
      <Option type="QString" name="name" value="buffer"/>
    </Option>
    <Option type="Map" name="input">
      <Option type="QString" name="component_description" value="input"/>
      <Option type="double" name="component_pos_x" value="153"/>
      <Option type="double" name="component_pos_y" value="50"/>
      <Option type="QString" name="name" value="input"/>
    </Option>
  </Option>
</Option>
1
  • Wow! Thank you. I still will need to test this on my machine. But it looks exactly like what I want to achieve!
    – JoeBe
    Mar 24 '20 at 14:38

Your Answer

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.