Home > other >  Powershell: How to create a JSON in the GeoJSON structure
Powershell: How to create a JSON in the GeoJSON structure

Time:09-12

I'm having problems creating a GeoJSON file. I'm looping through video files extracting info such as datetaken, name, coordinates, etc. I want to write this data to a JSON file so I can plot them on googlemaps. But I'm stuck. I can't get the lat/lng in the correct json format.

The GeoJSON structure is as follows:

"features": [{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Lost Islands"
  }
]}

My code, no matter what I try, generates the following or something similar.

"features": [{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": "System.Collections.Hashtable"
  },
  "properties": {
    "name": "Lost Island"
  }
]}

My code (simplified for here):

cls

$dirName = "C:\temp"
$filter = "*.mp4"
$jsonBase = @{}
$features = New-Object System.Collections.ArrayList
$coordinatesList = New-Object System.Collections.ArrayList
$coordinates = New-Object System.Collections.ArrayList
$geometry = New-Object System.Collections.ArrayList

Get-ChildItem $dirName -include $filter -recurse -File | foreach {
    $lat = 10.12345
    $lng = 20.12345
    $vidDate = "2022-09-11T12:00:00.000000Z"
    $coordinatesList = New-Object System.Collections.ArrayList
    $coordinatesList.Add(@{$lat=$lng;})
    $coordinates = New-Object System.Collections.ArrayList
    $coordinates.Add(@{"coordinates"=$coordinatesList})
    $geometry = @{}
    $geometry.Add("coordinates",$coordinates)
    $geometry.Add("type","Point")
    
    $features.Add(@{"geometry"=$geometry;
                    "type" = "Feature";
                    "properties" = @{"fileName"=($_).Name;"pathToFile"=($_).FullName;"takenDate"=$vidDate;}
    })
}
$jsonBase.Add("features",$features)
$jsonstring = $jsonBase | ConvertTo-Json -Depth 3
Write-Host $jsonstring 

Any thoughts on where I'm going wrong?

CodePudding user response:

Thanks to mclayton for spotting the depth mistake.
I still had to make a small change to get it in the correct format. Here's the final code:

cls

$dirName = "C:\temp"
$filter = "*.mp4"
$jsonBase = @{}
$features = New-Object System.Collections.ArrayList
$geometry = New-Object System.Collections.ArrayList

Get-ChildItem $dirName -include $filter -recurse -File | foreach {
    $lat = 10.12345
    $lng = 20.12345
    $vidDate = "2022-09-11T12:00:00.000000Z"
    $geometry = @{}
    $geometry.Add("coordinates",($lat,$lng))
    $geometry.Add("type","Point")
    
    $features.Add(@{"geometry"=$geometry;
                    "type" = "Feature";
                    "properties" = @{"fileName"=($_).Name;"pathToFile"=($_).FullName;"takenDate"=$vidDate;}
    })
}
$jsonBase.Add("features",$features)
$jsonstring = $jsonBase | ConvertTo-Json -Depth 10
Write-Host $jsonstring 

CodePudding user response:

The issue is in this line:

$coordinatesList.Add(@{ $lat = $lng })

$lat will become a double type Key on your hashtable and ConvertTo-Json only allows string type keys, probably you got this error but didn't notice it:

$lat = 10.12345
$lng = 20.12345
@{ $lat = $lng } | ConvertTo-Json

Errors with

The type 'System.Collections.Hashtable' is not supported for serialization or deserialization of a dictionary. Keys must be strings.

But also, looking at your expected Json, you most likely wanted coordinates to be an array instead of a key / value pair. Here is a streamlined version of your code:

@{
    features = @(Get-ChildItem $dirName -Filter $filter -Recurse -File | ForEach-Object {
        $lat = 10.12345
        $lng = 20.12345
        $vidDate = "2022-09-11T12:00:00.000000Z"

        [ordered]@{
            type     = 'Feature'
            geometry = [ordered]@{
                type        = 'Point'
                coordinates = $lat, $lng # Should be Array Here
            }
            properties = [ordered]@{
                fileName   = $_.Name
                pathToFile = $_.FullName
                takenDate  = $vidDate
            }
        }
    }
)} | ConvertTo-Json -Depth 99
  • Related