# 位置参照情報を用いて市町村の代表点を算出したい
at GeoSaturday Tokyo 2019/12/14
位置参照情報にある大字・丁目の代表点から市町村ごとに重心を求めてみたい。
市町村ごとに1ポイントがあればよく、代表点の代表としての正当性は求めない。
debian で MySQL サーバを起動
```shell
$ docker pull mysql:latest
# 稼働中の MariaDB があったため13306ポートをコンテナに割り当て
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=my-mysql-password -p 13306:3306 -d mysql:latest
```
Windows から MySQL Workbench で接続。
データベースとテーブルを作成する。
```sql
CREATE DATABASE isj;
CREATE TABLE `isj_point` (
MuniCode CHAR(20) NOT NULL,
MuniName CHAR(20) NOT NULL,
DistCode CHAR(20) NOT NULL,
DistName CHAR(20) NOT NULL,
lat DECIMAL(9,6) NOT NULL,
lon DECIMAL(9,6) NOT NULL,
location GEOMETRY SRID 4326 NOT NULL,
SPATIAL KEY (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
CSV からのインポートがはじかれたため、Windows で位置参照情報をダウンロード、頭の悪い PowerShell コマンドで INSERT クエリを作成。
```powershell
PS> $insertSQLHead=("INSERT INTO `isj_point` (MuniCode, MuniName, DistCode, DistName, lat, lon, location) VALUES ")
PS> Get-Content .\11_2018.csv -Encoding Default | Select-Object -skip 1 | % { $line=$_.split(",");Write-Output ("(" + $line[2] + ", " + $line[3] + ", " + $line[4] + ", " + $line[5] + ", "+ $line[6] + ", " + $line[7] + ", " + "ST_GeomFromText('POINT(" + $line[6].replace("`"","") + " " + $line[7].replace("`"","") + ")', 4326)),") } | Set-Variable values;Out-File ./insertsql.sql -Encoding UTF8 -inputObject $($insertSQLHead + [regex]::Replace($values, ",$", ";"))
```
出来上がった SQL を Workbench に貼り付けて実行。
MySQL で Workbench でクエリを実行し、重心を計算させる。
```sql
SELECT
MuniCode,
ST_AsText(
ST_Centroid(
ST_Union(locaion)
)
)
FROM
isj_point
GROUP BY
MuniCode
```
MySQL の ST_Union では3つ以上の地物を Union できないためエラーが発生する。
- 順次 ST_Union してから ST_Centroid する
- あらかじめ MultiPoint を生成してから ST_Centroid する
といった対応が必要
PostGIS や GeoPackages(ogr2ogr でクエリを実行) では計算可能。