読者です 読者をやめる 読者になる 読者になる

YOLP(地図)に市区町村の町目境界をマッピングする

ASP.NET MVC5 Azure C# Map

こんにちは。beaglesoftの真鍋です。

ちょっとお試しなのですが、YOLP(地図):YOLP(地図) - Yahoo!デベロッパーネットワークを利用して市区町村の町目境界を表示するアプリケーションを削井してみました。まだ、複数の市区町村が表示されるときに中心が1つ目の表示エリアになったり、表示倍率が変わらなかったりするのですがとても楽しく作成できたので公開してみます。

screencapture-yahoogeo20160410094759-azurewebsites-net-home-index-1460351618108.png (740.5 kB)

beaglemap - beaglemap

http://yahoogeo20160410094759.azurewebsites.net/home/index

できること

住所を入力することで市区町村の町目境界を表示します。

操作方法

検索ボタンの横に表示したい住所を入力します。住所は市まで含まれている住所が必要です。初期表示が弊社の事務所がある「千葉県松戸市横須賀2」となっていますが、例えば、「千葉県松戸市」で検索するとこんな感じになります。

9Cd7RMA9Pz.gif (10.4 MB)

APIについて

検索時に表示される町丁目境界のデータをAPIで取得することが可能です。町丁目のデータについてはA002005212010.pdf (170.0 kB)の内容を出力しています。

  • レスポンス形式:json
  • 取得できる項目
    • status:ステータスで正常終了がsuccess、エラーがfailとなります。
    • errorMessage:ステータスがfailのときにエラー内容を設定します。
    • chomokuRegionApiViewModels:検索結果の町丁目単位を保持します。
      • id:町丁目単位でユニークなキーを設定します。
      • kenCode:都道府県コードを設定します。
      • kenName:都道府県名を設定します。
      • cityCode:市区町村番号
      • gstName:郡市・特別区・政令指定都市名 を設定します。
      • kihon1Code:町字コード
      • cssName:区町村名
      • centralPoint:検索結果の町丁目の中心を保持します。
        • latitude:緯度
        • longtitude:経度
      • rangePoints:検索結果の町丁目の緯度経度の配列を保持します。
        • latitude:緯度
        • longtitude:経度

curlとjqを利用する

curlを利用して以下の通り実行することができます。

$ curl http://yahoogeo20160410094759.azurewebsites.net/api/v1/range-points-by-address/%E5%8D%83%E8%91%89%E7%9C%8C%E6%9D%BE%E6%88%B8%E5%B8%82%E6%A8%AA%E9%A0%88%E8%B3%802 | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2794  100  2794    0     0   2726      0  0:00:01  0:00:01 --:--:--  2728
{
  "status": "success",
  "errorMessage": "",
  "chomokuRegionApiViewModels": [
    {
      "id": 88216,
      "kenCode": "12",
      "kenName": "千葉県",
      "cityCode": "207",
      "gstName": "松戸市",
      "kihon1Code": "1350",
      "cssName": "横須賀2丁目",
      "centralPoint": {
        "latitude": 35.83525,
        "longtitude": 139.90906
      },
      "rangePoints": [
        {
          "latitude": 35.8365380962265,
          "longtitude": 139.910554562263
        },
...
      ]
    }
  ]
}

ChromeのPostmanを使用する

ChromeのPostman | Supercharge your API workflowなどのツールを利用して取得することができます。

ENpAEmqmqu.gif (903.8 kB)

プログラム言語から取得する

プログラム言語から取得する場合、Httpリクエストでデータを取得します。動作するサンプルは下記のGitHubを参照してください。

beaglesoftjp/beaglemap-csharp-example: beaglemapをC#で利用するときのサンプルプロジェクトです。

 const string url =
    "http://yahoogeo20160410094759.azurewebsites.net/api/v1/range-points-by-address/%E5%8D%83%E8%91%89%E7%9C%8C%E6%9D%BE%E6%88%B8%E5%B8%82%E6%A8%AA%E9%A0%88%E8%B3%802";

var request = WebRequest.Create(url);
var response = request.GetResponse();
Console.WriteLine(response);

foreach (var header in response.Headers)
{
    Console.WriteLine($"{header}:{response.Headers[header.ToString()]}");
}

using (var stream = response.GetResponseStream())
{
    if (stream == null)
    {
        Console.WriteLine("本文が取得できませんでした。");
        return;
    }

    using (var reader = new StreamReader(stream))
    {
        var jsonString = reader.ReadToEnd();
        Console.WriteLine("JSON ==========");
        Console.WriteLine(jsonString);
        Console.WriteLine("JSON ==========");
        Console.WriteLine("");

        var result = JsonConvert.DeserializeObject<ChomokuResultApiViewModel>(jsonString);
        Console.WriteLine($"status:{result.Status}");
        Console.WriteLine($"errorMessage:{result.ErrorMessage}");

        foreach (var region in result.ChomokuRegionApiViewModels)
        {
            Console.WriteLine($"chomokuRegionApiViewModel.Id:{region.Id}");
            Console.WriteLine($"chomokuRegionApiViewModel.KenCode:{region.KenCode}");
            Console.WriteLine($"chomokuRegionApiViewModel.KenName:{region.KenName}");
        }

        Console.WriteLine("...");
    }
    
}

データについて

町目境界を表示するためのデータは総務省のデータを Elasticsearch にぶち込んで、緯度経度から市区町村の何丁目までを取り出す - Qiitaを参考にさせていただきました。データの取得が大変ですが、すべてのデータを取得しました。

技術的なはなし

技術的にはASP.NET MVC5(C#)とSQL Serverで構築しました。ポリゴンの扱いはちょっと戸惑ってました。何回やっても正しく表示されないことに悩まされました。そのときは、SQL Server Spatial クイックツアー(1/7) - hogemanのコアダンプ(´皿`;)を参考にさせていただきました。(そうなんです。ポリゴンの右巻きと左巻きを知らなかったのです。ずっと町目以外が選択範囲となっていて…)

また、サーバーについては当初AWSを利用していたのですが、開発の途中からMicrosoft Azureを利用するようにしました。理由はデプロイが簡単だったためです。簡単に利用している構成をメモします。

  1. app serviceの無料プラン
  2. SQL データベースのStandard S0 プラン

※本当はSQL データベースもBasicプランにしたかったのですが、あまりにも遅いのでStandard S0プランにしました。

制限事項

動作環境のスペックが厳しいため、同一IPアドレスからのアクセスは2秒以上の間隔をあけるような制約を設けています。

まとめ

地図を利用したアプリケーションはこれまで業務システムの構築が多かった私にとってとっても楽しかったです。これから、いろいろな情報を地図上に表示して業務システムでの利用を進めたいと思ってます。たぶん、ウェブ進化論 本当の大変化はこれから始まる (ちくま新書)が流行ったころの技術(マッシュアップとか)なのかもしれませんが、とても楽しいですね。