API:Prohlížeč míst v okolí

From mediawiki.org
This page is a translated version of the page API:Nearby places viewer and the translation is 100% complete.

Přehled

V tomto průvodci se naučíte, jak vyhledávat wiki stránky v okolí vaší polohy pomocí MediaWiki Action API.

Tento průvodce vás naučí, jak to udělat pomocí:

Postup pro vytvoření této aplikace krok za krokem

Krok 1: Nastavení vývojového prostředí Python a Flask

Chcete-li nastavit vývojové prostředí Python pro aplikaci Flask, budete muset nainstalovat Python, vytvořit virtuální prostředí a nainstalovat Flask.

Tato aplikace používá Python3, doporučenou verzi pro nové projekty Pythonu. Další informace o rozdílech mezi Pythonem2 a Pythonem3 najdete zde. Chcete-li nainstalovat Python3 na svůj místní počítač, postupujte podle pokynů krok za krokem v těchto instalačních průvodcích.

Zde je návod, jak nastavit vývojové prostředí pro tvorbu aplikace:

$ 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

Krok 2: Vytvořte jednoduchou aplikaci Flask

Vytvoření jednoduché statické stránky

Vložte následující kód do $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, 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()

Přesuňte tento jeden řádek kódu <h1>Nearby places viewer</h1> do souboru HTML do složky templates: $HOME/nearby-places-viewer/templates/places.html

Poznámka: V této jednoduché aplikaci používáme metodu render_template, která vykreslí šablonu s názvem places.html z adresáře templates.

Poté spusťte aplikaci Flask pomocí příkazu python nearby.py a otevřete http://127.0.0.1:5000/, abyste si aplikaci zobrazili v prohlížeči. V okně prohlížeče byste měli vidět "Nearby places viewer" (prohlížeč míst v okolí).

Styl vaší aplikace

Pojďme udělat nějaký styl aplikace. Chcete-li načíst externí a interní šablonu stylů, přidejte prvek tlačítka pro přijetí vyhledávacího vstupu do souboru HTML a značky odkazů. Externí šablona stylů je v tomto případě adresa URL souboru CSS pro písmo Amatic.

Nahraďte stávající kód v $HOME/nearby-places-viewer/templates/places.html následujícím:

<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>

Vložte následující kód do $HOME/nearby-places-viewer/static/style.css

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;
}
Snímek obrazovky ukázkové aplikace prohlížeče míst v okolí (1)

Rozvržení aplikace

$HOME/nearby-places-viewer
├── templates/
│   └── places.html
├── static/
│   └── static.css
├── nearby.py
└── venv/

Krok 3: Získejte souřadnice vaší aktuální polohy

Chcete-li hledat wiki stránky v okolí, musíte nejprve získat souřadnice své aktuální polohy. K tomu můžete použít Geolocation API spolu s některým kódem JavaScript.

Když kliknete na tlačítko Click here to search (kliknutím sem vyhledáte), aplikace zavolá Geolocation API a načte aktuální polohu vašeho zařízení prostřednictvím objektu API Navigator.geolocation. Odpověď API je na oplátku objektem Position, ze kterého můžete získat zeměpisnou šířku a délku.

Poznámka: Když vaše aplikace zavolá rozhraní API, budete upozorněni a požádáni o udělení povolení vašemu prohlížeči pro přístup k vaší poloze.

Vložte následující kód do $HOME/nearby-places-viewer/static/places.js

$( 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;
	}
});

Propojte vlastní JavaScript /static/places.js a jQuery ze souboru HTML: $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>

Krok 4: Odešlete data o poloze na server pomocí AJAXu

Tato aplikace používá metodu AJAX jQuery k odeslání údajů o poloze získaných v kroku 3 na server a POST bez obnovení stránky na trasu Python Flask / na $HOME/nearby-places-viewer/nearby.py.

Jako další krok přidáme volání AJAXu k funkci fetchPlaces v $HOME/nearby-places-viewer/static/places.js.

Poznámka: V tomto okamžiku, pokud se pokusíte spustit svou aplikaci, je pravděpodobné, že se v okně prohlížeče zobrazí chyba, protože jsme do trasy / nepřidali podporu pro zpracování požadavků POST.

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!"; 
		}
	});
}

Krok 5: Získejte místa v okolí přes MediaWiki Action API

Nejprve rozšiřte cestu Python Flask / na $HOME/nearby-places-viewer/nearby.py, aby zpracovávala požadavky POST. Můžete tak učinit přidáním GET i POST do seznamu argumentů methods v dekorátoru trasy. Dále můžete získat údaje o poloze dostupné ve formátu JSON z objektu request a předat je funkci fetch_places_nearby() k dalšímu zpracování.

@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')

Kód ve funkci fetch_places_nearby() odešle GET požadavek na Action API k vyhledání wiki stránek v blízkosti místa. Volání API se skládá z koncového bodu https://en.wikipedia.org/w/api.php a parametrů řetězce dotazu. Některé z klíčových parametrů jsou:

  • action=query hlavní modul pro dotazování informací
  • generator=geosearch submodul modulu dotazu list používaný jako zdrojový modul k získání výsledků vyhledávání pro sadu stránek
  • prop=coordinates|pageimages|description|info říká, které vlastnosti se mají pro stránky vrátit

Poznámka: Pro více informací o modulu geosearch navštivte stránku API:Geosynchronizace .

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

Prohlédněte si kompletní kód Python a Flask s příkazy importu a zpracovaným seznamem places. Tato aplikace používá balíček Haversine dostupný v Pythonu k výpočtu vzdálenosti mezi dvěma zeměpisnými souřadnicemi.

$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)

Krok 6: Vytvořte uživatelské rozhraní pro seznam míst z odpovědi JSONu

Zpracujte vrácená data JSONu ze serveru ve zpětném volání AJAXu success a použijte vlastnost HTML DOM innerHTML ke změně obsahu div.

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>";
	}
}

Zobrazte kompletní kód JavaScriptu pomocí zpětného volání AJAXu.

$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!"; }
		});
	}
});

Krok 7: Změny stylu pomocí Bootstrapu

Možná jste si všimli, že fragment kódu v kroku 6 používá názvy tříd Bootstrap. Ano, v tomto kroku integrujeme rámec Bootstrap, abychom do uživatelského rozhraní Places UI přidali responzivní návrh rozvržení. Abychom tak učinili, udělejme několik dalších úprav v souborech CSS a HTML.

Zobrazit kompletní CSS a HTML kód.

$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>
Snímek obrazovky ukázkové aplikace prohlížeče míst v okolí (2)

Další kroky

  • Přispějte ukázkovou aplikací, kterou jste vyvinuli pomocí MediaWiki API, do tohoto [$url úložiště ukázek kódu].

Související odkazy