Skip to content

Commit

Permalink
#7 add support for commons.wikimedia.org (view Fotos)
Browse files Browse the repository at this point in the history
#8 add support for www.wikidata.org (view Knowledgebase)
#9 add button "share" (i.e. save as local file)
  • Loading branch information
k3b committed Mar 21, 2023
1 parent 7405678 commit 68b35f8
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 54 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# AndroidGeo2ArticlesMap

Plugin for [Location Map Viewer](https://f-droid.org/en/packages/de.k3b.android.locationMapViewer):
Show articles from Wikipedia™ or Wikivoyage™ near a given geographic location in an interactive map.
Show articles near a given geographic location in an interactive map from

* Wikipedia™ (The Free Encyclopedia that anyone can edit) or
* Wikivoyage™ (Free travel guide that anyone can edit) or
* Wikimedia™ (Free Fotos, Vidio, Audo collections) or
* Wikidata™ (knowledge base that anyone can edit).

Uscase: Suppose you are going on holiday. Your navigation app shows you a geo-map with your hotel
and you want to know: what is near this place that has an article in [wikipedia](https://en.wikipedia.org)
( or [wikivoyage](https://en.wikivoyage.org) ).
and you want to know: what is near this place that has an article in [wikipedia](https://en.wikipedia.org).

In your navigation app select "view in external app" (or "send location to" or "share location with" or ...)
choose "Show Articles in Map" and you will get a map with marks for articles. If you click on a mark you get
Expand Down Expand Up @@ -55,7 +59,7 @@ If you select view + "Show Articles in Map" from a geo app you will see the sett

![](https://raw.githubusercontent.com/k3b/AndroidGeo2ArticlesMap/main/fastlane/metadata/android/en-US/images/phoneScreenshots/2-ageo2ArticleMap-pick-service.png)

(3) pick one of the 93 bigger **known services**
(3) pick one of the 95 bigger **known services**

---

Expand All @@ -81,7 +85,7 @@ Technically speaking the AndroidGeo2ArticlesMap app
[Location Map Viewer](https://github.com/k3b/LocationMapViewer)
Copyright (c) by k3b, Licensed under GPL, Version 3.0 or later.

Wikipedia and Wikivoyage are [trademarks of the Wikimedia Foundation](https://foundation.wikimedia.org/wiki/Wikimedia_trademarks)
Wikipedia, Wikimedia, Wikidata and Wikivoyage are [trademarks of the Wikimedia Foundation](https://foundation.wikimedia.org/wiki/Wikimedia_trademarks)

-----

Expand Down
9 changes: 5 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ android {
// v1.3 (3) fixed fastlane description
// v1.4 (4) 2021-08-01: removed obsolete write permissions not neccessary since android-4.4 (api 19)
// v1.5 (5) 2021-08-??: Setting: option to (not) Load symbols/images; Bug Fixes
versionCode 5
versionName 'v1.5'
// v1.6 (6) 2023-03-21: Add support for Wikimedia (Fotos) and Wikidata (Knowledgebase) and Send
versionCode 6
versionName 'v1.6'

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -54,8 +55,8 @@ dependencies {
implementation 'org.slf4j:slf4j-api:1.7.7@jar'
implementation 'org.slf4j:slf4j-simple:1.7.7'
// implementation project(path: ':k3b-geoHelper')
implementation 'com.github.k3b:k3b-geoHelper:v1.1.9'
// implementation 'com.github.k3b:k3b-geoHelperAndroid:v1.1.9'
implementation 'com.github.k3b:k3b-geoHelper:v1.1.12'
// implementation 'com.github.k3b:k3b-geoHelperAndroid:v1.1.12'

implementation 'commons-io:commons-io:2.6'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
Expand Down
4 changes: 3 additions & 1 deletion app/src/debug/res/values/fdroid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ Note: You must also install [Location Map Viewer](https://f-droid.org/packages/d
This app adds the option *Show Articles in Map* to any app that can shown/send/share a geo location or **geo-uri** .
This app hooks into the android system to intercept "view geo-uri". When getting a geo-uri it asks wikipedia and shows the results in
This app hooks into the android system to intercept "view geo-uri". When getting a geo-uri it asks
encyclopedia *wikipedia* (or travelguide *wikivoyage* or knowledgebase *wikidata* or photogallery *wikimedia*)
and shows the results in
[Location Map Viewer](https://f-droid.org/packages/de.k3b.android.locationMapViewer)
(or in any other installed app that understands the format 'kmz').
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/assets/languages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#
# harvested on 2021-07-04: all html <option.. from https://www.wikipedia.org and https://www.wikivoyage.org/
# sorted by language-key
# en_m => commons.wikimedia.org
# en_d => www.wikidata.org
# xx_p => xx.wikipedia.org
# xx_v => xx.wikivoyage.org
ar_p=العربية 🇸🇦
Expand All @@ -28,6 +30,8 @@ de_p=Deutsch 🇩🇪
de_v=Deutsch 🇩🇪
el_p=Ελληνικά
el_v=Ελληνικά
en_d=Knowledgebase 🔬
en_m=Fotos 📷
en_p=English 🇺🇸 🇬🇧
en_v=English 🇺🇸 🇬🇧
eo_p=Esperanto 🗺
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private InputStream getInputStream(URL url) throws IOException {
}

private Result getGeoPointInfos(Object lat, Object lon, boolean withSymbols) {
String urlString = this.getQueryGeoUrlString(lat, lon, withSymbols);
String urlString = this.getQueryGeoUrlString(lat, lon, withSymbols, serviceName.contains(".wikidata."));
String message = "downloading articles from " + serviceName;
Log.i(TAG, message + " using " + urlString);
if (progressMessage != null) {
Expand All @@ -116,7 +116,7 @@ private Result getGeoPointInfos(Object lat, Object lon, boolean withSymbols) {
try (InputStream inputStream = this.getInputStream(urlString) ){
GpxReader<IGeoPointInfo> parser = new GpxReader<>();
message = "analysing articles ...";
Log.d(TAG,message);
Log.d(TAG,message);
if (progressMessage != null) {
progressMessage.message(message);
}
Expand All @@ -125,7 +125,7 @@ private Result getGeoPointInfos(Object lat, Object lon, boolean withSymbols) {
return new Result(null, points, 0, null);
} catch (Exception ex) {
message = "cannot read from '" + this.serviceName + "' using '" + urlString + "'" ;
Log.e(TAG, message,ex);
Log.e(TAG, message,ex);
if (progressMessage != null) {
progressMessage.message(message);
}
Expand Down Expand Up @@ -156,8 +156,13 @@ public Result saveAsEx(Object lat, Object lon, boolean withSymbols, File out) {
return result;
}

/** api creates url that encodes what we want to get from wikipedia */
private String getQueryGeoUrlString(Object lat, Object lon, boolean withSymbols) {
/** api creates url that encodes what we want to get from wikipedia
*
* examples
* * https://de.wikivoyage.org/w/api.php?action=query&format=xml&prop=coordinates|info|pageimages|extracts&inprop=url&piprop=thumbnail&generator=geosearch&ggscoord=28.12722|-15.43139&ggsradius=10000&ggslimit=5&pilimit=5&exsentences=2&explaintext&exintro
* * https://www.wikidata.org/w/api.php?action=query&format=xml&prop=entityterms|coordinates|info&inprop=url&generator=geosearch&ggscoord=36.45284|28.22016&ggsradius=10000&ggslimit=25
* */
private String getQueryGeoUrlString(Object lat, Object lon, boolean withSymbols, boolean fromWikiData) {
// see https://www.mediawiki.org/wiki/Special:MyLanguage/API:Main_page
StringBuilder urlString = new StringBuilder().append("https://")
.append(serviceName)
Expand All @@ -166,27 +171,35 @@ private String getQueryGeoUrlString(Object lat, Object lon, boolean withSymbols)
"&format=xml" +
"&prop=coordinates|info");

if (withSymbols) {
urlString.append("|pageimages");
if (fromWikiData) {
urlString.append("|entityterms");
} else {
if (withSymbols) {
urlString.append("|pageimages");
}

urlString.append("|extracts");
}

urlString.append("|extracts" +
urlString.append(
"&inprop=url" +
"&generator=geosearch" +
"&ggscoord=")
.append(lat).append("|").append(lon)
.append("&ggsradius=").append(radius)
.append("&ggslimit=").append(maxcount);

if (withSymbols) {
urlString.append("&piprop=thumbnail")
.append("&pithumbsize=").append(GeoConfig.THUMBSIZE)
.append("&pilimit=").append(maxcount);
}
if (!fromWikiData) {
if (withSymbols) {
urlString.append("&piprop=thumbnail")
.append("&pithumbsize=").append(GeoConfig.THUMBSIZE)
.append("&pilimit=").append(maxcount);
}

urlString
// prop extracts: 2Sentenses in non-html before TOC
.append("&exsentences=2&explaintext&exintro");
urlString
// prop extracts: 2Sentenses in non-html before TOC
.append("&exsentences=2&explaintext&exintro");
}
return urlString.toString();
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/de/k3b/android/articlemap/GeoConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

public class GeoConfig {
public String serviceName = null; // i.e. "en.wikipedia.org";
public final String USER_AGENT = "AndroidGeo2ArticlesMap/1.0 (https://github.com/k3b/AndroidGeo2ArticlesMap)";
public final String USER_AGENT = "AndroidGeo2ArticlesMap/1.1 (https://github.com/k3b/AndroidGeo2ArticlesMap)";
public final String outFileExtension = ".kmz";
public final String outMimeType = "application/vnd.google-earth.kmz";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

Expand All @@ -40,16 +39,18 @@ public class LanguageDefinition implements Comparable<LanguageDefinition> {
private final String key;
private final String name;

// ie new LanguageDefinition("en_d","Scientific Data 🔬")
public LanguageDefinition(String key, String value) {
String languageID = getLanguage(key);

this.url = languageID + (isWikipedia(key) ? ".wikipedia.org" : ".wikivoyage.org");
this.url = getUrl(key);
this.key = key;
this.name = languageID + " " + value + " " + this.getUrl();
this.name = getLanguage(key) + " " + value + " " + this.url;
}

private boolean isWikipedia(String key) {
return !key.endsWith("_v");
@NonNull
private String getUrl(String key) {
if (key.endsWith("_d")) return "www.wikidata.org";
if (key.endsWith("_m")) return "commons.wikimedia.org";
return getLanguage(key) + (key.endsWith("_v") ? ".wikivoyage.org" : ".wikipedia.org");
}

private String getLanguage(String key) {
Expand All @@ -73,7 +74,6 @@ public static Map<String, LanguageDefinition> getLanguages(Context context) thro
}

public static Map<String, LanguageDefinition> getLanguages(InputStream in) throws IOException {
String language = Locale.getDefault().getLanguage();
Properties properties = new Properties();
// note: Properties standard use iso-8859-1. However this app uses utf8
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
Expand Down Expand Up @@ -89,10 +90,10 @@ private Gui() {
editService );

Button cmdView = findViewById(R.id.cmd_view);
cmdView.setOnClickListener(v -> onStartQuery());
cmdView.setOnClickListener(v -> onStartQuery(false));
/*
Button cmdShare = findViewById(R.id.cmd_share);
cmdShare.setOnClickListener(v -> onStartQuery());
cmdShare.setOnClickListener(v -> onStartQuery(true));
*/
Button cmdCancel = findViewById(R.id.cmd_cancel);
cmdCancel.setOnClickListener(v -> cancel());
Expand Down Expand Up @@ -131,6 +132,8 @@ private void initServiceHistory() {
includeService(
languages.get("simple_v"), // last in list
languages.get("simple_p"),
languages.get("en_m"),
languages.get("en_d"),
languages.get("en_v"),
languages.get("en_p"),
languages.get(language + "_v"),
Expand Down Expand Up @@ -196,6 +199,10 @@ public void setGuiMessage(int stringId, Object... parameters) {
}

class GeoLoadTask extends AsyncTask<GeoPointDto, Void, ArticlesDownloadService.Result> {
private final boolean useActionSend;
public GeoLoadTask(boolean useActionSend) {
this.useActionSend = useActionSend;
}

@Override
protected ArticlesDownloadService.Result doInBackground(GeoPointDto... arg0) {
Expand All @@ -222,7 +229,7 @@ private ArticlesDownloadService.Result translateGeoToFile(GeoPointDto geoPointFr

@Override
protected void onPostExecute(ArticlesDownloadService.Result result) {
showResult(result);
showResult(result, useActionSend);
}
}

Expand All @@ -234,7 +241,7 @@ protected void onCreateEx(Bundle savedInstanceState) {
GeoPointDto geoPointFromIntent = getGeoPointDtoFromIntent(getIntent());

if (!geoConfig.showSettings && geoPointFromIntent != null && !GeoPointDto.isEmpty(geoPointFromIntent)) {
queryDataFromArticleServer(geoPointFromIntent, false);
queryDataFromArticleServer(geoPointFromIntent, false, false);
} else {
setContentView(R.layout.activity_choose_url);
gui = new Gui().load(geoConfig);
Expand All @@ -248,20 +255,20 @@ protected void onCreateEx(Bundle savedInstanceState) {
}
}

private void queryDataFromArticleServer(GeoPointDto geoPointFromIntent, boolean inDemoMode) {
private void queryDataFromArticleServer(GeoPointDto geoPointFromIntent, boolean inDemoMode, boolean useActionSend) {
geoConfig.inDemoMode = inDemoMode;
String name = createFileName(geoConfig.serviceName, geoPointFromIntent.getLatitude(), geoPointFromIntent.getLongitude());
File outFile = new File(
createSharedOutDir(name),
name + geoConfig.outFileExtension);
createSharedUri(outFile);

new GeoLoadTask().execute(geoPointFromIntent);
new GeoLoadTask(useActionSend).execute(geoPointFromIntent);
}

/** called in gui thread, after receiving answer from wikipedia */
@SuppressLint("StringFormatMatches")
private void showResult(ArticlesDownloadService.Result result) {
private void showResult(ArticlesDownloadService.Result result, boolean useActionSend) {

if (result.errorMessageId != 0) {
showErrorMessage(getString(result.errorMessageId, geoConfig.serviceName, result.outFile, toString(geoConfig.demoUri),""));
Expand All @@ -277,11 +284,24 @@ private void showResult(ArticlesDownloadService.Result result) {

Uri outUri = createSharedUri(result.outFile);

Intent newIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
newIntent.putExtra(Intent.EXTRA_TITLE, geoConfig.serviceName);

newIntent.setDataAndTypeAndNormalize(outUri, geoConfig.outMimeType);
Intent newIntent;
if (useActionSend) {
// https://developer.android.com/reference/android/content/Intent#ACTION_SEND
newIntent = new Intent(Intent.ACTION_SEND)
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.setType("*/*")
.putExtra(Intent.EXTRA_TITLE, geoConfig.serviceName)
.putExtra(Intent.EXTRA_STREAM, outUri);
newIntent.setClipData(ClipData.newRawUri("", outUri));

newIntent = Intent.createChooser(newIntent, geoConfig.serviceName);
} else {
// https://developer.android.com/reference/android/content/Intent#ACTION_VIEW
newIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.putExtra(Intent.EXTRA_TITLE, geoConfig.serviceName)
.setDataAndTypeAndNormalize(outUri, geoConfig.outMimeType);
}

try {
// start the image capture Intent
Expand Down Expand Up @@ -367,14 +387,18 @@ public boolean onPrepareOptionsMenu(Menu menu) {
public boolean onOptionsItemSelected(MenuItem menuItem) {
save();
int itemId = menuItem.getItemId();
boolean isCmdShare = itemId == R.id.cmd_share;
if (itemId == R.id.cmd_cancel_pick) {
finish();
return true;
} else if (itemId == R.id.cmd_ok) {
} else if (itemId == R.id.cmd_ok || isCmdShare) {
GeoPointDto geoPointFromIntent = getGeoPointDtoFromIntent(getIntent());

if (geoPointFromIntent == null) {
geoPointFromIntent = new GeoConfig(this).demoUri;
}
if (geoPointFromIntent != null) {
queryDataFromArticleServer(geoPointFromIntent, false);
queryDataFromArticleServer(geoPointFromIntent, false, isCmdShare);
} else {
finish();
}
Expand All @@ -385,9 +409,9 @@ public boolean onOptionsItemSelected(MenuItem menuItem) {

}

private void onStartQuery() {
private void onStartQuery(boolean useActionSend) {
save();
queryDataFromArticleServer(geoConfig.demoUri, true);
queryDataFromArticleServer(geoConfig.demoUri, true, useActionSend);
}

private void save() {
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/menu/menu_choose_url.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
-->
<!-- menue of gallery for modus pick/getContent -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/cmd_share" android:title="@string/share"
android:icon="@android:drawable/ic_menu_share"
android:orderInCategory="2" android:showAsAction="always" android:visible="true" />
<item android:id="@+id/cmd_ok" android:title="@android:string/ok"
android:icon="@drawable/ic_action_accept"
android:orderInCategory="2" android:showAsAction="always" android:visible="true" />
Expand Down
6 changes: 5 additions & 1 deletion fastlane/metadata/android/en-US/changelogs/6.txt
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
--- todo ---
v1.6 (6)

* #7 Added support for 📷 commons.wikimedia.org (i.e. gallery of photos)
* #8 Added support for 🔬 www.wikidata.org (Knowledgebase)
* #9 Added button "share" (i.e. share generated kmz to "save as local file")
1 change: 1 addition & 0 deletions fastlane/metadata/android/en-US/changelogs/7.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--- todo ---
Loading

0 comments on commit 68b35f8

Please sign in to comment.