1
1
use crate :: area:: { area, contains} ;
2
2
use crate :: error:: { new_error, ErrorKind , Result } ;
3
3
use crate :: isoringbuilder:: IsoRingBuilder ;
4
- use crate :: { Band , Contour , Float , Line , Ring } ;
5
- use geo_types:: { LineString , MultiLineString , MultiPolygon , Polygon } ;
4
+ use crate :: { Band , Contour , ContourValue , Float , Line , Ring } ;
5
+ use geo_types:: { CoordFloat , LineString , MultiLineString , MultiPolygon , Polygon } ;
6
6
use rustc_hash:: FxHashMap ;
7
7
8
8
/// Contours generator, using builder pattern, to
@@ -43,10 +43,10 @@ impl ContourBuilder {
43
43
dx,
44
44
dy,
45
45
smooth,
46
- x_origin : 0. ,
47
- y_origin : 0. ,
48
- x_step : 1. ,
49
- y_step : 1. ,
46
+ x_origin : 0.0 ,
47
+ y_origin : 0.0 ,
48
+ x_step : 1.0 ,
49
+ y_step : 1.0 ,
50
50
}
51
51
}
52
52
@@ -74,7 +74,7 @@ impl ContourBuilder {
74
74
self
75
75
}
76
76
77
- fn smooth_linear ( & self , ring : & mut Ring , values : & [ Float ] , value : Float ) {
77
+ fn smooth_linear < V : ContourValue > ( & self , ring : & mut Ring , values : & [ V ] , value : V ) {
78
78
let dx = self . dx ;
79
79
let dy = self . dy ;
80
80
let len_values = values. len ( ) ;
@@ -91,11 +91,11 @@ impl ContourBuilder {
91
91
let v1 = values[ ix] ;
92
92
if x > 0.0 && x < ( dx as Float ) && ( xt as Float - x) . abs ( ) < Float :: EPSILON {
93
93
v0 = values[ yt * dx + xt - 1 ] ;
94
- point. x = x + ( value - v0) / ( v1 - v0) - 0.5 ;
94
+ point. x = x + num_traits :: cast :: < V , Float > ( ( value - v0) / ( v1 - v0) - num_traits :: cast ( 0.5 ) . unwrap ( ) ) . unwrap ( ) ;
95
95
}
96
96
if y > 0.0 && y < ( dy as Float ) && ( yt as Float - y) . abs ( ) < Float :: EPSILON {
97
97
v0 = values[ ( yt - 1 ) * dx + xt] ;
98
- point. y = y + ( value - v0) / ( v1 - v0) - 0.5 ;
98
+ point. y = y + num_traits :: cast :: < V , Float > ( ( value - v0) / ( v1 - v0) - num_traits :: cast ( 0.5 ) . unwrap ( ) ) . unwrap ( ) ;
99
99
}
100
100
}
101
101
} )
@@ -111,7 +111,7 @@ impl ContourBuilder {
111
111
///
112
112
/// * `values` - The slice of values to be used.
113
113
/// * `thresholds` - The slice of thresholds values to be used.
114
- pub fn lines ( & self , values : & [ Float ] , thresholds : & [ Float ] ) -> Result < Vec < Line > > {
114
+ pub fn lines < V : ContourValue > ( & self , values : & [ V ] , thresholds : & [ V ] ) -> Result < Vec < Line < V > > > {
115
115
if values. len ( ) != self . dx * self . dy {
116
116
return Err ( new_error ( ErrorKind :: BadDimension ) ) ;
117
117
}
@@ -122,12 +122,12 @@ impl ContourBuilder {
122
122
. collect ( )
123
123
}
124
124
125
- fn line (
125
+ fn line < V : ContourValue > (
126
126
& self ,
127
- values : & [ Float ] ,
128
- threshold : Float ,
127
+ values : & [ V ] ,
128
+ threshold : V ,
129
129
isoring : & mut IsoRingBuilder ,
130
- ) -> Result < Line > {
130
+ ) -> Result < Line < V > > {
131
131
let mut result = isoring. compute ( values, threshold) ?;
132
132
let mut linestrings = Vec :: new ( ) ;
133
133
@@ -148,7 +148,7 @@ impl ContourBuilder {
148
148
linestrings. push ( LineString ( ring) ) ;
149
149
} ) ;
150
150
Ok ( Line {
151
- geometry : MultiLineString :: < Float > ( linestrings) ,
151
+ geometry : MultiLineString ( linestrings) ,
152
152
threshold,
153
153
} )
154
154
}
@@ -162,7 +162,7 @@ impl ContourBuilder {
162
162
///
163
163
/// * `values` - The slice of values to be used.
164
164
/// * `thresholds` - The slice of thresholds values to be used.
165
- pub fn contours ( & self , values : & [ Float ] , thresholds : & [ Float ] ) -> Result < Vec < Contour > > {
165
+ pub fn contours < V : ContourValue > ( & self , values : & [ V ] , thresholds : & [ V ] ) -> Result < Vec < Contour < V > > > {
166
166
if values. len ( ) != self . dx * self . dy {
167
167
return Err ( new_error ( ErrorKind :: BadDimension ) ) ;
168
168
}
@@ -173,12 +173,12 @@ impl ContourBuilder {
173
173
. collect ( )
174
174
}
175
175
176
- fn contour (
176
+ fn contour < V : ContourValue > (
177
177
& self ,
178
- values : & [ Float ] ,
179
- threshold : Float ,
178
+ values : & [ V ] ,
179
+ threshold : V ,
180
180
isoring : & mut IsoRingBuilder ,
181
- ) -> Result < Contour > {
181
+ ) -> Result < Contour < V > > {
182
182
let ( mut polygons, mut holes) = ( Vec :: new ( ) , Vec :: new ( ) ) ;
183
183
let mut result = isoring. compute ( values, threshold) ?;
184
184
@@ -197,7 +197,7 @@ impl ContourBuilder {
197
197
} ) ;
198
198
}
199
199
if area ( & ring) > 0.0 {
200
- polygons. push ( Polygon :: < Float > :: new ( LineString :: new ( ring) , vec ! [ ] ) )
200
+ polygons. push ( Polygon :: new ( LineString :: new ( ring) , vec ! [ ] ) )
201
201
} else {
202
202
holes. push ( LineString :: new ( ring) ) ;
203
203
}
@@ -213,7 +213,7 @@ impl ContourBuilder {
213
213
} ) ;
214
214
215
215
Ok ( Contour {
216
- geometry : MultiPolygon :: < Float > ( polygons) ,
216
+ geometry : MultiPolygon ( polygons) ,
217
217
threshold,
218
218
} )
219
219
}
@@ -228,7 +228,7 @@ impl ContourBuilder {
228
228
/// * `values` - The slice of values to be used.
229
229
/// * `thresholds` - The slice of thresholds values to be used
230
230
/// (have to be equal to or greater than 2).
231
- pub fn isobands ( & self , values : & [ Float ] , thresholds : & [ Float ] ) -> Result < Vec < Band > > {
231
+ pub fn isobands < V : ContourValue > ( & self , values : & [ V ] , thresholds : & [ V ] ) -> Result < Vec < Band < V > > > {
232
232
// We will compute rings as previously, but we will
233
233
// iterate over the contours in pairs and use the paths from the lower threshold
234
234
// and the path from the upper threshold to create the isoband.
@@ -268,7 +268,7 @@ impl ContourBuilder {
268
268
. collect :: < Vec < Ring > > ( ) ;
269
269
Ok ( ( rings, * threshold) )
270
270
} )
271
- . collect :: < Result < Vec < ( Vec < Ring > , Float ) > > > ( ) ?;
271
+ . collect :: < Result < Vec < ( Vec < Ring > , V ) > > > ( ) ?;
272
272
273
273
// We now have the rings for each isolines for all the given thresholds,
274
274
// we can iterate over them in pairs to compute the isobands.
@@ -281,7 +281,7 @@ impl ContourBuilder {
281
281
} )
282
282
. collect :: < Vec < _ > > ( ) ;
283
283
284
- let mut bands: Vec < Band > = Vec :: new ( ) ;
284
+ let mut bands: Vec < Band < V > > = Vec :: new ( ) ;
285
285
// Reconstruction of the polygons
286
286
b. into_iter ( ) . for_each ( |( rings, min_v, max_v) | {
287
287
let mut rings_and_area = rings
@@ -314,7 +314,7 @@ impl ContourBuilder {
314
314
315
315
for ( i, ( ring, _) ) in rings_and_area. into_iter ( ) . enumerate ( ) {
316
316
if * enclosed_by_n. get ( & i) . unwrap ( ) % 2 == 0 {
317
- polygons. push ( Polygon :: < Float > :: new ( ring. into ( ) , vec ! [ ] ) ) ;
317
+ polygons. push ( Polygon :: new ( ring. into ( ) , vec ! [ ] ) ) ;
318
318
} else {
319
319
interior_rings. push ( ring. into ( ) ) ;
320
320
}
@@ -331,7 +331,7 @@ impl ContourBuilder {
331
331
polygons. reverse ( ) ;
332
332
333
333
bands. push ( Band {
334
- geometry : MultiPolygon :: < Float > ( polygons) ,
334
+ geometry : MultiPolygon ( polygons) ,
335
335
min_v : * min_v,
336
336
max_v : * max_v,
337
337
} ) ;
0 commit comments