Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for polygon/linestring in results #823

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/es_embedded/es/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"coordinate": {
"type": "geo_point"
},
"geometry": {
"type": "geo_shape"
},
"country": {
"properties": {
"default": {
Expand Down
18 changes: 14 additions & 4 deletions app/es_embedded/src/main/java/de/komoot/photon/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class Server {
private static final String FIELD_VERSION = "database_version";
private static final String FIELD_LANGUAGES = "indexed_languages";
private static final String FIELD_IMPORT_DATE = "import_date";
private static final String FIELD_SUPPORT_POLYGONS = "support_polygons";

private Node esNode;

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

}

public DatabaseProperties recreateIndex(String[] languages, Date importDate, boolean supportStructuredQueries) throws IOException {
public DatabaseProperties recreateIndex(String[] languages, Date importDate, boolean supportStructuredQueries, boolean supportPolygons) throws IOException {
deleteIndex();

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

createAndPutIndexMapping(languages, supportStructuredQueries);

DatabaseProperties dbProperties = new DatabaseProperties(languages, importDate, false);
DatabaseProperties dbProperties = new DatabaseProperties()
.setLanguages(languages)
.setImportDate(importDate)
.setSupportPolygons(supportPolygons);

saveToDatabase(dbProperties);

return dbProperties;
Expand Down Expand Up @@ -239,6 +244,7 @@ public void saveToDatabase(DatabaseProperties dbProperties) throws IOException
.field(FIELD_VERSION, DATABASE_VERSION)
.field(FIELD_LANGUAGES, String.join(",", dbProperties.getLanguages()))
.field(FIELD_IMPORT_DATE, dbProperties.getImportDate() instanceof Date ? dbProperties.getImportDate().toInstant() : null)
.field(FIELD_SUPPORT_POLYGONS, Boolean.toString(dbProperties.getSupportPolygons()))
.endObject().endObject();

esClient.prepareIndex(PhotonIndex.NAME, PhotonIndex.TYPE).
Expand Down Expand Up @@ -276,11 +282,15 @@ public DatabaseProperties loadFromDatabase() {
}

String langString = properties.get(FIELD_LANGUAGES);

String importDateString = properties.get(FIELD_IMPORT_DATE);

String supportPolygons = properties.get(FIELD_SUPPORT_POLYGONS);

return new DatabaseProperties(langString == null ? null : langString.split(","),
importDateString == null ? null : Date.from(Instant.parse(importDateString)),
false);
importDateString == null ? null : Date.from(Instant.parse(importDateString)),
false,
Boolean.parseBoolean(supportPolygons));
}

public Importer createImporter(String[] languages, String[] extraTags) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.komoot.photon.elasticsearch;

import de.komoot.photon.Constants;
import de.komoot.photon.searcher.GeometryType;
import de.komoot.photon.searcher.PhotonResult;
import org.elasticsearch.search.SearchHit;
import org.slf4j.Logger;
Expand Down Expand Up @@ -66,6 +67,21 @@ public double[] getCoordinates() {
return new double[]{coordinate.get(Constants.LON), coordinate.get(Constants.LAT)};
}

@Override
public GeometryType getGeometryType() {
final Map<String, Object> geometry = (Map<String, Object>) result.getSource().get("geometry");

return GeometryType.valueOf((String) geometry.get("type"));
}

@Override
public double[][] getGeometry() {
final Map<String, Object> geometry = (Map<String, Object>) result.getSource().get("geometry");
final List<List<Double>> coords = (List<List<Double>>) geometry.get("coordinates");

return null;
}

@Override
public double[] getExtent() {
final Map<String, Object> extent = (Map<String, Object>) result.getSource().get("extent");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
import de.komoot.photon.Constants;
import de.komoot.photon.PhotonDoc;
import de.komoot.photon.nominatim.model.AddressType;

import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.io.geojson.GeoJsonWriter;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -38,6 +44,17 @@ public static XContentBuilder convert(PhotonDoc doc, String[] languages, String[
.endObject();
}

if (doc.getGeometry() != null) {
GeoJsonWriter g = new GeoJsonWriter();

XContentParser parser = JsonXContent
.jsonXContent
.createParser(NamedXContentRegistry.EMPTY, g.write(doc.getGeometry()));

builder.field("geometry");
builder.copyCurrentStructure(parser);
}

if (doc.getHouseNumber() != null) {
builder.field("housenumber", doc.getHouseNumber());
}
Expand Down
16 changes: 11 additions & 5 deletions app/es_embedded/src/test/java/de/komoot/photon/ESBaseTester.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import de.komoot.photon.searcher.PhotonResult;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.io.TempDir;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;

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

private ElasticTestServer server;

protected PhotonDoc createDoc(double lon, double lat, int id, int osmId, String key, String value) {
protected PhotonDoc createDoc(double lon, double lat, int id, int osmId, String key, String value) throws ParseException {
Point location = FACTORY.createPoint(new Coordinate(lon, lat));
return new PhotonDoc(id, "W", osmId, key, value).names(Collections.singletonMap("name", "berlin")).centroid(location);
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))"));
}

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

public void setUpES() throws IOException {
setUpES(dataDirectory, "en");
setUpES(dataDirectory, false,"en");
red-fenix marked this conversation as resolved.
Show resolved Hide resolved
}

public void setUpESWithPolygons() throws IOException {
setUpES(dataDirectory, true,"en");
}
/**
* Setup the ES server
*
* @throws IOException
*/
public void setUpES(Path testDirectory, String... languages) throws IOException {
public void setUpES(Path testDirectory, boolean supportPolygons, String... languages) throws IOException {
server = new ElasticTestServer(testDirectory.toString());
server.start(TEST_CLUSTER_NAME, new String[]{});
server.recreateIndex(languages, new Date(), false);
server.recreateIndex(languages, new Date(), false, supportPolygons);
refresh();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.komoot.photon.elasticsearch;

import de.komoot.photon.searcher.GeometryType;
import de.komoot.photon.searcher.PhotonResult;
import org.apache.commons.lang3.NotImplementedException;
import org.elasticsearch.action.get.GetResponse;
Expand Down Expand Up @@ -34,6 +35,15 @@ public double[] getCoordinates() {
throw new NotImplementedException();
}

@Override
public GeometryType getGeometryType() {
throw new NotImplementedException();
}

public double[][] getGeometry() {
throw new NotImplementedException();
}

@Override
public double[] getExtent() {
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected PhotonDoc createDoc(double lon, double lat, int id, int osmId, String

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void testSaveAndLoadFromDatabase() throws IOException {
setUpES();

Date now = new Date();
DatabaseProperties prop = new DatabaseProperties(new String[]{"en", "de", "fr"}, now, false);
DatabaseProperties prop = new DatabaseProperties(new String[]{"en", "de", "fr"}, now, false, false);
getServer().saveToDatabase(prop);

prop = getServer().loadFromDatabase();
Expand Down
2 changes: 1 addition & 1 deletion app/opensearch/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies {
implementation 'org.apache.httpcomponents.client5:httpclient5:5.4.1'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2'

implementation('org.codelibs.opensearch:opensearch-runner:2.18.0.0') {
implementation('org.codelibs.opensearch:opensearch-runner:2.18.0.1') {
exclude(module: 'repository-url')
exclude(module: 'reindex-client')
exclude(module: 'rank-eval-client')
Expand Down
16 changes: 9 additions & 7 deletions app/opensearch/src/main/java/de/komoot/photon/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ public class Server {

private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Server.class);

public static final String OPENSEARCH_MODULES =
"org.opensearch.transport.Netty4Plugin,"
+ "org.opensearch.analysis.common.CommonAnalysisPlugin";
// public static final String OPENSEARCH_MODULES =
// "org.opensearch.transport.Netty4Plugin,"
// + "org.opensearch.analysis.common.CommonAnalysisPlugin,"
// + "org.opensearch.geo.GeoModulePlugin,"
// + "org.opensearch.geospatial.plugin.GeospatialPlugin";

protected OpenSearchClient client;
private OpenSearchRunner runner = null;
Expand Down Expand Up @@ -86,7 +88,6 @@ private HttpHost[] startInternal(String clusterName) {
.basePath(dataDirectory)
.clusterName(clusterName)
.numOfNode(1)
.moduleTypes(OPENSEARCH_MODULES)
);

runner.ensureYellow();
Expand Down Expand Up @@ -119,7 +120,7 @@ public void shutdown() {
}
}

public DatabaseProperties recreateIndex(String[] languages, Date importDate, boolean supportStructuredQueries) throws IOException {
public DatabaseProperties recreateIndex(String[] languages, Date importDate, boolean supportStructuredQueries, boolean supportPolygons) throws IOException {
// delete any existing data
if (client.indices().exists(e -> e.index(PhotonIndex.NAME)).value()) {
client.indices().delete(d -> d.index(PhotonIndex.NAME));
Expand All @@ -129,7 +130,7 @@ public DatabaseProperties recreateIndex(String[] languages, Date importDate, boo

(new IndexMapping(supportStructuredQueries)).addLanguages(languages).putMapping(client, PhotonIndex.NAME);

var dbProperties = new DatabaseProperties(languages, importDate, supportStructuredQueries);
var dbProperties = new DatabaseProperties(languages, importDate, supportStructuredQueries, supportPolygons);
saveToDatabase(dbProperties);

return dbProperties;
Expand Down Expand Up @@ -180,7 +181,8 @@ public DatabaseProperties loadFromDatabase() throws IOException {

return new DatabaseProperties(dbEntry.source().languages,
dbEntry.source().importDate,
dbEntry.source().supportStructuredQueries);
dbEntry.source().supportStructuredQueries,
dbEntry.source().supportPolygons);
}

public Importer createImporter(String[] languages, String[] extraTags) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class DBPropertyEntry {
public Date importDate;
public String[] languages;
public boolean supportStructuredQueries;
public boolean supportPolygons;

public DBPropertyEntry() {}

Expand All @@ -17,5 +18,6 @@ public DBPropertyEntry(DatabaseProperties props, String databaseVersion) {
importDate = props.getImportDate();
languages = props.getLanguages();
supportStructuredQueries = props.getSupportStructuredQueries();
supportPolygons = props.getSupportPolygons();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.opensearch._types.Time;
import org.opensearch.client.opensearch.core.BulkRequest;
import org.opensearch.client.opensearch.core.bulk.BulkOperation;
import org.opensearch.client.opensearch.core.bulk.BulkResponseItem;
import org.slf4j.Logger;

import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ private void setupBaseMappings() {
}

mappings.properties("coordinate", b -> b.geoPoint(p -> p));
mappings.properties("geometry", b -> b.geoShape(p -> p));
mappings.properties("countrycode", b -> b.keyword(p -> p.index(true)));
mappings.properties("importance", b -> b.float_(p -> p.index(false)));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.komoot.photon.opensearch;

import de.komoot.photon.searcher.GeometryType;
import de.komoot.photon.searcher.PhotonResult;
import org.json.JSONObject;

Expand All @@ -11,14 +12,18 @@ public class OpenSearchResult implements PhotonResult {
private double score = 0.0;
private final double[] extent;
private final double[] coordinates;
private final double[][] geometry;
private final GeometryType geometryType;
private final Map<String, Object> infos;
private final Map<String, Map<String, String>> localeTags;

OpenSearchResult(double[] extent, double[] coordinates, Map<String, Object> infos, Map<String, Map<String, String>> localeTags) {
OpenSearchResult(double[] extent, double[] coordinates, Map<String, Object> infos, Map<String, Map<String, String>> localeTags, double[][] geometry, GeometryType geometryType) {
this.extent = extent;
this.coordinates = coordinates;
this.infos = infos;
this.localeTags = localeTags;
this.geometry = geometry;
this.geometryType = geometryType;
}

public OpenSearchResult setScore(double score) {
Expand Down Expand Up @@ -61,6 +66,15 @@ public double[] getCoordinates() {
return coordinates;
}

@Override
public GeometryType getGeometryType() {
return geometryType;
}

public double[][] getGeometry() {
return geometry;
}

@Override
public double[] getExtent() {
return extent;
Expand Down
Loading