Skip to content

Commit 2963873

Browse files
committed
add FeatureDictionary.byId
1 parent 8fa41fe commit 2963873

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,13 @@ List<Feature> matches = dictionary
8686
.find();
8787
// result list will have matches with at least amenity=bank, but not amenity=bench because it is a point-feature
8888
```
89+
90+
### Find by id
91+
92+
```java
93+
Feature feature = dictionary
94+
.byId("amenity/bank")
95+
.forLocale(Locale.GERMAN) // show results in German
96+
.inCountry("DE") // also include things (brands) that only exist in Germany
97+
.get();
98+
```

library/src/main/java/de/westnordost/osmfeatures/FeatureDictionary.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ public static FeatureDictionary create(String presetsBasePath, String brandPrese
5757
return new FeatureDictionary(featureCollection, brandsFeatureCollection);
5858
}
5959

60+
//region Get by id
61+
62+
/** Find feature by id */
63+
public QueryByIdBuilder byId(String id)
64+
{
65+
return new QueryByIdBuilder(id);
66+
}
67+
68+
private Feature get(String id, List<Locale> locales, String countryCode)
69+
{
70+
Feature feature = featureCollection.get(id, locales);
71+
if (feature != null) return feature;
72+
return brandFeatureCollection.get(id, Collections.singletonList(countryCode));
73+
}
74+
75+
//endregion
76+
6077
//region Query by tags
6178

6279
/** Find matches by a set of tags */
@@ -387,6 +404,48 @@ private FeatureTagsIndex createBrandTagsIndex(List<String> countryCodes)
387404

388405
//region Query builders
389406

407+
public class QueryByIdBuilder
408+
{
409+
private final String id;
410+
private Locale[] locale = new Locale[]{Locale.getDefault(), null};
411+
private String countryCode = null;
412+
413+
private QueryByIdBuilder(String id) { this.id = id; }
414+
415+
/** <p>Sets the locale(s) in which to present the results.</p>
416+
* <p>You can specify several locales in
417+
* a row to each fall back to if a translation does not exist in the locale before that.
418+
* For example <code>[new Locale("ca", "ES"), new Locale("es","ES")]</code> if you
419+
* wanted results preferredly in Catalan, but Spanish is also fine.</p>
420+
*
421+
* <p><code>null</code> means to include unlocalized results.</p>
422+
*
423+
* <p>If nothing is specified, it defaults to <code>[Locale.getDefault(), null]</code>,
424+
* i.e. unlocalized results are included by default.</p>
425+
* */
426+
public QueryByIdBuilder forLocale(Locale... locale)
427+
{
428+
this.locale = locale;
429+
return this;
430+
}
431+
432+
/** the ISO 3166-1 alpha-2 country code (e.g. "US") or the ISO 3166-2 (e.g. "US-NY") of the
433+
* country/state the element is in. If not specified, will only return matches that are not
434+
* county-specific. */
435+
public QueryByIdBuilder inCountry(String countryCode)
436+
{
437+
this.countryCode = countryCode;
438+
return this;
439+
}
440+
441+
/** Returns the feature associated with the given id or <code>null</code> if it does not
442+
* exist */
443+
public Feature get()
444+
{
445+
return FeatureDictionary.this.get(id, Arrays.asList(locale), countryCode);
446+
}
447+
}
448+
390449
public class QueryByTagBuilder
391450
{
392451
private final Map<String, String> tags;

library/src/test/java/de/westnordost/osmfeatures/FeatureDictionaryTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,51 @@ public class FeatureDictionaryTest
583583

584584
//endregion
585585

586+
//region by id
587+
588+
@Test public void find_no_entry_by_id()
589+
{
590+
FeatureDictionary dictionary = dictionary(bakery);
591+
assertNull(dictionary.byId("amenity/hospital").get());
592+
}
593+
594+
@Test public void find_no_entry_by_id_because_unlocalized_results_are_excluded()
595+
{
596+
FeatureDictionary dictionary = dictionary(bakery);
597+
assertNull(dictionary.byId("shop/bakery").forLocale(Locale.ITALIAN).get());
598+
}
599+
600+
@Test public void find_entry_by_id()
601+
{
602+
FeatureDictionary dictionary = dictionary(bakery);
603+
assertEquals(bakery, dictionary.byId("shop/bakery").get());
604+
assertEquals(bakery, dictionary.byId("shop/bakery").forLocale(Locale.CHINESE, null).get());
605+
}
606+
607+
@Test public void find_localized_entry_by_id()
608+
{
609+
FeatureDictionary dictionary = dictionary(panetteria);
610+
assertEquals(panetteria, dictionary.byId("shop/bakery").forLocale(Locale.ITALIAN).get());
611+
assertEquals(panetteria, dictionary.byId("shop/bakery").forLocale(Locale.ITALIAN, null).get());
612+
}
613+
614+
@Test public void find_no_entry_by_id_because_wrong_country()
615+
{
616+
FeatureDictionary dictionary = dictionary(ditsch);
617+
assertNull(dictionary.byId("shop/bakery/Ditsch").get());
618+
assertNull(dictionary.byId("shop/bakery/Ditsch").inCountry("IT").get());
619+
assertNull(dictionary.byId("shop/bakery/Ditsch").inCountry("AT-9").get());
620+
}
621+
622+
@Test public void find_entry_by_id_in_country()
623+
{
624+
FeatureDictionary dictionary = dictionary(ditsch);
625+
assertEquals(ditsch, dictionary.byId("shop/bakery/Ditsch").inCountry("AT").get());
626+
assertEquals(ditsch, dictionary.byId("shop/bakery/Ditsch").inCountry("DE").get());
627+
}
628+
629+
//endregion
630+
586631
@Test public void find_by_term_sorts_result_in_correct_order()
587632
{
588633
FeatureDictionary dictionary = dictionary(

0 commit comments

Comments
 (0)