tohokuaikiのチラシの裏

技術的ネタとか。

ゼンリンのマップAPIが日本測地系のミリ秒でデータを持っていたのでGoogleMapのデータ形式に変換したかった

緯度経度のデータ形式には、2つ壁があって、座標系と表示形式。

座標系

日本測地系世界測地系がある。3 日本測地系と世界測地系 | 国土地理院からの引用。

我が国では、改正測量法の施行前は、明治時代に採用したベッセル楕円体を使用していました。明治政府は、近代国家に不可欠な全国の正確な地図である5万分の1地形図を作るために、基準点網を全国に整備しました。この時採用された楕円体が、改正測量法の施行前まで使用されてきたベッセル楕円体です。そして、当時の東京天文台の経度・緯度が、天文観測により決定されました。この位置が現在の日本経緯度原点となっています。この測地基準系を「日本測地系」と呼んでいます。全国に設置された基準点の経度・緯度は、日本経緯度原点を絶対的な位置の基準として求められて行ったのです。

 しかし、VLBIや人工衛星により地球規模の観測ができるようになった今日では、日本測地系は、残念ながら、地球全体によく適合した測地基準系であるとは言えなくなってしまいました。

 一方で、地球全体によく適合した測地基準系として、世界測地系が構築されています。 世界測地系とは、VLBIや人工衛星を用いた観測によって明らかとなった地球の正確な形状と大きさに基づき、世界的な整合性を持たせて構築された経度・緯度の測定の基準で、国際的に定められている測地基準系をいいます。

なるほど。わからん。ガチで変換するとなると、データテーブルが必要だが、簡易的にはこんな式で出せるらしい。日本測地系と世界測地系相互変換についてからの引用

日本測地系世界測地系

世界測地系緯度 = 日本測地系緯度 – 0.00010695 * 日本測地系緯度 + 0.000017464 * 日本測地系経度 + 0.0046017
世界測地系経度 = 日本測地系経度 – 0.000046038 * 日本測地系緯度 – 0.000083043 * 日本測地系経度 + 0.010040

世界測地系日本測地系

日本測地系緯度 = 世界測地系緯度 + 0.00010696 * 世界測地系緯度 – 0.000017467 * 世界測地系経度 – 0.0046020
日本測地系経度 = 世界測地系経度 + 0.000046047 * 世界測地系緯度 + 0.000083049 * 世界測地系経度 – 0.010041

表示形式

表示形式は60進(度・分・秒・ミリ秒)と10進。60進と言いつつも度とミリ秒は10進なのがミソっで、10進は度に合わせたものとミリ秒に合わせたものがある。

60進(度・分・秒)は35.40.50.109(35度40分50秒109 *1)のように書く。度だけが10進法なので、分以下を10進法で度に合わせればよくて、これはただの進数変換。

(度に合わせた10進にする)
〇度■分▲秒◎ =  〇 + (■/60) + (▲/3600) + (◎/3600000)
(ミリ秒に合わせた10進にする)
〇度■分▲秒◎ =  〇*3600*1000 + ■*60 * 1000 + ▲*1000 + ◎

実例を挙げてまとめると。

表にまとめるとこんな感じ。例示の緯度経度は「東京都千代田区千代田1-1 皇居」です。

座標系

緯度 10進(度) 10進(ミリ秒) 60進(度・分・秒)
日本測地系 35.6805861 128450110 35.40.50.109
世界測地系 35.6838232 128461764 35.41.1.763

表示形式

経度 10進(度) 10進(ミリ秒) 60進(度・分・秒)
日本測地系 139.7570472 503125370 139.45.25.369
世界測地系 139.7538283 503113782 139.45.13.781

エクセルで使うならこんな感じ

A B C D E F
1 緯度(日本測地系・ミリ秒) 経度(日本測地系・ミリ秒) 緯度(日本測地系・10進(度)) 経度(日本測地系・10進(度)) 緯度(世界測地系・10進(度)) 経度(世界測地系・10進(度))
2 128450110 503125370 =A2/3600000 =B2/3600000 =C2-C2 * 0.00010695+D2 * 0.000017464+0.0046017 = D2 - C2 * 0.000046038 - D2 * 0.000083043 + 0.01004

GoogleMapへのリンク

GoogleMapは、世界測地系を度に合わせた10進で使ってるので、GoogleMapへのリンクは
https://www.google.com/maps?q=35.6838232,139.7538283
となる。

*1:あるいは、35度40分50.109秒とも書けるのか?

sedって難しいよね。俺たちは雰囲気でsedを使っている。

やりたいこと

複数のテキストファイルの中の文字列を別の文字列に一括置換したい。

俺たちは雰囲気でsedを使っている。

sedを20年使ってても(年に2~3回ペースなこともあって)使うのが難しい。何が難しいって、オプションとかフラグとか正規表現とか。そのたびに検索して事例見つけてコピペしている。

よく

$sed -i -e "s/foo/bar/g" file.txt

とかあって、-iオプションは上書き、g修飾子はグローバルマッチ(ファイル内のすべて置換)で、「あぁ、file.txtのなかのfooをbarに全部置き換えて上書きするんだな」ってわかるけど、じゃあ、-eオプションって何?/foo/bar/の前のsって何?必要?って言われるとわからん。俺たちは雰囲気でsedを使っている。

サクッとsedの代わりになるものとかないかなーって【脱sed】いい加減シェルスクリプトで文字列をsedで置換するなんてやめよう #Linux - Qiitaとか、trコマンドとか見てみるけど、なんかイマイチ理解できなかったりファイル上書きできなかったり*1で結局sedに戻ってくることになるので、ちゃんと自分用にメモしておく。

よく使うものだけ

例を挙げながらメモ。file.txtとして

foo bar
foo bar baz
foo bar baz qux

/foo/bar/
{foo} {bar} {baz}
@foo@bar@baz@qux@

を用意した。これをさっきの

$sed -i -e "s/foo/bar/g" file.txt

に通すと

bar bar
bar bar baz
bar bar baz qux

/bar/bar/
{bar} {bar} {baz}
@bar@bar@baz@qux@

になる。fooが全部barになっている。

-eオプション

【 sed 】コマンド(基礎編その4)――文字列を置き換える/置換した行を出力する:Linux基本コマンドTips(56) - @ITでは

 --expression=スクリプト  スクリプト(コマンド)を追加する

ってあるけど、スクリプト(コマンド)ってなんやねん?というと、この場合は"s/foo/bar/g"。2つつなげたい場合は-eオプションを使う。同時にbazをzzzにしたい場合は

$sed -i -e "s/foo/bar/g" -e "s/baz/zzz/g" file.txt

で、

bar bar
bar bar zzz
bar bar zzz qux

/bar/bar/
{bar} {bar} {zzz}
@bar@bar@zzz@qux@

となる。

なので、スクリプト(コマンド)が1つだけの場合は、-eオプションは不要。

s/foo/bar/のsとはスクリプト(コマンド)

スクリプト(コマンド)とは置換以外にもいろいろある。 例えばaスクリプト(コマンド)は「テキストの追加」を行う。

$sed "a add text" file.txt

とやると、

foo bar
add text
foo bar baz
add text
foo bar baz qux
add text

add text
/foo/bar/
add text
{foo} {bar} {baz}
add text
@foo@bar@baz@qux@
add text

とすべての行の次にadd textが加えられる。

sスクリプト(コマンド)は「テキストの置換」になる。

正規表現

sed正規表現は、POSIXの基本正規表現。簡単な置換ならこれで十分。

fo*でfooもfooooooも置換

$ sed -e "s/@fo*/bar/g" file.txt
foo bar
foo bar baz
foo bar baz qux

/foo/bar/
{foo} {bar} {baz}
bar@bar@baz@qux@

エスケープのバックスラッシュ

$ sed -e "s/foo\//bar/g" file.txt
foo bar
foo bar baz
foo bar baz qux

/barbar/
{foo} {bar} {baz}
@foo@bar@baz@qux@

行頭宣言の^

$ sed -e "s/^foo/bar/g" file.txt
bar bar
bar bar baz
bar bar baz qux

/foo/bar/
{foo} {bar} {baz}
@foo@bar@baz@qux@

拡張したPOSIX正規表現だとエスケープが不要になるみたい。sedで躓くLinux(POSIX)の正規表現|jig.jp engineers

だが、JavaScriptPerlなどのPCRE 形式の正規表現ではない。

空行を残さないで改行ごと置換する

sedはラインエディタなので行ごとにスクリプト(コマンド)を実行する。なので、1行丸ごと消したい場合に空行が残ってしまう。

$ sed -e "s/foo bar baz qux//" file.txt
foo bar
foo bar baz


/foo/bar/
{foo} {bar} {baz}
@foo@bar@baz@qux@

-zオプション

zオプションは改行ごとにスクリプト(コマンド)を実行するのではなく、Null文字ごとにスクリプト(コマンド)を実行する。NULL文字は\0で表現できる。普通のテキストファイル内にそんなものは無い。

改行コードは\n。Windowsだと\r\n

$ sed -z -e "s/foo bar baz qux\n//" file.txt
foo bar
foo bar baz

/foo/bar/
{foo} {bar} {baz}
@foo@bar@baz@qux@

…が、zオプションは2018年にリリースされたversion4.2.2で導入されたらしく、むしろまだsedに新機能入るのか!!!という驚きの方があるが、手元のCentOS6では動かなかった。そんな古いOS使うなって。

$ sed --version
GNU sed 4.2.1版

Copyright (C) 2009 Free Software Foundation, Inc.

*1:grep+xargsで一括上書きしたいんよ

SSLのCSRを作成するコマンドとかメモ

もう、なんどもググっているのでタトゥーにしてもいいんだけど、痛いのでここにメモしておく。

秘密鍵とかCSRとか

openssl genrsa -out servername.key 2048
openssl genrsa -aes256 -out servername.key 2048
openssl rsa -in servername.key -out servername_nopass.key
openssl rsa -in servername_nopass.key -out servername_pass.key -aes256
openssl req -new -key servername.key -out server.csr -sha256
openssl req -noout -text -in server.csr
openssl rsa -noout -modulus -in servername.key | openssl md5
openssl req -noout -modulus -in server.csr | openssl md5
openssl x509 -noout -modulus -in server.crt | openssl md5

Apache

    SSLCertificateFile     (SSL証明書)server.crt
    SSLCertificateKeyFile  (秘密鍵ファイル)servername.key
    SSLCertificateChainFile     (中間証明書)chain.pem

Apache 2.4.8以降は中間証明書のSSLCertificateChainFileは無くなったので、SSL証明書に2つ連結しておく。

cat server.crt chain.pem > serverchain.crt
SSLCertificateFile     (SSL証明書)serverchain.crt

ReactのJSXにおけるコンポーネントへの引数の渡し方

継ぎ足ししていく予定。

Propsで渡す

プロパティと子要素が必須でないなら、?を付けておく。

export const Text = (props:{content?:string, children?:React.ReactNode}) :JSX.Element => {
    return <div><span>{props.content}</span><p>{props.children}</p></div>
}

コンポーネントではこんな感じ。

import Text from "./components/export"

function App() {
  return (
    <div className="App">
        <Text content= "TextコンポーネントにPropsで渡したいテキスト">
             <p>子要素</p>
      </Text>
    </div>
  );
}

Propsには型を明示する

type TextContent = {
    content?: string,
    children?: React.ReactNode
}
export const Text = (props:TextContent):JSX.Element => {
    const {content, children} = props;
    return <div><span>{content}</span><p>?{children}</p></div>
}

となると、型だけを定義したファイルが欲しいな。

Reactの(というかES6の)import/exportについてメモ

こういうの書かないと忘れてしまう。49歳なので。

基本形(1つのファイルに1つExport)

export const Foo = () => {
    return <div className="foo">Foo</div>
}
import FooBar from 'components/export'
function App(){ 
     return <FooBar/>
}

export default しているので、受ける側は好きな名前でimportできる。

2つ以上exportする

色々な方法がある。とりあえず理解したのだけ。

1つのObjectにして返す

const Foo = () => {
}
const Bar = () => {
}
export default {Foo, Bar}
import FooBar from 'components/export'
function App(){ 
     return <FooBar.Foo/><FooBar.Bar/>
}

それぞれの定義時にexport宣言

export const Foo = () => {
}
export const Bar = () => {
}

これもimportで受けるときは1つのObjectとして扱う。

import {Foo, Bar} from 'components/export'
function App(){ 
     return <Foo/><Bar/>
}

それぞれの定義時にexport宣言でdefaultを使う

defaultは変数なので、変数代入しているアロー関数には使えない。そして、defaultは先頭のexportでなくてもどれにつけてもよい。

export const Foo = () => {
}
export default function Bar() {
}

受け取る側は、先頭にdefault宣言したものが来る。

import MyBar, {Foo} from 'components/export'
function App(){ 
     return <Foo/><MyBar/>
}

default宣言だけほしい場合は後のは書かなくてもよい。

import MyBar from 'components/export'
function App(){ 
     return <MyBar/>
}

名前を変えてexport

import するときじゃなくて、exportするときに名前を変えることもできる。

const Foo = () => {
}
const Bar = () => {
}
export {Foo as MyFoo, Bar}
import {MyFoo, Bar} from 'components/export'
function App(){ 
     return <MyFoo/><Bar/>
}

この時、export Foo as MyFoo だとだめ。export {Foo as MyFoo}としてimport側は import {MyFoo} from "components/export" とする。

たくさんexportしてるモジュールのimportが面倒な場合は*を使うとちょっと楽。

いっぱいexportしてるのを

export const Foo1 = () => {}
export const Foo2 = () => {}
export const Foo3 = () => {}
export const Foo4 = () => {}
export const Foo5 = () => {}
export const Foo6 = () => {}

受け取る側は、逐一調べてimportしないといけないの大変なので。

import {Foo1, Foo2, Foo3, Foo4, Foo5, Foo6 } from 'components/export'
function App(){ 
     return <Foo1/><Foo2/><Foo6/>
}

って逐一やらなくても

import * as F from 'components/export'
function App(){ 
     return <F.Foo1/><F.Foo2/><F.Foo6/>
}

とできる。