1717import org .elasticsearch .geometry .utils .GeometryValidator ;
1818import org .elasticsearch .geometry .utils .WellKnownText ;
1919import org .elasticsearch .test .ESTestCase ;
20+ import org .hamcrest .Matcher ;
21+ import org .hamcrest .Matchers ;
2022
2123import java .io .BufferedReader ;
2224import java .io .FileNotFoundException ;
2931import java .util .HashMap ;
3032import java .util .List ;
3133import java .util .PriorityQueue ;
34+ import java .util .function .Function ;
3235import java .util .zip .GZIPInputStream ;
3336
3437import static org .hamcrest .Matchers .closeTo ;
@@ -111,36 +114,44 @@ public void endSimplification(String description, List<SimplificationErrorCalcul
111114 simplifications .computeIfPresent (description , (k , v ) -> v .asCompleted ());
112115 }
113116
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+ ) {
115127 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 ));
121129 for (TestSimplificationState state : simplifications .values ()) {
122130 assertTrue ("Simplification should be completed: " + state .description , state .completed );
123131 }
124132 assertThat (
125- "Expected at least " + minAdded + " points added when maxPoints was " + maxPoints ,
133+ "Expected " + shouldHaveAdded + " points added when maxPoints was " + maxPoints ,
126134 added ,
127- greaterThanOrEqualTo ( minAdded )
135+ matcher . apply ( shouldHaveAdded )
128136 );
129137 assertThat (
130- "Expected at least " + minRemoved + " points removed when maxPoints was " + maxPoints ,
138+ "Expected " + shouldHaveRemoved + " points removed when maxPoints was " + maxPoints ,
131139 removed ,
132- greaterThanOrEqualTo ( minRemoved )
140+ matcher . apply ( shouldHaveRemoved )
133141 );
134142 }
135143 }
136144
137145 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 );
139149 Line line = new Line (new double [] { -1 , 0 , 1 }, new double [] { -1 , 0 , 1 });
140150
141151 // Test full geometry simplification
142152 Line simplified = simplifier .simplify (line );
143153 assertThat ("Same line" , simplified , equalTo (line ));
154+ monitor .assertCompleted (0 , 0 , 0 ); // simplification never actually used
144155
145156 // Test streaming simplification
146157 simplifier .reset ();
@@ -149,11 +160,14 @@ public void testShortLine() {
149160 }
150161 Line streamSimplified = simplifier .produce ();
151162 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
152165 }
153166
154167 public void testStraightLine () {
155168 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 );
157171 double [] x = new double [100 ];
158172 double [] y = new double [100 ];
159173 for (int i = 0 ; i < 100 ; i ++) {
@@ -165,6 +179,7 @@ public void testStraightLine() {
165179 // Test full geometry simplification
166180 Line simplified = simplifier .simplify (line );
167181 assertLineEnds (maxPoints , simplified , line );
182+ monitor .assertCompleted (1 , line .length (), line .length () - maxPoints );
168183
169184 // Test streaming simplification
170185 simplifier .reset ();
@@ -180,13 +195,16 @@ public void testStraightLine() {
180195 assertTrue (onLine , pointExistsOnLine (px , py , simplified ));
181196 assertTrue (onLine , pointExistsOnLine (px , py , streamSimplified ));
182197 }
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 ));
183200 }
184201
185202 public void testZigZagLine () {
186203 int maxPoints = 10 ;
187204 int zigSize = 2 ;
188205 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 );
190208 double [] x = new double [lineLength ];
191209 double [] y = new double [lineLength ];
192210 for (int i = 0 ; i < lineLength ; i ++) {
@@ -202,6 +220,7 @@ public void testZigZagLine() {
202220 Line simplified = simplifier .simplify (line );
203221 assertLineEnds (maxPoints , simplified , line );
204222 assertLinePointNeverHave (simplified , 0.0 );
223+ monitor .assertCompleted (1 , line .length (), line .length () - maxPoints );
205224
206225 // Test streaming simplification
207226 simplifier .reset ();
@@ -219,6 +238,8 @@ public void testZigZagLine() {
219238 assertTrue (onLine , pointExistsOnLine (px , py , streamSimplified ));
220239 }
221240 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 ));
222243 }
223244
224245 public void testCircularLine () {
@@ -238,14 +259,19 @@ public void testCircularLine() {
238259
239260 // Test streaming simplification
240261 simplifier .reset ();
262+ simplifier .notifyMonitorSimplificationStart ();
241263 for (int i = 0 ; i < line .length (); i ++) {
242264 simplifier .consume (line .getX (i ), line .getY (i ));
243265 }
266+ simplifier .notifyMonitorSimplificationEnd ();
244267 Line streamSimplified = simplifier .produce ();
245268 assertLineEnds (maxPoints , streamSimplified , line );
246269 assertPointsOnCircle (centerX , centerY , radius , streamSimplified );
247270 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 ));
249275 }
250276
251277 public void testCircularPolygon () {
@@ -275,7 +301,10 @@ public void testCircularPolygon() {
275301 assertPolygonEnds ("Polygon" , maxPoints , simplified , polygon );
276302 assertPointsOnCircle (centerX , centerY , radius , streamSimplified );
277303 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 ));
279308 }
280309
281310 public void testLineWithBackPaths () {
@@ -288,6 +317,7 @@ public void testLineWithBackPaths() {
288317 Line simplified = simplifier .simplify (line );
289318 assertLineEnds (maxPoints , simplified , line );
290319 monitor .assertCompleted (1 , x .length , x .length - maxPoints );
320+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
291321 }
292322
293323 public void testLineWithBackPaths2 () throws IOException , ParseException {
@@ -297,13 +327,16 @@ public void testLineWithBackPaths2() throws IOException, ParseException {
297327 -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,
298328 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))""" ;
299329 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 );
307340 }
308341
309342 public void testLineWithNarrowSpikes () {
@@ -328,6 +361,7 @@ public void testLineWithNarrowSpikes() {
328361 Line simplified = simplifier .simplify (line );
329362 assertLineWithNarrowSpikes (simplified , count );
330363 monitor .assertCompleted (1 , x .length , x .length - maxPoints );
364+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
331365 }
332366
333367 protected abstract void assertLineWithNarrowSpikes (Line simplified , int spikeCount );
@@ -355,6 +389,7 @@ public void testComplexGeoJsonPolygon() throws IOException, ParseException {
355389 Polygon simplified = simplifier .simplify (polygon );
356390 assertPolygonEnds ("Polygon" , maxPoints , simplified , polygon );
357391 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 ));
358393 }
359394 }
360395
@@ -370,6 +405,7 @@ public void testComplexGeoJsonPolygons() throws IOException, ParseException {
370405 Polygon simplified = simplifier .simplify (polygon );
371406 assertPolygonEnds ("Polygon" , maxPoints , simplified , polygon );
372407 monitor .assertCompleted (1 , length , length - maxPoints );
408+ assertThat ("Should create exactly the needed number of PointError objects" , simplifier .objCount , equalTo (maxPoints + 1 ));
373409 }
374410 }
375411 }
@@ -391,7 +427,12 @@ public void testComplexGeoJsonMultiPolygon() throws IOException, ParseException
391427 int maxPolyPoints = Math .max (4 , (int ) (simplificationFactor * polygon .getPolygon ().length ()));
392428 assertPolygonEnds ("Polygon[" + i + "]" , maxPolyPoints , simplified , polygon );
393429 }
394- monitor .assertCompleted (simplifiedMultiPolygon .size (), maxPolyLength , maxPolyLength - maxPoints );
430+ monitor .assertCompleted (
431+ simplifiedMultiPolygon .size (),
432+ maxPolyLength ,
433+ maxPolyLength - maxPoints ,
434+ Matchers ::greaterThanOrEqualTo
435+ );
395436 }
396437 }
397438
0 commit comments