Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion duckdb
Submodule duckdb updated 606 files
45 changes: 33 additions & 12 deletions src/sgl/sgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2857,7 +2857,10 @@ void prepared_geometry::build(allocator &allocator) {
box = extent_xy::smallest();

const auto beg = i * NODE_SIZE;
const auto end = math::min(beg + NODE_SIZE, vertex_count);

// We add +1 to the node size here, to get not just the start point of the segment, but also the end point,
// which may be in the next node. This ensures there is no gaps between node bounding boxes.
const auto end = math::min(beg + NODE_SIZE + 1, vertex_count);

for (uint32_t j = beg; j < end; j++) {
vertex_xy curr = {0, 0};
Expand Down Expand Up @@ -2921,6 +2924,7 @@ point_in_polygon_result prepared_geometry::contains(const vertex_xy &vert) const
const auto &box = level.entry_array[entry];

// Check if the vertex is in the box y-slice
D_ASSERT(box.min.y <= box.max.y);
if (box.min.y <= vert.y && box.max.y >= vert.y) {
if (depth != index.level_count - 1) {
// We are not at a leaf, so go downwards
Expand Down Expand Up @@ -2966,7 +2970,13 @@ point_in_polygon_result prepared_geometry::contains(const vertex_xy &vert) const
return crossings % 2 == 0 ? point_in_polygon_result::EXTERIOR : point_in_polygon_result::INTERIOR;
}

if (stack[depth] != index.level_array[depth].entry_count - 1) {
// The end of this node is either the end of the current node, or the end of the level
const auto node_end = ((stack[depth - 1] + 1) * NODE_SIZE) - 1;
const auto levl_end = index.level_array[depth].entry_count - 1;

const auto end = math::min(node_end, levl_end);

if(stack[depth] != end) {
// Go sideways!
stack[depth]++;
break;
Expand Down Expand Up @@ -3220,10 +3230,10 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
if (lhs_is_leaf && rhs_is_leaf) {

const auto lhs_beg_idx = pair.lhs_entry * NODE_SIZE;
const auto lhs_end_idx = math::min(lhs_beg_idx + NODE_SIZE, lhs.index.items_count);
const auto lhs_end_idx = math::min(lhs_beg_idx + NODE_SIZE + 1, lhs.index.items_count);

const auto rhs_beg_idx = pair.rhs_entry * NODE_SIZE;
const auto rhs_end_idx = math::min(rhs_beg_idx + NODE_SIZE, rhs.index.items_count);
const auto rhs_end_idx = math::min(rhs_beg_idx + NODE_SIZE + 1, rhs.index.items_count);

if (lhs_beg_idx >= lhs_end_idx || rhs_beg_idx >= rhs_end_idx) {
continue; // No segments to check
Expand All @@ -3240,9 +3250,15 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
for (uint32_t i = lhs_beg_idx + 1; i < lhs_end_idx; i++) {
memcpy(&lhs_next, lhs_vertex_array + i * lhs_vertex_width, sizeof(vertex_xy));

// Quick check. If the distance between the segment and the box (all the segments)
// Quick check: If the distance between the segment and the box (all the segments)
// is greater than min_dist, we can skip the exact distance check
extent_xy lhs_seg = {lhs_prev, lhs_next};

extent_xy lhs_seg;
lhs_seg.min.x = std::min(lhs_prev.x, lhs_next.x);
lhs_seg.min.y = std::min(lhs_prev.y, lhs_next.y);
lhs_seg.max.x = std::max(lhs_prev.x, lhs_next.x);
lhs_seg.max.y = std::max(lhs_prev.y, lhs_next.y);

if (lhs_seg.distance_to_sq(rhs_box) > min_dist) {
lhs_prev = lhs_next;
continue;
Expand All @@ -3252,17 +3268,21 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
for (uint32_t j = rhs_beg_idx + 1; j < rhs_end_idx; j++) {
memcpy(&rhs_next, rhs_vertex_array + j * rhs_vertex_width, sizeof(vertex_xy));

extent_xy rhs_seg = {rhs_prev, rhs_next};

// Quick check. If the distance between the segment bounds are greater than min_dist,
// Quick check: If the distance between the segment bounds are greater than min_dist,
// we can skip the exact distance check
if (lhs_seg.distance_to_sq(rhs_seg) > min_dist) {
extent_xy rhs_seg;
rhs_seg.min.x = std::min(rhs_prev.x, rhs_next.x);
rhs_seg.min.y = std::min(rhs_prev.y, rhs_next.y);
rhs_seg.max.x = std::max(rhs_prev.x, rhs_next.x);
rhs_seg.max.y = std::max(rhs_prev.y, rhs_next.y);

if (rhs_seg.distance_to_sq(lhs_seg) > min_dist) {
rhs_prev = rhs_next;
continue;
}

const auto dist = segment_segment_dist_sq(lhs_prev, lhs_next, rhs_prev, rhs_next);
if (dist <= min_dist) {
if (dist < min_dist) {
min_dist = dist;
found_any = true;
}
Expand Down Expand Up @@ -3346,7 +3366,7 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
}

if (found_any) {
distance = std::sqrt(min_dist);
distance = std::sqrt(min_dist); // Convert squared distance to actual distance
return true; // We found a distance
}
return false; // No distance found
Expand All @@ -3361,6 +3381,7 @@ bool prepared_geometry::try_get_distance(const prepared_geometry &other, double
// WKT Parsing
//======================================================================================================================


namespace sgl {

namespace {
Expand Down
4 changes: 3 additions & 1 deletion src/spatial/operators/spatial_join_physical.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,8 +613,10 @@ SinkFinalizeType PhysicalSpatialJoin::Finalize(Pipeline &pipeline, Event &event,

auto &sel = *FlatVector::IncrementalSelectionVector();
Vector geom_vec(GeoTypes::GEOMETRY());
auto &validity = FlatVector::Validity(geom_vec);

do {
validity.Reset();
const auto row_count = iterator.GetCurrentChunkCount();

// We only need to fetch the build-side key column to build the rtree.
Expand All @@ -628,7 +630,7 @@ SinkFinalizeType PhysicalSpatialJoin::Finalize(Pipeline &pipeline, Event &event,
const auto geom_ptr = FlatVector::GetData<geometry_t>(geom_vec);
// Push the bounding boxes into the R-Tree
for (idx_t row_idx = 0; row_idx < row_count; row_idx++) {
if (FlatVector::IsNull(geom_vec, row_idx)) {
if (!validity.RowIsValid(row_idx)) {
// Skip null geometries
continue;
}
Expand Down
Loading