Skip to content

Commit 1951add

Browse files
authored
Better support for highway types (#22)
* Better support for highway types * Move try catch block to be upper most, add point to external tests. * Fix typo in bycicle
1 parent bc809f7 commit 1951add

File tree

2 files changed

+180
-139
lines changed

2 files changed

+180
-139
lines changed

src/main/java/il/org/osm/israelhiking/PlanetSearchProfile.java

Lines changed: 164 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public List<OsmRelationInfo> preprocessOsmRelation(OsmElement.Relation relation)
9393
setIconColorCategory(pointDocument, relation);
9494

9595
if (!"icon-waterfall".equals(pointDocument.poiIcon) &&
96-
!"Biycle".equals(pointDocument.poiCategory) &&
96+
!"Bicycle".equals(pointDocument.poiCategory) &&
9797
!"Hiking".equals(pointDocument.poiCategory)) {
9898
return null;
9999
}
@@ -152,24 +152,29 @@ public void preprocessOsmWay(OsmElement.Way way) {
152152

153153
@Override
154154
public void processFeature(SourceFeature sourceFeature, FeatureCollector features) {
155-
if (sourceFeature.getSource() == "external") {
156-
processExternalFeautre(sourceFeature, features);
157-
return;
158-
}
159-
if (isBBoxFeature(sourceFeature, supportedLanguages)) {
160-
insertBboxToElasticsearch(sourceFeature, supportedLanguages);
161-
}
162-
// ignore nodes and ways that should only be treated as polygons
163-
if (sourceFeature.canBeLine()) {
164-
processOsmRelationFeature(sourceFeature, features);
165-
processMtbNameFeature(sourceFeature, features);
166-
processWaterwayFeature(sourceFeature, features);
167-
} else {
168-
processOtherSourceFeature(sourceFeature, features);
155+
try {
156+
if (sourceFeature.getSource() == "external") {
157+
processExternalFeautre(sourceFeature, features);
158+
return;
159+
}
160+
if (isBBoxFeature(sourceFeature, supportedLanguages)) {
161+
insertBboxToElasticsearch(sourceFeature, supportedLanguages);
162+
}
163+
// ignore nodes and ways that should only be treated as polygons
164+
if (sourceFeature.canBeLine()) {
165+
processOsmRelationFeature(sourceFeature, features);
166+
processMtbNameFeature(sourceFeature, features);
167+
processWaterwayFeature(sourceFeature, features);
168+
processHighwayFeautre(sourceFeature, features);
169+
} else {
170+
processOtherSourceFeature(sourceFeature, features);
171+
}
172+
} catch (GeometryException e) {
173+
// ignore bad geometries
169174
}
170175
}
171176

172-
private void processExternalFeautre(SourceFeature sourceFeature, FeatureCollector features) {
177+
private void processExternalFeautre(SourceFeature sourceFeature, FeatureCollector features) throws GeometryException {
173178
var pointDocument = new PointDocument();
174179
pointDocument.poiIcon = sourceFeature.getString("poiIcon");
175180
pointDocument.poiIconColor = sourceFeature.getString("poiIconColor");
@@ -184,16 +189,7 @@ private void processExternalFeautre(SourceFeature sourceFeature, FeatureCollecto
184189
pointDocument.wikimedia_commons = sourceFeature.getString("wikimedia_commons");
185190
Point point;
186191
var docId = pointDocument.poiSource + "_" + sourceFeature.getString("identifier");
187-
try {
188-
point = (Point)sourceFeature.centroidIfConvex();
189-
} catch (GeometryException e) {
190-
try {
191-
point = GeoUtils.point(sourceFeature.worldGeometry().getCoordinate());
192-
} catch (GeometryException e2) {
193-
// ignore bad geometries
194-
return;
195-
}
196-
}
192+
point = sourceFeature.canBeLine() ? GeoUtils.point(sourceFeature.worldGeometry().getCoordinate()) : (Point)sourceFeature.centroidIfConvex();
197193
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
198194
pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
199195

@@ -206,7 +202,7 @@ private void processExternalFeautre(SourceFeature sourceFeature, FeatureCollecto
206202
setFeaturePropertiesFromPointDocument(tileFeature, pointDocument);
207203
}
208204

209-
private void processOsmRelationFeature(SourceFeature sourceFeature, FeatureCollector features) {
205+
private void processOsmRelationFeature(SourceFeature sourceFeature, FeatureCollector features) throws GeometryException {
210206
// get all the RouteRelationInfo instances we returned from preprocessOsmRelation that
211207
// this way belongs to
212208
for (var routeInfo : sourceFeature.relationInfo(RelationInfo.class)) {
@@ -221,36 +217,32 @@ private void processOsmRelationFeature(SourceFeature sourceFeature, FeatureColle
221217
}
222218
var mergedLines = RelationLineMergers.get(relation.id());
223219
synchronized(mergedLines) {
224-
try {
225-
mergedLines.lineMerger.add(sourceFeature.line());
226-
relation.memberIds.remove(sourceFeature.id());
220+
mergedLines.lineMerger.add(sourceFeature.line());
221+
relation.memberIds.remove(sourceFeature.id());
227222

228-
if (relation.firstMemberId == sourceFeature.id()) {
229-
mergedLines.feature = sourceFeature;
230-
}
223+
if (relation.firstMemberId == sourceFeature.id()) {
224+
mergedLines.feature = sourceFeature;
225+
}
231226

232-
if (!relation.memberIds.isEmpty()) {
233-
continue;
234-
}
235-
// All relation members were reached. Add a POI element for line relation
236-
var point = getFirstPointOfLineRelation(mergedLines);
237-
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
238-
relation.pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
239-
240-
insertPointToElasticsearch(relation.pointDocument, "OSM_relation_" + relation.id());
241-
242-
var tileFeature = features.geometry(POINTS_LAYER_NAME, point)
243-
.setZoomRange(10, 14)
244-
.setId(relation.vectorTileFeatureId(config.featureSourceIdMultiplier()));
245-
setFeaturePropertiesFromPointDocument(tileFeature, relation.pointDocument);
246-
} catch (GeometryException e) {
247-
throw new RuntimeException(e);
227+
if (!relation.memberIds.isEmpty()) {
228+
continue;
248229
}
230+
// All relation members were reached. Add a POI element for line relation
231+
var point = getFirstPointOfLineRelation(mergedLines);
232+
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
233+
relation.pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
234+
235+
insertPointToElasticsearch(relation.pointDocument, "OSM_relation_" + relation.id());
236+
237+
var tileFeature = features.geometry(POINTS_LAYER_NAME, point)
238+
.setZoomRange(10, 14)
239+
.setId(relation.vectorTileFeatureId(config.featureSourceIdMultiplier()));
240+
setFeaturePropertiesFromPointDocument(tileFeature, relation.pointDocument);
249241
}
250242
}
251243
}
252244

253-
private void processMtbNameFeature(SourceFeature sourceFeature, FeatureCollector features) {
245+
private void processMtbNameFeature(SourceFeature sourceFeature, FeatureCollector features) throws GeometryException {
254246
if (!sourceFeature.hasTag("mtb:name")) {
255247
return;
256248
}
@@ -264,50 +256,46 @@ private void processMtbNameFeature(SourceFeature sourceFeature, FeatureCollector
264256
}
265257
var mergedLines = WaysLineMergers.get(minId);
266258
synchronized(mergedLines) {
267-
try {
259+
mergedLines.lineMerger.add(sourceFeature.worldGeometry());
260+
Singles.get(mtbName).ids.remove(sourceFeature.id());
268261

269-
mergedLines.lineMerger.add(sourceFeature.worldGeometry());
270-
Singles.get(mtbName).ids.remove(sourceFeature.id());
271-
272-
if (minId == sourceFeature.id()) {
273-
mergedLines.feature = sourceFeature;
274-
}
275-
if (!Singles.get(mtbName).ids.isEmpty()) {
276-
return;
277-
}
278-
var feature = mergedLines.feature;
279-
var point = GeoUtils.point(((Geometry)mergedLines.lineMerger.getMergedLineStrings().iterator().next()).getCoordinate());
280-
281-
var pointDocument = new PointDocument();
282-
for (String language : supportedLanguages) {
283-
CoalesceIntoMap(pointDocument.name, language, feature.getString("mtb:name:" + language), feature.getString("name:" + language), feature.getString("name"), feature.getString("mtb:name"));
284-
CoalesceIntoMap(pointDocument.description, language, feature.getString("description:" + language), feature.getString("description"));
285-
}
286-
pointDocument.wikidata = feature.getString("wikidata");
287-
pointDocument.image = feature.getString("image");
288-
pointDocument.wikimedia_commons = feature.getString("wikimedia_commons");
289-
pointDocument.poiCategory = "Bicycle";
290-
pointDocument.poiIcon = "icon-bike";
291-
pointDocument.poiIconColor = "gray";
292-
pointDocument.poiSource = "OSM";
293-
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
294-
pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
262+
if (minId == sourceFeature.id()) {
263+
mergedLines.feature = sourceFeature;
264+
}
265+
if (!Singles.get(mtbName).ids.isEmpty()) {
266+
return;
267+
}
268+
var feature = mergedLines.feature;
269+
var point = GeoUtils.point(((Geometry)mergedLines.lineMerger.getMergedLineStrings().iterator().next()).getCoordinate());
295270

296-
insertPointToElasticsearch(pointDocument, "OSM_way_" + minId);
297-
// This was the last way with the same mtb:name, so we can merge the lines and add the feature
298-
// Add a POI element for a SingleTrack
299-
var tileFeature = features.geometry(POINTS_LAYER_NAME, point)
300-
.setZoomRange(10, 14)
301-
// Override the feature id with the minimal id of the group
302-
.setId(feature.vectorTileFeatureId(config.featureSourceIdMultiplier()));
303-
setFeaturePropertiesFromPointDocument(tileFeature, pointDocument);
304-
} catch (GeometryException e) {
305-
throw new RuntimeException(e);
271+
var pointDocument = new PointDocument();
272+
for (String language : supportedLanguages) {
273+
CoalesceIntoMap(pointDocument.name, language, feature.getString("mtb:name:" + language), feature.getString("name:" + language), feature.getString("name"), feature.getString("mtb:name"));
274+
CoalesceIntoMap(pointDocument.description, language, feature.getString("description:" + language), feature.getString("description"));
306275
}
276+
pointDocument.wikidata = feature.getString("wikidata");
277+
pointDocument.image = feature.getString("image");
278+
pointDocument.wikimedia_commons = feature.getString("wikimedia_commons");
279+
pointDocument.poiCategory = "Bicycle";
280+
pointDocument.poiIcon = "icon-bike";
281+
pointDocument.poiIconColor = "gray";
282+
pointDocument.poiSource = "OSM";
283+
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
284+
pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
285+
286+
insertPointToElasticsearch(pointDocument, "OSM_way_" + minId);
287+
// This was the last way with the same mtb:name, so we can merge the lines and add the feature
288+
// Add a POI element for a SingleTrack
289+
var tileFeature = features.geometry(POINTS_LAYER_NAME, point)
290+
.setZoomRange(10, 14)
291+
// Override the feature id with the minimal id of the group
292+
.setId(feature.vectorTileFeatureId(config.featureSourceIdMultiplier()));
293+
setFeaturePropertiesFromPointDocument(tileFeature, pointDocument);
294+
307295
}
308296
}
309297

310-
private void processWaterwayFeature(SourceFeature sourceFeature, FeatureCollector features) {
298+
private void processWaterwayFeature(SourceFeature sourceFeature, FeatureCollector features) throws GeometryException {
311299
if (!sourceFeature.hasTag("waterway")) {
312300
return;
313301
}
@@ -321,53 +309,75 @@ private void processWaterwayFeature(SourceFeature sourceFeature, FeatureCollecto
321309
}
322310
var mergedLines = WaysLineMergers.get(minId);
323311
synchronized(mergedLines) {
324-
try {
325312

326-
mergedLines.lineMerger.add(sourceFeature.worldGeometry());
327-
Waterways.get(name).ids.remove(sourceFeature.id());
313+
mergedLines.lineMerger.add(sourceFeature.worldGeometry());
314+
Waterways.get(name).ids.remove(sourceFeature.id());
328315

329-
if (minId == sourceFeature.id()) {
330-
mergedLines.feature = sourceFeature;
331-
}
332-
if (!Waterways.get(name).ids.isEmpty()) {
333-
return;
334-
}
335-
var feature = mergedLines.feature;
336-
var point = GeoUtils.point(((Geometry)mergedLines.lineMerger.getMergedLineStrings().iterator().next()).getCoordinate());
337-
338-
var pointDocument = new PointDocument();
339-
for (String language : supportedLanguages) {
340-
CoalesceIntoMap(pointDocument.name, language, feature.getString("name:" + language), feature.getString("name"));
341-
CoalesceIntoMap(pointDocument.description, language, feature.getString("description:" + language), feature.getString("description"));
342-
}
343-
pointDocument.wikidata = feature.getString("wikidata");
344-
pointDocument.image = feature.getString("image");
345-
pointDocument.wikimedia_commons = feature.getString("wikimedia_commons");
346-
pointDocument.poiCategory = "Water";
347-
pointDocument.poiIcon = "icon-waterfall";
348-
pointDocument.poiIconColor = "blue";
349-
pointDocument.poiSource = "OSM";
350-
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
351-
pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
316+
if (minId == sourceFeature.id()) {
317+
mergedLines.feature = sourceFeature;
318+
}
319+
if (!Waterways.get(name).ids.isEmpty()) {
320+
return;
321+
}
322+
var feature = mergedLines.feature;
323+
var point = GeoUtils.point(((Geometry)mergedLines.lineMerger.getMergedLineStrings().iterator().next()).getCoordinate());
352324

353-
insertPointToElasticsearch(pointDocument, "OSM_way_" + minId);
354-
if (!isInterestingPoint(pointDocument)) {
355-
// Skip adding features without any description or image to tiles
356-
return;
357-
}
358-
359-
var tileFeature = features.geometry(POINTS_LAYER_NAME, point)
360-
.setZoomRange(10, 14)
361-
// Override the feature id with the minimal id of the group
362-
.setId(feature.vectorTileFeatureId(config.featureSourceIdMultiplier()));
363-
setFeaturePropertiesFromPointDocument(tileFeature, pointDocument);
364-
} catch (GeometryException e) {
365-
throw new RuntimeException(e);
325+
var pointDocument = new PointDocument();
326+
for (String language : supportedLanguages) {
327+
CoalesceIntoMap(pointDocument.name, language, feature.getString("name:" + language), feature.getString("name"));
328+
CoalesceIntoMap(pointDocument.description, language, feature.getString("description:" + language), feature.getString("description"));
366329
}
330+
pointDocument.wikidata = feature.getString("wikidata");
331+
pointDocument.image = feature.getString("image");
332+
pointDocument.wikimedia_commons = feature.getString("wikimedia_commons");
333+
pointDocument.poiCategory = "Water";
334+
pointDocument.poiIcon = "icon-waterfall";
335+
pointDocument.poiIconColor = "blue";
336+
pointDocument.poiSource = "OSM";
337+
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
338+
pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
339+
340+
insertPointToElasticsearch(pointDocument, "OSM_way_" + minId);
341+
if (!isInterestingPoint(pointDocument)) {
342+
// Skip adding features without any description or image to tiles
343+
return;
344+
}
345+
346+
var tileFeature = features.geometry(POINTS_LAYER_NAME, point)
347+
.setZoomRange(10, 14)
348+
// Override the feature id with the minimal id of the group
349+
.setId(feature.vectorTileFeatureId(config.featureSourceIdMultiplier()));
350+
setFeaturePropertiesFromPointDocument(tileFeature, pointDocument);
367351
}
368352
}
369353

370-
private void processOtherSourceFeature(SourceFeature feature, FeatureCollector features) {
354+
private void processHighwayFeautre(SourceFeature sourceFeature, FeatureCollector features) throws GeometryException {
355+
if (!sourceFeature.hasTag("highway")) {
356+
return;
357+
}
358+
var point = GeoUtils.point(sourceFeature.worldGeometry().getCoordinate());
359+
var pointDocument = new PointDocument();
360+
for (String language : supportedLanguages) {
361+
CoalesceIntoMap(pointDocument.name, language, sourceFeature.getString("name:" + language), sourceFeature.getString("name"));
362+
CoalesceIntoMap(pointDocument.description, language, sourceFeature.getString("description:" + language), sourceFeature.getString("description"));
363+
}
364+
365+
pointDocument.wikidata = sourceFeature.getString("wikidata");
366+
pointDocument.image = sourceFeature.getString("image");
367+
pointDocument.wikimedia_commons = sourceFeature.getString("wikimedia_commons");
368+
pointDocument.poiSource = "OSM";
369+
var lngLatPoint = GeoUtils.worldToLatLonCoords(point).getCoordinate();
370+
pointDocument.location = new double[]{lngLatPoint.getX(), lngLatPoint.getY()};
371+
setIconColorCategory(pointDocument, sourceFeature);
372+
373+
if (pointDocument.poiIcon == "icon-search") {
374+
return;
375+
}
376+
377+
insertPointToElasticsearch(pointDocument, sourceFeatureToDocumentId(sourceFeature));
378+
}
379+
380+
private void processOtherSourceFeature(SourceFeature feature, FeatureCollector features) throws GeometryException {
371381
if (!feature.hasTag("name") &&
372382
!feature.hasTag("wikidata") &&
373383
!feature.hasTag("image") &&
@@ -380,16 +390,7 @@ private void processOtherSourceFeature(SourceFeature feature, FeatureCollector f
380390
var docId = sourceFeatureToDocumentId(feature);
381391
Point point;
382392

383-
try {
384-
point = (Point)feature.centroidIfConvex();
385-
} catch (GeometryException e) {
386-
try {
387-
point = GeoUtils.point(feature.worldGeometry().getCoordinate());
388-
} catch (GeometryException e2) {
389-
// ignore bad geometries
390-
return;
391-
}
392-
}
393+
point = (Point)feature.centroidIfConvex();
393394

394395
var pointDocument = new PointDocument();
395396
for (String language : supportedLanguages) {
@@ -702,6 +703,31 @@ private void setIconColorCategory(PointDocument pointDocument, WithTags feature)
702703
return;
703704
}
704705

706+
if (feature.getString("highway") != null) {
707+
switch (feature.getString("highway")) {
708+
case "cycleway":
709+
pointDocument.poiIconColor = "black";
710+
pointDocument.poiCategory = "Bicycle";
711+
pointDocument.poiIcon = "icon-bike";
712+
return;
713+
case "footway":
714+
pointDocument.poiIconColor = "black";
715+
pointDocument.poiCategory = "Hiking";
716+
pointDocument.poiIcon = "icon-hike";
717+
return;
718+
case "path":
719+
pointDocument.poiIconColor = "black";
720+
pointDocument.poiCategory = "Hiking";
721+
pointDocument.poiIcon = "icon-hike";
722+
return;
723+
case "track":
724+
pointDocument.poiIconColor = "black";
725+
pointDocument.poiCategory = "4x4";
726+
pointDocument.poiIcon = "icon-four-by-four";
727+
return;
728+
}
729+
}
730+
705731
if (feature.getString("ref:IL:inature") != null) {
706732
pointDocument.poiIconColor = "#116C00";
707733
pointDocument.poiIcon = "icon-inature";

0 commit comments

Comments
 (0)