日本測地系の緯度経度を(誤って)世界測地系として地図上に表示した際の位置と距離を調べる

## 概要

- 日本測地系の緯度経度を(誤って)世界測地系として地図上にピン表示する
- 日本測地系の緯度経度を世界測地系に変換して地図上にピン表示する
- 両者の距離を算出する (日本測地系と世界測地系のズレ)
- 地図や緯度経度の算出は Ruby と [YOLP (Yahoo! Open Local Platform)](https://developer.yahoo.co.jp/webapi/map/) の API を利用する

## 日本測地系と世界測地系

- 日本測地系: 2002年4月1日まで使われていた測地系 (別名: Tokyo Datum)
- 世界測地系: 2002年4月1日から使われている測地系 (別名: 日本測地系2000、JGD2000)

[「測地成果2000」と「測地成果2011」｜国土地理院](https://www.gsi.go.jp/sokuchikijun/jgd2000-2011.html)

> 我が国では世界測地系を適用するため、平成１３年に測量法の一部を改正し、平成１４年４月１日から施行されました。また、測量法施行令の一部を改正する政令により、我が国の経度・緯度を世界測地系に変更するのに必要な数値が定められました。
> 
> 明治政府は、近代国家に不可欠な全国の正確な地図である５万分の１地形図を作るために、基準点網を全国に整備しました。この時採用された楕円体が、ベッセル楕円体です。そして、当時の東京天文台の経度・緯度が、天文観測により決定されました。この位置が現在の日本経緯度原点となっています。この測地基準系を「日本測地系」と呼んでいます。全国に設置された基準点の経度・緯度は、日本経緯度原点を絶対的な位置の基準として求められていったのです。
> 
> 一方、電波星を利用したVLBI観測や人工衛星観測により現代の科学的知識に基づいて設定された、世界共通に使える測地基準系を世界測地系といいます。世界測地系の楕円体の中心は、地球の重心と一致し地球の正確な形状と大きさに基づき設定されていますが、日本測地系の設定とは一致していません。 また、我が国の測地基準点成果は、明治時代の測量機器や測量技術による制約と過去１００年間の日本列島の地殻変動の影響等で基準点網にひずみが生じていました。
> 
> ＧＰＳ（全地球測位システム）及びＧＩＳ（地理情報システム）というコンピュ－タシステムによる位置情報の測定・利用技術が出現し、急速な普及が見込まれる中、両技術に対応する基準として、世界測地系に基づいた、高精度な測地基準点成果及び地図成果が求められていました。また、世界測地系への移行は世界的な動向であり、導入のメリットは計り知れません。

## 日本測地系の緯度経度を世界測地系に変換する

YOLP 測地系変換API を使う。

[YOLP\(地図\):測地系変換API \- Yahoo\!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/datum.html)

> 緯度経度を日本測地系と世界測地系で相互変換します。

> このプログラムは、国土地理院長の承認を得て、同院の技術資料H・1-No.2「測地成果2000のための座標変換ソフトウェアTKY2JGD」を利用し作成したものである。（承認番号 国地企調第187号平成22年9月17日）

## 日本測地系と世界測地系はどれぐらいズレるのか

日本測地系の緯度経度を誤って世界測地系として地図上に表示すると、正しい位置よりも南東方向へ450メートル程度ズレる。

[３　日本測地系と世界測地系 ｜国土地理院](https://www.gsi.go.jp/LAW/G2000-g2000-h3.htm)

> では、日本測地系は、世界測地系とどのくらい違っているのでしょうか？
> 
> 　例えば、日本測地系の経緯度で表されている地点を、世界測地系の経緯度で表わすと、東京付近では、経度が約－12秒、緯度が約＋12秒変化します。これを距離に換算すると、北西方向へ約450ｍずれることに相当します。

## 日本測地系の緯度経度を(誤って)世界測地系として地図上に表示した際の位置と距離を調べるためのソースコード

Ruby によるプログラム。

```ruby
require 'json'
require 'open-uri'

class YOLP

  def initialize(appid)
    @appid = appid
  end

  def get(base_url, params)
    url = base_url + '?' + URI.encode_www_form(params)
    open(url, 'User-Agent' => "Yahoo AppID: #{@appid}").read
  end

  # 世界測地系(JGD2000)の緯度経度を返す
  def jgd2000(tky)
    # YOLP 測地系変換API
    base_url = 'https://map.yahooapis.jp/datum/V1/datumConvert'
    params = {
      'coordinates' => "#{tky[:lon]},#{tky[:lat]}",
      'output' => 'json',
    }
    json = get(base_url, params)
    data = JSON.parse(json)
    ll = data['Feature'][0]['Geometry']['Coordinates'].split(',')
    # 小数第六位まで求める(四捨五入)
    {:lat => ll[1].to_f.round(6), :lon => ll[0].to_f.round(6)}
  end

  # 2点間の距離(km)を返す
  def distance(poi1, poi2)
    # YOLP 2点間距離API
    base_url = 'https://map.yahooapis.jp/dist/V1/distance'
    params = {
      'coordinates' => "#{poi1[:lon]},#{poi1[:lat]} #{poi2[:lon]},#{poi2[:lat]}",
      'output' => 'json',
    }
    json = get(base_url, params)
    data = JSON.parse(json)
    data['Feature'][0]['Geometry']['Distance'].to_f
  end

  # 地図画像を返す
  def map(poi, jgd)
    # YOLP Yahoo!スタティックマップAPI
    base_url = 'https://map.yahooapis.jp/map/V1/static'
    params = {
      'width'  => 600,
      'height' => 600,
      'l' => "0,255,0,100,5,#{poi[:lat]},#{poi[:lon]},#{jgd[:lat]},#{jgd[:lon]}",
      'pinx' => "#{poi[:lat]},#{poi[:lon]},日本測地系(誤り),red",
      'pino' => "#{jgd[:lat]},#{jgd[:lon]},世界測地系(正しい),blue",
    }
    get(base_url, params)
  end

  # 全体地図画像を返す
  def large_map(pois)
    # YOLP Yahoo!スタティックマップAPI
    base_url = 'https://map.yahooapis.jp/map/V1/static'
    params = {
      'width'  => 600,
      'height' => 600,
      'pin1' => "#{pois[0][:jgd][:lat]},#{pois[0][:jgd][:lon]},#{pois[0][:name]}",
      'pin2' => "#{pois[1][:jgd][:lat]},#{pois[1][:jgd][:lon]},#{pois[1][:name]}",
      'pin3' => "#{pois[2][:jgd][:lat]},#{pois[2][:jgd][:lon]},#{pois[2][:name]}",
    }
    get(base_url, params)
  end
end

# 日本測地系の緯度経度
# 調査用に北海道、愛知県、沖縄県の3地点を挙げる
pois = [
  {:name => 'ヲンネモトチャシ跡', :lat => 43.386039, :lon => 145.786660},
  {:name => '名古屋城 天守',      :lat => 35.182463, :lon => 136.902039},
  {:name => '首里城 守禮門',      :lat => 26.214218, :lon => 127.718750},
]

appid = 'YOUR APPLICATION ID' # アプリケーションIDを指定
yolp = YOLP.new(appid)

pois.each_with_index do |poi, idx|
  # 世界測地系の緯度経度を取得
  jgd = yolp.jgd2000(poi)
  # 日本測地系と世界測地系の距離を計算
  dist = yolp.distance(poi, jgd)
  # 地図画像を取得
  image = yolp.map(poi, jgd)
  # 各種情報を出力
  puts "#{poi[:name]}"
  puts "日本測地系: #{poi[:lat]}, #{poi[:lon]}"
  puts "世界測地系: #{jgd[:lat]}, #{jgd[:lon]}"
  puts "距離: #{(dist * 1000).to_i}メートル"
  puts ''
  open("map_#{idx}.png", 'wb').write(image)
  # 全体地図に使うためセット
  poi[:jgd] = jgd
end

# 全体地図を出力
open("map.png", 'wb').write(yolp.large_map(pois))
```

## 実行結果

macOS Catalina + Ruby 2.5.7 で実行。

```
ヲンネモトチャシ跡
日本測地系: 43.386039, 145.78666
世界測地系: 43.38859, 145.782565
距離: 436メートル

名古屋城 天守
日本測地系: 35.182463, 136.902039
世界測地系: 35.185688, 136.899084
距離: 447メートル

首里城 守禮門
日本測地系: 26.214218, 127.71875
世界測地系: 26.218139, 127.716889
距離: 472メートル
```

いずれも450メートル程度ずれているのがわかる。
北東の地点(北海道)は距離のずれが少なく、南西の地点(沖縄県)は距離のずれが大きい。

### 全体地図

![map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/dcbc566d-8f93-8ac8-7465-7797f1b81604.png)

### 北海道 ヲンネモトチャシ跡

```
ヲンネモトチャシ跡
日本測地系: 43.386039, 145.78666
世界測地系: 43.38859, 145.782565
距離: 436メートル
```

![map_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/f78d2ce1-09c2-e003-1232-88212e0fbe28.png)

### 愛知県 名古屋城 天守

```
名古屋城 天守
日本測地系: 35.182463, 136.902039
世界測地系: 35.185688, 136.899084
距離: 447メートル
```

![map_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/46f0b070-f595-a0ca-b9c7-85487dad4416.png)

### 沖縄県 首里城 守禮門

```
首里城 守禮門
日本測地系: 26.214218, 127.71875
世界測地系: 26.218139, 127.716889
距離: 472メートル
```

![map_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/4b758b99-c656-93f6-2ef6-dcdd00e40a71.png)

## 参考資料

- [世界測地系の導入に関して｜国土地理院](https://www.gsi.go.jp/LAW/jgd2000-AboutJGD2000.htm)
- [「測地成果2000」と「測地成果2011」｜国土地理院](https://www.gsi.go.jp/sokuchikijun/jgd2000-2011.html)
- [座標変換ソフトウェア　TKY2JGD｜国土地理院](https://www.gsi.go.jp/sokuchikijun/tky2jgd.html)
- [測地系 \- Wikipedia](https://ja.wikipedia.org/wiki/%E6%B8%AC%E5%9C%B0%E7%B3%BB)
- [YOLP\(地図\):測地系変換API \- Yahoo\!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/datum.html)
- [YOLP\(地図\):2点間距離API \- Yahoo\!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/distance.html)
- [YOLP\(地図\):Yahoo\!スタティックマップAPI \- Yahoo\!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/static.html)