17
17
import org .elasticsearch .geometry .utils .GeometryValidator ;
18
18
import org .elasticsearch .geometry .utils .WellKnownText ;
19
19
import org .elasticsearch .test .ESTestCase ;
20
+ import org .hamcrest .Matcher ;
21
+ import org .hamcrest .Matchers ;
20
22
21
23
import java .io .BufferedReader ;
22
24
import java .io .FileNotFoundException ;
29
31
import java .util .HashMap ;
30
32
import java .util .List ;
31
33
import java .util .PriorityQueue ;
34
+ import java .util .function .Function ;
32
35
import java .util .zip .GZIPInputStream ;
33
36
34
37
import static org .hamcrest .Matchers .closeTo ;
@@ -111,36 +114,44 @@ public void endSimplification(String description, List<SimplificationErrorCalcul
111
114
simplifications .computeIfPresent (description , (k , v ) -> v .asCompleted ());
112
115
}
113
116
114
- public void assertCompleted (int simplificationCount , int minAdded , int minRemoved ) {
117
+ public void assertCompleted (int simplificationCount , int shouldHaveAdded , int shouldHaveRemoved ) {
118
+ assertCompleted (simplificationCount , shouldHaveAdded , shouldHaveRemoved , Matchers ::equalTo );
119
+ }
120
+
121
+ public void assertCompleted (
122
+ int simplificationCount ,
123
+ int shouldHaveAdded ,
124
+ int shouldHaveRemoved ,
125
+ Function <Integer , Matcher <Integer >> matcher
126
+ ) {
115
127
int totalCount = simplifications .values ().stream ().mapToInt (v -> v .count ).sum ();
116
- assertThat (
117
- "Expected at least " + simplificationCount + " simplifications" ,
118
- totalCount ,
119
- greaterThanOrEqualTo (simplificationCount )
120
- );
128
+ assertThat ("Expected " + simplificationCount + " simplifications" , totalCount , matcher .apply (simplificationCount ));
121
129
for (TestSimplificationState state : simplifications .values ()) {
122
130
assertTrue ("Simplification should be completed: " + state .description , state .completed );
123
131
}
124
132
assertThat (
125
- "Expected at least " + minAdded + " points added when maxPoints was " + maxPoints ,
133
+ "Expected " + shouldHaveAdded + " points added when maxPoints was " + maxPoints ,
126
134
added ,
127
- greaterThanOrEqualTo ( minAdded )
135
+ matcher . apply ( shouldHaveAdded )
128
136
);
129
137
assertThat (
130
- "Expected at least " + minRemoved + " points removed when maxPoints was " + maxPoints ,
138
+ "Expected " + shouldHaveRemoved + " points removed when maxPoints was " + maxPoints ,
131
139
removed ,
132
- greaterThanOrEqualTo ( minRemoved )
140
+ matcher . apply ( shouldHaveRemoved )
133
141
);
134
142
}
135
143
}
136
144
137
145
public void testShortLine () {
138
- GeometrySimplifier <Line > simplifier = new GeometrySimplifier .LineStrings (10 , calculator ());
146
+ int maxPoints = 10 ;
147
+ var monitor = new TestMonitor ("ShortLine" , maxPoints );
148
+ GeometrySimplifier <Line > simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator (), monitor );
139
149
Line line = new Line (new double [] { -1 , 0 , 1 }, new double [] { -1 , 0 , 1 });
140
150
141
151
// Test full geometry simplification
142
152
Line simplified = simplifier .simplify (line );
143
153
assertThat ("Same line" , simplified , equalTo (line ));
154
+ monitor .assertCompleted (0 , 0 , 0 ); // simplification never actually used
144
155
145
156
// Test streaming simplification
146
157
simplifier .reset ();
@@ -149,11 +160,14 @@ public void testShortLine() {
149
160
}
150
161
Line streamSimplified = simplifier .produce ();
151
162
assertThat ("Same line" , streamSimplified , equalTo (simplified ));
163
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (line .length ()));
164
+ monitor .assertCompleted (0 , 3 , 0 ); // stream used for less than maxPoints
152
165
}
153
166
154
167
public void testStraightLine () {
155
168
int maxPoints = 10 ;
156
- GeometrySimplifier <Line > simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator ());
169
+ var monitor = new TestMonitor ("StraightLine" , maxPoints );
170
+ GeometrySimplifier <Line > simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator (), monitor );
157
171
double [] x = new double [100 ];
158
172
double [] y = new double [100 ];
159
173
for (int i = 0 ; i < 100 ; i ++) {
@@ -165,6 +179,7 @@ public void testStraightLine() {
165
179
// Test full geometry simplification
166
180
Line simplified = simplifier .simplify (line );
167
181
assertLineEnds (maxPoints , simplified , line );
182
+ monitor .assertCompleted (1 , line .length (), line .length () - maxPoints );
168
183
169
184
// Test streaming simplification
170
185
simplifier .reset ();
@@ -180,13 +195,16 @@ public void testStraightLine() {
180
195
assertTrue (onLine , pointExistsOnLine (px , py , simplified ));
181
196
assertTrue (onLine , pointExistsOnLine (px , py , streamSimplified ));
182
197
}
198
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
199
+ monitor .assertCompleted (1 , 2 * line .length (), 2 * (line .length () - maxPoints ));
183
200
}
184
201
185
202
public void testZigZagLine () {
186
203
int maxPoints = 10 ;
187
204
int zigSize = 2 ;
188
205
int lineLength = (maxPoints - 1 ) * zigSize + 1 ; // chosen to get rid of all y-crossings during simplification
189
- GeometrySimplifier <Line > simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator ());
206
+ var monitor = new TestMonitor ("ZigZagLine" , maxPoints );
207
+ GeometrySimplifier <Line > simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator (), monitor );
190
208
double [] x = new double [lineLength ];
191
209
double [] y = new double [lineLength ];
192
210
for (int i = 0 ; i < lineLength ; i ++) {
@@ -202,6 +220,7 @@ public void testZigZagLine() {
202
220
Line simplified = simplifier .simplify (line );
203
221
assertLineEnds (maxPoints , simplified , line );
204
222
assertLinePointNeverHave (simplified , 0.0 );
223
+ monitor .assertCompleted (1 , line .length (), line .length () - maxPoints );
205
224
206
225
// Test streaming simplification
207
226
simplifier .reset ();
@@ -219,6 +238,8 @@ public void testZigZagLine() {
219
238
assertTrue (onLine , pointExistsOnLine (px , py , streamSimplified ));
220
239
}
221
240
assertThat ("Same line" , streamSimplified , equalTo (simplified ));
241
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
242
+ monitor .assertCompleted (1 , 2 * line .length (), 2 * (line .length () - maxPoints ));
222
243
}
223
244
224
245
public void testCircularLine () {
@@ -238,14 +259,19 @@ public void testCircularLine() {
238
259
239
260
// Test streaming simplification
240
261
simplifier .reset ();
262
+ simplifier .notifyMonitorSimplificationStart ();
241
263
for (int i = 0 ; i < line .length (); i ++) {
242
264
simplifier .consume (line .getX (i ), line .getY (i ));
243
265
}
266
+ simplifier .notifyMonitorSimplificationEnd ();
244
267
Line streamSimplified = simplifier .produce ();
245
268
assertLineEnds (maxPoints , streamSimplified , line );
246
269
assertPointsOnCircle (centerX , centerY , radius , streamSimplified );
247
270
assertThat ("Same line" , streamSimplified , equalTo (simplified ));
248
- monitor .assertCompleted (1 , maxPoints * countFactor , maxPoints * (countFactor - 1 ));
271
+ int shouldHaveAdded = 2 * maxPoints * countFactor ;
272
+ int shouldHaveRemoved = shouldHaveAdded - maxPoints * 2 ;
273
+ monitor .assertCompleted (2 , shouldHaveAdded , shouldHaveRemoved );
274
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
249
275
}
250
276
251
277
public void testCircularPolygon () {
@@ -275,7 +301,10 @@ public void testCircularPolygon() {
275
301
assertPolygonEnds ("Polygon" , maxPoints , simplified , polygon );
276
302
assertPointsOnCircle (centerX , centerY , radius , streamSimplified );
277
303
assertThat ("Same line" , streamSimplified , equalTo (simplified ));
278
- monitor .assertCompleted (2 , maxPoints * countFactor , maxPoints * (countFactor - 1 ));
304
+ int shouldHaveAdded = 2 * maxPoints * countFactor + 2 ;
305
+ int shouldHaveRemoved = shouldHaveAdded - maxPoints * 2 ;
306
+ monitor .assertCompleted (2 , shouldHaveAdded , shouldHaveRemoved );
307
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
279
308
}
280
309
281
310
public void testLineWithBackPaths () {
@@ -288,6 +317,7 @@ public void testLineWithBackPaths() {
288
317
Line simplified = simplifier .simplify (line );
289
318
assertLineEnds (maxPoints , simplified , line );
290
319
monitor .assertCompleted (1 , x .length , x .length - maxPoints );
320
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
291
321
}
292
322
293
323
public void testLineWithBackPaths2 () throws IOException , ParseException {
@@ -297,13 +327,16 @@ public void testLineWithBackPaths2() throws IOException, ParseException {
297
327
-0.16 -0.1, -0.17 -0.13, -0.16 -0.16, -0.1 -0.175, 0.008 -0.175, 0.1 -0.15, 0.2 -0.05, 0.3 0.05, 0.4 0.12, 0.5 0.15,
298
328
0.67 0.1, 0.8 0.0, 0.7 -0.07, 0.6 -0.12, 0.7 -0.185, 0.85 -0.18, 0.96 -0.09, 1.0 0.0))""" ;
299
329
Line line = (Line ) WellKnownText .fromWKT (GeometryValidator .NOOP , true , lineString );
300
- int maxPoints = 15 ;
301
- var monitor = new TestMonitor ("LineWithBackPaths2" , maxPoints );
302
- GeometrySimplifier .LineStrings simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator (), monitor );
303
- simplifier .simplify (line );
304
- simplifier = new GeometrySimplifier .LineStrings (7 , calculator (), monitor );
305
- simplifier .simplify (line );
306
- monitor .assertCompleted (2 , 2 * line .length (), 2 * (line .length () - maxPoints ));
330
+ int [] maxPointsArray = new int [] { 15 , 7 };
331
+ var monitor = new TestMonitor ("LineWithBackPaths2" , maxPointsArray [0 ]);
332
+ for (int maxPoints : maxPointsArray ) {
333
+ var simplifier = new GeometrySimplifier .LineStrings (maxPoints , calculator (), monitor );
334
+ simplifier .simplify (line );
335
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
336
+ }
337
+ int shouldHaveAdded = maxPointsArray .length * line .length ();
338
+ int shouldHaveRemoved = shouldHaveAdded - Arrays .stream (maxPointsArray ).sum ();
339
+ monitor .assertCompleted (2 , shouldHaveAdded , shouldHaveRemoved );
307
340
}
308
341
309
342
public void testLineWithNarrowSpikes () {
@@ -328,6 +361,7 @@ public void testLineWithNarrowSpikes() {
328
361
Line simplified = simplifier .simplify (line );
329
362
assertLineWithNarrowSpikes (simplified , count );
330
363
monitor .assertCompleted (1 , x .length , x .length - maxPoints );
364
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
331
365
}
332
366
333
367
protected abstract void assertLineWithNarrowSpikes (Line simplified , int spikeCount );
@@ -355,6 +389,7 @@ public void testComplexGeoJsonPolygon() throws IOException, ParseException {
355
389
Polygon simplified = simplifier .simplify (polygon );
356
390
assertPolygonEnds ("Polygon" , maxPoints , simplified , polygon );
357
391
monitor .assertCompleted (1 , polygon .getPolygon ().length (), polygon .getPolygon ().length () - maxPoints );
392
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
358
393
}
359
394
}
360
395
@@ -370,6 +405,7 @@ public void testComplexGeoJsonPolygons() throws IOException, ParseException {
370
405
Polygon simplified = simplifier .simplify (polygon );
371
406
assertPolygonEnds ("Polygon" , maxPoints , simplified , polygon );
372
407
monitor .assertCompleted (1 , length , length - maxPoints );
408
+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
373
409
}
374
410
}
375
411
}
@@ -391,7 +427,12 @@ public void testComplexGeoJsonMultiPolygon() throws IOException, ParseException
391
427
int maxPolyPoints = Math .max (4 , (int ) (simplificationFactor * polygon .getPolygon ().length ()));
392
428
assertPolygonEnds ("Polygon[" + i + "]" , maxPolyPoints , simplified , polygon );
393
429
}
394
- monitor .assertCompleted (simplifiedMultiPolygon .size (), maxPolyLength , maxPolyLength - maxPoints );
430
+ monitor .assertCompleted (
431
+ simplifiedMultiPolygon .size (),
432
+ maxPolyLength ,
433
+ maxPolyLength - maxPoints ,
434
+ Matchers ::greaterThanOrEqualTo
435
+ );
395
436
}
396
437
}
397
438
0 commit comments