質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

簡易逆ジオコーディングサービスを利用して緯度・経度から、住所を取得したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,115

nagi2011

score 15

簡易逆ジオコーディングサービスを利用して、
緯度・経度から、住所を取得しようとしています。
以下のコードで、市町村までは取得できるのですが、
「local」配下の「section」が取得できません。
どのように取得できるのでしょうか。
(localは配列になっています。)

            // 結果JSONのデシリアライズ
            var desirializedData = (Dictionary<string, object>)Json.Deserialize(www.text);

            // 成功した場合のみ処理
            if ((long)desirializedData["status"] == 200)
            {
                // 都道府県+市区町村を文字列として保持
                var result = (Dictionary<string, object>)desirializedData["result"];
                var prefecture = (Dictionary<string, object>)result["prefecture"];
                var municipality = (Dictionary<string, object>)result["municipality"];
                var local = (Dictionary<string, object>)result["local"];
                //Address = (string)prefecture["pname"] + " " + (string)municipality["mname"];
                Address = (string)prefecture["pname"] + " " + (string)municipality["mname"] + " " + (string)local["section"] ;
            }

戻り値のサンプルは以下の通りです。
※実際に使用しているのJSON版なのですが、文字化けしてしまうので、xml版を貼り付けました。

xml <?xml version="1.0" encoding="UTF-8"?> <rgeocode xmlns="http://finds.jp/ts" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">   <status>200</status>   <result>     <prefecture>       <pcode>34</pcode>       <pname>広島県</pname>     </prefecture>     <municipality>       <mname>福山市</mname>       <mcode>34207</mcode>     </municipality>     <local>       <section>西深津町六丁目</section>       <homenumber>12</homenumber>       <distance>69.707053182466</distance>       <latitude>34.501616</latitude>       <longitude>133.384224</longitude>     </local>   </result>   <argument>     <latitude>34.5012296</latitude>     <longitude>133.384822</longitude>     <localradius>500</localradius>     <localmax>1</localmax>   </argument>   <meta name="thanks" content="このサービスは 国土交通省 提供 国土数値情報(行政区域) を利用しています" />   <meta name="thanks" content="このサービスは 国土交通省 提供 街区レベル位置参照情報および大字・町丁目レベル位置参照情報 を利用しています" /> </rgeocode>

【環境】
unity(c#)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • sakura_hana

    2019/04/03 11:16

    「取得できません」とのことですが、具体的にはどういうことでしょうか?(エラーが出る、nullになる、空文字になる等。エラーが出る場合はエラーメッセージを質問に追記お願いします)
    また、小数点付きの数字か要素の個数が怪しいと思うのですが、distance,latitude,longitudeを削ったJSONを渡した場合はどうなりますか?(www.textの代わりに自作した文字列を渡してみてください)

    キャンセル

  • SurferOnWww

    2019/04/03 11:24

    簡易逆ジオコーディングサービスというのはこれ https://www.finds.jp/rgeocode/index.html.ja のことですか? このページの「実行例」のセクションの「近畿中国四国農業研究センター」の JSON をクリックすると応答として返ってくる JSON 文字列を C# のオブジェクトにデシリアライズして「local」配下の「section」が文字列として取得できればいいのですか?

    キャンセル

  • SurferOnWww

    2019/04/03 11:41

    よく見てみれば Unity の話で、デシリアライズするのに MiniJSON というライブラリを使っているようですね。それの使用は必須で、C# では一般的に使われている JavaScriptSerializer とか Json.NET は使わないという条件ですか?

    キャンセル

回答 1

checkベストアンサー

0

>「local」配下の「section」が取得できません。どのように取得できるのでしょうか。

質問に対するコメントに書きましたが、簡易逆ジオコーディングサービスというのは

https://www.finds.jp/rgeocode/index.html.ja

のことで、このページの「実行例」のセクションの「近畿中国四国農業研究センター」の JSON をクリックすると応答として返ってくる JSON 文字列を、MiniJSON ライブラリを使って、C# のオブジェクトにデシリアライズして「local」配下の「section」を文字列として取得できればいいと理解してレスします。

質問者さんの開発環境で Visual Studio のデバッガが使えるかどうかわかりませんが、使えれば下の画像のように適当な場所にブレークポイントを置いてデシリアライズした結果の Dictionary<string, object> オブジェクト(質問者さんの場合は desirializedData)の構造を見てください。

イメージ説明

構造が分かれば目的の項目をどのように取得できるか分かると思います。上の画像には「local」配下の「section」を文字列として取得するコードもありますので見てください。

【追伸】

質問に対するコメントで、

C# では一般的に使われている JavaScriptSerializer とか Json.NET は使わないという条件ですか?

と書きましたが、Json.NET ライブラリを使った方法を紹介しておきます。自分的にはこちらがお勧めです。

問題はデシリアライズされる C# のクラス定義ですが、それは以下のようなサービスを利用すれば簡単です。

json2csharp
http://json2csharp.com/

簡易逆ジオコーディングサービス https://www.finds.jp/rgeocode/index.html.ja のページの「実行例」のセクションの「近畿中国四国農業研究センター」の JSON をクリックすると応答として返ってくる JSON 文字列を上記 json2csharp を利用して C# のクラス定義を取得すると以下の通りとなります。

public class Prefecture
{
    public int pcode { get; set; }
    public string pname { get; set; }
}

public class Municipality
{
    public string mname { get; set; }
    public int mcode { get; set; }
}

public class Local
{
    public string section { get; set; }
    public string homenumber { get; set; }
    public double distance { get; set; }
    public double latitude { get; set; }
    public double longitude { get; set; }
}

public class Result
{
    public Prefecture prefecture { get; set; }
    public Municipality municipality { get; set; }
    public List<Local> local { get; set; }
}

public class Argument
{
    public double latitude { get; set; }
    public double longitude { get; set; }
    public int localradius { get; set; }
    public int localmax { get; set; }
}

public class Meta
{
    public string name { get; set; }
    public string content { get; set; }
}

public class RootObject
{
    public int status { get; set; }
    public Result result { get; set; }
    public Argument argument { get; set; }
    public List<Meta> meta { get; set; }
}

上記が得られれば、Json.NET ライブラリを使って以下のコードで同じ結果が得られます。

RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(jsonText);

foreach (Local local in rootObject.result.local)
{
    Console.WriteLine(local.section);
}

MiniJSON でのデシリアライズの結果の Dictionary<string, object> の入れ子のオブジェクトの構造に頭を悩ますより、こちらの方がはるかに分かりやすいはずです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/03 22:16

    JsonConvert.DeserializeObjectを利用させて頂きました。
    やはり、dtoへの自動マッピングではないと可読性も低いですし。

    キャンセル

  • 2019/04/03 22:19

    ちなみに、他のAPIして取得処理については、以下のように取得していました。
    T ret = JsonConvert.DeserializeObject<T>(response.ToString(Formatting.None, new JavaScriptDateTimeConverter()));
    今回、MiniJSONを使っていたのは、サンプルソースがそうだったからというだけでした。
    Tは、戻り値のDTOのクラスをジュネリックで、
    JavaScriptDateTimeConverterを引数にいれているのは、日時取得の際にバグってしまうので入れました。

    キャンセル

  • 2019/04/03 22:21

    返答ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る