@@ -76,44 +76,54 @@ impl<S: Clone + Debug + Send + Sync> CSG<S> {
76
76
77
77
/// Convert internal polylines into polygons and return along with any existing internal polygons.
78
78
pub fn to_polygons ( & self ) -> Vec < Polygon < S > > {
79
- let mut all_polygons = Vec :: new ( ) ;
80
-
81
- for geom in & self . geometry {
82
- if let Geometry :: Polygon ( poly2d) = geom {
83
- // 1. Convert the outer ring to 3D.
84
- let mut outer_vertices_3d = Vec :: new ( ) ;
85
- for c in poly2d. exterior ( ) . coords_iter ( ) {
86
- outer_vertices_3d. push ( Vertex :: new ( Point3 :: new ( c. x , c. y , 0.0 ) , Vector3 :: z ( ) ) ) ;
79
+
80
+ /// Helper function to convert a geo::Polygon into one or more Polygon<S> entries.
81
+ fn process_polygon < S > (
82
+ poly2d : & geo:: Polygon < Real > ,
83
+ all_polygons : & mut Vec < Polygon < S > > ,
84
+ metadata : & Option < S > ,
85
+ ) where S : Clone + Send + Sync {
86
+ // 1. Convert the outer ring to 3D.
87
+ let mut outer_vertices_3d = Vec :: new ( ) ;
88
+ for c in poly2d. exterior ( ) . coords_iter ( ) {
89
+ outer_vertices_3d. push ( Vertex :: new ( Point3 :: new ( c. x , c. y , 0.0 ) , Vector3 :: z ( ) ) ) ;
90
+ }
91
+
92
+ if outer_vertices_3d. len ( ) >= 3 {
93
+ all_polygons. push ( Polygon :: new ( outer_vertices_3d, metadata. clone ( ) ) ) ;
94
+ }
95
+
96
+ // 2. Convert interior rings (holes), if needed as separate polygons.
97
+ for ring in poly2d. interiors ( ) {
98
+ let mut hole_vertices_3d = Vec :: new ( ) ;
99
+ for c in ring. coords_iter ( ) {
100
+ hole_vertices_3d. push ( Vertex :: new ( Point3 :: new ( c. x , c. y , 0.0 ) , Vector3 :: z ( ) ) ) ;
87
101
}
88
-
89
- // Push as a new Polygon<S> if it has at least 3 vertices.
90
- if outer_vertices_3d . len ( ) >= 3 {
91
- all_polygons. push ( Polygon :: new ( outer_vertices_3d , self . metadata . clone ( ) ) ) ;
102
+
103
+ if hole_vertices_3d . len ( ) >= 3 {
104
+ // Note: adjust this if your `Polygon<S>` type supports interior rings.
105
+ all_polygons. push ( Polygon :: new ( hole_vertices_3d , metadata. clone ( ) ) ) ;
92
106
}
107
+ }
108
+ }
109
+
110
+ let mut all_polygons = Vec :: new ( ) ;
93
111
94
- // 2. Convert each interior ring (hole) into its own Polygon<S>.
95
- for ring in poly2d. interiors ( ) {
96
- let mut hole_vertices_3d = Vec :: new ( ) ;
97
- for c in ring. coords_iter ( ) {
98
- hole_vertices_3d. push (
99
- Vertex :: new ( Point3 :: new ( c. x , c. y , 0.0 ) , Vector3 :: z ( ) )
100
- ) ;
101
- }
102
-
103
- if hole_vertices_3d. len ( ) >= 3 {
104
- // If your `Polygon<S>` type can represent holes internally,
105
- // adjust this to store hole_vertices_3d as a hole rather
106
- // than a new standalone polygon.
107
- all_polygons. push ( Polygon :: new ( hole_vertices_3d, self . metadata . clone ( ) ) ) ;
112
+ for geom in & self . geometry {
113
+ match geom {
114
+ Geometry :: Polygon ( poly2d) => {
115
+ process_polygon ( poly2d, & mut all_polygons, & self . metadata ) ;
116
+ }
117
+ Geometry :: MultiPolygon ( multipoly) => {
118
+ for poly2d in multipoly {
119
+ process_polygon ( poly2d, & mut all_polygons, & self . metadata ) ;
108
120
}
109
121
}
122
+ // Optional: handle other geometry types like LineString here.
123
+ _ => { }
110
124
}
111
- // else if let Geometry::LineString(ls) = geom {
112
- // // Example of how you might convert a linestring to a polygon,
113
- // // if desired. Omitted for brevity.
114
- // }
115
125
}
116
-
126
+
117
127
all_polygons
118
128
}
119
129
0 commit comments