【Day 13】 浅谈 OSM

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 应用我们留到明天再讲~


<<:  从零开始的8-bit迷宫探险【Level 20】搜集水晶可以召唤神龙吗?

>>:  DAY16-Style Components

[Day 30] 使用ChromeDriver来做单元测试(三)

同时开启多个浏览器 有时候可能需要多个浏览器来进行测试, 譬如说用多个浏览器来测试WebSocket...

D4 第二周 (回忆篇)

今天会是比较划水的回忆篇,可以斟酌看看。 这周开始正式学习 javascript,然後那时候疫情还没...

Day21 - 预览页加入按纽

今天状况不佳,稍微休息一下。 在Day02的时候有先粗略摆放预览页的几个按钮: 今天没什麽内容,就把...

【在 iOS 开发路上的大小事-Day11】透过 CocoaPods 来管理第三方套件

前情提要 一般在开发的时候,有些功能可能自己写不出来,但是网路上已经有别人写好的,那我们只需要将其引...

远端系列-3:如何更新远端数据库的档案?

角色情境 小华一边讲解、一边指导小明如何使用 GitHub 建立远端数据库。 小明认真地遵循小华的指...