Skip to content

Commit c50e4a9

Browse files
authored
Merge pull request #903 from hircumg/feature/dedupe-arg
Added dedupe arg for requests
2 parents 00caff7 + 5535d9b commit c50e4a9

File tree

5 files changed

+112
-3
lines changed

5 files changed

+112
-3
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ photon uses gradle for building. To build the package from source make sure you
113113
./gradlew build
114114
```
115115

116-
This will build and test photon in the ElasticSearch and OpenSearch version.
116+
This will build and test photon in the ElasticSearch and OpenSearch version.
117117
The final jar can be found in the `target` directory.
118118

119119
## Usage
@@ -431,6 +431,18 @@ http://localhost:2322/api?q=berlin&layer=city&layer=locality
431431

432432
Example above will return both cities and localities.
433433

434+
#### Dedupe results
435+
436+
```
437+
http://localhost:2322/api?q=berlin&dedupe=1
438+
```
439+
440+
Sometimes you have several objects in OSM identifying the same place or object in reality.
441+
The simplest case is a street being split into many different OSM ways due to different characteristics.
442+
Photon will attempt to detect such duplicates and only return one match.
443+
Setting `dedupe` parameter to `0` disables this deduplication mechanism and ensures that all results are returned.
444+
By default, Photon will attempt to deduplicate results which have the same `name`, `postcode`, and `osm_value` if exists.
445+
434446
### Results for Search and Reverse
435447

436448
Photon returns a response in [GeocodeJson format](https://github.com/geocoders/geocodejson-spec/tree/master/draft)

src/main/java/de/komoot/photon/GenericSearchHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ public void handle(@NotNull Context context) {
3030
var results = requestHandler.search(searchRequest);
3131

3232
// Further filtering
33-
results = new StreetDupesRemover(searchRequest.getLanguage()).execute(results);
33+
if (searchRequest.getDedupe()){
34+
results = new StreetDupesRemover(searchRequest.getLanguage()).execute(results);
35+
}
3436

3537
// Restrict to the requested limit.
3638
if (results.size() > searchRequest.getLimit()) {

src/main/java/de/komoot/photon/query/RequestBase.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class RequestBase {
88
private String language = "default";
99
private int limit = 15;
1010
private boolean debug = false;
11+
private boolean dedupe = true;
1112
private boolean returnGeometry = false;
1213

1314
private final List<TagFilter> osmTagFilters = new ArrayList<>(1);
@@ -25,6 +26,10 @@ public boolean getDebug() {
2526
return debug;
2627
}
2728

29+
public boolean getDedupe() {
30+
return dedupe;
31+
}
32+
2833
public boolean getReturnGeometry() {
2934
return returnGeometry;
3035
}
@@ -55,6 +60,12 @@ public void setDebug(Boolean debug) {
5560
}
5661
}
5762

63+
public void setDedupe(Boolean dedupe) {
64+
if (dedupe != null) {
65+
this.dedupe = dedupe;
66+
}
67+
}
68+
5869
public void setReturnGeometry(Boolean returnGeometry) {
5970
if (returnGeometry != null) {
6071
this.returnGeometry = returnGeometry;

src/main/java/de/komoot/photon/query/RequestFactoryBase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
public class RequestFactoryBase {
1414
protected static final Set<String> BASE_PARAMETERS = Set.of(
15-
"lang", "limit", "debug", "geometry", "osm_tag", "layer");
15+
"lang", "limit", "debug", "dedupe", "geometry", "osm_tag", "layer");
1616
private static final List<String> AVAILABLE_LAYERS = AddressType.getNames();
1717
private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(new PrecisionModel(), 4326);
1818

@@ -37,6 +37,8 @@ protected void completeBaseRequest(RequestBase request, Context context) {
3737

3838
request.setDebug(context.queryParamAsClass("debug", Boolean.class).getOrDefault(false));
3939

40+
request.setDedupe(context.queryParamAsClass("dedupe", Boolean.class).getOrDefault(true));
41+
4042
request.addLayerFilters(context.queryParamsAsClass("layer", String.class)
4143
.allowNullable()
4244
.check(AVAILABLE_LAYERS::containsAll,
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package de.komoot.photon.api;
2+
3+
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
4+
5+
import de.komoot.photon.App;
6+
import de.komoot.photon.Importer;
7+
import de.komoot.photon.PhotonDoc;
8+
import java.nio.file.Path;
9+
import java.util.List;
10+
import org.junit.jupiter.api.*;
11+
import org.junit.jupiter.api.io.TempDir;
12+
import org.junit.jupiter.params.ParameterizedTest;
13+
import org.junit.jupiter.params.provider.ValueSource;
14+
15+
/**
16+
* Tests for dedupe works correctly
17+
*/
18+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
19+
class ApiDedupeTest extends ApiBaseTester {
20+
21+
@BeforeAll
22+
void setUp(@TempDir Path dataDirectory) throws Exception {
23+
setUpES(dataDirectory);
24+
Importer instance = makeImporter();
25+
26+
instance.add(
27+
List.of(
28+
new PhotonDoc()
29+
.placeId(1000)
30+
.osmType("W")
31+
.osmId(1000)
32+
.tagKey("highway")
33+
.tagValue("residential")
34+
.postcode("1000")
35+
.rankAddress(26)
36+
.centroid(makePoint(15.94174, 45.80355))
37+
.names(makeDocNames("name", "Pfanove"))
38+
)
39+
);
40+
instance.add(
41+
List.of(
42+
new PhotonDoc()
43+
.placeId(1001)
44+
.osmType("W")
45+
.osmId(1001)
46+
.tagKey("highway")
47+
.tagValue("residential")
48+
.postcode("1000")
49+
.rankAddress(26)
50+
.centroid(makePoint(15.94192, 45.802429))
51+
.names(makeDocNames("name", "Pfanove"))
52+
)
53+
);
54+
55+
instance.finish();
56+
refresh();
57+
startAPI();
58+
}
59+
60+
@AfterAll
61+
public void tearDown() {
62+
App.shutdown();
63+
shutdownES();
64+
}
65+
66+
@ParameterizedTest
67+
@ValueSource(
68+
strings = {
69+
"/api?q=Pfanove", // basic search
70+
"/api?q=Pfanove&dedupe=1", // explicitly enabled dedupe
71+
}
72+
)
73+
void testEnabledDedupe(String baseUrl) throws Exception {
74+
assertThatJson(readURL(baseUrl)).isObject().node("features").isArray().hasSize(1);
75+
}
76+
77+
@ParameterizedTest
78+
@ValueSource(strings = { "/api?q=Pfanove&dedupe=0" })
79+
void testDisabledDedupe(String baseUrl) throws Exception {
80+
assertThatJson(readURL(baseUrl)).isObject().node("features").isArray().hasSize(2);
81+
}
82+
}

0 commit comments

Comments
 (0)