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