mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-27 06:52:10 +03:00
Clean up internal Polygon code in preparation for just storing Rings. #951
This commit is contained in:
parent
82dcb3fdbc
commit
b7172f876d
@ -89,7 +89,8 @@ impl Polygon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bounds(&self) -> Bounds {
|
pub fn get_bounds(&self) -> Bounds {
|
||||||
Bounds::from(&self.points)
|
// Interiors should always be strictly contained within the polygon's exterior
|
||||||
|
Bounds::from(self.get_outer_ring().points())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transformations must preserve Rings.
|
/// Transformations must preserve Rings.
|
||||||
@ -357,8 +358,7 @@ impl Polygon {
|
|||||||
|
|
||||||
/// Doesn't handle multiple crossings in and out.
|
/// Doesn't handle multiple crossings in and out.
|
||||||
pub fn clip_polyline(&self, input: &PolyLine) -> Option<Vec<Pt2D>> {
|
pub fn clip_polyline(&self, input: &PolyLine) -> Option<Vec<Pt2D>> {
|
||||||
let ring = Ring::must_new(self.points.clone());
|
let hits = self.get_outer_ring().all_intersections(input);
|
||||||
let hits = ring.all_intersections(input);
|
|
||||||
|
|
||||||
if hits.is_empty() {
|
if hits.is_empty() {
|
||||||
// All the points must be inside, or none
|
// All the points must be inside, or none
|
||||||
@ -388,7 +388,7 @@ impl Polygon {
|
|||||||
|
|
||||||
// TODO Only handles a few cases
|
// TODO Only handles a few cases
|
||||||
pub fn clip_ring(&self, input: &Ring) -> Option<Vec<Pt2D>> {
|
pub fn clip_ring(&self, input: &Ring) -> Option<Vec<Pt2D>> {
|
||||||
let ring = Ring::must_new(self.points.clone());
|
let ring = self.get_outer_ring();
|
||||||
let hits = ring.all_intersections(&PolyLine::unchecked_new(input.clone().into_points()));
|
let hits = ring.all_intersections(&PolyLine::unchecked_new(input.clone().into_points()));
|
||||||
|
|
||||||
if hits.is_empty() {
|
if hits.is_empty() {
|
||||||
@ -421,31 +421,23 @@ impl Polygon {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the polygon is just a single outer ring, produces a GeoJSON polygon. Otherwise, produces
|
/// Optionally map the world-space points back to GPS.
|
||||||
/// a GeoJSON multipolygon consisting of individual triangles. Optionally map the world-space
|
|
||||||
/// points back to GPS.
|
|
||||||
pub fn to_geojson(&self, gps: Option<&GPSBounds>) -> geojson::Geometry {
|
pub fn to_geojson(&self, gps: Option<&GPSBounds>) -> geojson::Geometry {
|
||||||
if let Ok(ring) = Ring::new(self.points.clone()) {
|
use geo::MapCoordsInPlace;
|
||||||
return ring.to_geojson(gps);
|
|
||||||
|
let mut geom: geo::Geometry = self.to_geo().into();
|
||||||
|
if let Some(ref gps_bounds) = gps {
|
||||||
|
geom.map_coords_in_place(|c| {
|
||||||
|
let gps = Pt2D::new(c.x, c.y).to_gps(gps_bounds);
|
||||||
|
(gps.x(), gps.y()).into()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut polygons = Vec::new();
|
geojson::Geometry {
|
||||||
for triangle in self.triangles() {
|
bbox: None,
|
||||||
let raw_pts = vec![triangle.pt1, triangle.pt2, triangle.pt3, triangle.pt1];
|
value: geojson::Value::from(&geom),
|
||||||
let mut pts = Vec::new();
|
foreign_members: None,
|
||||||
if let Some(gps) = gps {
|
|
||||||
for pt in gps.convert_back(&raw_pts) {
|
|
||||||
pts.push(vec![pt.x(), pt.y()]);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for pt in raw_pts {
|
|
||||||
pts.push(vec![pt.x(), pt.y()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
polygons.push(vec![pts]);
|
|
||||||
}
|
|
||||||
|
|
||||||
geojson::Geometry::new(geojson::Value::MultiPolygon(polygons))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts all polygons from raw bytes representing a GeoJSON file, along with the string
|
/// Extracts all polygons from raw bytes representing a GeoJSON file, along with the string
|
||||||
|
Loading…
Reference in New Issue
Block a user