mirror of https://github.com/tasks/tasks
Add NominatimGeocoder
parent
b8edd4fb72
commit
bb4ccd8dd8
@ -0,0 +1,64 @@
|
|||||||
|
package org.tasks.location
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import com.google.gson.JsonParser
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.tasks.DebugNetworkInterceptor
|
||||||
|
import org.tasks.data.Place
|
||||||
|
import org.tasks.data.Place.Companion.newPlace
|
||||||
|
import org.tasks.preferences.Preferences
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class NominatimGeocoder @Inject constructor(
|
||||||
|
private val preferences: Preferences,
|
||||||
|
private val interceptor: DebugNetworkInterceptor,
|
||||||
|
) : Geocoder {
|
||||||
|
override suspend fun reverseGeocode(mapPosition: MapPosition): Place? =
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
val builder = OkHttpClient().newBuilder()
|
||||||
|
if (preferences.isFlipperEnabled) {
|
||||||
|
interceptor.apply(builder)
|
||||||
|
}
|
||||||
|
val client = builder.build()
|
||||||
|
val url = "https://nominatim.openstreetmap.org/reverse?format=geocodejson&lat=${mapPosition.latitude}&lon=${mapPosition.longitude}"
|
||||||
|
val response = client.newCall(Request.Builder().get().url(url).build()).execute()
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
response.body?.string()?.let { jsonToPlace(it) }
|
||||||
|
} else {
|
||||||
|
throw IOException("${response.code} ${response.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun jsonToPlace(json: String): Place? =
|
||||||
|
JsonParser
|
||||||
|
.parseString(json).asJsonObject.getAsJsonArray("features")
|
||||||
|
.takeIf { it.size() > 0 }?.get(0)?.asJsonObject
|
||||||
|
?.let { feature ->
|
||||||
|
val geocoding = feature
|
||||||
|
.get("properties").asJsonObject
|
||||||
|
.get("geocoding").asJsonObject
|
||||||
|
val geometry = feature.get("geometry").asJsonObject
|
||||||
|
newPlace().apply {
|
||||||
|
val type = geocoding.get("type").asString
|
||||||
|
name = if (type.equals("house")) {
|
||||||
|
"${geocoding.get("housenumber").asString} ${geocoding.get("street").asString}"
|
||||||
|
} else {
|
||||||
|
geocoding.get("name").asString
|
||||||
|
}
|
||||||
|
address = geocoding.get("label").asString
|
||||||
|
geometry.get("coordinates").asCoordinates.let {
|
||||||
|
longitude = it.first
|
||||||
|
latitude = it.second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val JsonElement.asCoordinates: Pair<Double, Double>
|
||||||
|
get() = asJsonArray.let { Pair(it[0].asDouble, it[1].asDouble) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package org.tasks.location
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
import org.tasks.TestUtilities.readFile
|
||||||
|
|
||||||
|
class NominatimGeocoderTest {
|
||||||
|
@Test
|
||||||
|
fun pitchGeocode() {
|
||||||
|
val place = NominatimGeocoder.jsonToPlace(readFile("nominatim/pitch.json"))!!
|
||||||
|
|
||||||
|
assertEquals("Guaranteed Rate Field", place.name)
|
||||||
|
assertEquals(-87.63362064328714, place.longitude, 0.0)
|
||||||
|
assertEquals(41.82982845, place.latitude, 0.0)
|
||||||
|
assertEquals(
|
||||||
|
"Guaranteed Rate Field, West 36th Street, Armour Square, Chicago, Cook County, Illinois, 60616, United States",
|
||||||
|
place.address
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun houseGeocode() {
|
||||||
|
val place = NominatimGeocoder.jsonToPlace(readFile("nominatim/house.json"))!!
|
||||||
|
|
||||||
|
assertEquals("1 Løvenbergvegen", place.name)
|
||||||
|
assertEquals(11.1658572, place.longitude, 0.0)
|
||||||
|
assertEquals(60.2301296, place.latitude, 0.0)
|
||||||
|
assertEquals(
|
||||||
|
"1, Løvenbergvegen, Mogreina, Ullensaker, Viken, 2054, Norge",
|
||||||
|
place.address
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"geocoding": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"attribution": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
|
||||||
|
"licence": "ODbL",
|
||||||
|
"query": "60.2301296,11.1658572"
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {
|
||||||
|
"geocoding": {
|
||||||
|
"place_id": 39928913,
|
||||||
|
"osm_type": "node",
|
||||||
|
"osm_id": 3110596255,
|
||||||
|
"type": "house",
|
||||||
|
"accuracy": 0,
|
||||||
|
"label": "1, Løvenbergvegen, Mogreina, Ullensaker, Viken, 2054, Norge",
|
||||||
|
"country": "Norge",
|
||||||
|
"postcode": "2054",
|
||||||
|
"county": "Viken",
|
||||||
|
"city": "Mogreina",
|
||||||
|
"street": "Løvenbergvegen",
|
||||||
|
"housenumber": "1",
|
||||||
|
"admin": {
|
||||||
|
"level4": "Viken",
|
||||||
|
"level7": "Ullensaker"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
11.1658572,
|
||||||
|
60.2301296
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"geocoding": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"attribution": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
|
||||||
|
"licence": "ODbL",
|
||||||
|
"query": "41.8299365,-87.633806"
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {
|
||||||
|
"geocoding": {
|
||||||
|
"place_id": 258870464,
|
||||||
|
"osm_type": "relation",
|
||||||
|
"osm_id": 3834547,
|
||||||
|
"type": "pitch",
|
||||||
|
"accuracy": 0,
|
||||||
|
"label": "Guaranteed Rate Field, West 36th Street, Armour Square, Chicago, Cook County, Illinois, 60616, United States",
|
||||||
|
"name": "Guaranteed Rate Field",
|
||||||
|
"country": "United States",
|
||||||
|
"postcode": "60616",
|
||||||
|
"state": "Illinois",
|
||||||
|
"county": "Cook County",
|
||||||
|
"city": "Chicago",
|
||||||
|
"district": "Armour Square",
|
||||||
|
"street": "West 36th Street",
|
||||||
|
"admin": {
|
||||||
|
"level4": "Illinois",
|
||||||
|
"level6": "Cook County",
|
||||||
|
"level8": "Chicago",
|
||||||
|
"level10": "Armour Square"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
-87.63362064328714,
|
||||||
|
41.82982845
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue