halaxa / json-machine

Efficient, easy-to-use, and fast PHP JSON stream parser
Apache License 2.0
1.08k stars 65 forks source link

GeoJSON properties only #112

Open theamnesic opened 4 months ago

theamnesic commented 4 months ago

Hi!

I'm working with GeoJSON large files. An example of entry:

{
   "type":"FeatureCollection",
   "features":[
      {
         "type":"Feature",
         "id":"500410000A0055",
         "geometry":{
            "type":"Polygon",
            "coordinates":[
               [
                  [
                     -1.8556355,
                     49.6650877
                  ],
                  [
                     -1.8556206,
                     49.6650552
                  ],
                  [
                     -1.8555928,
                     49.6650017
                  ],
                  [
                     -1.8552808,
                     49.6650365
                  ],
                  [
                     -1.85531,
                     49.6651397
                  ],
                  [
                     -1.8555869,
                     49.6650975
                  ],
                  [
                     -1.8556355,
                     49.6650877
                  ]
               ]
            ]
         },
         "properties":{
            "id":"500410000A0055",
            "commune":"50041",
            "prefixe":"000",
            "section":"A",
            "numero":"55",
            "contenance":248,
            "arpente":false,
            "created":"1902-09-20",
            "updated":"2021-03-09"
         }
      }
   ]
}

I only need some properties informations like contenance, section and numero. From now, I using this:


$datas = Items::fromFile('datas/50041.json', ['pointer' => '/features']);

foreach ($datas as $key => $data) {

  if ($data->properties->contenance == 248) {

    echo $data->properties->commune;
    echo $data->properties->section;
    echo $data->properties->numero;
    //Etc

  }

}

But, I don't need geometry who takes a lot of time to load. So I tried to use this more precise pointer:


$datas = Items::fromFile('datas/50041.json', ['pointer' => '/features/-/properties']);

foreach ($datas as $key => $data) {
  var_dump($data);
}

But JSON Machine don't return an object...

So, is it possible to pointer GeoJSON properties as an object with JSON Machine without load geometry?

Thanks!

halaxa commented 3 months ago

Hi, thanks for the question, and sorry for the delay. I had much stuff going on in life 😄. I'll try to get to it asap. In the meantime, you can try dev-recursive version from #36 if it works for you. Let me know.

theamnesic commented 1 month ago

HI!

I tried this:


$datas = Items::fromFile('datas/50041.json', ['recursive' => true]);

foreach ($datas as $data) {

  foreach ($data as $d) {

    foreach ($d as $dKey => $dValue) {

      if ($dKey === 'properties') {

        if ($dValue->contenance == 248) {

          echo $dValue->commune;
          echo $dValue->section;
          echo $dValue->numero;
        }

      }

    }

  }

}

... but it doesn't seem more efficient.

Is it the good way to use recursive ?

halaxa commented 1 month ago

What exactly do you mean by efficient? Quicker or less memory usage?

theamnesic commented 1 month ago

This is the same execution time with the two methods.

halaxa commented 1 month ago

Yes. The recursive method is there to lower memory consumption in bigger subtrees. The speed is more or less the same.