mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2025-12-26 12:09:57 +00:00
Triangulation is not just a conversion.
The triangulation function in `triangle.rs` is now called `delaunay_to_triangles` and it accepts the output of a Delaunay triangulation from `i_triangle` and not a GeoRust multi-polygon. The translation of user polygons to `i_triangle` polygons and subsequent triangulation will take place outside of `triangle.rs`.
This commit is contained in:
committed by
Paul Masurel
parent
ccdf399cd7
commit
d3049cb323
@@ -5,9 +5,7 @@
|
|||||||
//! contain an additional vertex and packed reconstruction metadata, allowing exact triangle
|
//! contain an additional vertex and packed reconstruction metadata, allowing exact triangle
|
||||||
//! recovery when needed.
|
//! recovery when needed.
|
||||||
|
|
||||||
use geo_types::MultiPolygon;
|
use i_triangle::advanced::delaunay::IntDelaunay;
|
||||||
use i_triangle::i_overlay::i_float::int::point::IntPoint;
|
|
||||||
use i_triangle::int::triangulatable::IntTriangulatable;
|
|
||||||
use robust::{orient2d, Coord};
|
use robust::{orient2d, Coord};
|
||||||
|
|
||||||
const MINY_MINX_MAXY_MAXX_Y_X: i32 = 0;
|
const MINY_MINX_MAXY_MAXX_Y_X: i32 = 0;
|
||||||
@@ -303,65 +301,37 @@ impl Triangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triangulates a geographic polygon into encoded triangles for block kd-tree indexing.
|
/// Encodes the triangles of a Delaunay triangulation into block kd-tree triangles.
|
||||||
///
|
///
|
||||||
/// This function is used by applications to convert a `MultiPolygon` into triangles for indexing
|
/// Takes the output of a Delaunay triangulation from `i_triangle` and encodes each triangle into
|
||||||
/// in the block kd-tree. Once triangulated, the encoded triangles can be inserted into the block
|
/// the normalized triangle used by the block kd-tree. Each triangle includes its bounding box,
|
||||||
/// kd-tree and queries against the block kd-tree will return the associated `doc_id`.
|
/// vertex coordinates, and boundary edge flags that distinguish original polygon edges from
|
||||||
|
/// internal tessellation edges.
|
||||||
///
|
///
|
||||||
/// Takes a polygon with floating-point lat/lon coordinates, converts to integer coordinates with
|
/// The boundary edge information provided by the `i_triangle` Delaunay triangulation is essential
|
||||||
/// millimeter precision (using 2^32 scaling), performs constrained Delaunay triangulation, and
|
/// for CONTAINS and WITHIN queries to work correctly.
|
||||||
/// encodes the resulting triangles with boundary edge information.
|
pub fn delaunay_to_triangles(doc_id: u32, delaunay: &IntDelaunay, triangles: &mut Vec<Triangle>) {
|
||||||
///
|
for triangle in delaunay.triangles.iter() {
|
||||||
/// Handles polygons with holes correctly, preserving which triangle edges lie on the original
|
let bounds = [
|
||||||
/// polygon boundaries versus internal tessellation edges.
|
triangle.neighbors[0] == usize::MAX,
|
||||||
pub fn triangulate<G>(doc_id: u32, geometry: G, triangles: &mut Vec<Triangle>)
|
triangle.neighbors[1] == usize::MAX,
|
||||||
where G: Into<MultiPolygon<f64>> {
|
triangle.neighbors[2] == usize::MAX,
|
||||||
let multi = geometry.into();
|
];
|
||||||
for polygon in multi {
|
let v0 = &delaunay.points[triangle.vertices[0].index];
|
||||||
let exterior: Vec<IntPoint> = polygon
|
let v1 = &delaunay.points[triangle.vertices[1].index];
|
||||||
.exterior()
|
let v2 = &delaunay.points[triangle.vertices[2].index];
|
||||||
.coords()
|
triangles.push(Triangle::new(
|
||||||
.map(|coord| {
|
doc_id,
|
||||||
let lat = (coord.y / (180.0 / (1i64 << 32) as f64)).floor() as i32;
|
[v0.y, v0.x, v1.y, v1.x, v2.y, v2.x],
|
||||||
let lon = (coord.x / (360.0 / (1i64 << 32) as f64)).floor() as i32;
|
bounds,
|
||||||
IntPoint::new(lon, lat)
|
))
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let mut i_polygon = vec![exterior];
|
|
||||||
for interior in polygon.interiors() {
|
|
||||||
let hole: Vec<IntPoint> = interior
|
|
||||||
.coords()
|
|
||||||
.map(|coord| {
|
|
||||||
let lat = (coord.y / (180.0 / (1i64 << 32) as f64)).floor() as i32;
|
|
||||||
let lon = (coord.x / (360.0 / (1i64 << 32) as f64)).floor() as i32;
|
|
||||||
IntPoint::new(lon, lat)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
i_polygon.push(hole);
|
|
||||||
}
|
|
||||||
let delaunay = i_polygon.triangulate().into_delaunay();
|
|
||||||
for (_, triangle) in delaunay.triangles.iter().enumerate() {
|
|
||||||
let bounds = [
|
|
||||||
triangle.neighbors[0] == usize::MAX,
|
|
||||||
triangle.neighbors[1] == usize::MAX,
|
|
||||||
triangle.neighbors[2] == usize::MAX,
|
|
||||||
];
|
|
||||||
let v0 = &delaunay.points[triangle.vertices[0].index];
|
|
||||||
let v1 = &delaunay.points[triangle.vertices[1].index];
|
|
||||||
let v2 = &delaunay.points[triangle.vertices[2].index];
|
|
||||||
triangles.push(Triangle::new(
|
|
||||||
doc_id,
|
|
||||||
[v0.y, v0.x, v1.y, v1.x, v2.y, v2.x],
|
|
||||||
bounds,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use geo_types::polygon;
|
use i_triangle::i_overlay::i_float::int::point::IntPoint;
|
||||||
|
use i_triangle::int::triangulatable::IntTriangulatable;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -437,11 +407,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangulate_box() {
|
fn triangulate_box() {
|
||||||
let polygon = polygon![
|
let i_polygon = vec![vec![
|
||||||
(x: 0.0, y: 0.0), (x: 10.0, y: 0.0), (x: 10.0, y: 10.0), (x: 0.0, y: 10.0)
|
IntPoint::new(0, 0),
|
||||||
];
|
IntPoint::new(10, 0),
|
||||||
|
IntPoint::new(10, 10),
|
||||||
|
IntPoint::new(0, 10),
|
||||||
|
]];
|
||||||
let mut triangles = Vec::new();
|
let mut triangles = Vec::new();
|
||||||
triangulate(1, polygon, &mut triangles);
|
let delaunay = i_polygon.triangulate().into_delaunay();
|
||||||
|
delaunay_to_triangles(1, &delaunay, &mut triangles);
|
||||||
assert_eq!(triangles.len(), 2);
|
assert_eq!(triangles.len(), 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user