kakakakakku blog

Weekly Tech Blog: Keep on Learning!

位置情報や地図を仕事で使う前のキャッチアップに最適な「現場のプロがわかりやすく教える位置情報エンジニア養成講座」を読んだ

「現場のプロがわかりやすく教える位置情報エンジニア養成講座」を読んだ📕

今まで GIS: Geographic Information System など位置情報を取り扱うための技術的な知識や経験がなく,地図アプリケーションを使うと「便利だな〜w」という感想しか出てこないようなレベルだった💨

本書を読んで,そして本書の後半では実際にアプリケーションを写経しながら実装したことによって,位置情報を取り扱うための最低限の知識と開発の流れを把握できるようになった❗️本書の冒頭には「これから位置情報を扱うエンジニア」が読者層だと書いてあったけど,まさにその通りだと思った.位置情報や地図を仕事で使う前のキャッチアップに最適な一冊だった🗾

さらに OpenStreetMap / 国土数値情報 / 地理院タイルなど,地図関連の公開データ(ライセンスには注意)が多くあることも今までは全然知らなかった.

www.openstreetmap.org

nlftp.mlit.go.jp

maps.gsi.go.jp

目次

どの章も良かったけど,特に「第2章」で位置情報の知識を整理できたことと「第5章」でアプリケーションを一歩一歩動かしながら実装できたところが良かった👌

  • 第1章: 位置情報の世界
    • 1-1 位置情報とは
    • 1-2 位置情報アプリケーション
    • 1-3 位置情報アプリケーションの特徴
    • 1-4 自由に使える位置情報データ
  • 第2章: 位置情報の基本
    • 2-1 位置を表す方法:経緯度
    • 2-2 丸い地球をどう地図にするか:地図投影法
    • 2-3 位置情報のデータ形式
    • 2-4 位置情報のファイル形式
    • 2-5 位置情報の配信方法
    • 2-6 サーバーレスの潮流:Cloud Optimized
  • 第3章: 位置情報データの取得・加工
    • 3-1 QGISとは
    • 3-2 QGISのダウンロードとインストール
    • 3-3 位置情報データの取得
    • 3-4 位置情報データの表示
    • 3-5 位置情報データの加工:ベクトルデータ編
    • 3-6 位置情報データの加工:ラスターデータ編 
  • 第4章: 位置情報アプリケーション開発:入門編
    • 4-1 位置情報ライブラリの紹介
    • 4-2 テーマ別ハンズオン
    • 4-3 その他の位置情報技術
  • 第5章: 位置情報アプリケーション開発:実践編
    • 5-1 入門編との違い
    • 5-2 実践編Part1:「防災マップ」を作成する
    • 5-3 実践編Part2:スマートフォンで利用できるようにする

目次の詳細は出版社サイトを見てもらえればと!

www.shuwasystem.co.jp

実装したアプリケーション

「第4章」では Leaflet を使って,多くの地図表現を実装しながら学ぶ.そして「第5章」では MapLibre GL JS を使って,地図アプリケーション(防災マップ)を実装する.以下のような特徴がある👏

  • 背景の地図は OpenStreetMap のデータを使う
  • ハザードマップ(洪水浸水想定区域・津波浸水想定区域など)は「ハザードマップポータルサイト」のデータを使う
  • 指定緊急避難場所は「国土地理院」のデータを使う
  • etc

今回はできる限り写経しながら進めつつ,コピペで十分なところは本書のコードが公開されている GitHub リポジトリを参考にした.

github.com

そして実際にデプロイしたアプリケーション(一部)のキャプチャを紹介する❗️

防災マップ: 初期表示

防災マップ: 津波浸水想定区域と津波の指定緊急避難場所

防災マップ: 3D 表示

防災マップ: 指定緊急避難所の詳細情報など

本書のデモサイトも GitHub Pages にデプロイされていて実際に試せる👌ちなみに僕は GitHub Pages ではなく Vercel にデプロイして動作確認をしていた.

ちなみにキャプチャを載せたアプリケーションは完成後に復習も兼ねて Mapbox Controls の inspect と zoom を追加で導入してるので,右下のボタンは少しカスタマイズしてある💡

github.com

その他メモ

誤植

読みながら気付いたところをメモしておく📕

  • P.195: 開発実践編朱>開発実践編
  • P.233: 5-2-6 が2個ある

まとめ

「現場のプロがわかりやすく教える位置情報エンジニア養成講座」を読んだ📕

GIS: Geographic Information System や位置情報に関する知識がなかった僕にとってはとてもおもしろく勉強になる一冊だった.ユーザーとしては日々地図アプリケーションを使う機会があるため,今後は「どういう技術を使っているのかな〜」という目線で考えながら使ってみたいと思う.本当に読んで写経して良かった❗️

ちなみに本書には出てこなかったけど,AWS 関連で調べていたら Registry of Open Data on AWS に地理空間データが公開されていたり,事例もあったりして,今後はこのあたりの領域もウォッチしよう〜 \( 'ω')/

registry.opendata.aws

aws.amazon.com

Habitify API で習慣データを取得しよう

2024年から Habitify で個人的な習慣化の管理をしていて,もうとにかく便利で毎日の習慣化を支えてもらっている❗️朝活・読書・サプリメントなどを記録しつつ,Habitify のチャレンジ機能を使って毎日プランクを続けていたりもする💪Habitify は無料でも十分使えるけど,僕は Premium に課金して使っている〜 \( 'ω')/

www.habitify.me

実は Habitify を使うまでは数年間 Google Sheets で習慣化の管理をしていて,例えば朝活を例にすると「その日に取り組んだこと」を必ず記録していた.Habitify にも「習慣メモ」という機能があって記録はしてるけど,振り返りのために定期的に集計したく,今回は Habitify API を試してみた❗️API ドキュメントには以下にある.

docs.habitify.me

準備

まず Habitify API の API Key を取得する.ドキュメントにはウェブとアプリで取得できると書いてあったけど,現時点だとウェブでは取得できなさそうだった.Habitify をウェブで使うことはほとんどなく,普段使っているアプリ (Android) から API Key を取得した.

API: 習慣を取得する

/habits API (GET) で習慣化の一覧を取得できる👌(id は省略)今は4種類の習慣を登録している.ちなみにチャレンジ機能のデータは Habitify API では取得できなさそうだった.

$ curl -s -H "Authorization: ${API_KEY}" \
    https://api.habitify.me/habits | jq -r '.data[] | {id, name, goal: {periodicity: .goal.periodicity}}'
{
  "id": "wwwwwwwwwwwwwwwwwwww",
  "name": "ビタミンを摂る",
  "goal": {
    "periodicity": "daily"
  }
}
{
  "id": "xxxxxxxxxxxxxxxxxxxx",
  "name": "朝活をする",
  "goal": {
    "periodicity": "daily"
  }
}
{
  "id": "yyyyyyyyyyyyyyyyyyyy",
  "name": "1週間を振り返る",
  "goal": {
    "periodicity": "weekly"
  }
}
{
  "id": "zzzzzzzzzzzzzzzzzzzz",
  "name": "本を読む",
  "goal": {
    "periodicity": "daily"
  }
}

docs.habitify.me

API: 習慣メモを取得する

/notes API (GET) で習慣メモを取得できる👌パスパラメータには /habits API (GET) で取得した habit_id を設定する.クエリパラメータには Date Formatfromto を設定する.ただし普通にクエリパラメータを設定すると Only accept the format of from is YYYY-MM-DDThh:mm:ss±hh:mm というエラーになってしまうため,URL エンコードを忘れずに❗️

習慣メモを取得できるのは特に嬉しくて,今日までだと以下のような結果(数値は合計日数)だった.Start building with Next.js に取り組んだり,現場のプロがわかりやすく教える位置情報エンジニア養成講座を読み進めている結果を確認できた👏

$ curl -s --get -H "Authorization: ${API_KEY}" \
    --data-urlencode "from=2024-01-01T00:00:00+09:00" \
    --data-urlencode "to=2024-02-14T23:59:59+09:00" \
     https://api.habitify.me/notes/xxxxxxxxxxxxxxxxxxxx | jq -r '.data[].content' | sort | uniq -c | sort --reverse
  17 Start building with Next.js
  15 位置情報エンジニア養成講座
   8 Bedrock ワークショップ
   2 amazon-s3-multipart-upload-transfer-acceleration
   1 Hasura Tutorial PostgreSQL
   1 CDK x EventBridge Pipes
   1 Bedrock デジタルトレーニング

docs.habitify.me

まとめ

Habitify API の基本的なリソース HabitsNotes の取得を試してみた❗️個人的には習慣メモを取得できるのは助かる👌他にも実装されてる API はあるけど,取得できるデータが微妙に不足してたり,開発が止まってるように見えるのはちょっと気になる😨例えば習慣の「連続記録」などは API では取得できなかったりする💨

docs.habitify.me

今後も Habitify を毎日使っていくぞー \( 'ω')/

GitHub Actions から AWS CodeBuild のビルドを実行できる「aws-actions/aws-codebuild-run-build」

AWS CodeBuild Run Build for GitHub Actions (aws-actions/aws-codebuild-run-build) を使うと GitHub Actions から AWS CodeBuild のビルドを実行できる👌

github.com

シンプルに AWS CodeBuild のビルドを実行するだけなら project-name パラメータを指定すれば良くて簡単〜 \( 'ω')/

name: Start AWS CodeBuild build

on:
  workflow_dispatch:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1
      - name: Start AWS CodeBuild build
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: sandbox

ちなみに GitHub Actions で AWS アカウントの権限を取得する仕組みは以下の記事にまとめてある!

kakakakakku.hatenablog.com

もし GitHub リポジトリをモノリポ構成(例えば Yarn Workspaces など)で運用していて,アプリケーションごとに AWS CodeBuild を作らず共有するという選択肢もあると思う.

buildspec-override パラメータに packgages/app1/buildspec.yml などアプリケーションごとの buildspec.yml を設定すれば OK👌 さらにアプリケーションごとにビルド環境に必要なスペックが異なる場合は compute-type-override パラメータで BUILD_GENERAL1_SMALLBUILD_GENERAL1_MEDIUM などの環境タイプを設定すれば OK👌柔軟に AWS CodeBuild のビルドを実行できて便利❗️

docs.aws.amazon.com

name: Start AWS CodeBuild build

on:
  workflow_dispatch:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1
      - name: Start AWS CodeBuild build / app1
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: sandbox
          buildspec-override: packgages/app1/buildspec.yml
      - name: Start AWS CodeBuild build / app2
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: sandbox
          buildspec-override: packgages/app2/buildspec.yml
      - name: Start AWS CodeBuild build / app3
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: sandbox
          buildspec-override: packgages/app3/buildspec.yml
          compute-type-override: BUILD_GENERAL1_MEDIUM

Dependabot で AWS CDK を自動的にアップデートしよう

Dependabot version updates を使うと package.json に指定しているパッケージのアップデートを自動化できる❗️設定は比較的簡単で package-ecosystemnpm を設定して,あとは必須の directoryschedule.interval でアップデートの対象ディレクトリとスケジュールを決めれば OK👌個人的な AWS CDK 検証用プライベートリポジトリに設定して数週間試してみた \( 'ω')/

docs.github.com

ちなみに以下の AWS CDK ドキュメントでは Dependabotnpm-check-updates が紹介されていた.他には reviewdog を使うという選択肢もあると思う🐶

docs.aws.amazon.com

🤖 .github/dependabot.yml

version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: daily
    open-pull-requests-limit: 2
    target-branch: master
    groups:
      aws-cdk-dependencies:
        patterns:
          - aws-cdk
          - aws-cdk-lib
        update-types:
          - minor
          - patch
    ignore:
      - dependency-name: "*"
        update-types: ["version-update:semver-major"]

ちなみに aws-cdk と aws-cdk-lib に関しては同じプルリクエストにまとめるために groups を設定している👌 groups は2023年8月にリリースされている❗️

github.blog

動作確認

AWS CDK の aws-cdkaws-cdk-lib を自動的にアップデートするプルリクエストが作れたー👏

Python の独自パッケージを作って AWS CodeArtifact で管理する

開発チームで共通的に使うコードを独自ライブラリ(パッケージ)にして管理したい場面はあると思う.今回 AWS CodeArtifact で管理する流れを試す❗AWS CodeArtifact は npm / pip / Maven など複数のパッケージマネージャーをサポートしているけど,今回は pip (Python) を前提にする.

aws.amazon.com

AWS CodeArtifact と AWS CDK

AWS CodeArtifact には大きく「ドメイン」「リポジトリ」という概念がある.詳しくは以下のドキュメントにまとまっている👌

docs.aws.amazon.com

AWS CDK で AWS CodeArtifact を設定する場合,AWS CloudFormation に沿った L1 ConstructCfnDomainCfnRepository を使う.設定次第ではあるけど,特に難しいところはないかなーと思う.

docs.aws.amazon.com

docs.aws.amazon.com

👾 sandbox-cdk-codeartifact-stack.ts

今回は AWS CodeArtifact に kakakakakku ドメインと sandbox-cdk-repository リポジトリを設定する.リポジトリにアップストリームリポジトリとして pypi-store (Python Packaging Authority) を設定すると外部のパブリックリポジトリとして透過的にパッケージを扱えるようになる.今回はプライベートなパッケージのみを AWS CodeArtifact で管理する形を試したく,アップストリームリポジトリは設定しなかった.

import {
  Stack,
  StackProps,
  aws_codeartifact,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'

export class SandboxCdkCodeArtifactStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const domain = new aws_codeartifact.CfnDomain(this, 'SandboxCdkDomain', {
      domainName: 'kakakakakku'
    })

    new aws_codeartifact.CfnRepository(this, 'SandboxCdkRepository', {
      domainName: domain.domainName,
      repositoryName: 'sandbox-cdk-repository',
    })
  }
}

独自パッケージをパッケージングする

まずは以下の Python Packaging User Guide を参考にサンプルパッケージを実装する.今回はドキュメントに沿って example_package_kakakakakku という名前にした.

packaging.python.org

コード的には数値を +1 する add_one() 関数を追加している👌

def add_one(number):
    return number + 1

最終的に以下のようなディレクトリ階層になった.

$ tree . -a -I dist
.
├── .gitignore
├── LICENSE
├── README.md
├── pyproject.toml
└── src
    └── example_package_kakakakakku
        ├── __init__.py
        └── example.py

検証中に出たエラーも残しておく💨

ERROR 'example_package_kakakakakku-0.0.1/.gitignore' is a link to an absolute path
ERROR Backend subprocess exited when trying to invoke build_wheel

うまくパッケージングもできた❗

$ python3 -m build
(中略)
Successfully built example_package_kakakakakku-0.0.1.tar.gz and example_package_kakakakakku-0.0.1-py3-none-any.whl

$ ls -1 dist
example_package_kakakakakku-0.0.1-py3-none-any.whl
example_package_kakakakakku-0.0.1.tar.gz

パッケージを AWS CodeArtifact にアップロードする

ドキュメントに書いてある通り,パッケージを AWS CodeArtifact にアップロードする場合は twine を使う.

docs.aws.amazon.com

aws codeartifact login --tool twine コマンドを使って認証トークンを取得しつつ,twine upload --repository codeartifact コマンドでパッケージをアップロードする.

$ aws codeartifact login --tool twine --domain kakakakakku --repository sandbox-cdk-repository --region ap-northeast-1
$ twine upload --repository codeartifact dist/*

AWS CodeArtifact にアップロードできた

パッケージを使う

今度は AWS CodeArtifact にアップロードしたパッケージを使ったコードを実装する.ちなみに Python を Homebrew でインストールしていると aws codeartifact login --tool pip コマンドを実行したときに pip was not found. Please verify installation. というエラーが出てしまうという既知の問題がある.venv を使うと回避できるため今回は venv で仮想環境を作る.あとは普通に pip install コマンドで example-package-kakakakakku を取得する.

$ python -m venv venv
$ source venv/bin/activate

(venv) $ aws codeartifact login --tool pip --domain kakakakakku --repository sandbox-cdk-repository --region ap-northeast-1
(venv) $ pip install example-package-kakakakakku
Successfully installed example-package-kakakakakku-0.0.1

(venv) $ pip list
Package                     Version
--------------------------- -------
example_package_kakakakakku 0.0.1
pip                         23.3.1
setuptools                  69.0.2

そして以下のような main.py を実行するとうまく実行できる👏

👾 main.py

from example_package_kakakakakku import example

print(example.add_one(1))
print(example.add_one(2))
print(example.add_one(3))

注意点

今回は AWS CodeArtifact リポジトリにアップストリームリポジトリを設定しなかったため,例えば requests のような一般的なパッケージをインストールしようとするとエラーになってしまう💨

(venv) $ pip install requests
Looking in indexes: https://aws:****@kakakakakku-000000000000.d.codeartifact.ap-northeast-1.amazonaws.com/pypi/sandbox-cdk-repository/simple/
ERROR: Could not find a version that satisfies the requirement requests (from versions: none)
ERROR: No matching distribution found for requests

以下のドキュメントに載っている通り,pip コマンドの -i / --index-url オプションを使って pypi を明示的に指定するとインストールできるようになる.ただし正直これだと使いにくく感じるため,アップストリームリポジトリを設定すると良いのかなぁー \( 'ω')/ コストとのトレードオフになりそう.

$ pip install --index-url https://pypi.org/simple requests

docs.aws.amazon.com

あと AWS CodeArtifact の認証回りでうまく pip コマンドを実行できなくなったら以下の2ファイルを確認しつつ,削除してみると改善するかも💡

$ rm ~/.config/pip/pip.conf
$ rm ~/.pypirc

今回はここまで❗️

実は今まで AWS CodeArtifact は試したことがなくて勉強になった〜 \( 'ω')/