Skip to content

Commit eff3b06

Browse files
author
red-fenix
committed
feat: add support for all polygon types
1 parent 34cd622 commit eff3b06

File tree

18 files changed

+72
-142
lines changed

18 files changed

+72
-142
lines changed

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

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package de.komoot.photon.elasticsearch;
22

33
import de.komoot.photon.Constants;
4-
import de.komoot.photon.searcher.GeometryType;
54
import de.komoot.photon.searcher.PhotonResult;
65
import org.elasticsearch.search.SearchHit;
76
import org.slf4j.Logger;
@@ -68,18 +67,8 @@ public double[] getCoordinates() {
6867
}
6968

7069
@Override
71-
public GeometryType getGeometryType() {
72-
final Map<String, Object> geometry = (Map<String, Object>) result.getSource().get("geometry");
73-
74-
return GeometryType.valueOf((String) geometry.get("type"));
75-
}
76-
77-
@Override
78-
public double[][] getGeometry() {
79-
final Map<String, Object> geometry = (Map<String, Object>) result.getSource().get("geometry");
80-
final List<List<Double>> coords = (List<List<Double>>) geometry.get("coordinates");
81-
82-
return null;
70+
public String getGeometry() {
71+
return (String) result.getSource().get("geometry");
8372
}
8473

8574
@Override

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

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44
import de.komoot.photon.PhotonDoc;
55
import de.komoot.photon.nominatim.model.AddressType;
66

7-
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
8-
import org.elasticsearch.common.xcontent.XContentBuilder;
9-
import org.elasticsearch.common.xcontent.XContentFactory;
10-
import org.elasticsearch.common.xcontent.XContentParser;
7+
import org.elasticsearch.common.xcontent.*;
118
import org.elasticsearch.common.xcontent.json.JsonXContent;
129
import org.locationtech.jts.geom.Envelope;
1310
import org.locationtech.jts.io.geojson.GeoJsonWriter;
1411

1512
import java.io.IOException;
16-
import java.util.Arrays;
1713
import java.util.HashMap;
1814
import java.util.HashSet;
1915
import java.util.Map;
@@ -46,7 +42,7 @@ public static XContentBuilder convert(PhotonDoc doc, String[] languages, String[
4642

4743
if (doc.getGeometry() != null) {
4844
GeoJsonWriter g = new GeoJsonWriter();
49-
45+
5046
XContentParser parser = JsonXContent
5147
.jsonXContent
5248
.createParser(NamedXContentRegistry.EMPTY, g.write(doc.getGeometry()));

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

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.komoot.photon.elasticsearch;
22

3-
import de.komoot.photon.searcher.GeometryType;
43
import de.komoot.photon.searcher.PhotonResult;
54
import org.apache.commons.lang3.NotImplementedException;
65
import org.elasticsearch.action.get.GetResponse;
@@ -35,12 +34,7 @@ public double[] getCoordinates() {
3534
throw new NotImplementedException();
3635
}
3736

38-
@Override
39-
public GeometryType getGeometryType() {
40-
throw new NotImplementedException();
41-
}
42-
43-
public double[][] getGeometry() {
37+
public String getGeometry() {
4438
throw new NotImplementedException();
4539
}
4640

Diff for: app/opensearch/src/main/java/de/komoot/photon/opensearch/Importer.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,14 @@ private void saveDocuments() {
5656
var response = client.bulk(bulkRequest.build());
5757

5858
if (response.errors()) {
59-
LOGGER.error("Error during bulk import.");
59+
for (BulkResponseItem bri: response.items()) {
60+
LOGGER.error("Error during bulk import.");
61+
if (bri.error() != null) {
62+
LOGGER.error(bri.error().reason());
63+
LOGGER.error(bri.error().type());
64+
LOGGER.error(bri.error().stackTrace());
65+
}
66+
}
6067
}
6168
} catch (IOException e) {
6269
LOGGER.error("Error during bulk import", e);

Diff for: app/opensearch/src/main/java/de/komoot/photon/opensearch/OpenSearchResult.java

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.komoot.photon.opensearch;
22

3-
import de.komoot.photon.searcher.GeometryType;
43
import de.komoot.photon.searcher.PhotonResult;
54
import org.json.JSONObject;
65

@@ -12,18 +11,16 @@ public class OpenSearchResult implements PhotonResult {
1211
private double score = 0.0;
1312
private final double[] extent;
1413
private final double[] coordinates;
15-
private final double[][] geometry;
16-
private final GeometryType geometryType;
14+
private final String geometry;
1715
private final Map<String, Object> infos;
1816
private final Map<String, Map<String, String>> localeTags;
1917

20-
OpenSearchResult(double[] extent, double[] coordinates, Map<String, Object> infos, Map<String, Map<String, String>> localeTags, double[][] geometry, GeometryType geometryType) {
18+
OpenSearchResult(double[] extent, double[] coordinates, Map<String, Object> infos, Map<String, Map<String, String>> localeTags, String geometry) {
2119
this.extent = extent;
2220
this.coordinates = coordinates;
2321
this.infos = infos;
2422
this.localeTags = localeTags;
2523
this.geometry = geometry;
26-
this.geometryType = geometryType;
2724
}
2825

2926
public OpenSearchResult setScore(double score) {
@@ -66,12 +63,7 @@ public double[] getCoordinates() {
6663
return coordinates;
6764
}
6865

69-
@Override
70-
public GeometryType getGeometryType() {
71-
return geometryType;
72-
}
73-
74-
public double[][] getGeometry() {
66+
public String getGeometry() {
7567
return geometry;
7668
}
7769

Diff for: app/opensearch/src/main/java/de/komoot/photon/opensearch/OpenSearchResultDeserializer.java

+4-41
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.fasterxml.jackson.databind.node.ArrayNode;
88
import com.fasterxml.jackson.databind.node.ObjectNode;
99
import de.komoot.photon.Constants;
10-
import de.komoot.photon.searcher.GeometryType;
1110
import de.komoot.photon.searcher.PhotonResult;
1211

1312
import java.io.IOException;
@@ -30,17 +29,9 @@ public OpenSearchResult deserialize(JsonParser p, DeserializationContext ctxt) t
3029
final Map<String, Object> tags = new HashMap<>();
3130
final Map<String, Map<String, String>> localeTags = new HashMap<>();
3231

33-
double[][] geometry = new double[0][];
34-
GeometryType geometryType = GeometryType.UNKNOWN;
35-
36-
if (node.get("geometry") != null && node.get("geometry").get("type") != null) {
37-
if (node.get("geometry").get("type").asText().equals("Polygon")) {
38-
geometry = extractPolygon((ObjectNode) node.get("geometry"));
39-
geometryType = GeometryType.POLYGON;
40-
} else if (node.get("geometry").get("type").asText().equals("LineString")) {
41-
geometry = extractLineString((ObjectNode) node.get("geometry"));
42-
geometryType = GeometryType.LINESTRING;
43-
}
32+
String geometry = null;
33+
if (node.get("geometry") != null) {
34+
geometry = node.get("geometry").toString();
4435
}
4536

4637
var fields = node.fields();
@@ -69,7 +60,7 @@ public OpenSearchResult deserialize(JsonParser p, DeserializationContext ctxt) t
6960
}
7061
}
7162

72-
return new OpenSearchResult(extent, coordinates, tags, localeTags, geometry, geometryType);
63+
return new OpenSearchResult(extent, coordinates, tags, localeTags, geometry);
7364
}
7465

7566
private double[] extractExtent(ObjectNode node) {
@@ -92,32 +83,4 @@ private double[] extractCoordinate(ObjectNode node) {
9283

9384
return new double[]{node.get(Constants.LON).doubleValue(), node.get(Constants.LAT).doubleValue()};
9485
}
95-
96-
private double[][] extractPolygon(ObjectNode node) {
97-
if (node == null) {
98-
return PhotonResult.INVALID_GEOMETRY;
99-
}
100-
101-
double[][] coordinates = new double[node.get("coordinates").get(0).size()][];
102-
for(int i=0; i<node.get("coordinates").get(0).size(); i++) {
103-
double[] coordinate = new double[] {node.get("coordinates").get(0).get(i).get(0).doubleValue(), node.get("coordinates").get(0).get(i).get(1).doubleValue()};
104-
coordinates[i] = coordinate;
105-
}
106-
107-
return coordinates;
108-
}
109-
110-
private double[][] extractLineString(ObjectNode node) {
111-
if (node == null) {
112-
return PhotonResult.INVALID_GEOMETRY;
113-
}
114-
115-
double[][] coordinates = new double[node.get("coordinates").size()][];
116-
for(int i=0; i<node.get("coordinates").size(); i++) {
117-
double[] coordinate = new double[] {node.get("coordinates").get(i).get(0).doubleValue(), node.get("coordinates").get(i).get(1).doubleValue()};
118-
coordinates[i] = coordinate;
119-
}
120-
121-
return coordinates;
122-
}
12386
}

Diff for: app/opensearch/src/main/java/de/komoot/photon/opensearch/PhotonDocSerializer.java

+7-24
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@
66
import de.komoot.photon.Constants;
77
import de.komoot.photon.PhotonDoc;
88
import de.komoot.photon.Utils;
9-
import org.locationtech.jts.geom.Coordinate;
109
import org.locationtech.jts.geom.Envelope;
1110
import org.locationtech.jts.io.geojson.GeoJsonWriter;
1211

1312
import java.io.IOException;
14-
import java.io.StringWriter;
1513
import java.util.HashMap;
1614
import java.util.HashSet;
1715
import java.util.Map;
@@ -51,28 +49,13 @@ public void serialize(PhotonDoc value, JsonGenerator gen, SerializerProvider pro
5149
gen.writeEndObject();
5250
}
5351

54-
if (value.getGeometry() != null) {
55-
gen.writeObjectFieldStart("geometry");
56-
gen.writeStringField("type", value.getGeometry().getGeometryType());
52+
if (value.getGeometry() != null && !value.getGeometry().getGeometryType().equals("Point")) {
53+
// Convert JTS Geometry to GeoJSON
54+
GeoJsonWriter geoJsonWriter = new GeoJsonWriter();
55+
String geoJson = geoJsonWriter.write(value.getGeometry());
5756

58-
gen.writeArrayFieldStart("coordinates");
59-
60-
if (value.getGeometry().getGeometryType().equals("Polygon")) {
61-
gen.writeStartArray();
62-
}
63-
64-
for (Coordinate c: value.getGeometry().getCoordinates()) {
65-
gen.writeStartArray();
66-
gen.writeNumber(c.x);
67-
gen.writeNumber(c.y);
68-
gen.writeEndArray();
69-
}
70-
if (value.getGeometry().getGeometryType().equals("Polygon")) {
71-
gen.writeEndArray();
72-
}
73-
74-
gen.writeEndArray(); // end 'coordinates'
75-
gen.writeEndObject(); // end 'geometry'
57+
gen.writeFieldName("geometry");
58+
gen.writeRawValue(geoJson);
7659
}
7760

7861
if (value.getHouseNumber() != null) {
@@ -109,7 +92,7 @@ public void serialize(PhotonDoc value, JsonGenerator gen, SerializerProvider pro
10992
gen.writeEndObject();
11093
}
11194

112-
private void writeName(JsonGenerator gen, PhotonDoc doc, String[] languages) throws IOException {
95+
private void writeName(JsonGenerator gen, PhotonDoc doc, String[] languages) throws IOException {
11396
Map<String, String> fNames = new HashMap<>();
11497

11598
doc.copyName(fNames, "default", "name");

Diff for: app/opensearch/src/test/java/de/komoot/photon/opensearch/ImporterTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void setUp() throws IOException {
2727
void testAddSimpleDoc() throws ParseException {
2828
Importer instance = makeImporterWithExtra("");
2929

30-
instance.add(new PhotonDoc(1234, "N", 1000, "place", "city", new WKTReader().read("POLYGON ((1 1, 1 2, 2 1, 1 1))"))
30+
instance.add(new PhotonDoc(1234, "N", 1000, "place", "city", 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)))"))
3131
.extraTags(Collections.singletonMap("maxspeed", "100")), 0);
3232
instance.finish();
3333

Diff for: src/main/java/de/komoot/photon/Constants.java

+1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ public class Constants {
2424
public static final String OSM_VALUE = "osm_value";
2525
public static final String OBJECT_TYPE = "type";
2626
public static final String CLASSIFICATION = "classification";
27+
public static final String GEOMETRY = "geometry";
2728
}

Diff for: src/main/java/de/komoot/photon/PhotonDoc.java

+25
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,29 @@ public Point getCentroid() {
360360
public Geometry getGeometry() {
361361
return this.geometry;
362362
}
363+
364+
@Override
365+
public String toString() {
366+
return "PhotonDoc{" +
367+
"placeId=" + placeId +
368+
", osmType='" + osmType + '\'' +
369+
", osmId=" + osmId +
370+
", tagKey='" + tagKey + '\'' +
371+
", tagValue='" + tagValue + '\'' +
372+
", name=" + name +
373+
", postcode='" + postcode + '\'' +
374+
", extratags=" + extratags +
375+
", bbox=" + bbox +
376+
", parentPlaceId=" + parentPlaceId +
377+
", importance=" + importance +
378+
", countryCode='" + countryCode + '\'' +
379+
", linkedPlaceId=" + linkedPlaceId +
380+
", rankAddress=" + rankAddress +
381+
", addressParts=" + addressParts +
382+
", context=" + context +
383+
", houseNumber='" + houseNumber + '\'' +
384+
", centroid=" + centroid +
385+
", geometry=" + geometry +
386+
'}';
387+
}
363388
}

Diff for: src/main/java/de/komoot/photon/nominatim/NominatimImporter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public void readCountry(String countryCode, ImportThread importThread) {
101101
" parent.rank_address as parent_rank_address, parent.name as parent_name, ";
102102

103103
if (useGeometryColumn) {
104-
query += "p.geometry, ";
104+
query += "p.geometry as geometry, ";
105105
}
106106
template.query(
107107
query +

Diff for: src/main/java/de/komoot/photon/nominatim/PostgisDataAdapter.java

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public Geometry extractGeometry(ResultSet rs, String columnName) throws SQLExcep
3737
return new WKTReader().read(sb.toString());
3838
} catch (ParseException e) {
3939
// ignore
40+
System.out.println(e);
4041
}
4142
}
4243

Diff for: src/main/java/de/komoot/photon/nominatim/model/PlaceRowMapper.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ public PhotonDoc mapRow(ResultSet rs, int rowNum) throws SQLException {
4343
.postcode(rs.getString("postcode"));
4444

4545
if (useGeometryColumn) {
46-
doc.geometry(dbutils.extractGeometry(rs, "geometry"));
46+
try {
47+
doc.geometry(dbutils.extractGeometry(rs, "geometry"));
48+
} catch (IllegalArgumentException e) {
49+
System.out.println("Could not get Geometry: " + e);
50+
}
4751
}
4852

4953
double importance = rs.getDouble("importance");

Diff for: src/main/java/de/komoot/photon/searcher/GeocodeJsonFormatter.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@ public String convert(List<PhotonResult> results, String debugInfo) {
3434
.put("type", "Feature")
3535
.put("properties", getResultProperties(result))
3636
.put("geometry", result.get("geometry")));
37-
} else {
38-
var geom = new JSONObject().put("type", result.getGeometryType().getName()).put("coordinates", result.getGeometry());
37+
}
38+
else {
39+
// We need to un-escape the JSON String first
40+
JSONObject jsonObject = new JSONObject(result.getGeometry());
41+
3942
features.put(new JSONObject()
4043
.put("type", "Feature")
4144
.put("properties", getResultProperties(result))
42-
.put("geometry", geom));
45+
.put("geometry", jsonObject));
4346
}
4447
} else {
4548
final double[] coordinates = result.getCoordinates();

Diff for: src/main/java/de/komoot/photon/searcher/GeometryType.java

-17
This file was deleted.

Diff for: src/main/java/de/komoot/photon/searcher/PhotonResult.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010
public interface PhotonResult {
1111
final double[] INVALID_COORDINATES = new double[]{0, 0};
12-
final double[][] INVALID_GEOMETRY = new double[][]{{0, 0}};
1312

1413
/**
1514
* Get the value for the given field.
@@ -26,9 +25,7 @@ public interface PhotonResult {
2625

2726
double[] getCoordinates();
2827

29-
GeometryType getGeometryType();
30-
31-
double[][] getGeometry();
28+
String getGeometry();
3229

3330
double[] getExtent();
3431

0 commit comments

Comments
 (0)