-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Misc Issues PR #70
Misc Issues PR #70
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks already very good to me, thank you for the effort to add a first iteration of the path finding algorithm and getting the ball rolling!
I added a couple of questions regarding edge cases. You documented the code amazingly well, it was a pleasure to read as always @herbiebradley ! 🎉
geograph/geograph.py
Outdated
# Here we loop through all barrier_nbrs and calculate the | ||
# set difference between the buffered polygon and the | ||
# barrier polygon. If this results in multiple polygons, | ||
# then the barrier polygon fully cuts the buffered polygon. | ||
# | ||
# Therefore we find the largest polygon in the result, | ||
# which will contain the original node polygon, and check | ||
# if it intersects the neighbour polygon we're trying to | ||
# reach. If it does not, there is no path. | ||
# If it does, there may be a path or there may not - it | ||
# would require complex pathfinding code to discover, but | ||
# we add the edge anyway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice description! This is incredibly helpful, thank you!
With regards to edge cases, how would the following case be handled:
Here if we consider classes 7 and 13 as barriers separately, they do not cut off the access between 2 and 4. If they are considered as a joint barrier however, they will cut off the access. Do I understand it correctly that in this algorithm the barrier polygons would be processed sequentially (i.e. first 2, then 4, ...) and therefore the edge would be added?
Or am I overlooking sth?
If the former is the case, we could go around this by performing a difference between the buffered original polygon and all barrier polygons that intersect with the buffered original polygon first and then checking, as you did, whether the piece that contains the original node will still intersect with the neighbour (or in fact any of its neighbours, this might give us a quite a speedup?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I implemented this in the latest commit. I got around a 60% speedup, so it's looking good!
Add pypi badge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not much more to add beyond Simon's comments... looks great! 🚀
geograph/geograph.py
Outdated
# Therefore we find the largest polygon in the result, | ||
# which will contain the original node polygon, and check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good enough assumption but note that I don't think this will not always hold. For large travel distances in particular - for example imagine a circular road around a patch and a large travel distance. If we want to be certain we could also check if it overlaps with the original node, but it might not be worth it in terms of computational cost.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point - I realised that it is easier to check which polygon in the MultiPolygon
contains a point in the original, like this:
diff = buff_poly - barrier_poly
if isinstance(diff, shapely.geometry.MultiPolygon):
if len(diff) > 1:
bools = [poly.contains(repr_point) for poly in diff]
node_poly = diff[bools.index(True)]
if not node_poly.intersects(nbr_polygon):
add_edge = False
This should be of similar speed.
Co-authored-by: Simon Mathis <svm34@cam.ac.uk>
@Croydon-Brixton @rdnfn Thanks for the feedback - all issues have hopefully been resolved now! 🚀 |
Co-authored-by: Simon Mathis <svm34@cam.ac.uk>
This PR contains several miscellaneous features:
_add_nodes
function ingeograph
.merge_classes
function by detecting neighbouring polygons of the same class and merging them. Closes Merge polygons in the GeoGraph merge_classes function #44barrier_classes
inadd_habitat
, with basic pathfinding functionality. This will only detect pathfinding problems if the polygon of the barrier node completely cuts the buffered polygon of the main node in half, preventing all access to the neighbouring polygon. This works by using Shapely's polygon difference function, see the comments for the actual algorithm.The pathfinding code slows

add_habitat
down quite a bit, as might be expected, but it seems to make some difference to the final edge count:When this one is merged I will create the 0.0.2 release, upload it to PyPi and add it to Zenodo.