4
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【備忘録】Yahoo!ローカルサーチAPIで牛丼チェーン店の位置情報を取得してdeck.glで表示してみました

Last updated at Posted at 2021-09-20

はじめに

  • Yahoo!ローカルサーチAPIで牛丼チェーン店の位置情報を取得してdeck.glで表示してみました。
  • Yahoo!ローカルサーチAPIでは「丼もの、牛丼、親子丼(業種コード:0101031)」で絞り込み、位置情報を取得しています。
  • 取得した牛丼チェーン店の位置情報はエクセル等で「すき家」「吉野家」「松屋」で抽出してdeck.glで表示しています。

アウトプットイメージ

前提条件

  • Yahoo!ローカルサーチAPIのアプリケーションIDが必要です。
  • 都道府県ごとに位置情報を取得して出力しているため、都道府県コードのリストが必要です。
  • 都道府県コードのリスト(PrefCode.csv)は以下のとおりとします(01:北海道~47:沖縄県)。
  • 今回は、業種コードが「0101031(丼もの、牛丼、親子丼)」を用いていますが、業種コードは変更可能です。
  • 業種コードはこちらで確認することができます。

image.png

python

localSearchAPI.py
import json
import socket
import urllib.error
import urllib.request
import csv

# Yahoo!ローカルサーチAPI

baseurl = 'https://map.yahooapis.jp/search/local/V1/localSearch'

# アプリケーションIDを指定
appid = 'Yahoo!ローカルサーチAPIのアプリケーションIDを入力してください'

# 都道府県コードのリストを作成する
PrefCodelist = []

# csvファイル(都道府県コードのリスト)の読み込み
with open('都道府県コードのリスト(PrefCode.csv)のパスを入力してください') as f:
    header = next(csv.reader(f))
    for row in csv.reader(f):
        s = row[0]
        PrefCodelist.append(s)

print(PrefCodelist)

# 都道府県コードのリストの数でループ
for PrefCode in PrefCodelist:
    # 出力csvファイルの指定
    output_csvfile = "出力フォルダのパスを入力してください" + "/" + PrefCode + ".csv"

    result = []
    i = 1
    total = 3102
    while i < total:
        params = {
            'appid': appid,
            'ac': str(PrefCode),    # 住所コード(都道府県コード)
            'gc': '0101031',        # 業種コード(丼もの、牛丼、親子丼)
            'output': 'json',
            'sort': 'score',
            'start': i,
            'results': 100
        }

        url = '{}?{}'.format(baseurl, urllib.parse.urlencode(params))
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=3) as res:
            data = res.read()
        # print(data)
        ydf = json.loads(data)
        # print(ydf)
        # Count(データ件数)取得
        Count = ydf['ResultInfo']['Count']
        # Countがゼロの場合、ループを抜ける
        if Count == 0:
            break
        features = ydf['Feature']
        for f in features:
            if f['Geometry']['Type'] == 'point':
                latlng = f['Geometry']['Coordinates'].split(',')
                poi = {
                    'uid': f['Property']['Uid'],                        # ユニークID
                    'name': f['Name'],                                  # 地域・拠点情報名
                    'address': f['Property']['Address'],                # 住所
                    'lat': latlng[1],                                   # 緯度
                    'lng': latlng[0]                                    # 経度
                }
            result.append(poi)
        i += 100

    # 出力ファイルオープン
    with open(output_csvfile, 'a', encoding='cp932') as f:
        # ヘッダー行出力
        fieldnames = ['i', 'uid', 'name', 'address', 'lat', 'lng']
        # writeオブジェクト作成
        csvfile_writer = csv.DictWriter(
            f, fieldnames=fieldnames, lineterminator='\n')
        csvfile_writer.writeheader()

        for j, poi in enumerate(result, 1):
            csvfile_writer.writerow({
                'i': j,
                'uid': poi['uid'],
                'name': poi['name'],
                'address': poi['address'],
                'lat': poi['lat'],
                'lng': poi['lng']
            })

print(u'処理終了')

deck.gl

  • 上記で取得した牛丼チェーン店の位置情報(csvファイル)をdeck.glで表示します。
  • Mapboxのアクセストークンが必要になります。
  • 牛丼チェーン店の位置情報(csvファイル)をdeck.glで表示するためにQGIS等でgeojson形式(yahoo_gc0101031_MergeFile.geojson)に変換しています。
  • また、国土数値情報の鉄道データ(令和元年)から鉄道路線のラインデータ(N02-19_RailroadSection.geojson)を読み込んでいます。

html

Yahoo_Gyudon_chain_store.html
<html>

<head>
  <title>牛丼チェーン店の立地状況(Yahoo!ローカルサーチAPI)</title>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/deck.gl@^7.0.0/dist.min.js"></script>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js"></script>
  <link rel="stylesheet" href="style.css" />
</head>

<body>
  <div id="tooltip"></div>
  <script src="script.js"></script>
</body>

</html>

CSS

style.css
html,body {
  font-family: Helvetica, Arial, sans-serif;
  width: 100vw;
  height: 100vh;
  margin: 0;
}
.deck-tooltip {
  font-family: Helvetica, Arial, sans-serif;
  padding: 6px !important;
  margin: 8px;
  max-width: 300px;
  font-size: 20px;
}

#control-panel {
  position: absolute;
  top: 0;
  left: 0;
  margin: 12px;
  padding: 20px;
  font-size: 12px;
  line-height: 1.5;
  z-index: 1;
  background: #fff;
  font-family: Helvetica, Arial, sans-serif;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
}

label {
  display: inline-block;
  width: 140px;
}

javascript

script.js
const deckgl = new deck.DeckGL({
  mapboxApiAccessToken: 'Mapboxのアクセストークンを入力してください',
  mapStyle: 'mapbox://styles/mapbox/dark-v9',
  // mapStyle: 'mapbox://styles/mapbox/streets-v9',
  initialViewState: {
    latitude: 35.1801494,
    longitude: 136.9034925,
    zoom: 5,
    maxZoom: 16
  },
  controller: true,
});

const railway = d3.json('data/N02-19_RailroadSection.geojson');
const yahoo = d3.json('data/yahoo_gc0101031_MergeFile.geojson');
const renderLayer = () => {

  const LINE_COLOR_SCALE = d3.scaleLinear()
    .domain([1, 2, 3])
    .range([
      [216, 25, 0],
      [0, 65, 33],
      [255, 217, 58]
    ]);

  const FILL_COLOR_SCALE = d3.scaleLinear()
    .domain([1, 2, 3])
    .range([
      [255, 204, 216],
      [216, 255, 204],
      [255, 255, 204]
    ]);

  const geoJsonLayer_1 = new deck.GeoJsonLayer({
    id: 'railway-geojson',
    data: railway,
    stroked: false,
    filled: false,
    lineWidthMinPixels: 1,
    parameters: {
      depthTest: false
    },
    opacity: 0.5,
    getLineColor: [240, 240, 240],
    getLineWidth: 1,
    pickable: false,
  });

  const geoJsonLayer_2 = new deck.GeoJsonLayer({
    id: 'yahoo-geojson',
    data: yahoo,
    lineWidthMinPixels: 2,
    pointRadiusUnits: 'meters',
    pointRadiusScale: 20,
    getRadius: 50,
    getLineColor: d => LINE_COLOR_SCALE(d.properties.flg),
    getFillColor: d => FILL_COLOR_SCALE(d.properties.flg),
    opacity: 0.5,
    pickable: true
  });

  deckgl.setProps({
    layers: [geoJsonLayer_2, geoJsonLayer_1],
    getTooltip: ({ object }) => object && `${object.properties.name}`
  });

}

renderLayer();

参考文献

4
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?