iT邦幫忙

2021 iThome 鐵人賽

DAY 13
6

Open Street Map

開放街圖,OpenStreetMap,簡稱 OSM,我們把它當成一個地圖版的維基百科
是由世界各地多名註冊使用者協同維護網站。

開放街圖 wiki

那為甚麼我們要講到這個嗎?

有時候我們 Line chatbot 的應用除了爬蟲,還有爬地圖。
但是如果使用 Google API 的話,一個不小心可能就要付錢了。(怕.jpg)

所以我們可以傳送位址訊息給 Line API 來定位,或是搜尋附近的東西。

OpenStreetMap Search

標記出固定區域內的同類型行業

Folium

Folium 是基於 leaflet.js 的 python 地圖視覺化工具套件。

可以在 jupyter 直接顯示或是輸出成 HTML。

Folium 內建許多 Open Source 的 Map:OpenStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox 和 Stamen。而且支援使用 Mapbox 或 Cloudmade 的 API 金鑰来制定客制化的地圖元件。

由於使用 Google Map API 免費版有使用次數上的限制,也就是會記錄透過金鑰去 request API 的次數。故此專案使用完全開源的地圖 OpenStreetMap (OSM)。

Install Folium

Anaconda 安裝

pip install folium

或是

conda install -c conda-forge folium

type: location

我們來看看我們的 location message

{
    "type": "location",
    "title": "my location",
    "address": "1-6-1 Yotsuya, Shinjuku-ku, Tokyo, 160-0004, Japan", 
    "latitude": 35.687574,
    "longitude": 139.72922
}

latitude: 緯度
longitude: 經度

我們可以用這種方式回送一個地址到 Chat room,也可以透過傳送定位來接收經緯度。

例如說我們這樣:

from django.shortcuts import render

# Create your views here.

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings

from linebot import LineBotApi, WebhookParser
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import *
import os

line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN)
parser = WebhookParser(settings.LINE_CHANNEL_SECRET)

@csrf_exempt
def callback(request):
    if request.method == 'POST':
        signature = request.META['HTTP_X_LINE_SIGNATURE']
        body = request.body.decode('utf-8')

        try:
            events = parser.parse(body, signature)  # 傳入的事件
        except InvalidSignatureError:
            return HttpResponseForbidden()
        except LineBotApiError:
            return HttpResponseBadRequest()

        for event in events:
            print("event", event.message.id)
            # print("event", type(event))
            if isinstance(event, MessageEvent):  # 如果有訊息事件
                print("message", event.message)
                message = []

                if event.message.type == 'location':
                    print(event)
                    location = "latitude = {}\nlongitude = {}".format(event.message.latitude, event.message.longitude)
                    message.append(TextSendMessage(text=location))


                line_bot_api.reply_message(event.reply_token, message)

        return HttpResponse()
    else:
        return HttpResponseBadRequest()

我們在 if event.message.type == 'location': 就判定傳過的 object type 為何?如果是 location,那就顯示出當下的經緯度,也可以透過 event.message.address 印出地址。

Documentation

Folium Documentation


那剩下的 OSM 應用我們留到明天再講~


上一篇
【Day 12】Rich Menu 主選單
下一篇
【Day 14】OSM 淺談 part 2
系列文
陪聊_伃時不候 Line Bot 聊天機器人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
周藍
iT邦新手 5 級 ‧ 2021-11-04 14:01:29

你好,可以請問OpenStreetMap API是否也有次數限制嗎?

tyc97-sys iT邦新手 5 級 ‧ 2021-11-06 11:25:16 檢舉

OpenStreetMap 是純開源的 沒有次數限制

周藍 iT邦新手 5 級 ‧ 2021-11-11 08:46:30 檢舉

好的,感謝回覆/images/emoticon/emoticon07.gif

我要留言

立即登入留言