Skip to main content
deleted 13 characters in body
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245
with_variable( 'connection', make_line ( $geometry, geometry ( get_feature_by_id ('destination',@id) ) ), with_variable( 'splitbuffer', length(@connection) / 1000000, case when intersects ( @connection, aggregate( 'barrier', 'collect', @geometry ) ) then difference ( with_variable( 'res', boundary( difference( convex_hull( collect_geometries( array( @geometry, geometry ( get_feature_by_id ('destination',@id) ), collect_geometries( overlay_nearest ( 'barrier', nodes_to_points (@geometry) ) ) ) ) ), buffer (@connection, @splitbuffer) ) ), if ( length (geometries_to_array(@res)[0]) > length (geometries_to_array(@res)[1]), geometries_to_array(@res)[1], geometries_to_array(@res)[0] ) ), buffer (@connection, @splitbuffer +* @splitbuffer*01.1) ) else @connection end )) 
with_variable( 'connection', make_line ( $geometry, geometry ( get_feature_by_id ('destination',@id) ) ), with_variable( 'splitbuffer', length(@connection) / 1000000, case when intersects ( @connection, aggregate( 'barrier', 'collect', @geometry ) ) then difference ( with_variable( 'res', boundary( difference( convex_hull( collect_geometries( array( @geometry, geometry ( get_feature_by_id ('destination',@id) ), collect_geometries( overlay_nearest ( 'barrier', nodes_to_points (@geometry) ) ) ) ) ), buffer (@connection, @splitbuffer) ) ), if ( length (geometries_to_array(@res)[0]) > length (geometries_to_array(@res)[1]), geometries_to_array(@res)[1], geometries_to_array(@res)[0] ) ), buffer (@connection, @splitbuffer + @splitbuffer*0.1) ) else @connection end )) 
with_variable( 'connection', make_line ( $geometry, geometry ( get_feature_by_id ('destination',@id) ) ), with_variable( 'splitbuffer', length(@connection) / 1000000, case when intersects ( @connection, aggregate( 'barrier', 'collect', @geometry ) ) then difference ( with_variable( 'res', boundary( difference( convex_hull( collect_geometries( array( @geometry, geometry ( get_feature_by_id ('destination',@id) ), collect_geometries( overlay_nearest ( 'barrier', nodes_to_points (@geometry) ) ) ) ) ), buffer (@connection, @splitbuffer) ) ), if ( length (geometries_to_array(@res)[0]) > length (geometries_to_array(@res)[1]), geometries_to_array(@res)[1], geometries_to_array(@res)[0] ) ), buffer (@connection, @splitbuffer * 1.1) ) else @connection end )) 
added 1457 characters in body
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245

A vector based solution how to draw the shortest connecting linestring from point A to point B, but not crossing a barrier. At the very end of this solution, you find an expression for Geometry generator that shows the result in realtime when you move around points/change barrier lines.

Basic idea: create a convex hull around start/destination points and all nodes of the barrier, than use routing (shortest path algorithm) on the edges of the hull. Details below.

enter image description here

Expression for geometry generator that directly (in one step) shows the shortest connection:

enter image description here

with_variable( 'connection', make_line ( $geometry, geometry ( get_feature_by_id ('destination',@id) ) ), with_variable( 'splitbuffer', length(@connection) / 1000000, case when intersects ( @connection, aggregate( 'barrier', 'collect', @geometry ) ) then difference ( with_variable( 'res', boundary( difference( convex_hull( collect_geometries( array( @geometry, geometry ( get_feature_by_id ('destination',@id) ), collect_geometries( overlay_nearest ( 'barrier', nodes_to_points (@geometry) ) ) ) ) ), buffer (@connection, @splitbuffer) ) ), if ( length (geometries_to_array(@res)[0]) > length (geometries_to_array(@res)[1]), geometries_to_array(@res)[1], geometries_to_array(@res)[0] ) ), buffer (@connection, @splitbuffer + @splitbuffer*0.1) ) else @connection end )) 

A vector based solution how to draw the shortest connecting linestring from point A to point B, but not crossing a barrier. Basic idea: create a convex hull around start/destination points and all nodes of the barrier, than use routing (shortest path algorithm) on the edges of the hull. Details below.

enter image description here

A vector based solution how to draw the shortest connecting linestring from point A to point B, but not crossing a barrier. At the very end of this solution, you find an expression for Geometry generator that shows the result in realtime when you move around points/change barrier lines.

Basic idea: create a convex hull around start/destination points and all nodes of the barrier, than use routing (shortest path algorithm) on the edges of the hull. Details below.

enter image description here

Expression for geometry generator that directly (in one step) shows the shortest connection:

enter image description here

with_variable( 'connection', make_line ( $geometry, geometry ( get_feature_by_id ('destination',@id) ) ), with_variable( 'splitbuffer', length(@connection) / 1000000, case when intersects ( @connection, aggregate( 'barrier', 'collect', @geometry ) ) then difference ( with_variable( 'res', boundary( difference( convex_hull( collect_geometries( array( @geometry, geometry ( get_feature_by_id ('destination',@id) ), collect_geometries( overlay_nearest ( 'barrier', nodes_to_points (@geometry) ) ) ) ) ), buffer (@connection, @splitbuffer) ) ), if ( length (geometries_to_array(@res)[0]) > length (geometries_to_array(@res)[1]), geometries_to_array(@res)[1], geometries_to_array(@res)[0] ) ), buffer (@connection, @splitbuffer + @splitbuffer*0.1) ) else @connection end )) 
added 136 characters in body
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245

A vector based solution withhow to draw the result in this screenshot. Theshortest connecting lines toucheslinestring from point A to point B, but does not cross, the barrier (red line). You could easily addcrossing a buffer around the barrier to avoid that (see last screenshot at the bottom).

  Basic idea of the solution is to: create a convex hull around start/destination points and all nodes of the barrier, than use routing (shortest path algorithm) on the edges of the hull. Details below.

See the result in the screenshot. The connecting lines (black) touch, but do not cross, the barrier (red line). If you want the connecting line to have a certain distance from the barrier, you could easily do that by adding a buffer around the barrier: see last screenshot at the bottom.

  1. Create the direct, connecting linesconnecting lines between start and destination points.

  2. Keep only lines that do not crossOnly keep lines that do not cross a barrier.

  3. Where the line crosses a barrier, create the convex hullconvex hull from the geometry collection, containing: A) start point, B) destination point, plusC) all nodes (vertices) of the barrier line that the line from step 1 crosses.

  4. ConvertGet the boundary of the convex hull to the boundary.

  5. Use shortest pathshortest path algorithm from start to destination, using the boundary from step 4 as network.

For steps 1 to 4, I use the followingthis expression:

A vector based solution with the result in this screenshot. The connecting lines touches, but does not cross, the barrier (red line). You could easily add a buffer around the barrier to avoid that (see last screenshot at the bottom).

  Basic idea of the solution is to create a convex hull around start/destination points and all nodes of the barrier, than use routing (shortest path algorithm) on the edges of the hull. Details below.

  1. Create the direct, connecting lines between start and destination points.

  2. Keep only lines that do not cross a barrier.

  3. Where the line crosses a barrier, create the convex hull from the geometry collection, containing: start point, destination point, plus all nodes (vertices) of the barrier line that the line from step 1 crosses.

  4. Convert the convex hull to the boundary.

  5. Use shortest path algorithm from start to destination, using the boundary from step 4 as network.

For steps 1 to 4, I use the following expression:

A vector based solution how to draw the shortest connecting linestring from point A to point B, but not crossing a barrier. Basic idea: create a convex hull around start/destination points and all nodes of the barrier, than use routing (shortest path algorithm) on the edges of the hull. Details below.

See the result in the screenshot. The connecting lines (black) touch, but do not cross, the barrier (red line). If you want the connecting line to have a certain distance from the barrier, you could easily do that by adding a buffer around the barrier: see last screenshot at the bottom.

  1. Create the direct, connecting lines between start and destination points.

  2. Only keep lines that do not cross a barrier.

  3. Where the line crosses a barrier, create the convex hull from the geometry collection, containing: A) start point, B) destination point, C) all nodes (vertices) of the barrier line.

  4. Get the boundary of the convex hull.

  5. Use shortest path algorithm from start to destination, using the boundary from step 4 as network.

For steps 1 to 4, use this expression:

added 423 characters in body
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245
Loading
added 262 characters in body
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245
Loading
added 1762 characters in body
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245
Loading
Source Link
Babel
  • 80.4k
  • 15
  • 97
  • 245
Loading