From 6b66b42201f564603153f26e46d3f33617554600 Mon Sep 17 00:00:00 2001 From: Dave Craig Date: Mon, 30 Dec 2024 16:07:18 +0000 Subject: [PATCH] Add localization of generic OSM tag names This adds support for the tags that the iOS app was already translating. For reasons best known to itself it was altering strings like bicycle_parking to bike_parking in the Swift JSON parsing code. We just use the stock OSM values in our lookup. --- .../soundscape/geoengine/GeoEngine.kt | 42 ++++++---- .../geoengine/utils/ResourceMapper.kt | 78 +++++++++++++++++++ 2 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/org/scottishtecharmy/soundscape/geoengine/utils/ResourceMapper.kt diff --git a/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/GeoEngine.kt b/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/GeoEngine.kt index 6cd4e595..796cde7c 100644 --- a/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/GeoEngine.kt +++ b/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/GeoEngine.kt @@ -30,23 +30,15 @@ import org.scottishtecharmy.soundscape.MainActivity.Companion.MOBILITY_KEY import org.scottishtecharmy.soundscape.MainActivity.Companion.PLACES_AND_LANDMARKS_KEY import org.scottishtecharmy.soundscape.R import org.scottishtecharmy.soundscape.audio.NativeAudioEngine -import org.scottishtecharmy.soundscape.geojsonparser.geojson.Feature import org.scottishtecharmy.soundscape.dto.BoundingBox import org.scottishtecharmy.soundscape.geoengine.filters.CalloutHistory import org.scottishtecharmy.soundscape.geoengine.filters.LocationUpdateFilter import org.scottishtecharmy.soundscape.geoengine.filters.TrackedCallout -import org.scottishtecharmy.soundscape.geojsonparser.geojson.FeatureCollection -import org.scottishtecharmy.soundscape.geojsonparser.geojson.LngLatAlt -import org.scottishtecharmy.soundscape.geojsonparser.geojson.Point -import org.scottishtecharmy.soundscape.geojsonparser.geojson.Polygon -import org.scottishtecharmy.soundscape.locationprovider.DirectionProvider -import org.scottishtecharmy.soundscape.locationprovider.LocationProvider -import org.scottishtecharmy.soundscape.network.ITileDAO -import org.scottishtecharmy.soundscape.network.ProtomapsTileClient -import org.scottishtecharmy.soundscape.network.SoundscapeBackendTileClient -import org.scottishtecharmy.soundscape.network.TileClient import org.scottishtecharmy.soundscape.geoengine.mvttranslation.InterpolatedPointsJoiner +import org.scottishtecharmy.soundscape.geoengine.mvttranslation.vectorTileToGeoJson +import org.scottishtecharmy.soundscape.geoengine.utils.FeatureTree import org.scottishtecharmy.soundscape.geoengine.utils.RelativeDirections +import org.scottishtecharmy.soundscape.geoengine.utils.ResourceMapper import org.scottishtecharmy.soundscape.geoengine.utils.TileGrid import org.scottishtecharmy.soundscape.geoengine.utils.TileGrid.Companion.getTileGrid import org.scottishtecharmy.soundscape.geoengine.utils.checkIntersection @@ -56,7 +48,7 @@ import org.scottishtecharmy.soundscape.geoengine.utils.distance import org.scottishtecharmy.soundscape.geoengine.utils.distanceToPolygon import org.scottishtecharmy.soundscape.geoengine.utils.getCompassLabelFacingDirection import org.scottishtecharmy.soundscape.geoengine.utils.getCompassLabelFacingDirectionAlong -import org.scottishtecharmy.soundscape.utils.getCurrentLocale +import org.scottishtecharmy.soundscape.geoengine.utils.getFeatureNearestPoint import org.scottishtecharmy.soundscape.geoengine.utils.getFovIntersectionFeatureCollection import org.scottishtecharmy.soundscape.geoengine.utils.getFovRoadsFeatureCollection import org.scottishtecharmy.soundscape.geoengine.utils.getIntersectionRoadNames @@ -73,11 +65,20 @@ import org.scottishtecharmy.soundscape.geoengine.utils.processTileFeatureCollect import org.scottishtecharmy.soundscape.geoengine.utils.processTileString import org.scottishtecharmy.soundscape.geoengine.utils.removeDuplicateOsmIds import org.scottishtecharmy.soundscape.geoengine.utils.sortedByDistanceTo -import org.scottishtecharmy.soundscape.geoengine.mvttranslation.vectorTileToGeoJson -import org.scottishtecharmy.soundscape.geoengine.utils.FeatureTree -import org.scottishtecharmy.soundscape.geoengine.utils.getFeatureNearestPoint +import org.scottishtecharmy.soundscape.geojsonparser.geojson.Feature +import org.scottishtecharmy.soundscape.geojsonparser.geojson.FeatureCollection +import org.scottishtecharmy.soundscape.geojsonparser.geojson.LngLatAlt +import org.scottishtecharmy.soundscape.geojsonparser.geojson.Point +import org.scottishtecharmy.soundscape.geojsonparser.geojson.Polygon +import org.scottishtecharmy.soundscape.locationprovider.DirectionProvider +import org.scottishtecharmy.soundscape.locationprovider.LocationProvider +import org.scottishtecharmy.soundscape.network.ITileDAO +import org.scottishtecharmy.soundscape.network.ProtomapsTileClient +import org.scottishtecharmy.soundscape.network.SoundscapeBackendTileClient +import org.scottishtecharmy.soundscape.network.TileClient import org.scottishtecharmy.soundscape.services.SoundscapeService import org.scottishtecharmy.soundscape.services.getOttoBus +import org.scottishtecharmy.soundscape.utils.getCurrentLocale import retrofit2.awaitResponse import java.util.Locale import kotlin.coroutines.cancellation.CancellationException @@ -85,6 +86,7 @@ import kotlin.math.abs import kotlin.time.Duration.Companion.milliseconds import kotlin.time.TimeSource + data class PositionedString(val text : String, val location : LngLatAlt? = null, val earcon : String? = null) class GeoEngine { @@ -667,13 +669,19 @@ class GeoEngine { var name = feature.properties?.get("name") as String? var generic = false if(name == null) { - name = feature.properties?.get("class") as String? + val osmClass = feature.properties?.get("class") as String? + val id = ResourceMapper.getResourceId(osmClass!!) + name = if(id == null) { + osmClass + } else { + localizedContext.getString(id) + } generic = true } // Check the history and if the POI has been called out recently, skip it (iOS uses 60 seconds) val nearestPoint = getFeatureNearestPoint(location, feature) - if((name != null) && ( nearestPoint != null)) { + if( nearestPoint != null) { val callout = TrackedCallout(name, nearestPoint, feature.geometry.type == "Point", generic) if (poiCalloutHistory.find(callout)) { Log.d(TAG, "Discard ${callout.callout}") diff --git a/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/utils/ResourceMapper.kt b/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/utils/ResourceMapper.kt new file mode 100644 index 00000000..60778062 --- /dev/null +++ b/app/src/main/java/org/scottishtecharmy/soundscape/geoengine/utils/ResourceMapper.kt @@ -0,0 +1,78 @@ +package org.scottishtecharmy.soundscape.geoengine.utils + +import org.scottishtecharmy.soundscape.R + +class ResourceMapper { + companion object { + private val resourceMap: HashMap by + lazy { + HashMap().apply { + put("crossing", R.string.osm_tag_crossing) + put("construction", R.string.osm_tag_construction) + put("dangerous_area", R.string.osm_tag_dangerous_area) + put("townhall", R.string.osm_tag_townhall) + put("steps", R.string.osm_tag_steps) + put("elevator", R.string.osm_tag_elevator) + put("walking_path", R.string.osm_tag_walking_path) + put("pedestrian_street", R.string.osm_tag_pedestrian_street) + put("bicycle_path", R.string.osm_tag_bicycle_path) + put("residential_street", R.string.osm_tag_residential_street) + put("service_road", R.string.osm_tag_service_road) + put("road", R.string.osm_tag_road) + put("highway", R.string.osm_tag_highway) + put("highway_named", R.string.osm_tag_highway_named) + put("highway_refed", R.string.osm_tag_highway_refed) + put("intersection", R.string.osm_tag_intersection) + put("roundabout", R.string.osm_tag_roundabout) + put("highway_ramp", R.string.osm_tag_highway_ramp) + put("merging_lane", R.string.osm_tag_merging_lane) + put("office", R.string.osm_tag_office_building) + put("school", R.string.osm_tag_school_building) + put("roof", R.string.osm_tag_covered_pavilion) + put("convenience", R.string.osm_tag_convenience_store) + put("entrance", R.string.osm_tag_building_entrance) + put("assembly_point", R.string.osm_tag_assembly_point) + put("cycle_barrier", R.string.osm_tag_cycle_barrier) + put("turnstile", R.string.osm_tag_turnstile) + put("cattle_grid", R.string.osm_tag_cattle_grid) + put("gate", R.string.osm_tag_gate) + put("lift_gate", R.string.osm_tag_gate) + put("toilets", R.string.osm_tag_restroom) + put("parking", R.string.osm_tag_parking_lot) + put("parking_entrance", R.string.osm_tag_parking_entrance) + put("bench", R.string.osm_tag_bench) + put("taxi", R.string.osm_tag_taxi_waiting_area) + put("post_office", R.string.osm_tag_post_office) + put("post_box", R.string.osm_tag_post_box) + put("waste_basket", R.string.osm_tag_waste_basket) + put("shower", R.string.osm_tag_shower) + put("bicycle_parking", R.string.osm_tag_bike_parking) + put("cafe", R.string.osm_tag_cafe) + put("restaurant", R.string.osm_tag_restaurant) + put("telephone", R.string.osm_tag_telephone) + put("fuel", R.string.osm_tag_gas_station) + put("bank", R.string.osm_tag_bank) + put("atm", R.string.osm_tag_atm) + put("atm_named", R.string.osm_tag_atm_named) + put("atm_refed", R.string.osm_tag_atm_refed) + put("bus_stop", R.string.osm_tag_bus_stop) + put("recycling", R.string.osm_tag_recycling_bin) + put("fountain", R.string.osm_tag_fountain) + put("place_of_worship", R.string.osm_tag_place_of_worship) + put("drinking_water", R.string.osm_tag_water_fountain) + put("car_wash", R.string.osm_tag_car_wash) + put("vending_machine", R.string.osm_tag_vending_machine) + put("playground", R.string.osm_tag_playground) + put("pitch", R.string.osm_tag_sports_field) + put("swimming_pool", R.string.osm_tag_swimming_pool) + put("garden", R.string.osm_tag_garden) + put("park", R.string.osm_tag_park) + put("picnic_table", R.string.osm_tag_picnic_table) + put("picnic_site", R.string.osm_tag_picnic_area) + } + } + fun getResourceId(key: String): Int? { + return resourceMap[key] + } + } +} \ No newline at end of file