TransWikia.com

picojsonで階層構造のjsonファイルを読ませたい

スタック・オーバーフロー Asked by ksk4 on September 1, 2021

VisualStudio2012 C++に picojson を組み込んで json ファイルを読みこませようとしたのですが、json ファイルの階層構造に対応した読み込みが意図した通りできません。
(一番欲しいデータは、jsonファイルにある"polygonListのarrayにある配列( pointId, X, Y です)

以前お聞きした質問 を参考に読ませようとしたのですが、"field"をarray型で読ませたあと
中のPointA, PointB,…およびarray型のpolygonListを読ませようとしたのですがうまくいきません。


読ませたいjsonファイル

{
    "field": [
        {
             "PointA": "10",
             "PointB": "12",
             "fieldId": "12345",
             "polygonList": [
                 {
                     "pointId": "0",
                     "X": "36.4",
                     "Y": "137.8"
                 },
                 {
                     "pointId": "1",
                     "X": "36.4",
                     "Y": "137.8"
                 },
                 {
                     "pointId": "2",
                     "X": "36.4",
                     "Y": "137.8"
                 },
                 {
                     "pointId": "3",
                     "X": "36.4",
                     "Y": "137.8"
                 }
             ]
        }
    ]
}

試したこと

作成していたソースコードの部分

  // ファイルを読み込むための変数
  std::ifstream fs;

  // ファイルを読み込む
  fs.open("sample.json", std::ios::binary);

  // 読み込みチェック
  // fs変数にデータがなければエラー
  assert(fs);

  // Picojsonへ読み込む
  picojson::value val;
  fs >> val;

  // fs変数はもう使わないので閉鎖
  fs.close();

  // Playerの名前を取得
    picojson::object& obj = val.get<picojson::object>();
    picojson::array& feat = obj["field"].get<picojson::array>();

で、fieldの範囲をarray型で取得しておいて

for (unsigned int i = 0; i < feat.size(); i++) {

として、複数のfieldに対応した読込をさせてようとしていました。しかし、参考にした回答の通りに
各arrayをobjectにして変換して各タグの値を読ませる方法をとろうとしたのですが

picojson::object& featN = feat[i].get<picojson::object>();
double hoge = featN["PointA"].get<double>();

という記述をしてみましたが、エラーがでて通りませんでした。(get()の行の処理でエラーがおきます)
array型の座標値についても

picojson::array& pathD2 = paths["polygonList"].get<picojson::array>();
for (unsigned int k = 0; k < pathD2.size(); k++) {
        double id = pathD2["pointId"].get<double>();
        double x = pathD2["X"].get<double>();
        double y = pathD2["Y"].get<double>();
}

と記述してもエラーが出て取得できませんでした。

以前質問して回答をいただいた処理とほぼ同じ処理なので、動くと思ったのですがどこか異なるのか、うまく動作しない状態です。

何か記述方法に間違いがあるのでしょうか。
記述方法の間違いなどありましたらご指摘いただけますよう、よろしくお願いいたします。

One Answer

この前と違ってvalue部分が"で囲まれて文字列となっているので、いったんstd::stringgetしてstodとかstrtodで変換すれば良いでしょう。
以下のようになります。

for (unsigned int i = 0; i < feat.size(); i++) {
    picojson::object& featN = feat[i].get<picojson::object>();

    double pointA = std::stod(featN["PointA"].get<std::string>());
    double pointB = std::stod(featN["PointB"].get<std::string>());
    std::string fieldId = featN["fieldId"].get<std::string>();
    std::cout << "PointA: " << pointA << ",  PointB: " << pointB << ",  fieldId: " << fieldId << std::endl;

    picojson::array& pgList = featN["polygonList"].get<picojson::array>();  // 変数名は変更
    for (unsigned int k = 0; k < pgList.size(); k++) {
        
        picojson::object& pg = pgList[k].get<picojson::object>();
        
        double id = std::stod(pg["pointId"].get<std::string>());
        double x = std::stod(pg["X"].get<std::string>());
        double y = std::stod(pg["Y"].get<std::string>());
        std::cout << "    pointId: " << id << ",  X: " << x << ",  Y: " << y << std::endl;
    }
}

Answered by kunif on September 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP