-
Notifications
You must be signed in to change notification settings - Fork 157
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
Better support for binary predicates with large inputs. #1166
Changes from all commits
3e9e10b
3332ab9
fa9bbe6
2117883
93b3b92
3af37c3
6dc2169
875ad9f
46cdb8c
7f950dd
06e8f06
60391dd
217a99a
bf77069
c8cb7ea
2bf49e3
285b0c7
7889603
a28ec99
a94c232
8e38e8e
6e9884f
d0d1888
aa49915
6d1bd1b
dce140a
29abbbf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,38 +78,57 @@ def _compute_polygon_polygon_contains(self, lhs, rhs, preprocessor_result): | |
# A closed polygon has an extra line segment that is not used in | ||
# counting the number of points. We need to subtract this from the | ||
# number of points in the polygon. | ||
polygon_size_reduction = rhs.polygons.part_offset.take( | ||
rhs.polygons.geometry_offset[1:] | ||
) - rhs.polygons.part_offset.take(rhs.polygons.geometry_offset[:-1]) | ||
return contains + intersects >= rhs.sizes - polygon_size_reduction | ||
multipolygon_part_offset = rhs.polygons.part_offset.take( | ||
rhs.polygons.geometry_offset | ||
) | ||
polygon_size_reduction = ( | ||
multipolygon_part_offset[1:] - multipolygon_part_offset[:-1] | ||
) | ||
result = contains + intersects >= rhs.sizes - polygon_size_reduction | ||
return result | ||
|
||
def _test_interior(self, lhs, rhs): | ||
# We only need to test linestrings that are length 2. | ||
# Divide the linestring in half and test the point for containment | ||
# in the polygon. | ||
size_two = rhs.sizes == 2 | ||
if (size_two).any(): | ||
center_points = _linestrings_to_center_point(rhs[size_two]) | ||
size_two_results = _false_series(len(lhs)) | ||
size_two_results.iloc[rhs.index[size_two]] = ( | ||
_basic_contains_count(lhs, center_points) > 0 | ||
) | ||
return size_two_results | ||
else: | ||
return _false_series(len(lhs)) | ||
|
||
def _compute_polygon_linestring_contains( | ||
self, lhs, rhs, preprocessor_result | ||
): | ||
contains = _basic_contains_count(lhs, rhs).reset_index(drop=True) | ||
intersects = self._intersection_results_for_contains(lhs, rhs) | ||
if (contains == 0).all() and (intersects != 0).all(): | ||
# The hardest case. We need to check if the linestring is | ||
# contained in the boundary of the polygon, the interior, | ||
# or the exterior. | ||
# We only need to test linestrings that are length 2. | ||
# Divide the linestring in half and test the point for containment | ||
# in the polygon. | ||
|
||
if (rhs.sizes == 2).any(): | ||
center_points = _linestrings_to_center_point( | ||
rhs[rhs.sizes == 2] | ||
) | ||
size_two_results = _false_series(len(lhs)) | ||
size_two_results[rhs.sizes == 2] = ( | ||
_basic_contains_count(lhs, center_points) > 0 | ||
) | ||
return size_two_results | ||
else: | ||
line_intersections = _false_series(len(lhs)) | ||
line_intersections[intersects == rhs.sizes] = True | ||
return line_intersections | ||
return contains + intersects >= rhs.sizes | ||
|
||
# If a linestring has intersection but not containment, we need to | ||
# test if the linestring is in the interior of the polygon. | ||
final_result = _false_series(len(lhs)) | ||
intersection_with_no_containment = (contains == 0) & (intersects != 0) | ||
interior_tests = self._test_interior( | ||
lhs[intersection_with_no_containment].reset_index(drop=True), | ||
rhs[intersection_with_no_containment].reset_index(drop=True), | ||
) | ||
interior_tests.index = intersection_with_no_containment[ | ||
intersection_with_no_containment | ||
].index | ||
# LineStrings that have intersection but no containment are set | ||
# according to the `intersection_with_no_containment` mask. | ||
final_result[intersection_with_no_containment] = interior_tests | ||
# LineStrings that do not are contained if the sum of intersecting | ||
# and containing points is greater than or equal to the number of | ||
# points that make up the linestring. | ||
Comment on lines
+125
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am having trouble parsing this comment (and all of the code in this function). Can it be made clearer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have written an improvement to this function in #1186, please review when this is merged? |
||
final_result[~intersection_with_no_containment] = ( | ||
contains + intersects >= rhs.sizes | ||
) | ||
return final_result | ||
|
||
def _compute_predicate(self, lhs, rhs, preprocessor_result): | ||
if contains_only_points(rhs): | ||
|
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.
Wish there's a more intuitive name, what does this function do?
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.
This function is addressed in #1186, wait till this is merged and review it and this function is removed. :)