Skip to content

Commit 21c0433

Browse files
authored
Add option for polygon/linestring in results (#823)
At the moment, photon only returns the point of a location, and not the polygon (see #259). This PR will add the option to add the polygon (i.e. geometry) to the Elasticsearch Index and a API parameter polygon to return said polygon. If no polygon exists, the point is returned. WARNING: This will increase the Elasticsearch Index size! (~575GB for a Planet import). To enable: add the command line argument -use-geometry-column whilst importing and add &geometry=true to the API call.
1 parent bf7798c commit 21c0433

File tree

58 files changed

+632
-130
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+632
-130
lines changed

app/es_embedded/es/mappings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
"coordinate": {
5050
"type": "geo_point"
5151
},
52+
"geometry": {
53+
"type": "geo_shape"
54+
},
5255
"country": {
5356
"properties": {
5457
"default": {

app/es_embedded/src/main/java/de/komoot/photon/Server.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class Server {
5656
private static final String FIELD_VERSION = "database_version";
5757
private static final String FIELD_LANGUAGES = "indexed_languages";
5858
private static final String FIELD_IMPORT_DATE = "import_date";
59+
private static final String FIELD_SUPPORT_GEOMETRIES = "support_geometries";
5960

6061
private Node esNode;
6162

@@ -177,14 +178,18 @@ private void setupDirectories(URL directoryName) throws IOException, URISyntaxEx
177178

178179
}
179180

180-
public DatabaseProperties recreateIndex(String[] languages, Date importDate, boolean supportStructuredQueries) throws IOException {
181+
public DatabaseProperties recreateIndex(String[] languages, Date importDate, boolean supportStructuredQueries, boolean supportGeometries) throws IOException {
181182
deleteIndex();
182183

183184
loadIndexSettings().createIndex(esClient, PhotonIndex.NAME);
184185

185186
createAndPutIndexMapping(languages, supportStructuredQueries);
186187

187-
DatabaseProperties dbProperties = new DatabaseProperties(languages, importDate, false);
188+
DatabaseProperties dbProperties = new DatabaseProperties()
189+
.setLanguages(languages)
190+
.setImportDate(importDate)
191+
.setSupportGeometries(supportGeometries);
192+
188193
saveToDatabase(dbProperties);
189194

190195
return dbProperties;
@@ -239,6 +244,7 @@ public void saveToDatabase(DatabaseProperties dbProperties) throws IOException
239244
.field(FIELD_VERSION, DATABASE_VERSION)
240245
.field(FIELD_LANGUAGES, String.join(",", dbProperties.getLanguages()))
241246
.field(FIELD_IMPORT_DATE, dbProperties.getImportDate() instanceof Date ? dbProperties.getImportDate().toInstant() : null)
247+
.field(FIELD_SUPPORT_GEOMETRIES, Boolean.toString(dbProperties.getSupportGeometries()))
242248
.endObject().endObject();
243249

244250
esClient.prepareIndex(PhotonIndex.NAME, PhotonIndex.TYPE).
@@ -276,11 +282,15 @@ public DatabaseProperties loadFromDatabase() {
276282
}
277283

278284
String langString = properties.get(FIELD_LANGUAGES);
285+
279286
String importDateString = properties.get(FIELD_IMPORT_DATE);
280287

288+
String supportGeometries = properties.get(FIELD_SUPPORT_GEOMETRIES);
289+
281290
return new DatabaseProperties(langString == null ? null : langString.split(","),
282-
importDateString == null ? null : Date.from(Instant.parse(importDateString)),
283-
false);
291+
importDateString == null ? null : Date.from(Instant.parse(importDateString)),
292+
false,
293+
Boolean.parseBoolean(supportGeometries));
284294
}
285295

286296
public Importer createImporter(String[] languages, String[] extraTags) {

app/es_embedded/src/main/java/de/komoot/photon/elasticsearch/ElasticResult.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ public double[] getCoordinates() {
6666
return new double[]{coordinate.get(Constants.LON), coordinate.get(Constants.LAT)};
6767
}
6868

69+
@Override
70+
public String getGeometry() {
71+
return (String) result.getSource().get("geometry");
72+
}
73+
6974
@Override
7075
public double[] getExtent() {
7176
final Map<String, Object> extent = (Map<String, Object>) result.getSource().get("extent");

app/es_embedded/src/main/java/de/komoot/photon/elasticsearch/PhotonDocConverter.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import de.komoot.photon.Constants;
44
import de.komoot.photon.PhotonDoc;
55
import de.komoot.photon.nominatim.model.AddressType;
6-
import org.elasticsearch.common.xcontent.XContentBuilder;
7-
import org.elasticsearch.common.xcontent.XContentFactory;
6+
7+
import org.elasticsearch.common.xcontent.*;
8+
import org.elasticsearch.common.xcontent.json.JsonXContent;
89
import org.locationtech.jts.geom.Envelope;
10+
import org.locationtech.jts.io.geojson.GeoJsonWriter;
911

1012
import java.io.IOException;
1113
import java.util.HashMap;
@@ -38,6 +40,17 @@ public static XContentBuilder convert(PhotonDoc doc, String[] languages, String[
3840
.endObject();
3941
}
4042

43+
if (doc.getGeometry() != null) {
44+
GeoJsonWriter g = new GeoJsonWriter();
45+
46+
XContentParser parser = JsonXContent
47+
.jsonXContent
48+
.createParser(NamedXContentRegistry.EMPTY, g.write(doc.getGeometry()));
49+
50+
builder.field("geometry");
51+
builder.copyCurrentStructure(parser);
52+
}
53+
4154
if (doc.getHouseNumber() != null) {
4255
builder.field("housenumber", doc.getHouseNumber());
4356
}

app/es_embedded/src/test/java/de/komoot/photon/ESBaseTester.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import de.komoot.photon.searcher.PhotonResult;
88
import org.junit.jupiter.api.AfterEach;
99
import org.junit.jupiter.api.io.TempDir;
10+
import org.locationtech.jts.io.ParseException;
11+
import org.locationtech.jts.io.WKTReader;
1012

1113
import java.io.IOException;
1214
import java.nio.file.Path;
@@ -25,9 +27,9 @@ public class ESBaseTester {
2527

2628
private ElasticTestServer server;
2729

28-
protected PhotonDoc createDoc(double lon, double lat, int id, int osmId, String key, String value) {
30+
protected PhotonDoc createDoc(double lon, double lat, int id, int osmId, String key, String value) throws ParseException {
2931
Point location = FACTORY.createPoint(new Coordinate(lon, lat));
30-
return new PhotonDoc(id, "W", osmId, key, value).names(Collections.singletonMap("name", "berlin")).centroid(location);
32+
return new PhotonDoc(id, "W", osmId, key, value).names(Collections.singletonMap("name", "berlin")).centroid(location).geometry(new WKTReader().read("POLYGON ((6.4440619 52.1969454, 6.4441094 52.1969158, 6.4441408 52.1969347, 6.4441138 52.1969516, 6.4440933 52.1969643, 6.4440619 52.1969454))"));
3133
}
3234

3335
protected PhotonResult getById(int id) {
@@ -45,17 +47,21 @@ public void tearDown() throws IOException {
4547
}
4648

4749
public void setUpES() throws IOException {
48-
setUpES(dataDirectory, "en");
50+
setUpES(dataDirectory, false,"en");
51+
}
52+
53+
public void setUpESWithGeometry() throws IOException {
54+
setUpES(dataDirectory, true,"en");
4955
}
5056
/**
5157
* Setup the ES server
5258
*
5359
* @throws IOException
5460
*/
55-
public void setUpES(Path testDirectory, String... languages) throws IOException {
61+
public void setUpES(Path testDirectory, boolean supportGeometries, String... languages) throws IOException {
5662
server = new ElasticTestServer(testDirectory.toString());
5763
server.start(TEST_CLUSTER_NAME, new String[]{});
58-
server.recreateIndex(languages, new Date(), false);
64+
server.recreateIndex(languages, new Date(), false, supportGeometries);
5965
refresh();
6066
}
6167

app/es_embedded/src/test/java/de/komoot/photon/elasticsearch/ElasticGetIdResult.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public double[] getCoordinates() {
3434
throw new NotImplementedException();
3535
}
3636

37+
public String getGeometry() {
38+
throw new NotImplementedException();
39+
}
40+
3741
@Override
3842
public double[] getExtent() {
3943
throw new NotImplementedException();

app/es_embedded/src/test/java/de/komoot/photon/elasticsearch/ElasticResultTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ protected PhotonDoc createDoc(double lon, double lat, int id, int osmId, String
4444

4545
@BeforeAll
4646
void setUp() throws Exception {
47-
setUpES(instanceTestDirectory, "en", "de", "fr", "it");
47+
setUpES(instanceTestDirectory, false, "en", "de", "fr", "it");
4848
Importer instance = getServer().createImporter(new String[]{"en", "de", "fr", "it"},
4949
new String[]{"population", "capital"});
5050

app/es_embedded/src/test/java/de/komoot/photon/elasticsearch/ImporterTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import de.komoot.photon.searcher.PhotonResult;
77
import org.junit.jupiter.api.BeforeEach;
88
import org.junit.jupiter.api.Test;
9+
import org.locationtech.jts.io.ParseException;
10+
import org.locationtech.jts.io.WKTReader;
911

1012
import java.io.IOException;
1113
import java.util.Collections;
@@ -22,10 +24,11 @@ public void setUp() throws IOException {
2224
}
2325

2426
@Test
25-
void testAddSimpleDoc() {
27+
void testAddSimpleDoc() throws ParseException {
2628
Importer instance = makeImporterWithExtra("");
2729

2830
instance.add(new PhotonDoc(1234, "N", 1000, "place", "city")
31+
.geometry(new WKTReader().read("MULTIPOLYGON (((6.111933 51.2659309, 6.1119417 51.2659247, 6.1119554 51.2659249, 6.1119868 51.2659432, 6.111964 51.2659591, 6.1119333 51.2659391, 6.111933 51.2659309)))"))
2932
.extraTags(Collections.singletonMap("maxspeed", "100")), 0);
3033
instance.finish();
3134
refresh();

app/es_embedded/src/test/java/de/komoot/photon/elasticsearch/ServerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void testSaveAndLoadFromDatabase() throws IOException {
1616
setUpES();
1717

1818
Date now = new Date();
19-
DatabaseProperties prop = new DatabaseProperties(new String[]{"en", "de", "fr"}, now, false);
19+
DatabaseProperties prop = new DatabaseProperties(new String[]{"en", "de", "fr"}, now, false, false);
2020
getServer().saveToDatabase(prop);
2121

2222
prop = getServer().loadFromDatabase();

app/opensearch/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ dependencies {
2222
implementation 'org.apache.httpcomponents.client5:httpclient5:5.4.1'
2323
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2'
2424

25-
implementation('org.codelibs.opensearch:opensearch-runner:2.18.0.0') {
25+
implementation('org.codelibs.opensearch:opensearch-runner:2.18.0.1') {
2626
exclude(module: 'repository-url')
2727
exclude(module: 'reindex-client')
2828
exclude(module: 'rank-eval-client')

0 commit comments

Comments
 (0)