Merge pull request #600 from whym/nearby-file

Read once and reuse the query file's content
This commit is contained in:
Josephine Lim 2017-05-19 15:36:49 +02:00 committed by GitHub
commit f6a7759317
4 changed files with 42 additions and 42 deletions

View file

@ -13,7 +13,7 @@ SELECT
SERVICE wikibase:around { SERVICE wikibase:around {
?item wdt:P625 ?location. ?item wdt:P625 ?location.
bd:serviceParam wikibase:center "Point(${LONG} ${LAT})"^^geo:wktLiteral. bd:serviceParam wikibase:center "Point(${LONG} ${LAT})"^^geo:wktLiteral.
bd:serviceParam wikibase:radius "${RADIUS}" . # Radius in kilometers. bd:serviceParam wikibase:radius "${RAD}" . # Radius in kilometers.
} }
# ... and without an image. # ... and without an image.

View file

@ -41,10 +41,7 @@ public class NearbyController {
NearbyPlaces nearbyPlaces = CommonsApplication.getInstance().getNearbyPlaces(); NearbyPlaces nearbyPlaces = CommonsApplication.getInstance().getNearbyPlaces();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
List<Place> places = prefs.getBoolean("useWikidata", true) List<Place> places = prefs.getBoolean("useWikidata", true)
? nearbyPlaces.getFromWikidataQuery( ? nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage())
context,
curLatLng,
Locale.getDefault().getLanguage())
: nearbyPlaces.getFromWikiNeedsPictures(); : nearbyPlaces.getFromWikiNeedsPictures();
if (curLatLng != null) { if (curLatLng != null) {
Timber.d("Sorting places by distance..."); Timber.d("Sorting places by distance...");

View file

@ -1,6 +1,5 @@
package fr.free.nrw.commons.nearby; package fr.free.nrw.commons.nearby;
import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.StrictMode; import android.os.StrictMode;
@ -9,7 +8,6 @@ import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -25,22 +23,32 @@ import timber.log.Timber;
public class NearbyPlaces { public class NearbyPlaces {
private static final int MIN_RESULTS = 40; private static final int MIN_RESULTS = 40;
private static final double INITIAL_RADIUS = 1.0; // in kilometer private static final double INITIAL_RADIUS = 1.0; // in kilometers
private static final double MAX_RADIUS = 300.0; // in kilometer private static final double MAX_RADIUS = 300.0; // in kilometers
private static final double RADIUS_MULTIPLIER = 1.618; private static final double RADIUS_MULTIPLIER = 1.618;
private static final String WIKIDATA_QUERY_URL = "https://query.wikidata.org/sparql?query=${QUERY}"; private static final Uri WIKIDATA_QUERY_URL = Uri.parse("https://query.wikidata.org/sparql");
private static final Uri WIKIDATA_QUERY_UI_URL = Uri.parse("https://query.wikidata.org/");
private final String wikidataQuery;
private double radius = INITIAL_RADIUS; private double radius = INITIAL_RADIUS;
private List<Place> places; private List<Place> places;
List<Place> getFromWikidataQuery(Context context, public NearbyPlaces() {
LatLng curLatLng, try {
String lang) { String query = FileUtils.readFromResource("/assets/queries/nearby_query.rq");
wikidataQuery = query;
Timber.v(wikidataQuery);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
List<Place> getFromWikidataQuery(LatLng curLatLng, String lang) {
List<Place> places = Collections.emptyList(); List<Place> places = Collections.emptyList();
try { try {
// increase the radius gradually to find a satisfactory number of nearby places // increase the radius gradually to find a satisfactory number of nearby places
while (radius < MAX_RADIUS) { while (radius < MAX_RADIUS) {
places = getFromWikidataQuery(context, curLatLng, lang, radius); places = getFromWikidataQuery(curLatLng, lang, radius);
Timber.d("%d results at radius: %f", places.size(), radius); Timber.d("%d results at radius: %f", places.size(), radius);
if (places.size() >= MIN_RESULTS) { if (places.size() >= MIN_RESULTS) {
break; break;
@ -58,28 +66,24 @@ public class NearbyPlaces {
return places; return places;
} }
private List<Place> getFromWikidataQuery(Context context, private List<Place> getFromWikidataQuery(LatLng cur,
LatLng cur,
String lang, String lang,
double radius) double radius)
throws IOException { throws IOException {
List<Place> places = new ArrayList<>(); List<Place> places = new ArrayList<>();
String query = FileUtils.readFromFile(context, "queries/nearby_query.rq") String query = wikidataQuery
.replace("${RADIUS}", String.format(Locale.ROOT, "%.2f", radius)) .replace("${RAD}", String.format(Locale.ROOT, "%.2f", radius))
.replace("${LAT}", String.format(Locale.ROOT, "%.4f", cur.latitude)) .replace("${LAT}", String.format(Locale.ROOT, "%.4f", cur.latitude))
.replace("${LONG}", String.format(Locale.ROOT, "%.4f", cur.longitude)) .replace("${LONG}", String.format(Locale.ROOT, "%.4f", cur.longitude))
.replace("${LANG}", lang); .replace("${LANG}", lang);
Timber.d("Wikidata query "+ query); Timber.v("# Wikidata query: \n" + query);
// format as a URL // format as a URL
String url = WIKIDATA_QUERY_URL.replace( Timber.d(WIKIDATA_QUERY_UI_URL.buildUpon().fragment(query).build().toString());
"${QUERY}", String url = WIKIDATA_QUERY_URL.buildUpon()
URLEncoder.encode(query, "utf-8").replace("+", "%20") .appendQueryParameter("query", query).build().toString();
);
Timber.d(url);
URLConnection conn = new URL(url).openConnection(); URLConnection conn = new URL(url).openConnection();
conn.setRequestProperty("Accept", "text/tab-separated-values"); conn.setRequestProperty("Accept", "text/tab-separated-values");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

View file

@ -1,37 +1,36 @@
package fr.free.nrw.commons.utils; package fr.free.nrw.commons.utils;
import android.content.Context;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import timber.log.Timber; import fr.free.nrw.commons.CommonsApplication;
public class FileUtils { public class FileUtils {
public static String readFromFile(Context context, String fileName) { /**
String stringBuilder = ""; * Read and return the content of a resource file as string.
*
* @param fileName asset file's path (e.g. "/assets/queries/nearby_query.rq")
* @return the content of the file
*/
public static String readFromResource(String fileName) throws IOException {
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null; BufferedReader reader = null;
try { try {
reader = new BufferedReader( reader = new BufferedReader(
new InputStreamReader(context.getAssets().open(fileName))); new InputStreamReader(
String mLine; CommonsApplication.class.getResourceAsStream(fileName), "UTF-8"));
while ((mLine = reader.readLine()) != null) { String line;
stringBuilder += mLine + "\n"; while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
} }
} catch (IOException e) {
Timber.e("File not found exception", e);
} finally { } finally {
if (reader != null) { if (reader != null) {
try {
reader.close(); reader.close();
} catch (IOException e) {
//log the exception
} }
} }
} return buffer.toString();
return stringBuilder;
} }
/** /**