API:Nahegelegene-Orte-Betrachter
Diese Seite ist Teil der Dokumentation der MediaWiki action API. |
Überblick
In dieser Anleitung wirst du lernen, wie du mit der MediaWiki Action API nach Wiki-Seiten in deiner Nähe suchen kannst.
In diesem Lernprogramm lernst du, wie du dies tun kannst:
- Python- und Flask-Framework
- JavaScript-, jQuery und Bootstrap-Framework The latter are loaded from Wikimedia Toolforge for privacy reasons.
- Geosearch -Modul der MediaWiki Action API
- Geolocation-API
Eine Schritt-für-Schritt-Anleitung, um diese Anwendung zu erstellen
Schritt 1: Python- und Flask-Entwicklungsumgebung aufsetzen
Um die Python-Entwicklungsumgebung für eine Flask-Anwendung aufzusetzen, musst du Python installieren, eine virtuelle Umgebung erstellen und Flask installieren.
Die Entwicklungsumgebung, um die Anwendung aufzubauen, wird wie folgt aufgesetzt:
$ mkdir nearby-places-viewer
$ cd nearby-places-viewer/
This will create a new directory and change into it
$ python3 --version #Python 3.6.5
This command checks your Python version
$ python3 -m venv venv
This command will create a virtual environment named 'venv'
$ source venv/bin/activate
This will activate the virtual environment
$ pip install Flask
This command will install the Flask package with all its dependencies
|
Schritt 2: Eine einfache Flask-Anwendung erstellen
Eine einfache statische Seite rendern
Setze den folgenden Code in $HOME/nearby-places-viewer/nearby.py
ein
#!/usr/bin/python3
"""
nearby.py
MediaWiki Action API Code Samples
Nearby places viewer app: Demo of geo search for wiki pages
near a location using the Geolocation API and MediaWiki Action
API's Geosearch module.
MIT license
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
""" Displays the index page accessible at '/'
"""
return render_template('places.html')
if __name__ == '__main__':
app.run()
|
Setze die Code-Zeile <h1>Nearby places viewer</h1>
in eine HTML-Datei im Ordner templates
ein: $HOME/nearby-places-viewer/templates/places.html
Hinweis:
Bei dieser einfachen Anwendung nutzen wir die Methode render_template
, die die Vorlage mit dem Namen places.html
aus dem Verzeichnis templates
rendert.
Führe als nächstes deine Flask-App mit dem Befehl python nearby.py
aus und öffne http://127.0.0.1:5000/
, um dir deine App im Browser anzusehen.
Du solltest "Nearby places viewer" in deinem Browser-Fenster sehen können.
Gestalte deine App
Lass uns die App gestalten.
Füge ein Schaltflächen-Element hinzu, um die Such-Eingabe in der HTML-Datei zu akzeptieren und verlinke Markierungen, um externe und interne Stylesheets zu laden.
Externe Stylesheets sind in diesem Fall die URL einer CSS-Datei für die Schriftart Amatic
.
Ersetze den vorhandenen Code in $HOME/nearby-places-viewer/templates/places.html
durch folgendes:
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="/static/style.css">
<h1>Nearby places viewer</h1>
<button>Click here to search</button>
Setze den folgenden Code in $HOME/nearby-places-viewer/static/style.css
ein
h1 {
font-family: 'Amatic SC', cursive;
font-size: 2.5em;
font-weight: normal;
color: black;
}
button {
font-size: 16px;
padding: 10px 25px;
cursor: pointer;
text-decoration: none;
color: white;
border-radius: 4px;
background-color: #7c7ce0;
margin-bottom: 20px;
}
|
Anwendungslayout
$HOME/nearby-places-viewer ├── templates/ │ └── places.html ├── static/ │ └── static.css ├── nearby.py └── venv/
Schritt 3: Erhalte Koordinaten deines Aufenthaltsortes
Als erstes musst du die Koordinaten deines aktuellen Aufenthaltsortes erhalten, um nach Wiki-Seiten in der Nähe zu suchen. Um dies zu tun, kannst du die Geolocation-API zusammen mit JavaScript-Code nutzen.
Wenn du auf die Schaltfläche Click here to search klickst, ruft die App die Geolocation-API an und ruft den aktuellen Standort deines Gerätes über das Navigator.geolocation
-Objekt der API ab.
Die Antwort der API ist ein Position
-Objekt, aus dem du den Breitengrad und Längengrad erhalten kannst.
Hinweis: Wenn deine App die API anruft, wirst du benachrichtigt und gebeten, deinem Browser die Berechtigung zu erteilen, auf deinen Standort zuzugreifen.
Setze den folgenden Code in $HOME/nearby-places-viewer/static/places.js
ein
$( document ).ready(function() {
var x = document.getElementById( "places-list" );
$( 'button' ).click(function() {
getLocation();
});
function getLocation() {
x.innerHTML = "Searching your location..";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(fetchPlaces);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function fetchPlaces(position) {
x.innerHTML = position.coords.latitude + "|" + position.coords.longitude;
}
});
Verlinke das benutzerdefinierte JavaScript /static/places.js
und jQuery
von der HTML
-Datei:
$HOME/nearby-places-viewer/templates/places.html
<!-- Add these two lines at the top -->
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/static/places.js"></script>
<!-- Add this line after the button element -->
<div id="places-list"></div>
Schritt 4: Sende Standortdaten an den Server mit AJAX
Diese App nutzt die AJAX-Methode von jQuery, um die in Schritt 3 erhaltenen Standort-Daten an den Server zu senden und sie ohne Neuladen der Seite an eine Python-Flask-Route /
in $HOME/nearby-places-viewer/nearby.py
zu senden.
Lass uns als nächsten den AJAX-Anruf zur Funktion fetchPlaces
in $HOME/nearby-places-viewer/static/places.js
hinzufügen.
Hinweis:
Wenn du an diesem Punkt versuchst, deine App auszuführen, ist es wahrscheinlich, dass dir im Browser-Fenster ein Fehler angezeigt wird, da wir die Unterstützung der /
-Route, um mit POST-Abfragen umzugehen, noch nicht hinzugefügt haben.
function fetchPlaces(position) {
var data = {
"latitude": position.coords.latitude,
"longitude": position.coords.longitude
};
$.ajax({
url: "/",
type: "POST",
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
success: function (response) {
x.innerHTML = "Success!";
},
error: function () {
x.innerHTML = "An error occurred while fetching places!";
}
});
}
Schritt 5: Nahegelegene Orte über die MediaWiki Action API erhalten
Erweitere als erstes die Python-Flask-Route /
in $HOME/nearby-places-viewer/nearby.py
, um POST-Abfragen zu nutzen.
Du kannst dies tun, indem du GET und POST zur methods
-Argumentliste im Route-Decorator hinzufügst.
Du kannst als nächstes die in einem JSON
-Format verfügbaren Standort-Daten aus dem request
-Objekt erhalten und es zur weiteren Verarbeitung an die fetch_places_nearby()
-Funktion übergeben.
@app.route('/', methods=['GET', 'POST'])
def index():
""" Displays the index page accessible at '/'
"""
if request.method == "POST":
data = request.get_json()
latitude = data['latitude']
longitude = data['longitude']
results = fetch_places_nearby(latitude, longitude)
return jsonify(results=results)
return render_template('places.html')
Der Code in der Funktion fetch_places_nearby()
stellt eine GET
-Abfrage an die Action API, um nach Wiki-Seiten in der Nähe eines Ortes zu suchen.
Der API-Anruf besteht aus einem Endpunkt https://en.wikipedia.org/w/api.php
und Parametern der Abfrage-Zeichenkette.
Einige der Schlüsselparameter sind:
action=query
Hauptmodul zur Informationsabfragegenerator=geosearch
Submodullist
des Abfrage-Moduls, genutzt als Generator-Modul, um Suchergebnisse für eine Reihe von Seiten zu erhaltenprop=coordinates|pageimages|description|info
Gibt an, welche Eigenschaften für Seiten zurückgegeben werden sollen
Hinweis: Für weitere Informationen zum Geosuche-Modul besuche API:Geosuche .
def fetch_places_nearby(lat, lon):
params = {
"action": "query",
"prop": "coordinates|pageimages|description|info",
"inprop": "url",
"pithumbsize": 144,
"generator": "geosearch",
"ggsradius": 10000,
"ggslimit": 10,
"ggscoord": str(lat) + "|" + str(lon),
"format": "json",
}
res = SESSION.get(url=API_ENDPOINT, params=params)
data = res.json()
places = data['query'] and data['query']['pages']
# TODO: further process 'places' list
return places
Sieh dir den vollständigen Python- und Flask-Code mit Import-Aussagen und verarbeiteter places
-Liste an.
Diese App nutzt das in Python verfügbare Haversine
-Paket, um Entfernungen zwischen zwei geografischen Koordinaten zu berechnen.
$HOME/nearby-places-viewer/nearby.py |
---|
#!/usr/bin/python3
"""
nearby.py
MediaWiki Action API Code Samples
Nearby places viewer app: Demo of geo search for wiki pages near a location using
the Geolocation API and MediaWiki Action API's Geosearch module.
MIT license
"""
from flask import Flask, request, render_template, jsonify
import requests
from haversine import haversine
APP = Flask(__name__)
SESSION = requests.Session()
API_ENDPOINT = 'https://en.wikipedia.org/w/api.php'
@APP.route('/', methods=['GET', 'POST'])
def index():
""" Displays the index page accessible at '/'
"""
if request.method == "POST":
data = request.get_json()
latitude = data['latitude']
longitude = data['longitude']
results = fetch_places_nearby(latitude, longitude)
return jsonify(results=results)
return render_template('places.html')
def fetch_places_nearby(lat, lon):
""" Fetches nearby places via MediaWiki Action API's Geosearch module
"""
params = {
"action": "query",
"prop": "coordinates|pageimages|description|info",
"inprop": "url",
"pithumbsize": 144,
"generator": "geosearch",
"ggsradius": 10000,
"ggslimit": 10,
"ggscoord": str(lat) + "|" + str(lon),
"format": "json",
}
res = SESSION.get(url=API_ENDPOINT, params=params)
data = res.json()
places = data['query'] and data['query']['pages']
results = []
for k in places:
title = places[k]['title']
description = places[k]['description'] if "description" in places[k] else ''
thumbnail = places[k]['thumbnail']['source'] if "thumbnail" in places[k] else ''
article_url = places[k]['fullurl']
cur_loc = (lat, lon)
place_loc = (places[k]['coordinates'][0]['lat'], places[k]['coordinates'][0]['lon'])
distance = round(haversine(cur_loc, place_loc, unit='mi'), 2)
results.append({
'title': title,
'description': description,
'thumbnail': thumbnail,
'articleUrl': article_url,
'distance': distance
})
return results
if __name__ == '__main__':
APP.run(debug=True)
|
Schritt 6: Aus der JSON-Antwort eine Benutzeroberfläche für Listen von Orten erstellen
Behandle die vom Server zurückgegebenen JSON-Daten im AJAX-success
-Callback und nutze die HTML-DOM-innerHTML
-Eigenschaft, um die div
-Inhalte zu ändern.
success: function (response) {
var places = response["results"],
no_thumb = "..";
x.innerHTML = "";
for (var p in places) {
var thumbnail = places[p].thumbnail || no_thumb;
x.innerHTML += "<div class=\"item\"><div class=\"col-xs-8 no-padding\"><h5><a href=\"" +
places[p]["articleUrl"] + "\" target=\"_blank\">" +
places[p]["title"] + "</a></h5><p>" +
places[p]["description"] + "</p><span>📍" + places[p]["distance"] +
" miles</p></div><div class=\"col-xs-4 no-padding\"><img src=\"" +
thumbnail + " \"></div></div>";
}
}
Sieh dir den vollständigen JavaScript-Code mit erfolgreichem AJAX-Callback an.
$HOME/nearby-places-viewer/static/places.js |
---|
$( document ).ready(function() {
var x = document.getElementById( "places-list" );
$( ".btn-search" ).click(function() {
getLocation();
});
function getLocation() {
x.innerHTML = "Searching your location..";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(fetchPlaces);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function fetchPlaces(position) {
var data = {
"latitude": position.coords.latitude,
"longitude": position.coords.longitude
};
$.ajax({
url: "/",
type: "POST",
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
success: function (response) {
var places = response["results"],
no_thumb = "https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Gnome-image-missing.svg/200px-Gnome-image-missing.svg.png";
x.innerHTML = "";
for (var p in places) {
var thumbnail = places[p].thumbnail || no_thumb;
x.innerHTML += "<div class=\"item\"><div class=\"col-xs-8 no-padding\"><h5><a href=\"" +
places[p]["articleUrl"] + "\" target=\"_blank\">" +
places[p]["title"] + "</a></h5><p>" +
places[p]["description"] + "</p><span>📍" + places[p]["distance"] +
" miles</p></div><div class=\"col-xs-4 no-padding\"><img src=\"" +
thumbnail + " \"></div></div>";
}
},
error: function () { x.innerHTML = "An error occurred while fetching places!"; }
});
}
});
|
Schritt 7: Gestaltung ändern mit Bootstrap
Du hast vielleicht bemerkt, dass der Code-Ausschnitt in Schritt 6 Namen von Bootstrap-Klassen nutzt. Ja, wir integrieren in diesem Schritt das Bootstrap-Framework, um ein responsoves Layout-Design zum Orte-UI hinzuzufügen. Lass uns CSS- und HTML-Dateien optimieren, um dies zu tun.
Sieh dir den vollständigen CSS- und HTML-Code an.
$HOME/nearby-places-viewer/static/style.css |
---|
.places-container .no-padding {
padding: 0;
}
.places-container .info {
text-align: center;
}
.places-container .viewer-heading {
font-family: 'Amatic SC', cursive;
font-size: 2.5em;
font-weight: normal;
color: black;
}
.places-container .btn-search {
font-size: 16px;
padding: 10px 25px;
cursor: pointer;
text-decoration: none;
color: white;
border-radius: 4px;
background-color: #7c7ce0;
}
.places-container .list {
margin-top: 20px;
}
.places-container .item {
min-height: 100px;
}
.places-container .item p,
span {
font-size: 12px;
margin: 2px;
}
.places-container .item span {
color: gray;
}
.places-container .item img {
float: right;
width: 80px;
height: 80px;
border-radius: 5px;
object-fit: cover;
}
.places-container .item a {
color: #7c7ce0;
}
|
$HOME/nearby-places-viewer/templates/places.html |
---|
<title>Nearby places viewer</title>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="/static/places.js"></script>
<link rel="stylesheet" href="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="/static/style.css">
<div class="container places-container col-lg-4 col-xs-12">
<div class="col-xs-12 no-padding info">
<h1 class="viewer-heading">Nearby places viewer</h1>
<button class="btn-search">Click here to search</button>
</div>
<div class="col-xs-12 no-padding list" id="places-list">
</div>
</div>
|
Nächste Schritte
- Trage eine Demo-App, die du mithilfe der MediaWiki API entwickelt hast, zu dem Code-Beispiel-Repositorium bei.
Siehe auch
- API:Geosuche
- Flask-Anleitungen
- Nearby ist eine App für die Pebble-Smartwatch, die Wikipedia-Artikel in deiner Nähe anzeigt.