@@ -108,7 +108,7 @@ public static EncodingManager create(EncodedValueFactory evFactory, FlagEncoderF
108
108
throw new IllegalStateException ("Cannot load properties to fetch EncodingManager configuration at: "
109
109
+ dir .getLocation ());
110
110
111
- EncodingManager .Builder builder = new EncodingManager .Builder (false );
111
+ EncodingManager .Builder builder = new EncodingManager .Builder ();
112
112
String encodedValuesStr = properties .get ("graph.encoded_values" );
113
113
if (!Helper .isEmpty (encodedValuesStr ))
114
114
builder .addAll (evFactory , encodedValuesStr );
@@ -144,15 +144,14 @@ public void releaseParsers() {
144
144
145
145
public static class Builder {
146
146
private EncodingManager em ;
147
+ List <AbstractFlagEncoder > flagEncoderList = new ArrayList <>();
148
+ List <EncodedValue > encodedValueList = new ArrayList <>();
149
+ List <TagParser > tagParsers = new ArrayList <>();
150
+ List <TurnCostParser > turnCostParsers = new ArrayList <>();
151
+ List <RelationTagParser > relationTagParsers = new ArrayList <>();
147
152
148
153
public Builder () {
149
- this (true );
150
- }
151
-
152
- private Builder (boolean addRoundabout ) {
153
154
em = new EncodingManager ();
154
- if (addRoundabout )
155
- add (new OSMRoundaboutParser ());
156
155
}
157
156
158
157
/**
@@ -186,67 +185,46 @@ public Builder setEnableInstructions(boolean enable) {
186
185
* For backward compatibility provide a way to add multiple FlagEncoders
187
186
*/
188
187
public Builder addAll (FlagEncoderFactory factory , String flagEncodersStr ) {
188
+ check ();
189
189
for (FlagEncoder fe : parseEncoderString (factory , flagEncodersStr )) {
190
- add (fe );
190
+ flagEncoderList . add (( AbstractFlagEncoder ) fe );
191
191
}
192
192
return this ;
193
193
}
194
194
195
195
public Builder addAll (EncodedValueFactory factory , String encodedValueString ) {
196
- em .add (this , factory , encodedValueString );
196
+ check ();
197
+ em .add (encodedValueList , factory , encodedValueString );
197
198
return this ;
198
199
}
199
200
200
201
public Builder addAll (TagParserFactory factory , String tagParserString ) {
201
- em .add (this , factory , tagParserString );
202
+ check ();
203
+ em .add (tagParsers , factory , tagParserString );
202
204
return this ;
203
205
}
204
206
205
207
public Builder addTurnCostParser (TurnCostParser parser ) {
206
- List <EncodedValue > list = new ArrayList <>();
207
- parser .createTurnCostEncodedValues (em , list );
208
- for (EncodedValue ev : list ) {
209
- ev .init (em .turnCostConfig );
210
- if (em .encodedValueMap .containsKey (ev .getName ()))
211
- throw new IllegalArgumentException ("Already defined: " + ev .getName () + ". Please note that " +
212
- "EncodedValues for edges and turn cost are in the same namespace." );
213
- em .encodedValueMap .put (ev .getName (), ev );
214
- }
215
- em .turnCostParsers .put (parser .getName (), parser );
208
+ check ();
209
+ turnCostParsers .add (parser );
216
210
return this ;
217
211
}
218
212
219
213
public Builder addRelationTagParser (RelationTagParser tagParser ) {
220
- List <EncodedValue > list = new ArrayList <>();
221
- tagParser .createRelationEncodedValues (em , list );
222
- for (EncodedValue ev : list ) {
223
- ev .init (em .relationConfig );
224
- }
225
- em .relationTagParsers .add (tagParser );
226
-
227
- // add as "edge" TagParser
228
- add (tagParser , true );
214
+ check ();
215
+ relationTagParsers .add (tagParser );
229
216
return this ;
230
217
}
231
218
232
219
public Builder add (FlagEncoder encoder ) {
233
220
check ();
234
- if (encoder instanceof BikeCommonFlagEncoder && !em .hasEncodedValue (getKey ("bike" , RouteNetwork .EV_SUFFIX ))) {
235
- addRelationTagParser (new OSMBikeNetworkTagParser ());
236
- } else if (encoder instanceof FootFlagEncoder && !em .hasEncodedValue (getKey ("foot" , RouteNetwork .EV_SUFFIX ))) {
237
- addRelationTagParser (new OSMFootNetworkTagParser ());
238
- }
239
-
240
- em .addEncoder ((AbstractFlagEncoder ) encoder );
221
+ flagEncoderList .add ((AbstractFlagEncoder ) encoder );
241
222
return this ;
242
223
}
243
224
244
225
public Builder add (EncodedValue encodedValue ) {
245
226
check ();
246
- if (!em .edgeEncoders .isEmpty ())
247
- throw new IllegalArgumentException ("Always add shared EncodedValues before FlagEncoders to ensure they can be loaded first" );
248
-
249
- em .addEncodedValue (encodedValue , false );
227
+ encodedValueList .add (encodedValue );
250
228
return this ;
251
229
}
252
230
@@ -255,34 +233,115 @@ public Builder add(EncodedValue encodedValue) {
255
233
* createEncodedValues.
256
234
*/
257
235
public Builder add (TagParser tagParser ) {
258
- return add (tagParser , false );
236
+ check ();
237
+ tagParsers .add (tagParser );
238
+ return this ;
259
239
}
260
240
261
- private Builder add (TagParser tagParser , boolean encValBoundToFlagEncoder ) {
241
+ private void check () {
242
+ if (em == null )
243
+ throw new IllegalStateException ("Cannot call method after Builder.build() was called" );
244
+ }
245
+
246
+ private void _addEdgeTagParser (TagParser tagParser , boolean withNamespace , boolean insert ) {
262
247
List <EncodedValue > list = new ArrayList <>();
263
248
tagParser .createEncodedValues (em , list );
264
249
for (EncodedValue ev : list ) {
265
- em .addEncodedValue (ev , encValBoundToFlagEncoder );
250
+ em .addEncodedValue (ev , withNamespace );
266
251
}
267
- em .edgeTagParsers .add (tagParser );
268
- return this ;
252
+ if (insert )
253
+ em .edgeTagParsers .add (0 , tagParser );
254
+ else
255
+ em .edgeTagParsers .add (tagParser );
269
256
}
270
257
271
- private void check () {
272
- if (em == null )
273
- throw new IllegalStateException ("Cannot call method after Builder.build() was called" );
258
+ private void _addRelationTagParser (RelationTagParser tagParser ) {
259
+ List <EncodedValue > list = new ArrayList <>();
260
+ tagParser .createRelationEncodedValues (em , list );
261
+ for (EncodedValue ev : list ) {
262
+ ev .init (em .relationConfig );
263
+ }
264
+ em .relationTagParsers .add (tagParser );
265
+
266
+ // for simplicity add into edge-EncodedValue
267
+ _addEdgeTagParser (tagParser , true , false );
268
+ }
269
+
270
+ private void _addTurnCostParser (TurnCostParser parser ) {
271
+ List <EncodedValue > list = new ArrayList <>();
272
+ parser .createTurnCostEncodedValues (em , list );
273
+ for (EncodedValue ev : list ) {
274
+ ev .init (em .turnCostConfig );
275
+ if (em .encodedValueMap .containsKey (ev .getName ()))
276
+ throw new IllegalArgumentException ("Already defined: " + ev .getName () + ". Please note that " +
277
+ "EncodedValues for edges and turn cost are in the same namespace." );
278
+ em .encodedValueMap .put (ev .getName (), ev );
279
+ }
280
+ em .turnCostParsers .put (parser .getName (), parser );
274
281
}
275
282
276
283
public EncodingManager build () {
277
284
check ();
278
- if (em .encodedValueMap .isEmpty ())
279
- throw new IllegalStateException ("No EncodedValues found" );
280
285
281
- for (AbstractFlagEncoder encoder : em .edgeEncoders ) {
286
+ for (RelationTagParser tagParser : relationTagParsers ) {
287
+ _addRelationTagParser (tagParser );
288
+ }
289
+
290
+ List <SpatialRuleParser > insertLater = new ArrayList <>();
291
+ for (TagParser tagParser : tagParsers ) {
292
+ if (SpatialRuleParser .class .isAssignableFrom (tagParser .getClass ())) {
293
+ insertLater .add ((SpatialRuleParser ) tagParser );
294
+ } else {
295
+ _addEdgeTagParser (tagParser , false , false );
296
+ }
297
+ }
298
+
299
+ for (EncodedValue ev : encodedValueList ) {
300
+ em .addEncodedValue (ev , false );
301
+ }
302
+
303
+ if (!em .encodedValueMap .containsKey (RoadAccess .KEY ))
304
+ _addEdgeTagParser (new OSMRoadAccessParser (), false , true );
305
+ if (!em .encodedValueMap .containsKey (MaxSpeed .KEY ))
306
+ _addEdgeTagParser (new OSMMaxSpeedParser (), false , true );
307
+ if (!em .encodedValueMap .containsKey (RoadEnvironment .KEY ))
308
+ _addEdgeTagParser (new OSMRoadEnvironmentParser (), false , true );
309
+ if (!em .encodedValueMap .containsKey (RoadClassLink .KEY ))
310
+ _addEdgeTagParser (new OSMRoadClassLinkParser (), false , true );
311
+ if (!em .encodedValueMap .containsKey (RoadClass .KEY ))
312
+ _addEdgeTagParser (new OSMRoadClassParser (), false , true );
313
+ if (!em .encodedValueMap .containsKey (Roundabout .KEY ))
314
+ _addEdgeTagParser (new OSMRoundaboutParser (), false , true );
315
+
316
+ // TODO can we avoid this hack without complex dependency management?
317
+ // ensure that SpatialRuleParser come after required EncodedValues like max_speed or road_access
318
+ for (SpatialRuleParser srp : insertLater ) {
319
+ _addEdgeTagParser (srp , false , true );
320
+ }
321
+
322
+ for (AbstractFlagEncoder encoder : flagEncoderList ) {
323
+ if (encoder instanceof BikeCommonFlagEncoder && !em .hasEncodedValue (getKey ("bike" , RouteNetwork .EV_SUFFIX ))) {
324
+ _addRelationTagParser (new OSMBikeNetworkTagParser ());
325
+ } else if (encoder instanceof FootFlagEncoder && !em .hasEncodedValue (getKey ("foot" , RouteNetwork .EV_SUFFIX ))) {
326
+ _addRelationTagParser (new OSMFootNetworkTagParser ());
327
+ }
328
+
329
+ em .addEncoder (encoder );
330
+ }
331
+
332
+ for (TurnCostParser parser : turnCostParsers ) {
333
+ _addTurnCostParser (parser );
334
+ }
335
+
336
+ // FlagEncoder can demand TurnCostParsers => add them after the explicitly added ones
337
+ for (AbstractFlagEncoder encoder : flagEncoderList ) {
282
338
if (encoder .supports (TurnWeighting .class ) && !em .turnCostParsers .containsKey (encoder .toString ()))
283
- addTurnCostParser (new OSMTurnRelationParser (encoder .toString (), encoder .getMaxTurnCosts ()));
339
+ _addTurnCostParser (new OSMTurnRelationParser (encoder .toString (), encoder .getMaxTurnCosts ()));
284
340
}
285
341
342
+ if (em .encodedValueMap .isEmpty ())
343
+ throw new IllegalStateException ("No EncodedValues found" );
344
+
286
345
EncodingManager tmp = em ;
287
346
em = null ;
288
347
return tmp ;
@@ -315,7 +374,7 @@ static List<FlagEncoder> parseEncoderString(FlagEncoderFactory factory, String e
315
374
return resultEncoders ;
316
375
}
317
376
318
- private void add (Builder builder , EncodedValueFactory factory , String evList ) {
377
+ private void add (List < EncodedValue > returnList , EncodedValueFactory factory , String evList ) {
319
378
if (!evList .equals (toLowerCase (evList )))
320
379
throw new IllegalArgumentException ("Use lower case for EncodedValues: " + evList );
321
380
@@ -325,14 +384,14 @@ private void add(Builder builder, EncodedValueFactory factory, String evList) {
325
384
continue ;
326
385
327
386
EncodedValue evObject = factory .create (entry );
328
- builder .add (evObject );
329
387
PMap map = new PMap (entry );
330
388
if (!map .has ("version" ))
331
389
throw new IllegalArgumentException ("encoded value must have a version specified but it was " + entry );
390
+ returnList .add (evObject );
332
391
}
333
392
}
334
393
335
- private void add (Builder builder , TagParserFactory factory , String tpList ) {
394
+ private void add (List < TagParser > returnList , TagParserFactory factory , String tpList ) {
336
395
if (!tpList .equals (toLowerCase (tpList )))
337
396
throw new IllegalArgumentException ("Use lower case for TagParser: " + tpList );
338
397
@@ -343,7 +402,7 @@ private void add(Builder builder, TagParserFactory factory, String tpList) {
343
402
344
403
PMap map = new PMap (entry );
345
404
TagParser tp = factory .create (entry , map );
346
- builder .add (tp );
405
+ returnList .add (tp );
347
406
}
348
407
}
349
408
@@ -398,13 +457,13 @@ private void addEncoder(AbstractFlagEncoder encoder) {
398
457
edgeEncoders .add (encoder );
399
458
}
400
459
401
- private void addEncodedValue (EncodedValue ev , boolean encValBoundToFlagEncoder ) {
460
+ private void addEncodedValue (EncodedValue ev , boolean withNamespace ) {
402
461
if (encodedValueMap .containsKey (ev .getName ()))
403
462
throw new IllegalStateException ("EncodedValue " + ev .getName () + " already exists " + encodedValueMap .get (ev .getName ()) + " vs " + ev );
404
- if (!encValBoundToFlagEncoder && ev .getName ().contains (SPECIAL_SEPARATOR ))
405
- throw new IllegalArgumentException ("EncodedValue " + ev .getName () + " must not contain '" + SPECIAL_SEPARATOR + "'" );
406
- if (encValBoundToFlagEncoder && !ev .getName ().contains (SPECIAL_SEPARATOR ))
407
- throw new IllegalArgumentException ("EncodedValue " + ev .getName () + " must contain '" + SPECIAL_SEPARATOR + "' as reserved for a single profile " );
463
+ if (!withNamespace && ev .getName ().contains (SPECIAL_SEPARATOR ))
464
+ throw new IllegalArgumentException ("EncodedValue " + ev .getName () + " must not contain namespace character '" + SPECIAL_SEPARATOR + "'" );
465
+ if (withNamespace && !ev .getName ().contains (SPECIAL_SEPARATOR ))
466
+ throw new IllegalArgumentException ("EncodedValue " + ev .getName () + " must contain namespace character '" + SPECIAL_SEPARATOR + "'" );
408
467
ev .init (edgeConfig );
409
468
encodedValueMap .put (ev .getName (), ev );
410
469
}
0 commit comments