Python を使って緯度経度から地域メッシュコードを算出する
緯度経度(latitude, longitude)から日本の地域メッシュコードを算出する Python3.7 のプログラムを作成しました。
プログラム
緯度経度から1-3次メッシュコード(基準地域メッシュコード)を算出します。精度を出すためにミリ秒で計算しています。
import math # 計算の単位(ミリ秒) MILLISECOND = 3600000 class FirstGrid(object): def __init__(self, lat, lon): ''' 1次メッシュコード計算 ''' self.lat = lat self.lon = lon # メッシュの高さ self.height_ms = MILLISECOND * (40 / 60) # メッシュの幅 self.width_ms = MILLISECOND # メッシュコードの上位桁 self.upper = int(math.floor(lat * 15 / 10)) # メッシュコードの下位桁 self.lower = int(math.floor(lon - 100)) # 南端(緯度) self.south_ms = self.upper * MILLISECOND / 1.5 # 西端(経度) self.west_ms = (self.lower + 100) * MILLISECOND def code(self): ''' メッシュコード ''' return f'{self.upper}{self.lower}' def origin(self): ''' メッシュの南西端(緯度経度) ''' return self.south_ms / MILLISECOND, self.west_ms / MILLISECOND class Grid(FirstGrid): def __init__(self, parent, divide): ''' 2,3次メッシュコード計算 :param parent 親メッシュ :param divide 分割単位 ''' self.lat = parent.lat self.lon = parent.lon lat_ms = parent.lat * MILLISECOND lon_ms = parent.lon * MILLISECOND # 親メッシュの高さと幅から当該メッシュの高さと幅を算出する self.height_ms = parent.height_ms / divide self.width_ms = parent.width_ms / divide h = self.height_ms w = self.width_ms # 上位桁 self.upper = int(math.floor((lat_ms - parent.south_ms) / h)) # 下位桁 self.lower = int(math.floor((lon_ms - parent.west_ms) / w)) # 南端 self.south_ms = self.upper * h + parent.south_ms # 西端 self.west_ms = self.lower * w + parent.west_ms def code(self): return f'{self.upper}{self.lower}' def origin(self): return self.south_ms / MILLISECOND, self.west_ms / MILLISECOND class LatLon2Code(object): def __init__(self, lat, lon): f = FirstGrid(lat, lon) # 2次メッシュは1次メッシュを8分割する s = Grid(f, 8) self.__first = f self.__second = s # 3次メッシュは2次メッシュを10分割する self.__third = Grid(s, 10) def first(self): return self.__first.code() def second(self): return f'{self.__first.code()}{self.__second.code()}' def third(self): return f'{self.__first.code()}{self.__second.code()}{self.__third.code()}'
地域メッシュは英語だと Grid Square と表現するらしいのでクラス名は Grid にしています。1次メッシュの計算が特殊で2次3次は同じ計算をするので、1次と2次3次でクラスを分けました。
使い方
LatLon2Code クラスのコンストラクタに緯度経度を渡してコードを取得します。
def test_latlon2code(): # 渋谷 ll2c = LatLon2Code(35.6640352, 139.6982122) assert(ll2c.first() == '5339') assert(ll2c.second() == '533935') assert(ll2c.third() == '53393595')
参考記事
PostGISでgeometry型からgeography型に変換するときは座標系に注意する
SRID=4612(JGD2000測地系+地理座標系)のgeometry型フィールドだとgeography型に変換できる
postgres=> SELECT ST_SetSRID(geom, 4612)::geography FROM map WHERE id=1; st_setsrid ---------------------------------------------------- 0101000020041200006B405577CB756140404749F6A1BF4140
SRID=3857(WGS84測地系球面+メルカトル図法)のgeometry型フィールドをgeography型に変換しようとするとエラーになる
postgres=> SELECT ST_SetSRID(geom, 3857)::geography FROM map WHERE id=1; ERROR: Only lon/lat coordinate systems are supported in geography.
EPSG: 3857は投影座標系で単位がメートルなのでダイレクトに変換できないみたいです。
参考
プライバシーポリシー
はじめに
A Day In The Life(https://glassonion.hatenablog.com、以下当サイト)は、個人情報に関する法令等を順守し、個人情報を適切に取り扱います。
個人情報の管理
当サイトは、お問い合わせいただいた内容についての確認・相談、情報提供のためのメール送信(返信)の目的以外には使用しません。また知り得た個人情報を第三者に開示することは、警察・裁判所など公的機関からの書面をもった請求以外に一切利用いたしません。
広告について
当ブログでは、第三者配信の広告サービス(Googleアドセンス)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。
クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。 Cookieを無効にする方法やGoogleアドセンスに関する詳細は「広告 – ポリシーと規約 – Google」をご確認ください。
また、当ブログは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。
免責事項
当ブログからのリンクやバナーなどで移動したサイトで提供される情報、サービス等について一切の責任を負いません。 また当ブログのコンテンツ・情報について、できる限り正確な情報を提供するように努めておりますが、正確性や安全性を保証するものではありません。情報が古くなっていることもございます。 当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。
著作権について
当ブログで掲載している文章や画像などにつきましては、無断転載することを禁止します。 当ブログは著作権や肖像権の侵害を目的としたものではありません。著作権や肖像権に関して問題がございましたら、お問い合わせメールよりご連絡ください。迅速に対応いたします。
リンクについて
当ブログは基本的にリンクフリーです。リンクを行う場合の許可や連絡は不要です。 ただし、インラインフレームの使用や画像の直リンクはご遠慮ください。
お問い合わせ
当ブログに関するお問い合わせは以下のメールアドレスまでおねがいします。 glassonion999 @ gmail.com
Golang書くときのちょっとしたテクニック
MarshalJSONを使ってJSONに表示用のフィールドを追加する
無限ループしないように元の構造体を拡張する
// UTCな時間をJsonに変換するタイミングでJSTに変換する例 import "time" type Hoge struct { ID uint CreatedAt time.Time } func (h Hoge) MarshalJSON() ([]byte, error) { type Alias Hoge return json.Marshal(&struct { Alias CreatedAtJST time.Time }{ Alias: (Alias)(h), CreatedAtJST: h.CreatedAt.In(time.LoadLocation("Asia/Tokyo")), } }
参考
Enum
数値系Enum
ゼロ値をUnknownにするのがGolang流
type DeviceType uint const ( Unknown DeviceType = iota Android IOS )
文字列系Enum
type Status string const ( Success Status = "success" Failure Status = "failure" )
関数にオプショナルな引数を設定したいとき
FunctionalOptionPatternを使って実装する
https://blog.web-apps.tech/go-functional-option-pattern/
リクエストボディの読み出しが1回しかできないときの対処方法
リクエストボディを ioutil.ReadAll 関数で読み出すと2回目以降は中身空っぽになります。それの回避方法です。
http - How to read response body twice in Golang middleware? - Stack Overflow
Gotestでいい感じのスタブを作る方法
gomockインストールするのはちょっとなぁって時に良いです。
Golangでサーバプログラミングするなら始めに読むべき記事
最近 Golng 使ってサーバのプログラム書いてます。 始める前に読んでおけばよかったと感じた記事が2つあったのでメモ程度に紹介します。
Handlerのチェインをどうやって解決するか
- Making a RESTful JSON API in Go - The New Stack
Context問題どうするか
- Go's net/context and http.Handler – joe shaw
micro:bitを使って子供と一緒に夏休みの自由研究をしてみました
夏休みのことなので少し前の話になりますが、小学生の娘と一緒に夏休みの自由研究にmicro:bit を使ったギターを制作しました。
micro:bit って何ですか?
イギリスの BBC が開発した小学生向けの小型コンピュータです。子供向けではありますが、傾きセンサや光センサ、温度センサなんかもついていて本格的です。スピーカーに繋げば音を出すこともできます。Raspberry Pie や Arduino の子供版といった感じです。
マイクロソフトが開発した Scratch ライクな開発環境があるのでブラウザ上で手軽にプログラミングができます。
ギターの制作
小学2年生の娘が工作担当、自分がプログラミング担当といった感じで作りました。本当は娘にプログラミングもやって欲しかったのですが制作期間の関係で私が担当しました。以下の二つの工作例が元ネタです。
ちなみに電源供給とスピーカーは MI:power board で行いました。
ワニ口クリップがあるといろいろ捗ります
mcro:bit から音を出すためにスピーカーに繋いだりするのにワニ口クリップがあると便利です。mcro:bit 単体でも十分遊べるのですがワニ口クリップがあると遊びの幅がグッと広がるのでオススメです。
接着にはグルーガンがおすすめです
ダンボール同士をくっつける時なんかはボンドやノリを使うよりもグルーガンを使った方が丈夫に仕上がります。うちの小学2年生の娘も初めこそ苦戦してましたがそこそこちゃんと使えるようになってました。