MyMap

背景 地理、楽しいっすよね。めっちゃ好きです。 でも Google Maps って使うと、結局は Google って会社にお世話になってるわけですよ。 僕はこの「どっかの会社のお世話になっている状態」があまり好きではない。 だからサーバやデータセンターも自前運用するし、 Slack の代わりに Rocket.Chat を使うし、 JIRA ではなく Redmine を使うんです。 じゃあ Google Maps を自前で運用するにはどうするか? これが今回のテーマです。 地図アプリがどうやって動いているか 必要なものは大きく分けて二つ。 レンダリングエンジン(地図を描画するライブラリ) マップデータ(地図そのもののソース) OSSのレンダリングエンジン(ライブラリ) Leaflet OpenLayers MapLibre GL JS それぞれでベースマップを比較できるデモも作りました。 👉 比較サイト OSSのマップデータ 選択肢は色々あります。 OpenStreetMap (OSM) 世界中のボランティアが作る地図データ。ラスタ(画像タイル)も配布されているが、見た目は少し古臭い。 実際の中身はベクタだが、配信されている地図はあらかじめ描画されているラスタタイル。(元がベクタならそれを出せばいいじゃん、、とは思った) OpenMapTiles OSMデータをベクトルタイル化するOSS。 これを使えば、Google Maps 並みにきれいなベクトル地図を完全自前で運用できる。 ラスタはやっぱり綺麗に映らないですね。なのでベクトルマップが欲しいのですが、 ベクトルマップは自分で作るしかないっぽいです。(Maptilerって会社がOSMを所有しようとしているので気をつけて) 実際に OSM → Vector Map を自前ホストする流れ 1. OSMデータのダウンロード Geofabrik から地域ごとの .osm.pbf を落とす。 例: 日本全体 https://download.geofabrik.de/asia/japan.html 2. OpenMapTiles でベクトルタイル生成 まずは GitHub から OpenMapTiles を取得します。 ...

August 23, 2025 · 3 min · 492 words · Me

Googleapi Gmail Autoreply

背景 受託開発先の方からLLMを使って問い合わせや予約業務の自動化ができないかと聞かれた。 もちろんできますよ、と僕は答えたわけです。 しかし、一回gmailの内容をローカルに持って来ないと始まりませんよね?? なので、gmailのメールをサーバに持ってくるためにgoogle apiを叩きます。 構成 webフロントエンド -> サーバ(アプリ) -> google api google apiの設定方法 1. プロジェクト作成 https://console.cloud.google.com/ にアクセス 以下の写真のgoogle cloudロゴの隣にあるボタンをクリック。この画像で言うと、gmail api access(ここから新しいプロジェクトを作る) プロジェクト名(例:gmail-auto-reply)を入力し、「作成」 2. Gmail API を有効にする google cloudロゴの隣にあるボタンから、先ほど作ったプロジェクトにプロジェクトを変更する 左側メニュー「APIとサービス」 → 「ライブラリ」を押す 検索ボックスに Gmail API と入力し、クリック。 enableボタンを押す 3. OAuth 同意画面を設定する 左側メニュー「APIとサービス」→「OAuth同意画面」 次のような画面が出てくる。get startedを押す 以下の情報を入力する ユーザータイプ 外部(基本はこれでOK) アプリ名 任意(例:Auto Mailer) サポートメール 自分のGmailでOK 開発者連絡先情報 自分のメールアドレス 4. 認証情報を作成(OAuth 2.0 クライアントID) 左メニュー「認証情報」→「+認証情報を作成」→「OAuth クライアントID」 以下を入力する アプリケーションの種類 → 「Web アプリ」 名前は何でもOK(例:auto-mail-backend) 「承認済みのリダイレクトURI」に以下を追加: http://localhost:3000/auth/google/callback https://yourdomain.com/auth/google/callback (実際に使うサーバ) 作成ボタンを押す。クライアントシークレットが表示されるのでめももしくはダウンロード 5 スコープを追加(必要なら) ここまでで設定が完了。次にやることは以下。 ...

May 10, 2025 · 2 min · 363 words · Me

ルーム型オンラインマルチプレイヤーゲームの作り方

ルーム型オンラインゲームの作り方 La-keibaのAgentとバックエンドの通信にはpythonのwebsocketを使うことになっている。なぜpythonかというと、AgentはpythonのLightGBMを使ってトレーニングされた勝ち馬予測モデルを使っているから。となると、python以外に使える物はなく、仕方なくpythonを使うことにした。あと、プロセス間の通信にはhttp通信を使ってもいいんだけど、httpは一回きりの通信だし、モジュール間で双方向通信が必要なことが後々生じることもあるだろうと思いWebsocketを使うことにした。大(websocket)は小(htt)を兼ねるともいうし。(しかし、websocketの方がhttpよりオーバヘッドが大きいのも確か) websocketでも普通にJSONが扱える。 pythonを使ったwebsocket通信をするために、このサイトで勉強したのだが、これがかなり優秀だった。今まで手探りでやっていた、websocketを使ったルームベースのアプリ(ルーム型チャット等)のフレームに対する最適解を提示してくれるものとなった。このルームベースアプリケーションのフレームは様々なアプリに適応できる。ぱっと思いつくものでいうと、将棋とか、一対一で行われるゲームはそうだし、一対一ではなくとも、ルームという概念が存在するゲーム(ないしはアプリ)にはこれが適応可能である。BFだって通信に使っているプロトコルはおそらく独自の高速プロトコルだけど、全体で見た時のフレームはこれと同じだと思う。まあ、ルームを一つの物理サーバに複数立てるのではなく、1サーバに対し1ルームという感じではあると思うが。 チュートリアルでは、まるばつゲームの拡張版であるconnect4というゲームを扱った。ポイントだと思う点を以下にまとめる。 ゲームそのものを管理するゲームエンジンの存在 オブジェクト指向の真骨頂がここで使えるわけです。「ゲーム」をオブジェクトとみなして、ゲームとインタラクションする手段として、ゲームオブジェクトがメソッドを提供する。メソッドはコントローラみたいなものだね。内部の状態もゲームオブジェクトは保持する。 ルームオブジェクト そして、特定のゲームオブジェクトと、そのゲームをコントロールする権利を持つwebsocketをまとめて保持するオブジェクト(以下、ルームオブジェクト)を作り、このルームオブジェクトにidをつける。c++でもそうだったけど、websocketオブジェクトは、sendメソッドを介していつでもフロントエンドにメッセージを送れる仕様になっている。つまり、フロントエンド間(2ユーザ間)でメッセージをやり取りするには、ルームオブジェクトでそのルームに所属するwebsocketを論理的に管理し、到着したメッセージをルームに所属するwebsocketオブジェクトに返せればよい、ということになる。 JSONでメッセージのやり取り jsonメッセージの一番最初には、メッセージの種類を表す、typeを 持ってきます。そのあとは、typeに即したメッセージのやり取りをするわけですね。これがアプリケーション層でのメッセージプロトコルですね。 前に実装した独自の通信プロトコルでもそうだったけど、やはり、やり取りするメッセージの一番最初にはメッセージのタイプを持ってくるのが普通みたいですね。 タイプには例えば、initや、join、watch,playがある。initは最初にやりとりするメッセージのことでしょう。joinは、そのルームへのjoin。watchは、そのルームの観戦。playはプレイヤーの動きが入っています。typeでplayが来たら、内容に合わせてゲームオブジェクトにメッセージを送ります。 pythonのwebsocketには、 websocket.wait_closed() という、そのフロントエンドから送られてくる通信はreceiveしないけど、サーバ側からは送れる、っていう便利なメソッドがあります。これを使うことで、そのwebsocketセッションを傍観者にすることが可能です。観戦だけできるようにするってことですね。 c++にはおそらくこれがないんだけど、websocketを継承して、新しいmywebsocketクラスを作り、その中でis_player変数とかを作ることで、傍観者かそうでないか、を見分けることもできますね。これはなかなかに便利だと思います。 フロントエンド(javascript)の処理 javascriptはすでにイベントドリブンな仕様になっている。よって、イベントを登録するだけでよい。メッセージを受信した時の動作を規定する関数と、メッセージを送信した時の動作を規定する関数を作る。関数の引数にはwebsocketオブジェクトを渡しておく。その中で、websocket.addEventlistner()をする。 便利だと思った機能 便利だと思ったメソッドは、replayメソッドだね。gameオブジェクトでは、過去のムーブをすべてレコードしてある。そのレコードをひとつづつ送れば、すべて再現できるようになっている。 これは、例えば途中から入ってきた観客にこれを使って得られるメッセージを送る、といった用途で使える。 websocketとhttpの使い分けについて Websocketとhttpどっちがいいとかはなくて、それぞれ適切な用途があります。 httpは一回きりのステートレスな通信をするためのプロトコル。しかし、webアプリではhttpで通信をするけど、誰が通信してきているかを管理したいことがある。そこで、Cookieを使ってセッションを管理する。 http+Cookie = ステートフルになる。なのでhttpのセッション管理が必要なのは、フロントエンドからアプリを使いたいユーザだけ。 そして、httpはバックエンドのモジュール間の通信にも普通に使える。リクエストにJSONをのっけてpostしたり、url自体にpostする内容をのっけたりすることもできる。(RESTful)。モジュール間での通信がセッションを必要としない一度きりのもであればhttpを使えばいいし、そうでない場合はwebsocketを使えばいい。ブラウザでのゲームはステートを保持しないといけない、かつサーバからブラウザに通信が来ることがあるからhttpでは対応できなくて、Websockeを使わないといけない。

August 17, 2022 · 1 min · 30 words · Me