replace nominatimClient with copied/pacthes version replacing legacy httpClient with okhttp3

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
This commit is contained in:
Andy Scherzinger 2021-06-11 00:24:21 +02:00
parent ba64d693ef
commit f52d7f29d9
No known key found for this signature in database
GPG Key ID: 6CADC7E3523C308B
4 changed files with 356 additions and 32 deletions

View File

@ -294,8 +294,10 @@ dependencies {
implementation 'com.elyeproj.libraries:loaderviewlibrary:2.0.0'
implementation 'org.osmdroid:osmdroid-android:6.1.10'
//noinspection DuplicatePlatformClasses
implementation 'fr.dudie:nominatim-api:3.4'
implementation ('fr.dudie:nominatim-api:3.4', {
//noinspection DuplicatePlatformClasses
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
})
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:3.11.0'

View File

@ -46,20 +46,14 @@ import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.databinding.ControllerGeocodingBinding
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.UserUtils
import fr.dudie.nominatim.client.JsonNominatimClient
import fr.dudie.nominatim.client.TalkJsonNominatimClient
import fr.dudie.nominatim.model.Address
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.apache.http.client.HttpClient
import org.apache.http.conn.ClientConnectionManager
import org.apache.http.conn.scheme.Scheme
import org.apache.http.conn.scheme.SchemeRegistry
import org.apache.http.conn.ssl.SSLSocketFactory
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.impl.conn.SingleClientConnManager
import okhttp3.OkHttpClient
import org.osmdroid.config.Configuration
import javax.inject.Inject
@ -78,8 +72,11 @@ class GeocodingController(args: Bundle) :
@Inject
lateinit var userUtils: UserUtils
@Inject
lateinit var okHttpClient: OkHttpClient
var roomToken: String?
var nominatimClient: JsonNominatimClient? = null
var nominatimClient: TalkJsonNominatimClient? = null
var searchItem: MenuItem? = null
var searchView: SearchView? = null
@ -178,13 +175,9 @@ class GeocodingController(args: Bundle) :
}
private fun initGeocoder() {
val registry = SchemeRegistry()
registry.register(Scheme("https", SSLSocketFactory.getSocketFactory(), HTTPS_PORT))
val connexionManager: ClientConnectionManager = SingleClientConnManager(null, registry)
val httpClient: HttpClient = DefaultHttpClient(connexionManager, null)
val baseUrl = context!!.getString(R.string.osm_geocoder_url)
val email = context!!.getString(R.string.osm_geocoder_contact)
nominatimClient = JsonNominatimClient(baseUrl, httpClient, email)
nominatimClient = TalkJsonNominatimClient(baseUrl, okHttpClient, email)
}
private fun searchLocation(): Boolean {
@ -223,6 +216,5 @@ class GeocodingController(args: Bundle) :
companion object {
private const val TAG = "GeocodingController"
private const val HTTPS_PORT: Int = 443
}
}

View File

@ -57,7 +57,7 @@ import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import com.nextcloud.talk.utils.database.user.UserUtils
import fr.dudie.nominatim.client.JsonNominatimClient
import fr.dudie.nominatim.client.TalkJsonNominatimClient
import fr.dudie.nominatim.model.Address
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
@ -67,13 +67,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.apache.http.client.HttpClient
import org.apache.http.conn.ClientConnectionManager
import org.apache.http.conn.scheme.Scheme
import org.apache.http.conn.scheme.SchemeRegistry
import org.apache.http.conn.ssl.SSLSocketFactory
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.impl.conn.SingleClientConnManager
import okhttp3.OkHttpClient
import org.osmdroid.config.Configuration.getInstance
import org.osmdroid.events.DelayedMapListener
import org.osmdroid.events.MapListener
@ -103,7 +97,10 @@ class LocationPickerController(args: Bundle) :
@Inject
lateinit var userUtils: UserUtils
var nominatimClient: JsonNominatimClient? = null
@Inject
lateinit var okHttpClient: OkHttpClient
var nominatimClient: TalkJsonNominatimClient? = null
var roomToken: String?
@ -425,13 +422,9 @@ class LocationPickerController(args: Bundle) :
}
private fun initGeocoder() {
val registry = SchemeRegistry()
registry.register(Scheme("https", SSLSocketFactory.getSocketFactory(), HTTPS_PORT))
val connexionManager: ClientConnectionManager = SingleClientConnManager(null, registry)
val httpClient: HttpClient = DefaultHttpClient(connexionManager, null)
val baseUrl = context!!.getString(R.string.osm_geocoder_url)
val email = context!!.getString(R.string.osm_geocoder_contact)
nominatimClient = JsonNominatimClient(baseUrl, httpClient, email)
nominatimClient = TalkJsonNominatimClient(baseUrl, okHttpClient, email)
}
private fun searchPlaceNameForCoordinates(lat: Double, lon: Double): Boolean {
@ -483,6 +476,5 @@ class LocationPickerController(args: Bundle) :
private const val ZOOM_LEVEL_RECEIVED_RESULT: Double = 14.0
private const val ZOOM_LEVEL_DEFAULT: Double = 14.0
private const val GEOCODE_ZERO: Double = 0.0
private const val HTTPS_PORT: Int = 443
}
}

View File

@ -0,0 +1,338 @@
package fr.dudie.nominatim.client;
/*
* [license]
* Nominatim Java API client
* ~~~~
* Copyright (C) 2010 - 2014 Dudie
* ~~~~
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* [/license]
*/
import android.util.Log;
import com.github.filosganga.geogson.gson.GeometryAdapterFactory;
import com.github.filosganga.geogson.jts.JtsAdapterFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import fr.dudie.nominatim.client.request.NominatimLookupRequest;
import fr.dudie.nominatim.client.request.NominatimReverseRequest;
import fr.dudie.nominatim.client.request.NominatimSearchRequest;
import fr.dudie.nominatim.client.request.paramhelper.OsmType;
import fr.dudie.nominatim.gson.ArrayOfAddressElementsDeserializer;
import fr.dudie.nominatim.gson.ArrayOfPolygonPointsDeserializer;
import fr.dudie.nominatim.gson.BoundingBoxDeserializer;
import fr.dudie.nominatim.gson.PolygonPointDeserializer;
import fr.dudie.nominatim.model.Address;
import fr.dudie.nominatim.model.BoundingBox;
import fr.dudie.nominatim.model.Element;
import fr.dudie.nominatim.model.PolygonPoint;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* An implementation of the Nominatim Api Service.
*
* @author Jérémie Huchet
* @author Sunil D S
* @author Andy Scherzinger
*/
public final class TalkJsonNominatimClient implements NominatimClient {
private static final String TAG = "TalkNominationClient";
/**
* The default nominatim base URL.
*/
private static final String DEFAULT_BASE_URL = "https://nominatim.openstreetmap.org/";
/**
* UTF-8 encoding.
*/
public static final String ENCODING_UTF_8 = "UTF-8";
private final OkHttpClient httpClient;
/**
* Gson instance for Nominatim API calls.
*/
private final Gson gson;
/**
* The url to make search queries.
*/
private final String searchUrl;
/**
* The url for reverse geocoding.
*/
private final String reverseUrl;
/**
* The url for address lookup.
*/
private final String lookupUrl;
/**
* The default search options.
*/
private final NominatimOptions defaults;
/**
* Creates the json nominatim client with the default base URL ({@value #DEFAULT_BASE_URL}.
*
* @param httpClient an HTTP client
* @param email an email to add in the HTTP requests parameters to "sign" them
*/
public TalkJsonNominatimClient(final OkHttpClient httpClient, final String email) {
this(DEFAULT_BASE_URL, httpClient, email, new NominatimOptions());
}
/**
* Creates the json nominatim client with the default base URL ({@value #DEFAULT_BASE_URL}.
*
* @param httpClient an HTTP client
* @param email an email to add in the HTTP requests parameters to "sign" them
* @param defaults defaults options, they override null valued requests options
*/
public TalkJsonNominatimClient(final OkHttpClient httpClient, final String email, final NominatimOptions defaults) {
this(DEFAULT_BASE_URL, httpClient, email, defaults);
}
/**
* Creates the json nominatim client.
*
* @param baseUrl the nominatim server url
* @param httpClient an HTTP client
* @param email an email to add in the HTTP requests parameters to "sign" them (see
* https://wiki.openstreetmap.org/wiki/Nominatim_usage_policy)
*/
public TalkJsonNominatimClient(final String baseUrl, final OkHttpClient httpClient, final String email) {
this(baseUrl, httpClient, email, new NominatimOptions());
}
/**
* Creates the json nominatim client.
*
* @param baseUrl the nominatim server url
* @param httpClient an HTTP client
* @param email an email to add in the HTTP requests parameters to "sign" them (see
* https://wiki.openstreetmap.org/wiki/Nominatim_usage_policy)
* @param defaults defaults options, they override null valued requests options
*/
public TalkJsonNominatimClient(final String baseUrl, final OkHttpClient httpClient, final String email, final NominatimOptions defaults) {
String emailEncoded;
try {
emailEncoded = URLEncoder.encode(email, ENCODING_UTF_8);
} catch (UnsupportedEncodingException e) {
emailEncoded = email;
}
this.searchUrl = String.format("%s/search?format=jsonv2&email=%s", baseUrl.replaceAll("/$", ""), emailEncoded);
this.reverseUrl = String.format("%s/reverse?format=jsonv2&email=%s", baseUrl.replaceAll("/$", ""), emailEncoded);
this.lookupUrl = String.format("%s/lookup?format=json&email=%s", baseUrl.replaceAll("/$", ""), emailEncoded);
Log.d(TAG, "API search URL: " + searchUrl);
Log.d(TAG, "API reverse URL: " + reverseUrl);
this.defaults = defaults;
// prepare gson instance
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Element[].class, new ArrayOfAddressElementsDeserializer());
gsonBuilder.registerTypeAdapter(PolygonPoint.class, new PolygonPointDeserializer());
gsonBuilder.registerTypeAdapter(PolygonPoint[].class, new ArrayOfPolygonPointsDeserializer());
gsonBuilder.registerTypeAdapter(BoundingBox.class, new BoundingBoxDeserializer());
gsonBuilder.registerTypeAdapterFactory(new JtsAdapterFactory());
gsonBuilder.registerTypeAdapterFactory(new GeometryAdapterFactory());
gson = gsonBuilder.create();
// prepare httpclient
this.httpClient = httpClient;
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#search(fr.dudie.nominatim.client.request.NominatimSearchRequest)
*/
@Override
public List<Address> search(final NominatimSearchRequest search) throws IOException {
defaults.mergeTo(search);
final String apiCall = String.format("%s&%s", searchUrl, search.getQueryString());
Log.d(TAG, "search url: " + apiCall);
Request requesthttp = new Request.Builder()
.addHeader("accept", "application/json")
.url(apiCall)
.build();
Response response = httpClient.newCall(requesthttp).execute();
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
return gson.fromJson(responseBody.string(), new TypeToken<List<Address>>() {
}.getType());
}
}
return new ArrayList<>();
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#getAddress(fr.dudie.nominatim.client.request.NominatimReverseRequest)
*/
@Override
public Address getAddress(final NominatimReverseRequest reverse) throws IOException {
final String apiCall = String.format("%s&%s", reverseUrl, reverse.getQueryString());
Log.d(TAG, "reverse geocoding url: " + apiCall);
Request requesthttp = new Request.Builder()
.addHeader("accept", "application/json")
.url(apiCall)
.build();
Response response = httpClient.newCall(requesthttp).execute();
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
return gson.fromJson(responseBody.string(), Address.class);
}
}
return null;
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#lookupAddress(fr.dudie.nominatim.client.request.NominatimLookupRequest)
*/
@Override
public List<Address> lookupAddress(final NominatimLookupRequest lookup) throws IOException {
final String apiCall = String.format("%s&%s", lookupUrl, lookup.getQueryString());
Log.d(TAG, "lookup url: " + apiCall);
Request requesthttp = new Request.Builder()
.addHeader("accept", "application/json")
.url(apiCall)
.build();
Response response = httpClient.newCall(requesthttp).execute();
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
return gson.fromJson(responseBody.string(), new TypeToken<List<Address>>() {
}.getType());
}
}
return new ArrayList<>();
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#search(java.lang.String)
*/
@Override
public List<Address> search(final String query) throws IOException {
final NominatimSearchRequest q = new NominatimSearchRequest();
q.setQuery(query);
return this.search(q);
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#getAddress(double, double)
*/
@Override
public Address getAddress(final double longitude, final double latitude) throws IOException {
final NominatimReverseRequest q = new NominatimReverseRequest();
q.setQuery(longitude, latitude);
return this.getAddress(q);
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#getAddress(double, double, int)
*/
@Override
public Address getAddress(final double longitude, final double latitude, final int zoom)
throws IOException {
final NominatimReverseRequest q = new NominatimReverseRequest();
q.setQuery(longitude, latitude);
q.setZoom(zoom);
return this.getAddress(q);
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#getAddress(int, int)
*/
@Override
public Address getAddress(final int longitudeE6, final int latitudeE6) throws IOException {
return this.getAddress((double) (longitudeE6 / 1E6), (double) (latitudeE6 / 1E6));
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#getAddress(String, long)
*/
@Override
public Address getAddress(final String type, final long id) throws IOException {
final NominatimReverseRequest q = new NominatimReverseRequest();
q.setQuery(OsmType.from(type), id);
return this.getAddress(q);
}
/**
* {@inheritDoc}
*
* @see fr.dudie.nominatim.client.NominatimClient#lookupAddress(java.util.List)
*/
@Override
public List<Address> lookupAddress(final List<String> typeId) throws IOException {
final NominatimLookupRequest q = new NominatimLookupRequest();
q.setQuery(typeId);
return this.lookupAddress(q);
}
}