A Day In The Life

とあるプログラマの備忘録

緯度経度を世界メッシュコード(標準地域メッシュの世界拡張仕様)に変換するライブラリを公開しました。

日本限定の標準地域メッシュを世界に拡張した世界メッシュという規格がある

普段、データ分析業務などで総務省が策定した標準地域メッシュ(JISX0410)を利用しています。この規格は日本でしか利用できないのですが漠然と定義を拡張して全世界で使えたりしないのかなと思って、いろいろ探してみたところ世界メッシュというものを発見しました。

ブラウザで世界標準メッシュを利用してみたかったので自前で TypeScript でライブラリを開発しました。

開発したライブラリはこちら

ブラウザでの利用はもちろん Node.js でも利用できます。他のライブラリに依存してないので BigQuery の UDF としても利用できると思います(ちゃんと試してないです)。 github.com

使い方

6次メッシュ(分割地域メッシュ125m)を生成する

import wgs from 'world-grid-square'

const code = wgs.toCode(139.745433, 35.658581, 6)
// 2053393599212
console.log(code)

通常の標準地域メッシュの生成もできます。

import wgs from 'world-grid-square'

const code = wgs.toJisCode(139.745433, 35.658581, 6)
// 53393599212
console.log(code)

世界メッシュを地図上に可視化する

こちらのサイトで世界メッシュを地図上に可視化して確認することができます。

標準地域メッシュのロジックはコチラを参考にしています。

私が以前書いたPythonの記事です。

参考

最近なにやってったっけ

最近の個人活動

忘れないようにメモ

Webサービス開発

Web Tools

Texを出力するサービスとか地域標準メッシュやQuadkey、Geohashの可視化サービスなど。世の中インフレだけど年収が上がる気配が1mmもないので収入増を狙って作ってみた。しばらくはこのサービスを拡充したい。

tools.9revolution9.com

OSS開発

anonypy

Pythonのk-匿名化ライブラリ。勢いで開発して放置してたにも関わらず思ったよりもスターがついていてびっくり

osrm-server-demo

OSRMというOpen Street Mapの道路情報を使ったマップマッチや経路探索ができるライブラリを利用してマップマッチサーバを立てるデモ。Node.js(Java Script)で開発

quadkey-tilemath

TypeScriptで開発した緯度経度をQuadkeyに変換するライブラリ。個人的にはQuadkeyもっと日本で流行ってほしい。

xgo

Goの便利関数を集めたライブラリ。開発自体はそこそこ前だけど細々と機能追加を続けている。

試験

2022年の秋に情報処理安全確保支援士試験を受けた。人生初の高度試験合格だったのでものすごく嬉しかった。登録セキュスペになるかどうかはまだなにも考えていない。

zenn.dev

自己研鑽的な

ここ1年くらい高校数学の勉強をしている。やっと数3までいった。早く大学数学が勉強できるようになりたい。今読んでる本はこちら

k-匿名化ライブラリを開発しています

k-匿名化ライブラリ

個人活動でPythonでk-匿名化するライブラリを開発しています。l-多様化とt-近似化にも対応しています。まだまだ改善点たくさんありますが少しづつ良いライブラリにしていきたいとおもいます。 github.com

開発にあたりこちらの書籍がめちゃくちゃ参考になりました。

フロー情報はブログに、ストック情報はZenn.devに投稿することにしました。

今後技術記事はZenn.devに投稿します。

長年ブログに技術記事をかいてきましたが、フロー情報とストック情報を分けて投稿することにしました。 今後、技術記事はZenn.devに投稿します。

最近投稿したZenn.devの記事

最近は主にGoの記事を書いています。

引き続き、本ブログをよろしくお願いします。

引き続き、お気持ち表明とか、近況報告、おすすめの本情報なんかはこちらのブログに書いていきます。

GCPマネージドサービス向けLoggerライブラリを開発しました。

GCPマネージドサービス(GAE/GKE/Cloud Run)向けのGoのLoggerライブラリを開発しました。 github.com

Google App Engine 第1世代のロガー(google.golang.org/appengine/log)からの移行ができるように関数のインフタフェースを揃えてあります。

CABTMIDILocalPeripheralViewControllerを使わずにMIDI over BLEでアドバータイズする方法

ワイヤレスMIDI接続をしてアプリから他の端末にMIDIデータを送信したい

CoreAudioKit の CABTMIDILocalPeripheralViewController を使うとiPhone(またはiPad)アプリ上に MIDI over Bluetooth LE のアドバータイズの設定画面を表示することができます。

CABTMIDILocalPeripheralViewControllerを使うと設定画面が立ち上がりアドバータイズ設定ができるようになります

上記画面の Advertise MIDI Service の項目をオンにするとアプリ側を BLE ペリフェラルとしてアドバータイズすることができます。

CABTMIDILocalPeripheralViewControllerを使わずにアドバータイズしたい

SwiftUI や SpriteKit で画面構築をしていると CABTMIDILocalPeripheralViewController のような UIViewController を継承したクラスを使うのは少し大変です。そこで CABTMIDILocalPeripheralViewController を使わずに直接 CoreBluetooth を使ってMIDI over BLE のアドバータイズができないか調べてみました。その結果サービスのIDとキャラクタリスティックのIDに特定の値を指定するとできることがわかりました。 以下は SpriteKit のシーンで BLE のアドバータイジングをするコードです。

import SpriteKit
import CoreBluetooth

class GameScene: SKScene {
    var manager: CBPeripheralManager!
    var service: CBMutableService!
    // MIDI Service UUID
    let serviceID = CBUUID(string: "03B80E5A-EDE8-4B33-A751-6CE34EC4C700")
    // MIDI I/O Characteristic UUID
    let characteristicID = CBUUID(string: "7772E5DB-3868-4112-A1A9-F2669D106BF3")

    override func didMove(to view: SKView) {
        super.didMove(to: view)
        self.manager = CBPeripheralManager(delegate : self, queue : nil, options: nil)
    }
}

extension GameScene: CBPeripheralManagerDelegate {
    // ペリフェラルの状態通知
    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        guard peripheral.state == .poweredOn else {
            print("error: \(peripheral.state)")
            return
        }
        
        print("bluetooth pwoer on")
        // サービスとキャラクタリスティックの追加
        self.service = CBMutableService(type: self.serviceID,
                                       primary: true)

        let properties: CBCharacteristicProperties = [.notify, .read, .writeWithoutResponse]
        let permissions: CBAttributePermissions = [.readable, .writeable]
        let characteristic = CBMutableCharacteristic(type: self.characteristicID,
                                                     properties: properties,
                                                     value: nil, permissions: permissions)
        
        self.service.characteristics = [characteristic]
        self.manager.add(self.service)
    }
    // サービス追加の成功失敗通知
    func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
        guard (error == nil) else {
            print("Add service failed")
            return
        }
        print("Add service succeeded")
        
        // アドバタイズ開始
        let advertisementData = [CBAdvertisementDataLocalNameKey: "Penguin Drums",
                                 CBAdvertisementDataServiceUUIDsKey: [self.serviceID]] as [String : Any]
        manager.startAdvertising(advertisementData)
        
        print("Service starts advertising!")
    }
}

サービスのIDには 03B80E5A-EDE8-4B33-A751-6CE34EC4C700 をキャラクタリスティックのIDには 7772E5DB-3868-4112-A1A9-F2669D106BF3 を指定します。またキャラクタリスティックのプロパティに Read, Write, Notify を指定します。

参考記事

SpriteKit SceneをiPhone/iPadのホームバーに対応させる

3年間放置していたiOSアプリをホームバーに対応させた話

かれこれ3年くらい放置していた iPhone/iPad 両対応のアプリをホームバーに対応させようと思ったら結構大変だったのでその記録です。 ちなみに放置していたアプリはこちらです。

ピアノ - 即興ピアノ

ピアノ - 即興ピアノ

  • taisuke fujita
  • ミュージック
  • 無料
apps.apple.com

対応前の設定はこんな感じ

4.7インチの iPhone(6, 6S, 7, 8, 第2世代SEなど1334 * 750ピクセル)をベースにiPadにも対応させるため、SKScene の幅を1334ピクセル高さを1000.5ピクセル(4:3)に設定し、アンカーポイントを(0, 0)に設定してました。 以前の画面 4:3の iPad を表示領域として、スプライトを16:9の iPhone の領域におさまるように配置するイメージです。この設定だと iPhone だとぴったりで iPad だと上下に余白ができます。 シーンのスケールモードの設定は aspectFill に設定してました。

class GameViewController: UIViewController {
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        
        if let view = self.view as! SKView? {
            // Load the SKScene from 'GameScene.sks'
            if let scene = GameScene(fileNamed: "GameScene") { 
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFill
                // Present the scene
                view.presentScene(scene)
            }
        }
    }
}

ホームバーの無い iPhone 8iPad Pro 第2世代では問題なく表示できていました。しかし iPhone X 以降(またはiPad Pro 11, 12.9インチ)のホームバー付きの端末で表示させる以下のようになりました。 はみ出た 全体が拡大されてスプライトがはみ出ています。

ホームバーに対応する手順

iPhone X 以降(またはiPad Pro 11, 12.9インチ)のホームバーに対応する手順は以下のようになります。

  1. SKSceneのサイズを16:9に合わせて変更する
  2. アンカーポイントを(0, 0)から(0.5, 0.5)に変更する
  3. presentSceneを呼び出すタイミングでSceneのサイズを調整する

手順1と2でシーンエディタの修正をします。手順3でプログラムの修正をします。

SKSceneのサイズを16:9に合わせて変更する

SKScene のサイズを16:9に合うように変更します。私の場合は1334 * 1000.5だった設定を1334 * 750に変更しました。16:9であれば960 * 540だったり、2208 * 1242だったりでも問題ないようです。作成したスプライトの画像サイズに合うように適宜変更すれば良いようです。ポイントは縦横比が16:9になるように SKScene のサイズを設定することです。

Sceneのアンカーポイントを中央にする

16:9 の iPhone の画面にぴったり合うようにスプライトを配置すると iPhone 11 系では左右に余白ができ、iPad 系では上下に余白ができます。この余白に影響を受けないようにするにはアンカーポイントを中央(0.5, 0.5)に設定する必要があります。シーンのアンカーポイントを変更するとスプライトの位置が変わってしまうので適宜スプライトの位置も変更します(地味にこの作業が一番めんどくさい)。

ここまでの修正を反映するとこんな感じです

修正後の画面

presentSceneを呼び出すタイミングでSceneのサイズを調整する

UIView の presentScene メソッドを呼ぶタイミングで、UIView のサイズ(機種によってサイズがかわる)と SKScene のサイズの比率を計算して SKScene のサイズを調整してあげます。スケールモードの設定は aspectFill から aspectFit に変更します。

class GameViewController: UIViewController {
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        
        if let view = self.view as! SKView? {
            // Load the SKScene from 'GameScene.sks'
            if let scene = GameScene(fileNamed: "GameScene") {
                var factor = view.frame.size.height / scene.size.height
                // iPad
                if view.frame.size.width / factor < scene.size.width {
                    factor = view.frame.size.width / scene.size.width
                }
                scene.size = CGSize(width: view.frame.size.width / factor,
                                       height: view.frame.size.height / factor)
                
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFit
                // Present the scene
                view.presentScene(scene)
            }
        }
    }
}

手順を適用した結果はこちら

手順1から3を適用して修正した結果は以下のようになります。

iPhone 8

ホームバーなし(ホームボタンあり)の従来型の iPhone 画面です。 iPhone8

iPhone 11

ホームバーありの新型の iPhone 画面です。左右に余白ができています。 iPhone11

iPad Pro 11インチ

ホームバーありの新型の iPad 画面です。上下に余白ができています。 iPad Pro

参考記事