[CmdletBinding()] param ( [string] $DataSource = './Gesamtergebnis-Gemeinderatswahl-2019_stripped.csv' ) function Get-OverpassStreet { param ( [string] $Name ) if (!$cache.$Name) { $query = @' '@ -f $Name $overpassSplat = @{ Method = 'Post' Uri = 'https://overpass-api.de/api/interpreter' Body = $query } $cache.$Name = Invoke-RestMethod @overpassSplat } $cache.$Name } if (Test-Path ./cache.xml) { $cache = Import-Clixml ./cache.xml } else { $cache = @{} } $data = Import-Csv $DataSource $greenParty = ($data[0].PSObject.Properties.Name -like '*Grüne*')[0] $dataMeasure = $data.$greenParty | Where-Object {$_ -match '%$'} | ForEach-Object {$_ -replace '%$'} | Measure-Object -Minimum -Maximum $minimumResultValue = $dataMeasure.Minimum $maximumResultValue = $dataMeasure.Maximum # nested array instead of hashtable, because hashtable keys are case-insensitive $replacementList = @( ,('strasse','straße') ,('Strasse','Straße') ,('Albrecht-von-Bernegger-S','Albrecht-von-Bernegger-Straße') ,('Geschwister-Scholl-Str.','Geschwister-Scholl-Straße') ,('Albert-Schweitzer-Str.','Albert-Schweitzer-Straße') ,('Freiherr-V-Stein-Str','Freiherr-vom-Stein-Straße') ,('Nussbaumweg','Nußbaumweg') ,('Elstarweg ','Elstarweg') ) $featureList = Import-Csv ./polling_stations.csv | Sort-Object -Unique Strassenname | Group-Object Concat | ForEach-Object { $pollingStation = $_ $electionResultObject = $data | Where-Object Description -eq $pollingStation.Name if ($electionResultObject) { # form into an array for easier handling and to preserve sorting $electionResultArray = $electionResultObject.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'Description') { [pscustomobject]@{ Party = $_.Name ResultValue = [decimal](($_.Value -eq '-' ? 0 : $_.Value) -replace '%$') Formatted = $_.Value } } } | Sort-Object -Descending ResultValue Write-Host $pollingStation.Name $electionResultString = ($electionResultArray | ForEach-Object { $_.Formatted + "`t" + $_.Party }) -join "`n" $greenResultValue = ($electionResultArray | Where-Object Party -eq $greenParty).ResultValue $colorGreen = (($greenResultValue - $minimumResultValue) * (100 - 220)) / ($maximumResultValue - $minimumResultValue) + 220 $color = "rgb(0, $colorGreen, 0)" $opacity = (($greenResultValue - $minimumResultValue) * (1.0 - 0.4)) / ($maximumResultValue - $minimumResultValue) + 0.4 } else { $electionResultString = 'no data available' $opacity = 0.5 $color = '#ff00ff' } $umapOptiones = [PSCustomObject]@{ color = $color weight = 10 opacity = $opacity } $pollingStation.Group | ForEach-Object { $street = $_.Strassenname foreach ($replacement in $replacementList) { $street = $street.Replace($replacement[0], $replacement[1]) } $description = $street $description += "`n`n" $description += $electionResultString $overpassResult = Get-OverpassStreet -Name $street if (!$overpassResult.osm.way.nd) { Write-Error ('way "{0}" for polling station "{1}" probably not found' -f $street,$pollingStation.name) return } $overpassResult.osm.way | ForEach-Object { $coordinateList = $_.nd.ref | ForEach-Object { $overpassResult.osm.node | Where-Object id -eq $_ | ForEach-Object{ ,($_.lon,$_.lat) } } [PSCustomObject]@{ type = 'Feature' properties = [PSCustomObject]@{ _umap_options = $umapOptiones name = $pollingStation.Name description = $description } geometry = [PSCustomObject]@{ type = 'LineString' coordinates = $coordinateList } } } } } $output = [PSCustomObject]@{ type = 'FeatureCollection' features = $featureList } $output | ConvertTo-Json -Depth 99 | Out-File output.geojson $cache | Export-Clixml ./cache.xml