python:LINEの位置情報であれこれ
今回は、メモ書きみたいな形ですが、LINE MessengerAPIで位置情報を受け取って、その位置情報で最寄り駅を算出したり、色々してみます。
主に上記の記事をかみ砕いた内容です。
おおまなかな流れは以下
①LINEで現在位置情報を受け取る
②現在位置情報をSIMPLE API キーで抽出
③最寄り駅の情報をGoogle Place キーで取得
④現在地と最寄り駅との情報をGoogle Directionキーで取得
⑤マップをGoogle Staticmapsキーで取得
ライブラリ関連
import sys
import os
from flask import Flask, request, abort, send_file
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import (
MessageEvent, TextMessage, LocationMessage, LocationSendMessage,TextSendMessage, StickerSendMessage, MessageImagemapAction, ImagemapArea, ImagemapSendMessage, BaseSize
)
from io import BytesIO, StringIO
from PIL import Image
import requests
import urllib.parse
import xml.etree.ElementTree as ET
flaskの設定
app = Flask(__name__)
LINEAPIの設定
line_bot_api = LineBotApi('CHANNEL ACCESS TOKENを記載')
handler = WebhookHandler('CHANNEL SECRET KEYを記載')
イメージマップの生成
@app.route("/imagemap/<path:url>/<size>")
def imagemap(url, size):
map_image_url = urllib.parse.unquote(url)
response = requests.get(map_image_url)
img = Image.open(BytesIO(response.content))
img_resize = img.resize((int(size), int(size)))
byte_io = BytesIO()
img_resize.save(byte_io, 'PNG')
byte_io.seek(0)
return send_file(byte_io, mimetype='image/png')
@app.route("/imagemap/<path:url>/<size>")
上記は、path型に変換されたurl変数とsize変数で構成されるURLを示す
urllib.parse.unquote()
上記でURLをデコードする。デコードとはURL内に日本語がある暗号みたいな文字に自動変換されてしまうことであるが、それをもとの日本語の状態に戻すこと。
img = Image.open(BytesIO(response.content))
通常、http経由で画像urlを取得するとバイナリデータで取得されてしまうが、Pillowで読み込むためのコード
byte_io = BytesIO()
img_resize.save(byte_io, 'PNG')
byte_io.seek(0)
空のバイナリファイルを作成し、PNGで保存。一番前までseekで戻る。
return send_file(byte_io, mimetype='image/png')
MIMEタイプとは「タイプ名/サブタイプ名」の形式の文字列で、WEBサーバーとWEBブラウザの間はこのMIMEタイプを用いてデータの形式を指定しています。ファイルの種類を表す情報。
SIMPLE APIで現在地の情報を取得
import urllib.parse
import xml.etree.ElementTree as ET
lat = 34.488677
lon = 135.742735
url = 'http://map.simpleapi.net/stationapi?x={}&y={}&output=xml'.format(lon, lat)
req = urllib.request.Request(url)
with urllib.request.urlopen(req) as response:
xml = response.read()
data = ET.fromstring(xml)
station_list = data.findall(".//name")
walk_list = data.findall(".//traveltime")
#出力結果確認
for i in station_list:
n = urllib.parse.unquote_plus(i.text)
print(n)
print("-----")
for ii in walk_list:
m = urllib.parse.unquote_plus(ii.text)
print(m)
lat,lonの変数の箇所は、テストで絶対値を入力してる状態ですが、通常であれば、下記のように記載しておく。
lat = event.message.latitude
lon = event.message.longitude
Google Place APIキーで最寄り駅を抽出
geo_url = 'https://maps.googleapis.com/maps/api/place/textsearch/xml?query={}&key={}'.format(urllib.parse.quote_plus(station_list[0].text, encoding='utf-8'), "google place api keyを入力する")
geo_req = urllib.request.Request(geo_url)
with urllib.request.urlopen(geo_req) as response:
geo_xml = response.read()
geo_data = ET.fromstring(geo_xml)
geo_name = geo_data.findtext(".//name")
geo_address = geo_data.findtext(".//formatted_address")
geo_lat = geo_data.findtext(".//lat")
geo_lon = geo_data.findtext(".//lng")
SIMPLE APIキーで最寄り駅を抽出し、その最寄り駅の情報をGoogle Place APIキーで抽出していきます。
Google Direction APIキーで現在地と最寄り駅との情報を抽出
direction_url = 'https://maps.googleapis.com/maps/api/directions/xml?origin={},{}&destination={},{}&mode=walking&key={}'.format(lat, lon, geo_lat, geo_lon, "direction api キーを入力");
direction_req = urllib.request.Request(direction_url)
with urllib.request.urlopen(direction_req) as response:
direction_xml = response.read()
direction_data = ET.fromstring(direction_xml)
direction_time_second = int(direction_data.findtext(".//leg/duration/value"))
direction_distance_meter = int(direction_data.findtext(".//leg/distance/value"))
direction_time_min = direction_time_second//60
direction_distance_kilo = direction_distance_meter//1000 + ((near_station_direction_distance_meter//100)%10)*0.1
google direction apiでLINEで受け取った緯度、経度と最寄り駅の緯度、経度の距離や徒歩時間を抽出します。
Google Staticmaps APIキーでマップを作成
map_image_url = 'https://maps.googleapis.com/maps/api/staticmap?size=520x520&scale=2&maptype=roadmap&key={}'.format(google_staticmaps_api_key);
map_image_url += '&markers=color:{}|label:{}|{},{}'.format('red', '', geo_lat, geo_lon)
map_image_url += '&markers=color:{}|label:{}|{},{}'.format('blue', '', lat, lon)
google staticmaps apiで地図を表示させます。
&markers=color:{}|label:{}|{},{}'.format('red', '', geo_lat, geo_lon)
上記は最寄り駅を赤マーカーで印。
map_image_url += '&markers=color:{}|label:{}|{},{}'.format('blue', '', lat, lon)
上記はLINEの位置情報で受け取った場所を青マーカーで印
その他
event.message.latitudeやlongitude等を使用してきましたが、event.typeは下記のURLで確認ができます。
chr(0x10002D)で絵文字を使うことができる。
TextSendMessage(text='お疲れ様です'+ chr(0x10002D)),
上記で位置情報画面を開くことができる。
TextSendMessage(text='line://nv/location')
過去記事
この記事が気に入ったらサポートをしてみませんか?