Perl obk csv2json.pl: verschil tussen versies

Uit wiki.openbomenkaart.org
Naar navigatie springen Naar zoeken springen
(Nieuwe pagina aangemaakt met '==Download data archief van STRATO== Download met FileZilla alle folders binnen /data/.. ==Download perl bestanden (6) van STRATO== *Haal alle perl files die met...')
 
 
(64 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 1: Regel 1:
==Download data archief van STRATO==  
Terug naar [[perl scripts|Perl scripts]]
 
script naam is eigenlijk '''obk_csv2json.pl''' (incl underscore)
 
Hoofddoel: Dit script vormt een gemeentebestand in csv formaat om naar een json bestand, klaar om in '''obk.htm''' ingeladen te worden. 
 
Tevens genereert het tellingen, en input voor een tile set die in editor ID gebruikt kan worden om species, positie en admin_ref over te halen naar OSM.
 
'''Main script:
*[https://openbomenkaart.org/scripts/perl/obk_csv2json.pl obk_csv2json.pl]'''
'''Modules
*[https://openbomenkaart.org/scripts/perl/obk_counts.pl obk_counts.pl]
*[https://openbomenkaart.org/scripts/perl/obk_normalize.pl obk_normalize.pl]
*[https://openbomenkaart.org/scripts/perl/obk_parse_csv.pl obk_parse_csv.pl]
*[https://openbomenkaart.org/scripts/perl/obk_report.pl obk_report.pl]
*[https://openbomenkaart.org/scripts/perl/obk_setup.pl obk_setup.pl]
 
==Initieel==
===Download data archief van STRATO===  
Download met FileZilla alle folders binnen /data/..
Download met FileZilla alle folders binnen /data/..


==Download perl bestanden (6) van STRATO==
===Download perl bestanden (6) van STRATO===


*Haal alle perl files die met obk_.. beginnen op van STRATO server en sla die lokaal op (allemaal in dezelfde folder ../perl..)
*Haal alle perl files die met obk_.. beginnen op van STRATO server en sla die lokaal op (allemaal in dezelfde folder ../perl..)
Regel 13: Regel 31:
  obk_report.pl    rapporteer over de uitkomst
  obk_report.pl    rapporteer over de uitkomst


==Test obk_csv2json.pl met een bestaand bestand==
===Test met een bestaand bestand===
 
Open al deze bestanden in de IDE.
 
Kies voor welke gemeente je aan de slag wilt. In obk_setup.pl staat vanaf regel 55 een serie bestanden in commentaar (begint met #)
 
Activeer bijvoorbeeld Arnhem door de hash symbol weg te halen. Save obk_setup.pl.
 
[[Bestand:Invoerbestanden voor obk csv2json.png|thumb|left|400px]]<br clear=all>
 
Klik daarna in de IDE de hoofdmodule aan (obk_csv2json.pl), en toets F7 ("Run without debugging"), klik "OK"
 
In window 'Run output' verschijnt de voortgangslog.
 
Bijna onderaan in die log staat 'Ready'. Dan heeft het script normaal gelopen.
 
Er kunnen daar nog andere regels achteraan volgen, die komen dan uit ./scripts/perl/STDERR.txt
Als het script niet goed ten einde komt, is er geen 'Ready' en worden foutboodschappen uit STDERR.txt ook niet op het scherm getoond,
Altijd goed om dan even zelf te kijken wat er in ./scripts/perl/STDERR.txt staat.
 
[[bestand:Run perl.png|thumb|left|400px]]<br clear=all>
 
[[bestand:Perl tutorial arnhem.png|thumb|left|400px|output (bestanden met datum 02/18/2023)]]<br clear=all>
 
==Voeg nieuwe gemeente 'Demo' toe==
 
Prepareer bestand voor een nieuwe gemeente (converteer zonodig eerst coordinaten naar lengte- en breedtegraden via QGIS) en sla op in ./bomen/data/demo/gemeente/yyyy_mm_dd/obk_demo_in.csv
 
Voeg een regel toe aan obk_setup.pl voor dit nieuwe invoerbestand 'obk_demo_in.csv'
 
Voeg onderstaande sectie toe in obk_parse_csv.pl in, waar de beschikbare velden en hun kolom titels nog ingevuld moeten.(sortering is alfabetisch)
 
# Demo
  if ($csv_columns eq 'demo') 
  {
    $valid_city = 1 ;
    ($id, $species_nl, $species, $stamdiameterklasse,
      $hoogte, $plantjaar, $beheerder, $locatie,
      $long, $lat) = ($csv -> fields ()) [$..,$..,$..,$.., (bijv. [$A,$F,$G,$H etc)
                                          $..,$..,$..,$..,     
                                          $..,$..] ;


*Test telkens na kleine (nee, '''heel''' kleine aanpassingen). Zodat als een fout optreedt je nog weet wat je laatste aanpassing was. En je bijvoobeeld met ''undo'' (Ctrl-Z) je de laatste wijzingen ongedaan kunt maken.
Zie [[Perl_obk_csv2json.pl/Voorbereiding|voorbereiding]]
*En copieer regelmatig naar een backup folder, voor als je er niet meer uitkomt, en je verder terug dan met undo kan naar een '''recente''' eerdere revisie).
*Begin bijvoorbeeld met alleen $long en $lat in obk_parse_csv.pl op te nemen, dat levert alleen lon en lat in de json file, de rest zijn defaults. Als deze test run goed loopt voeg dan telkens 1 of 2 velden toe, en test opnieuw.
N.B. sommige scripts gebruiken lon'''g''' en lat (o.a. gemeentes), andere lon en lat (OSM). Ook in deze deze scripts kom die inconsequentie voor.


[[bestand:Alleen lat long.png|thumb|left|400px|slecht twee velden (lat,long) in invoer, de rest zijn default waarden]]<br clear=all>
==Input==
voorbeeld voor Leiden:


==Review output==
<table border=1>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_leiden_in.csv obk_leiden_in.csv]</td><td>Het gemeentebestand (na omzetting in Excel naar csv)<br>(staat in '''..data/Leiden/Gemeente/[yyyy-mm-dd]''' folder)</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/file_in_overpass obk_leiden_overpass_2023_01_23.json]</td><td>(optioneel) Extract uit OSM voor bomen die door ons zelf zijn geinventariseerd (en die in plaats moeten komen van data uit het gemeentebestand)<br>(staat in '''..data/Leiden/Gemeente/[yyyy-mm-dd]''' folder)</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/obk_skip_trees.txt obk_skip_trees.txt]</td><td>(optioneel) Nummers van bomen die niet uit het gemeentebestand geladen moeten worden want er is OSM een versie met recentere data, maar die voor sommige bomen niet op basis van boomnummer met het gemeentebestand matcht<br>(staat in '''..data/Leiden/Gemeente''' folder) / '''(zie [[obk csv2json.pl/selectielijsten|Selectielijsten]])'''</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/file_in_park_trees obk_park_trees.txt]</td><td>(optioneel) Lijst van parken, met per park id's van bomen (ref:id of coordinaten)<br>(staat in '''..data/Leiden/Gemeente''' folder) / '''(zie [[obk csv2json.pl/selectielijsten|Selectielijsten]])'''</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/diff/diff_revisions_taxon.csv diff_revisions_taxon.csv]</td><td>(optioneel) Lijst van verschillen tussen twee revisies van het gemeentebestand, gegenereerd met [[Perl_diff_revisions.pl]]<br>(staat in '''..data/Leiden/Gemeente/[yyyy-mm-dd]/diff''' subfolder) </td></tr>
<tr><td>[https://www.openbomenkaart.org/data/obk_in_gemeenten.csv obk_in_gemeenten.csv]</td><td>Extract uit Wikipedia met cijfers per gemeente, nodig voor updaten obk_city_stats.csv (staat in '''../data''' folder)</td></tr>
<tr><td>[https://www.openbomenkaart.org/scripts/active/taxon_names.js taxon_names.js]</td><td>Javascript bestand met ale naamdefinities voor soorten (staat in '''../scripts/active''' folder)</td></tr>
</table>


Als het goed is heb je nu 6 nieuwe bestanden.
==Output==
Twee daarvan zijn identiek, namelijk obk_[gemeente].json en trees_[gemeente].json.
De javascript files verwachten trees_...  Dit perl script hanteert obk_ prefix voor input en output. File handmatig renamen had ook gekund. Maar is mogelijk net zo verwarrend.
<hr><hr>


==oud:csv2json.pl==
Als het goed is heb je nu een aantal nieuwe bestanden, aantal kan verschillen per gemeente.
(oud, vervangen door obk_*.pl bestanden) zie boven
Twee daarvan zijn qua inhoud identiek, en verschillen alleen in naam, namelijk obk_[gemeente].json en trees_[gemeente].json.  


Perl script '''[https://openbomenkaart.org/scripts/perl/csv2json.pl csv2json.pl]''' voert een aantal bewerkingen uit op een bomenbestand.  
<small>Reden: de javascript files verwachten prefix trees_... Voor dit perl script is prefix obk_... standaard voor input en output. De file handmatig renamen van obk_... naar trees_... had ook gekund, maar zou mogelijk net zo verwarrend zijn geweest. Daarom twee identieke bestanden bestanden, de ene (obk_...) om het generatieproces te reviewen, en de andere (trees_...) om naar de folder te copieren, waar de web pagina het kan downloaden.</small> 


Het is een beetje Q&D (Quick and Dirty). Zo moet je eerst wat regels in het script aanpassen, wanneer je van invoerbestand wilt wisselen.
voorbeeld voor Leiden:
<table border=1>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_leiden_counts.csv obk_leiden-counts.csv]</td><td>Synopsis: totaal aantal bomen en soorten per park</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_leiden_counts.txt obk_leiden-counts.txt]</td><td>Details: aantal bomen, per soort per park</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_leiden.csv obk_leiden.csv]</td><td>Bestand dat in QGIS omgezet kan worden in een tegelset (tile set) voor gebruik in OSM editor ID,
                        met per boom coordinaten, id, species, diameter, hoogte,  plantjaar, kort label (bijv: '2028728'-Que rob), owner </td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_leiden.log obk_leiden.log]</td><td>Tellingen per veld, voor nerds </td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_leiden.json obk_leiden.json]</td><td>Zelfde als volgende bestand (copy), alleen om bestandsnamen consequent te houden<br><small> (json file met bomendata die door web site ingelezen wordt begint altijd met trees_..., vandaar</small></td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/trees_leiden.json trees_leiden.json]</td><td>Het bestand dat op de OBK server wordt geplaatst, om vandaar door '''obk.htm''' opgehaald te worden</td></tr>
<tr><td>obk_leiden.js</td><td>Variant van obk_leiden.json voor lokaal testen, bestand is met 1 regel uitgebreid, en wordt als javascript module geladen, zie ook [[Perl_obk_csv2json.pl_testen|hier]]</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/Leiden/Gemeente/2022_06_13/obk_park_trees_log.txt obk_park_trees_log.txt]</td><td>Log file met resultaten van verwerken van obk_park_trees.txt</td></tr>
<tr><td>[https://www.openbomenkaart.org/data/obk_city_stats.csv obk_city_stats.csv]</td><td>Centraal statistics bestand info over laatste run voor alle gemeentes
</table>


Zelfs de naam had beter gekund, want intussen produceert het niet alleen een json bestand, maar ook een csv en txt bestanden.
==Processing==
functies binnen '''obk_csv2json.pl'''
<table border=1>
<tr><td valign=top>main
</td><td>
<ul c>
<li>Voer '''Setup''' uit die alle namen van bestanden bepaalt, en ook tabellen inleest
<li>Open alle bestanden
<li>'''collectReferences'''
<li>Genereer header en print naar output json files
<li>Lees input csv file per regel
<p>Normaal is de input een hele csv line, maar als er minder dan verwacht aantal commas is, dan was er een end-of-line character in de data, suppleer met volgende halve regel
<li>Haal een set variabelen uit de regel via '''NormalizeInput'''  (niet elk veld is voor elke gemeente aanwezig)
<li>Filter input evt. op bomen die binnen een bounding box staan (bijv. om alleen bomen uit 1 gebied op een kaart te zetten)
<li>Sla een boom over als we zijn nummer of coordinaten al bij '''Setup''' in de Overpass json file tegenkwamen
<li>Kijk voor elke boom of die voorkomt in '''obk_park_trees.txt''', zo ja vul de data aan met place=parknaam.
<li>Standaardiseer metrics via '''NormalizeMetrics'''
<li>Check of boom met dit $id in eerdere versie van gemeentebestand een ander taxon (kan op genus, soort, cultivar nivo) vermeld was
<li>Schrijf enkele regels door naar ReportFields wat debugging makkelijker maakt
<li>Vind locatie via FindPark (kan via coordinaten of $id)
<li>Copieer output ook naar test bestand (dat op 1 regel anders is, en zo als javascript lokaal ingelezen kan worden)
<li>Copieer daarna bomen uit OSM via '''AddTreesFromOverpass'''
<li>Verricht tellingen via '''CountSpeciesPerPark'''
<li>Rapporteer via '''DoReport'''
<li>Update overzicht voor alle gemeentes via '''ReportMunicipalityStats'''
<li>Rapporteer opgespaarde warnings via '''ReportWarningsToLog'''
<li>Rapporteer opgespaarde errors
<li>eventueel start browser meteen als alles klaar is, via '''StartChrome'''
</ul>
</td></tr>
<tr><td valign=top>sub '''Setup'''</td><td>Bepaal alle bestandsnamen op basis van de gemeentenaam (uit de invoer  '''obk_[leiden]_in.csv''').<br>
Indien bestand aanwezig, lees boomnummers uit obk_skip_trees.txt en plaats deze in een hash %skip_trees.<br> 
Indien bestand aanwezig, lees boomnummers uit obk_park_trees.txt en plaats deze in een hash %park_trees.<br>
Lees taxonnamen uit javascript bestand ..scripts/active/taxon_names.js en plaats deze in een hash %taxons_defined. 
</td></tr>
<tr><td valign=top>sub '''collectReferences'''</td><td>Lees door Overpass geexporteerde json bestand.<br>Verzamel all boomnummers uit tags 'admin_ref' of 'tree:ref' in hash %admin_refs.<br>Daarmee kunnen bomen in het gemeentebestand overgeslagen worden, omdat ze ook in OSM staan<br>Leg ''en passant'' ook soortnaam en diameter in hashes vast. (normaliseer eerst inhoud van diameter)</td></tr>
<tr><td valign=top>sub '''AddTreesFromOverpass'''</td><td>Nu alleen voor Leiden: voeg bomen uit OSM toe aan wat uit het gemeentebestand is gehaald.<br> Dat zullen deels bomen zijn die nog niet in het gemeentebestand stonden.<br>Maar ook bomen die er al waren, met betere data op OSM.
Filteren van ongewenste bomen uit het gemeentebestand heeft plaatsgevonden, dus nu is het vooral inlezen van de Overpass json bestand en doorschrijven naar de output json bestand.<br>
Wel worden tags waar we niet in geintereseerd zijn hier nog uitgefilterd (denk aan user, changeset, etc). <br>
''En passant'' wordt ook nog gedetecteerd op dezelfde $admin_ref bij meer dan 1 boom voorkomt.
</td></tr>
<tr><td valign=top>sub '''SendLinesToOutput'''</td><td>Vervang locatie (straat , park) in de input, indien aanwezig, door andere locatie (uit obk_park_trees.txt), voordat json output door wordt gestuurd.<br>
Eerder ook: zorg dat laatste regel niet op een komma eindigt. (niet elke input regel wordt doorgestuurd naar output). <br>
Dit lijkt niet meer nodig of wordt nu elders opgelost.
</td></tr>
<tr><td valign=top>sub '''FindPark'''</td><td>Check hash %park_trees of daar boom bekend is, zo ja retourneer park naam.</td></tr>
<tr><td valign=top>sub '''FindPlace'''</td><td>Aangeroepen door '''SendLinesToOutput'''<br>Vind nieuwe locatie via '''FindPark''' op basis van coordinaten of 'place=' tag of 'tree:ref' of 'admin_ref' tag</td></tr>
<tr><td valign=top>sub '''NormalizeInput'''</td><td>Aanroep per regel uit het gemeentebestand. Normaliseer (standaardiseer) input:<br>
Vervang via sub '''ReplaceEmbeddedCommas''' alle comma's uit de input die onderdeel zijn van een veld en niet bedoeld waren om velden te scheiden<br>
Per gemeente wisselt de layout van de csv input (kolomnamen, volgorde van kollommen).<br>
Voor elke gemeentenaam is er een blok code die een csv regel interpreteert, en evt. iets aan de data verandert, voorbeelden:
<ul>
<li>Samenvoegen van $straat en $huisnummer in veld $locatie
<li>Uitfilteren van bomen met een bepaald (hardcoded) nummer (obsolete?)
<li>Uitblanken (of reparen) van ongeldige diameters
<li>Bomen tellen per 'straat' (eigenlijk park)
<li>Alleen voor Leiden: Overslaan van bomen voor een aantal locaties (eigenlijk parknamen), want die gaan uit OSM komen.
<li>Alleen voor Leiden: Overslaan van bomen met een bekend nummer dat in hash %admin_refs voorkomt, want bijv. die staan er niet meer
<li>Alleen voor Den Haag, bomen markeren als parkbomen aan de hand van een superlange lijst straatnamen (achterhaald, dat loopt nu via obk_parks.csv)
</ul>
</td></tr>
<tr><td valign=top>sub '''NormalizeMetrics'''</td><td>Standaardiseer een aantal metrics, die per gemeente anders gecodeerd zijn.</td></tr>
<tr><td valign=top>sub '''ConvertDelimitersEindhoven'''</td><td>(achterhaald) Converteer een gemeentebestand waar de delimiter een punt-comma is in plaats van een komma.</td></tr>
<tr><td valign=top>sub '''ReplaceEmbeddedCommas'''</td><td>(aanroep door NormalizeInput) Vervang alle comma's uit de input die onderdeel zijn van een veld en niet bedoeld waren om velden te scheiden.</td></tr>
<tr><td valign=top>sub '''FixTaxonName'''</td><td>Uit te breiden met naam correcties die nu vooral in javascript plaatsvinden, waar ze altijd aan bod komen, hier alleen voor gemeentes, maar hier geen performance kosten.</td></tr>
<tr><td valign=top>sub '''CountSpeciesPerPark'''</td><td>Soorten tellen per park en formatteer namen voor kruisingen voor ze getoond worden<br>Dat eerste is minder relevant nu tellingen vooral via obk_parks.csv lopen, dat laatste kan beter naar aparte routine</td></tr>
<tr><td valign=top>sub '''ReportMunicipalityStats'''</td><td>Maak of update tellingen per gemeente in bestand obk_city_stats.csv (zie boven)</td></tr>
<tr><td valign=top>sub '''StartChrome'''</td><td>Laadt de net gegenereerde json file automatisch in Chrome browser<br>Alleen voor wie moe is om dat in een paar stappen zelf te doen.</td></tr>
<tr><td valign=top>sub '''DoReport'''</td><td>Dupliceer info onder andere filenaam.<br>
Log tellingen, bijv. hoe vaak elke kruising (hybrid) voorkomt
</td></tr>
<tr><td valign=top>sub '''sub ReportWarningsToLog'''</td><td>Rapporteer anomalies, bijv. ongeldige reference numbers</td></tr>
<tr><td valign=top>sub '''sub GetMunicipalityStats'''</td><td>Lees cijfers per gemeente uit '''obk_in_gemeenten.csv'''</td></tr>
<tr><td valign=top>sub '''STDERR'''</td><td>Rapporteer alleen eerste 5 errors in running error log STDERR, maar alles in file STDERR</td></tr>
<table>


Aug 2022: nu ook tellingen per park: aantal bomen, aantal soorten (park = 'park' in straatnaam, plus voor Leiden bekende namen van parken die dat niet hebben, bijv 'Leidse Hout')
==Zie ook==
*[[Perl_obk_csv2json.pl/Nieuwe_gemeente|Voeg nieuwe gemeente toe]]
*[[Perl obk_csv2json.pl testen|Lokaal testen (advanced)]]

Huidige versie van 22 mei 2023 om 09:16

Terug naar Perl scripts

script naam is eigenlijk obk_csv2json.pl (incl underscore)

Hoofddoel: Dit script vormt een gemeentebestand in csv formaat om naar een json bestand, klaar om in obk.htm ingeladen te worden.

Tevens genereert het tellingen, en input voor een tile set die in editor ID gebruikt kan worden om species, positie en admin_ref over te halen naar OSM.

Main script:

Modules

Initieel

Download data archief van STRATO

Download met FileZilla alle folders binnen /data/..

Download perl bestanden (6) van STRATO

  • Haal alle perl files die met obk_.. beginnen op van STRATO server en sla die lokaal op (allemaal in dezelfde folder ../perl..)
Het gaat om deze modules:
obk_csv2json.pl  hoofdscript , dit run je in de IDE
obk_setup.pl     genereer alle bestandsnamen, de meeste worden afgeleid uit de naam van het invoerbestand (csv bestand)
obk_parse_csv.pl breek een regel uit het csv bestand op in bruikbare kolommen 
obk_counts.pl    genereer tellingen 
obk_normalize.pl standaardiseer zaken als hoogte en stamdikte, die worden in elke gemeente weer iets anders gecodeerd 
obk_report.pl    rapporteer over de uitkomst

Test met een bestaand bestand

Zie voorbereiding

Input

voorbeeld voor Leiden:

obk_leiden_in.csvHet gemeentebestand (na omzetting in Excel naar csv)
(staat in ..data/Leiden/Gemeente/[yyyy-mm-dd] folder)
obk_leiden_overpass_2023_01_23.json(optioneel) Extract uit OSM voor bomen die door ons zelf zijn geinventariseerd (en die in plaats moeten komen van data uit het gemeentebestand)
(staat in ..data/Leiden/Gemeente/[yyyy-mm-dd] folder)
obk_skip_trees.txt(optioneel) Nummers van bomen die niet uit het gemeentebestand geladen moeten worden want er is OSM een versie met recentere data, maar die voor sommige bomen niet op basis van boomnummer met het gemeentebestand matcht
(staat in ..data/Leiden/Gemeente folder) / (zie Selectielijsten)
obk_park_trees.txt(optioneel) Lijst van parken, met per park id's van bomen (ref:id of coordinaten)
(staat in ..data/Leiden/Gemeente folder) / (zie Selectielijsten)
diff_revisions_taxon.csv(optioneel) Lijst van verschillen tussen twee revisies van het gemeentebestand, gegenereerd met Perl_diff_revisions.pl
(staat in ..data/Leiden/Gemeente/[yyyy-mm-dd]/diff subfolder)
obk_in_gemeenten.csvExtract uit Wikipedia met cijfers per gemeente, nodig voor updaten obk_city_stats.csv (staat in ../data folder)
taxon_names.jsJavascript bestand met ale naamdefinities voor soorten (staat in ../scripts/active folder)

Output

Als het goed is heb je nu een aantal nieuwe bestanden, aantal kan verschillen per gemeente. Twee daarvan zijn qua inhoud identiek, en verschillen alleen in naam, namelijk obk_[gemeente].json en trees_[gemeente].json.

Reden: de javascript files verwachten prefix trees_... Voor dit perl script is prefix obk_... standaard voor input en output. De file handmatig renamen van obk_... naar trees_... had ook gekund, maar zou mogelijk net zo verwarrend zijn geweest. Daarom twee identieke bestanden bestanden, de ene (obk_...) om het generatieproces te reviewen, en de andere (trees_...) om naar de folder te copieren, waar de web pagina het kan downloaden.

voorbeeld voor Leiden:

obk_leiden-counts.csvSynopsis: totaal aantal bomen en soorten per park
obk_leiden-counts.txtDetails: aantal bomen, per soort per park
obk_leiden.csvBestand dat in QGIS omgezet kan worden in een tegelset (tile set) voor gebruik in OSM editor ID, met per boom coordinaten, id, species, diameter, hoogte, plantjaar, kort label (bijv: '2028728'-Que rob), owner
obk_leiden.logTellingen per veld, voor nerds
obk_leiden.jsonZelfde als volgende bestand (copy), alleen om bestandsnamen consequent te houden
(json file met bomendata die door web site ingelezen wordt begint altijd met trees_..., vandaar
trees_leiden.jsonHet bestand dat op de OBK server wordt geplaatst, om vandaar door obk.htm opgehaald te worden
obk_leiden.jsVariant van obk_leiden.json voor lokaal testen, bestand is met 1 regel uitgebreid, en wordt als javascript module geladen, zie ook hier
obk_park_trees_log.txtLog file met resultaten van verwerken van obk_park_trees.txt
obk_city_stats.csvCentraal statistics bestand info over laatste run voor alle gemeentes

Processing

functies binnen obk_csv2json.pl

main
  • Voer Setup uit die alle namen van bestanden bepaalt, en ook tabellen inleest
  • Open alle bestanden
  • collectReferences
  • Genereer header en print naar output json files
  • Lees input csv file per regel

    Normaal is de input een hele csv line, maar als er minder dan verwacht aantal commas is, dan was er een end-of-line character in de data, suppleer met volgende halve regel

  • Haal een set variabelen uit de regel via NormalizeInput (niet elk veld is voor elke gemeente aanwezig)
  • Filter input evt. op bomen die binnen een bounding box staan (bijv. om alleen bomen uit 1 gebied op een kaart te zetten)
  • Sla een boom over als we zijn nummer of coordinaten al bij Setup in de Overpass json file tegenkwamen
  • Kijk voor elke boom of die voorkomt in obk_park_trees.txt, zo ja vul de data aan met place=parknaam.
  • Standaardiseer metrics via NormalizeMetrics
  • Check of boom met dit $id in eerdere versie van gemeentebestand een ander taxon (kan op genus, soort, cultivar nivo) vermeld was
  • Schrijf enkele regels door naar ReportFields wat debugging makkelijker maakt
  • Vind locatie via FindPark (kan via coordinaten of $id)
  • Copieer output ook naar test bestand (dat op 1 regel anders is, en zo als javascript lokaal ingelezen kan worden)
  • Copieer daarna bomen uit OSM via AddTreesFromOverpass
  • Verricht tellingen via CountSpeciesPerPark
  • Rapporteer via DoReport
  • Update overzicht voor alle gemeentes via ReportMunicipalityStats
  • Rapporteer opgespaarde warnings via ReportWarningsToLog
  • Rapporteer opgespaarde errors
  • eventueel start browser meteen als alles klaar is, via StartChrome
sub SetupBepaal alle bestandsnamen op basis van de gemeentenaam (uit de invoer obk_[leiden]_in.csv).

Indien bestand aanwezig, lees boomnummers uit obk_skip_trees.txt en plaats deze in een hash %skip_trees.
Indien bestand aanwezig, lees boomnummers uit obk_park_trees.txt en plaats deze in een hash %park_trees.
Lees taxonnamen uit javascript bestand ..scripts/active/taxon_names.js en plaats deze in een hash %taxons_defined.

sub collectReferencesLees door Overpass geexporteerde json bestand.
Verzamel all boomnummers uit tags 'admin_ref' of 'tree:ref' in hash %admin_refs.
Daarmee kunnen bomen in het gemeentebestand overgeslagen worden, omdat ze ook in OSM staan
Leg en passant ook soortnaam en diameter in hashes vast. (normaliseer eerst inhoud van diameter)
sub AddTreesFromOverpassNu alleen voor Leiden: voeg bomen uit OSM toe aan wat uit het gemeentebestand is gehaald.
Dat zullen deels bomen zijn die nog niet in het gemeentebestand stonden.
Maar ook bomen die er al waren, met betere data op OSM.

Filteren van ongewenste bomen uit het gemeentebestand heeft plaatsgevonden, dus nu is het vooral inlezen van de Overpass json bestand en doorschrijven naar de output json bestand.
Wel worden tags waar we niet in geintereseerd zijn hier nog uitgefilterd (denk aan user, changeset, etc).
En passant wordt ook nog gedetecteerd op dezelfde $admin_ref bij meer dan 1 boom voorkomt.

sub SendLinesToOutputVervang locatie (straat , park) in de input, indien aanwezig, door andere locatie (uit obk_park_trees.txt), voordat json output door wordt gestuurd.

Eerder ook: zorg dat laatste regel niet op een komma eindigt. (niet elke input regel wordt doorgestuurd naar output).
Dit lijkt niet meer nodig of wordt nu elders opgelost.

sub FindParkCheck hash %park_trees of daar boom bekend is, zo ja retourneer park naam.
sub FindPlaceAangeroepen door SendLinesToOutput
Vind nieuwe locatie via FindPark op basis van coordinaten of 'place=' tag of 'tree:ref' of 'admin_ref' tag
sub NormalizeInputAanroep per regel uit het gemeentebestand. Normaliseer (standaardiseer) input:

Vervang via sub ReplaceEmbeddedCommas alle comma's uit de input die onderdeel zijn van een veld en niet bedoeld waren om velden te scheiden
Per gemeente wisselt de layout van de csv input (kolomnamen, volgorde van kollommen).
Voor elke gemeentenaam is er een blok code die een csv regel interpreteert, en evt. iets aan de data verandert, voorbeelden:

  • Samenvoegen van $straat en $huisnummer in veld $locatie
  • Uitfilteren van bomen met een bepaald (hardcoded) nummer (obsolete?)
  • Uitblanken (of reparen) van ongeldige diameters
  • Bomen tellen per 'straat' (eigenlijk park)
  • Alleen voor Leiden: Overslaan van bomen voor een aantal locaties (eigenlijk parknamen), want die gaan uit OSM komen.
  • Alleen voor Leiden: Overslaan van bomen met een bekend nummer dat in hash %admin_refs voorkomt, want bijv. die staan er niet meer
  • Alleen voor Den Haag, bomen markeren als parkbomen aan de hand van een superlange lijst straatnamen (achterhaald, dat loopt nu via obk_parks.csv)
sub NormalizeMetricsStandaardiseer een aantal metrics, die per gemeente anders gecodeerd zijn.
sub ConvertDelimitersEindhoven(achterhaald) Converteer een gemeentebestand waar de delimiter een punt-comma is in plaats van een komma.
sub ReplaceEmbeddedCommas(aanroep door NormalizeInput) Vervang alle comma's uit de input die onderdeel zijn van een veld en niet bedoeld waren om velden te scheiden.
sub FixTaxonNameUit te breiden met naam correcties die nu vooral in javascript plaatsvinden, waar ze altijd aan bod komen, hier alleen voor gemeentes, maar hier geen performance kosten.
sub CountSpeciesPerParkSoorten tellen per park en formatteer namen voor kruisingen voor ze getoond worden
Dat eerste is minder relevant nu tellingen vooral via obk_parks.csv lopen, dat laatste kan beter naar aparte routine
sub ReportMunicipalityStatsMaak of update tellingen per gemeente in bestand obk_city_stats.csv (zie boven)
sub StartChromeLaadt de net gegenereerde json file automatisch in Chrome browser
Alleen voor wie moe is om dat in een paar stappen zelf te doen.
sub DoReportDupliceer info onder andere filenaam.

Log tellingen, bijv. hoe vaak elke kruising (hybrid) voorkomt

sub sub ReportWarningsToLogRapporteer anomalies, bijv. ongeldige reference numbers
sub sub GetMunicipalityStatsLees cijfers per gemeente uit obk_in_gemeenten.csv
sub STDERRRapporteer alleen eerste 5 errors in running error log STDERR, maar alles in file STDERR

Zie ook