35
35
36
36
/**
37
37
* Manager class to register encoder, assign their flag values and check objects with all encoders
38
- * during parsing.
38
+ * during parsing. Create one via:
39
39
* <p>
40
+ * EncodingManager.start(4).add(new CarFlagEncoder()).build();
40
41
*
41
42
* @author Peter Karich
42
43
* @author Nop
@@ -46,7 +47,7 @@ public class EncodingManager implements EncodedValueLookup {
46
47
private static final String WAY_ERR = "Decrease the number of vehicles or increase the flags to take long via graph.bytes_for_flags: 8" ;
47
48
private final List <AbstractFlagEncoder > edgeEncoders = new ArrayList <>();
48
49
private final Map <String , EncodedValue > encodedValueMap = new LinkedHashMap <>();
49
- private final Map <EncodedValue , OSMTagParser > sharedEncodedValueMap = new LinkedHashMap <>();
50
+ private final Map <EncodedValue , TagParser > sharedEncodedValueMap = new LinkedHashMap <>();
50
51
private final int bitsForEdgeFlags ;
51
52
private final int bitsForTurnFlags = 8 * 4 ;
52
53
private int nextNodeBit = 0 ;
@@ -63,61 +64,139 @@ public class EncodingManager implements EncodedValueLookup {
63
64
*
64
65
* @param flagEncodersStr comma delimited list of encoders. The order does not matter.
65
66
*/
66
- public EncodingManager (String flagEncodersStr ) {
67
- this (flagEncodersStr , 4 );
67
+ public static EncodingManager create (String flagEncodersStr ) {
68
+ return create (flagEncodersStr , 4 );
68
69
}
69
70
70
- public EncodingManager (String flagEncodersStr , int bytesForEdgeFlags ) {
71
- this (FlagEncoderFactory .DEFAULT , flagEncodersStr , bytesForEdgeFlags );
71
+ public static EncodingManager create (String flagEncodersStr , int bytesForEdgeFlags ) {
72
+ return create (FlagEncoderFactory .DEFAULT , flagEncodersStr , bytesForEdgeFlags );
72
73
}
73
74
74
- public EncodingManager (FlagEncoderFactory factory , String flagEncodersStr , int bytesForEdgeFlags ) {
75
- this (parseEncoderString (factory , flagEncodersStr ), bytesForEdgeFlags );
75
+ public static EncodingManager create (FlagEncoderFactory factory , String flagEncodersStr , int bytesForEdgeFlags ) {
76
+ return create (parseEncoderString (factory , flagEncodersStr ), bytesForEdgeFlags );
76
77
}
77
78
78
79
/**
79
80
* Instantiate manager with the given list of encoders.
80
81
*
81
82
* @param flagEncoders comma delimited list of encoders. The order does not matter.
82
83
*/
83
- public EncodingManager (FlagEncoder ... flagEncoders ) {
84
- this (Arrays .asList (flagEncoders ));
84
+ public static EncodingManager create (FlagEncoder ... flagEncoders ) {
85
+ return create (Arrays .asList (flagEncoders ));
85
86
}
86
87
87
88
/**
88
89
* Instantiate manager with the given list of encoders.
89
90
*
90
91
* @param flagEncoders comma delimited list of encoders. The order does not matter.
91
92
*/
92
- public EncodingManager (List <? extends FlagEncoder > flagEncoders ) {
93
- this (flagEncoders , 4 );
93
+ public static EncodingManager create (List <? extends FlagEncoder > flagEncoders ) {
94
+ return create (flagEncoders , 4 );
94
95
}
95
96
96
- public EncodingManager (List <? extends FlagEncoder > flagEncoders , int bytesForEdgeFlags ) {
97
- if (bytesForEdgeFlags <= 0 || (bytesForEdgeFlags / 4 ) * 4 != bytesForEdgeFlags )
98
- throw new IllegalStateException ("For 'edge flags' only a multiple of 4 is supported" );
97
+ public static EncodingManager create (List <? extends FlagEncoder > flagEncoders , int bytesForEdgeFlags ) {
98
+ Builder builder = new Builder (bytesForEdgeFlags );
99
+ for (FlagEncoder flagEncoder : flagEncoders ) {
100
+ builder .add (flagEncoder );
101
+ }
102
+ return builder .build ();
103
+ }
99
104
100
- this .bitsForEdgeFlags = bytesForEdgeFlags * 8 ;
105
+ /**
106
+ * Create the EncodingManager from the provided GraphHopper location. Throws an
107
+ * IllegalStateException if it fails. Used if no EncodingManager specified on load.
108
+ */
109
+ public static EncodingManager create (FlagEncoderFactory factory , String ghLoc ) {
110
+ Directory dir = new RAMDirectory (ghLoc , true );
111
+ StorableProperties properties = new StorableProperties (dir );
112
+ if (!properties .loadExisting ())
113
+ throw new IllegalStateException ("Cannot load properties to fetch EncodingManager configuration at: "
114
+ + dir .getLocation ());
115
+
116
+ // check encoding for compatibility
117
+ properties .checkVersions (false );
118
+ String acceptStr = properties .get ("graph.flag_encoders" );
119
+
120
+ if (acceptStr .isEmpty ())
121
+ throw new IllegalStateException ("EncodingManager was not configured. And no one was found in the graph: "
122
+ + dir .getLocation ());
123
+
124
+ int bytesForFlags = 4 ;
125
+ try {
126
+ bytesForFlags = Integer .parseInt (properties .get ("graph.bytes_for_flags" ));
127
+ } catch (NumberFormatException ex ) {
128
+ }
129
+ return create (factory , acceptStr , bytesForFlags );
130
+ }
131
+
132
+ /**
133
+ * Starts the build process of an EncodingManager
134
+ */
135
+ public static Builder start () {
136
+ return new Builder (4 );
137
+ }
138
+
139
+ private EncodingManager (int bytes ) {
140
+ if (bytes <= 0 || (bytes / 4 ) * 4 != bytes )
141
+ throw new IllegalStateException ("bytesForEdgeFlags can be only a multiple of 4" );
142
+
143
+ this .bitsForEdgeFlags = bytes * 8 ;
101
144
this .config = new EncodedValue .InitializerConfig ();
102
- final BooleanEncodedValue roundaboutEnc = new SimpleBooleanEncodedValue ("roundabout" , false );
103
- sharedEncodedValueMap .put (roundaboutEnc , new OSMTagParser () {
104
- @ Override
105
- public IntsRef handleWayTags (IntsRef edgeFlags , ReaderWay way , long allowed , long relationFlags ) {
106
- boolean isRoundabout = way .hasTag ("junction" , "roundabout" ) || way .hasTag ("junction" , "circular" );
107
- if (isRoundabout )
108
- roundaboutEnc .setBool (false , edgeFlags , true );
109
- return edgeFlags ;
145
+ }
146
+
147
+ public static class Builder {
148
+ private final EncodingManager em ;
149
+ private boolean buildCalled = false ;
150
+
151
+ public Builder (int bytes ) {
152
+ em = new EncodingManager (bytes );
153
+ final BooleanEncodedValue roundaboutEnc = new SimpleBooleanEncodedValue ("roundabout" , false );
154
+ put (roundaboutEnc , new TagParser () {
155
+ @ Override
156
+ public IntsRef handleWayTags (IntsRef edgeFlags , ReaderWay way , long allowed , long relationFlags ) {
157
+ boolean isRoundabout = way .hasTag ("junction" , "roundabout" ) || way .hasTag ("junction" , "circular" );
158
+ if (isRoundabout )
159
+ roundaboutEnc .setBool (false , edgeFlags , true );
160
+ return edgeFlags ;
161
+ }
162
+ });
163
+ }
164
+
165
+ /**
166
+ * For backward compatibility provide a way to add multiple FlagEncoders
167
+ */
168
+ public Builder addAll (FlagEncoderFactory factory , String flagEncodersStr ) {
169
+ for (FlagEncoder fe : parseEncoderString (factory , flagEncodersStr )) {
170
+ add (fe );
110
171
}
111
- });
112
- for (EncodedValue ev : sharedEncodedValueMap .keySet ()) {
113
- addEncodedValue (ev );
172
+ return this ;
114
173
}
115
- for (FlagEncoder flagEncoder : flagEncoders ) {
116
- registerEncoder ((AbstractFlagEncoder ) flagEncoder );
174
+
175
+ public Builder add (FlagEncoder encoder ) {
176
+ em .addEncoder ((AbstractFlagEncoder ) encoder );
177
+ return this ;
117
178
}
118
179
119
- if (edgeEncoders .isEmpty ())
120
- throw new IllegalStateException ("No vehicles found" );
180
+ public Builder add (EncodedValue encodedValue ) {
181
+ em .addEncodedValue (encodedValue );
182
+ return this ;
183
+ }
184
+
185
+ public Builder put (EncodedValue encodedValue , TagParser tagParser ) {
186
+ add (encodedValue );
187
+ em .sharedEncodedValueMap .put (encodedValue , tagParser );
188
+ return this ;
189
+ }
190
+
191
+ public EncodingManager build () {
192
+ if (buildCalled )
193
+ throw new IllegalStateException ("Cannot call Builder.build() twice" );
194
+ if (em .encodedValueMap .isEmpty ())
195
+ throw new IllegalStateException ("No EncodedValues found" );
196
+
197
+ buildCalled = true ;
198
+ return em ;
199
+ }
121
200
}
122
201
123
202
static List <FlagEncoder > parseEncoderString (FlagEncoderFactory factory , String encoderList ) {
@@ -159,38 +238,11 @@ static String fixWayName(String str) {
159
238
return str .replaceAll (";[ ]*" , ", " );
160
239
}
161
240
162
- /**
163
- * Create the EncodingManager from the provided GraphHopper location. Throws an
164
- * IllegalStateException if it fails. Used if no EncodingManager specified on load.
165
- */
166
- public static EncodingManager create (FlagEncoderFactory factory , String ghLoc ) {
167
- Directory dir = new RAMDirectory (ghLoc , true );
168
- StorableProperties properties = new StorableProperties (dir );
169
- if (!properties .loadExisting ())
170
- throw new IllegalStateException ("Cannot load properties to fetch EncodingManager configuration at: "
171
- + dir .getLocation ());
172
-
173
- // check encoding for compatibility
174
- properties .checkVersions (false );
175
- String acceptStr = properties .get ("graph.flag_encoders" );
176
-
177
- if (acceptStr .isEmpty ())
178
- throw new IllegalStateException ("EncodingManager was not configured. And no one was found in the graph: "
179
- + dir .getLocation ());
180
-
181
- int bytesForFlags = 4 ;
182
- try {
183
- bytesForFlags = Integer .parseInt (properties .get ("graph.bytes_for_flags" ));
184
- } catch (NumberFormatException ex ) {
185
- }
186
- return new EncodingManager (factory , acceptStr , bytesForFlags );
187
- }
188
-
189
241
public int getBytesForFlags () {
190
242
return bitsForEdgeFlags / 8 ;
191
243
}
192
244
193
- private void registerEncoder (AbstractFlagEncoder encoder ) {
245
+ private void addEncoder (AbstractFlagEncoder encoder ) {
194
246
if (encoder .isRegistered ())
195
247
throw new IllegalStateException ("You must not register a FlagEncoder (" + encoder .toString () + ") twice!" );
196
248
@@ -243,7 +295,7 @@ private void addEncodedValue(EncodedValue ev) {
243
295
/**
244
296
* @return true if the specified encoder is found
245
297
*/
246
- public boolean supports (String encoder ) {
298
+ public boolean hasEncoder (String encoder ) {
247
299
return getEncoder (encoder , false ) != null ;
248
300
}
249
301
@@ -290,7 +342,7 @@ public long handleRelationTags(long oldRelationFlags, ReaderRelation relation) {
290
342
*/
291
343
public IntsRef handleWayTags (ReaderWay way , long includeWay , long relationFlags ) {
292
344
IntsRef edgeFlags = createEdgeFlags ();
293
- for (OSMTagParser parser : sharedEncodedValueMap .values ()) {
345
+ for (TagParser parser : sharedEncodedValueMap .values ()) {
294
346
parser .handleWayTags (edgeFlags , way , includeWay , relationFlags );
295
347
}
296
348
for (AbstractFlagEncoder encoder : edgeEncoders ) {
@@ -466,7 +518,7 @@ public ObjectEncodedValue getObjectEncodedValue(String key) {
466
518
public <T extends EncodedValue > T getEncodedValue (String key , Class <T > encodedValueType ) {
467
519
EncodedValue ev = encodedValueMap .get (key );
468
520
if (ev == null )
469
- throw new IllegalArgumentException ("Cannot find encoded value " + key + " in collection: " + ev );
521
+ throw new IllegalArgumentException ("Cannot find EncodedValue " + key + " in collection: " + ev );
470
522
return (T ) ev ;
471
523
}
472
524
@@ -479,8 +531,7 @@ public static final String getKey(FlagEncoder encoder, String str) {
479
531
return encoder .toString () + "." + str ;
480
532
}
481
533
482
- // for now keep private as public IntsRef is too ugly and relationFlags is unclear
483
- interface OSMTagParser {
534
+ public interface TagParser {
484
535
IntsRef handleWayTags (IntsRef edgeFlags , ReaderWay way , long allowed , long relationFlags );
485
536
}
486
537
}
0 commit comments