Google Maps API をローカル環境で使う際のAPIキーの利用制限について

Google Maps APIAPIキーを取得したらAPIキーの利用制限をする必要がある。制限をかけないと、他の人にAPIキーを自由に使われてしまい、無料の割り当て量がすぐに超えてしまう可能性があるからだ。

とりあえずローカル環境でAPIを使ってみようと思ったときに、どうやってAPIキーの利用制限をするか試行錯誤したのでまとめておく。

なお、OSはWindows10を使用。

ローカルのファイルパス(file:///)の登録

file:///__file_url__//と書き換えてURLを入れればOK。

やり方がわからず色々調べていたが公式ドキュメントに載っていた。

例えば、C:/Users以下のファイルを登録したい場合は下図のようにワイルドカードである「*」を使い__file_url__//C:/Users/*と書いて保存すればよい。

APIキーの制限にファイルパスを登録する場合

WEBサーバーのローカル環境(localhost)の登録

Apacheでwebサーバーを立ち上げた場合、http://localhost/*と入力すればOK。

APIキーの制限にローカルのwebサーバーのパスを登録する場合

APIを使ってみる

公式ドキュメントにのっているコードを使う。
取得したAPIキーはscript要素のYOUR_API_KEYのところに入れる。
マップの表示位置を変える場合は、initMap関数のlatとlongの数値を変えればよい(コードでは東京駅付近の緯度経度を設定)。

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: 35.681, lng: 139.765},
          zoom: 17
        });
      }
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
    async defer></script>
  </body>
</html>

無事ローカル環境でマップの表示ができました!

Google Maps APIを使ってマップを表示

GoogleマップのAPIを使うためにGoogle Cloud Platformに登録してみた

GoogleマップAPIを使ってみたいなと思い調べてみると、Google Cloud Platform (GCP) にクレカ情報を登録してAPIキーを取得しないといけないことが分かった。

そもそもAPIというものを使ったことがなく、GCP??という感じの全くの初心者だが、とりあえずGCPを使ってみることにした。

参考になったサイト

nendeb.com

基本的に上記のサイトをの通りに進めていったらAPIキーの取得までできた。

 

悩んだ点

上記サイトの「APIと認証情報の設定方法」という項目で「Maps JavaScript API」を有効にして新しいAPIキーを作成しているが、サイトの手順通り最初からやっていると「Maps JavaScript API」はすでに有効になっているし、そもそもAPIキーはすでにできている。そして他の(16個?)のAPIも有効になっており、これはちゃんと設定できているのか??と不安になった。

しばし考えたが、別に最初に作られたAPIキーをそのまま使って問題ないと思われる。とりあえずサイトに合わせて「Maps JavaScript API」以外に有効になっていたAPIをすべて無効にしたが、別に無効にしなくてもよさそう。認証の「アプリケーションの制限」のところで使うAPIを選べばよいと思われる。

そして「アプリケーションの制限」の「HTTPリファラー」のところは結構悩んだ。これは別記事に書こうと思う。

とりあえず、GCPに登録してAPIキーを取得という目標を達成したので良かった。

 

 

 

ラズベリーパイ3でサーボモーターSG90を使ってみた

リーズナブルでよく使われていそうな「SG90」というサーボを買ってラズパイで動かしてみた。
標準入力で角度を指定すると、サーボがその角度動くようにしてみた。
割とすんなり動いて感動しました。

デジタル・マイクロサーボ SG90 (5個)

デジタル・マイクロサーボ SG90 (5個)

SG90とラズパイの配線

ラズベリーパイ3とSG90の配線

上図のように配線した。サーボ制御用のPWM出力のピンをBCMの17番にしている。

ラズパイのGPIOからサーボを直接駆動させるとラズパイに良くないみたいな記事があった気がする。理由は理解できていないが、モータードライバを介してサーボを動かした方がよいかもしれない。(本プログラムでサーボは動くが、動かすとガタガタする。)

サーボの角度制御

SG90のデータシート

秋月にのっていたSG90のデータシートより引用

SG90のデータシートによると、50HzのPWM信号に設定した場合、デューティー比とサーボの角度の関係は、

  • 0.5ms (デューティー比1%)   ⇒ -90°
  • 1.45 ms (デューティー比2.9%)  ⇒ 0°
  • 2.4 ms (デューティー比4.8%)  ⇒ 90°

のようになっている。

デューティー比とサーボの角度は比例関係なので、動かしたいサーボの角度をX[deg]とすると、それに対応するデューティーサイクルY[ms]は以下の式で求まる。

Y = (12-2.5)/180*(X + 90) + 2.5

ラズパイにこの値を渡せば、サーボを動かすことができる。

サーボを動かすプログラム

標準入力でサーボの角度を指定して、サーボを動かせるようにしてみた。while文を使い、繰り返しサーボを動かせるようになっている。endを入力すればサーボは止まる。

動かすと少しガタガタするが、指定した通りの角度にサーボが動く。
次はモータードライバを使って動かしてみたい。

import time
import RPi.GPIO as GPIO
import sys  # 引数取得

# pin number
PIN_servo = 17   # for servo

GPIO.setmode(GPIO.BCM)      # GPIOへアクセスする番号をBCM番号で指定することを宣言
GPIO.setup(PIN_servo, GPIO.OUT)     # 出力ピンに設定

# servo setup
servo = GPIO.PWM(PIN_servo, 50)
servo.start(0)

# サーボの角度を初期化(0degにする、とりあえず)
time.sleep(0.5)
servo.ChangeDutyCycle(7.25)
time.sleep(0.5)

# servo -90deg <= x <= 90deg
# -90deg -> 0.5ms, 90deg -> 2.4ms (from spec. sheet)

# whileで繰り返し処理
while True:
    # 標準入力によりサーボの角度を指定
    print('サーボの角度(-90~90deg)を指定してください。endを入力すると止まります。')
    input_num = input('>')

    if input_num != 'end':
        # サーボを動かす
        move_servo_msec = (12-2.5)/180*(int(input_num) + 90) + 2.5 
        servo.ChangeDutyCycle(move_servo_msec)
        time.sleep(0.5)
    else:
        break

# while文抜けたらサーボストップ
servo.stop()
GPIO.cleanup()

写真データのメタデータ Exifについてのメモ

写真に入っているGPS情報を抽出したいなあと思いExifについて調べたのでメモっておく。

Exif (Exchangenable image file format) とは

Wikipediaによると以下の通り。

富士フイルムが開発し、当時の日本電子工業振興協会 (JEIDA)で規格化された、写真用のメタデータを含む画像ファイルフォーマット。デジタルカメラの画像の保存に使われる。

 デジタルなカメラで撮影したデータには、そのデータの属性情報が色々含まれるということ。

これもWikipediaに載っていたものだが、例えば、

「撮影日時・メーカー名・画像の解像度・撮影方向・シャッター速度・F値ISO感度焦点距離GPS情報・サムネイル(160x120)」

など色々な情報が記録される。

 

PythonExifに含まれるデータを取得するには

今後pythonでデータ抽出してみようかなと思っていたので調べてみた。

まだ試していないが、画像処理ライブラリのPillow (PIL)を使えば比較的簡単にできそう。

以下参考サイト

 

その他Exifを確認する方法(Windowsを対象)

お手軽な方法

写真データを右クリックして、「詳細」タブ内にExifデータがある。Exifデータの削除もできる。

 

ソフトウェア(Exiftool)を使用

色々なフリーソフトがあるが、「ExifTool」は使いやすく、おそらくExifの全情報を表示してくれる。

作者のサイト(ExifTool by Phil Harvey)からファイル一式をダウンロードして、exeファイルに写真ファイルをドラッグ&ドロップすると、その写真データのExifデータ一覧が画面に表示される。便利である。

 

WEBアプリケーションを利用

試していないが、「Exif確認君」(http://exif-check.org/)、「Exifチェッカー」(https://lab.syncer.jp/Tool/Exif-Checker/)など色々ある。

 

とりあえず、以上の方法でExif内の情報を調べることができそう。
WEBアプリはどういう仕組でできているのか気になるところ。面白そうだ。

 

ブロックチェーンのマイニング模擬実験

Interface8月号のブロックチェーン特集をちょこちょこ読んでいる。

その中のマイニングの体験が面白かったのでメモしておく。

マイニング

マイニングとは、ブロックチェーン上に新規ブロックを作成するための作業。

実際何をやっているかというと暗号学的ハッシュ関数を用いてハッシュ値を計算している。
ハッシュ値の入力は、前のブロックのハッシュ値と未承認の取引履歴のハッシュ値、そしてナンスと呼ばれる32ビットの数値の3つ。
新規ブロック生成の条件は、そのブロックのハッシュ値がある値以下(例えば0が16個並ぶ)となるようなブロック。

マイニング実施者(マイナー)は、ある数以下のハッシュ値(例えば0が16個並ぶ値)を見つけるため、ナンスをランダムに変化させてひたすらハッシュ値を計算する。
条件を満たすナンスを発見できたらマイニング成功となり、マイナーはマイニング報酬を得ることができる。

Pythonによるマイニングの体験

ナンス値を変えてある値以下(先頭文字に0が複数並ぶ)のハッシュ値を見つける。
コードはInterface8月号のコードを一部改変し使用している(ほぼ引用)。

なお、python3.7.1を使用した。

まずは、先頭4文字が0になるハッシュ値を見つけてみる。

import random
import hashlib
import re

transaction_1 = "A -> B 1BTC"

def text2hash(mynonce):
    hash_object = hashlib.sha256(transaction1.encode() + str(mynonce).encode())
    chk = re.match('0000', hash_object.hexdigest())
    if chk != None:
        print("Nonce: " + str(nonce))
        print("HASH: " + hash_object.hexdigest())
        print("=================================")

max_nonce = 10**7
extract_nonce_num = 10**6 

nonce_list = random.sample(list(range(0, max_nonce)), k=extract_nonce_num)
for nonce in nonce_list:
    text2hash(nonce)

実行すると以下のような結果になった。すぐ計算結果がでた(1秒もまってない)。

結果を見るとたしかにハッシュ値の先頭4文字が0になっている。
ハッシュ値全体からすると、先頭4文字が0になる確率は16^60/16^64 = 1/16^4 = 1/65536だから大体0.0015%くらい。
今回、100万個のナンスから12個の条件を満たすナンスを見つけたから確率は12/10^6で、大体0.0012%くらいなので整合的かな。

Nonce: 6487403
HASH: 00006660c4c89abf1cc9654dff2a5ffac1ed65e7f0d9d43d008924a5d775f6f5
=================================
Nonce: 8845617
HASH: 00005943b43aa3f90987d07d6d6755af11ed20e4096ad5ed30ba466653f8aff1
=================================
Nonce: 8949731
HASH: 000015497ca43abb7e07322361be25955e83dac3f60014a0d253800513ae7092
=================================
Nonce: 7875493
HASH: 0000109c55bb3ae22deba78eccc3fe7ae5e259f2f3f47f407d35ae00a530ef79
=================================
Nonce: 6319689
HASH: 000023b6c8e4f9925c28bb749b7e2b07850471f852e1dfa76615abe0c57a763c
=================================
Nonce: 1908741
HASH: 00002634d326f64212aaf6f15b2ea60fd69a0d6c1ef4c8f8c2f3b596f5b83bd5
=================================
Nonce: 1739868
HASH: 0000bd16e990309b203ad6b620e2f59c75747d2fc91a7a6e8d52e958ae02c275
=================================
Nonce: 1579836
HASH: 00009958c87100b48c79e8be3602a5ba94150c5454ad3a9a1b43ce75081fa581
=================================
Nonce: 3768602
HASH: 00005cddc0bac1e2d6c3825bef4a4edc2c0901531d4039822857583bf3cbbbe7
=================================
Nonce: 7397948
HASH: 0000cc416e9872b5af5b45bbf94ba1dbaec984b5f80b7ee86c1268d7ab77dcf3
=================================
Nonce: 2561779
HASH: 0000c4137ca7636f9475069585f170271a899de1c55f20c56507f8d597403b0f
=================================
Nonce: 8532683
HASH: 000076388f9767d973ce8090bb3de94759c73f93743d880adbe096573bb3375a
=================================

次に、先頭5文字が0になるナンスを見つけてみる。

コード内のtext2hash関数内のパラメータchkの値を変えて実行する。

何回か実行すると、条件を満たすナンスが下記のように1件発見できたり、できなかったりする。大体0~2個くらいの発見数。

先頭文字の0を一つ増やすと条件を満たすナンスを見つける確率は16分の1に減るので、先程の結果(発見したナンスの個数:12)と比べるとまあ整合的かと思われる。

Nonce: 4196833
HASH: 000002e0c4d4158f51626be52ea8a53da9bc55cba1a272cfc9509b2548b1889e
=================================

ビットコインでのマイング

ビットコインでは先頭文字が16個(難易度によって増減するが)の0になるハッシュ値を見つけなければならない。
条件を満たすナンスを見つける確率はめちゃくちゃ低い。確率は、1/16^16。約0.00000000000000001% (10^-17 %)

マイニングは大変ってことがよく分かった。勉強になりました。

Surface Laptop 2 買ったが、キーボードの革のにおいが気になる

ヨドバシでsurface laptop 2見てたらかっけーなあと思いそのまま買ってしまった。

Surface Laptop 2 ブラック Core i5 8GBメモリ 256GB SSD で16万弱。

f:id:hhgingisland:20181024172411j:plain

黒かっこいい。

f:id:hhgingisland:20181024172427j:plain

f:id:hhgingisland:20181024172440j:plain

 めちゃかっこよくて画面もきれいでキーボードも打ちやすくて良いんだけど、キーボード周り(パームレスト)がアルカンターラとかいう革みたいな素材で覆われていて、そのにおいがキツくて結構気になる。

いわゆる新車のにおい。

今の所使ってから二日経っているがまだくさくて気になる。やばい。

新車の革のにおいが苦手でにおいに敏感な人は注意した方がいいと思う。
店でよく嗅いでから購入することをおすすめする。

それ以外は良いんだけどなあ。

 

Anacondaでpythonの仮想環境作成

Anacondaを使いpythonの仮想環境を作成する際に使用したコマンドをメモしておく。 今まで仮想環境について何もわかっていなかったが、便利なものということを理解した。

仮想環境を作るメリット

バージョンの異なるpythonやライブラリの組み合わせ環境を複数作成できること。 プロジェクトごとに仮想環境を作ることで、バージョンの違いによるエラーなどを避けることができる。

conda コマンド

基本的にAnaconda prompt上でcondaコマンドを打って作成する。windows付属のコマンドプロンプトを用いて作成する際は環境変数PATHにAnacondaのパスを通す必要がある。

なお、Anaconda Navigatorを使えばGUIで仮想環境を作成できる。

仮想環境の作成

conda create -n py36 python=3.6

-nの後に環境名を入れる(py36)。その後にソフトやライブラリのバージョンを記載する(python=3.6)。

仮想環境の確認

conda info -e

作成した仮想環境の一覧が表示。現在アクティブになっている環境に「*」がつく。

仮想環境のActivate

conda activate py36

仮想環境名(py36)を指定する。

現在の仮想環境のDeactivate

conda deactivate

root(base)環境に戻る。

仮想環境の削除

conda remove -n py36 -all