Commit 00f2b808 authored by Branko Kokanovic's avatar Branko Kokanovic

Inicijalna verzija

parent e71bb8e2
.idea
*.pbf
stambene-jedinice-analysis.log*
result.csv
progress.pickle
index.html
# stambene-zajednice-analysis
# Najbitniji linkovi
Analiza registra stambenih zajednica - https://data.gov.rs/sr/datasets/registar-stambenikh-zajednitsa-2/
\ No newline at end of file
* [Registar stambenih zajednica](https://data.gov.rs/sr/datasets/registar-stambenikh-zajednitsa-2/)
* [Analiza rezultata](https://notebooks.azure.com/brankokokanovic/projects/stambene-zajednice/html/StambeneZajednice.ipynb)
* [Thread na OSM forumu](https://forum.openstreetmap.org/viewtopic.php?id=66945)
* [Tabela (avgust 2019.) sa spojenim podacima (PAŽNJA: veličina je 20MB!)](https://stambenezajednice.z6.web.core.windows.net/avgust2019.html)
* [CSV (avgust 2019.) sa spojenim podacima](https://stambenezajednice.z6.web.core.windows.net/avgust2019.csv)
# Analiza stambenih zajednica (zgrada)
Portal otvorenih podataka je ponudio registar stambenih zajednica (zgrada) na adresi:
https://data.gov.rs/sr/datasets/registar-stambenikh-zajednitsa-2/
Ovaj projekat ima za cilj da iskoristi gorepomenuti registar da bi na najbolji način doprineo
[OSM](https://www.openstreetmap.org) (OpenStreetMap) projektu.
Za cilj je da se vidi koje zgrade već postoje u OSM-u, da se vidi njihov kvalitet tagovanja u OSM-u i da ovaj projekat
izgeneriše šta sve fali da se unese u OSM.
Originalni thread na OSM forumu: https://forum.openstreetmap.org/viewtopic.php?id=66945
## Dohvatanje podataka
Da bi se ovo uradilo, napravljena je prosta Python skripta (`main.py`) koja svaku zgradu iz registra pokušava da nađe u OSM-u.
Korišćeni su .PBF i Overpass. Prvo nađemo sve entitete (nodes, ways) koji imaju odgovarajuću ulicu i broj, a onda im
nalazimo okrug i opštinu preko Overpass Turbo query-ja. Takve rezultate čuvamo u pickle formatu (da možemo da nastavimo
posle restarta programa) i u .CSV-u. Rezultat programa je novi CSV koji je korišćen u daljoj analizi.
Osim ako ne želite da ga opet generišete, **nema potrebe da pokrećete ovu skriptu**. Rezultat je već [ovde
kao result.csv (avgust 2019.)](https://stambenezajednice.z6.web.core.windows.net/avgust2019.csv).
Inače, da bi se skripta pokrenula, potreban je Python 3.5 (ili noviji) i biblioteke pomenute u requirements.txt. Posto
se koristi Osmium da se čita .pbf, preporučuje se Linux. Skripti treba oko dan-dva neprekidnog rada da završi.
Po generisanju result.csv fajla, potrebno je i izvršiti `generate_html.py` da bi se dobila konačna HTML strana.
### Uočene mane programa/moguća unapređenja
* Postoje entiteti koji nisu pronađeni pošto im se ime ulice ili broj razlikuju u odnosu na registar. Namerno o njima nije vođeno računa, da primetimo i pogrešno nazvane ulice!
* Nije rađena nikakava transliteralizacija prilikom pretrage entiteta. Npr. kućni broj "17Г" nije nađen ako je u OSM-u unesen kao "17G". Opet - i ovo može da se okarakteriše kao namerna odluka.
* Nominatim pretraga nekad daje bolje rezultate nego prosta .pbf pretraga. Tako je moguće da Nominatim vrati node koji nema "addr:street", ali je pored te ulice. Odluka je bila da je ovo ipak nepravilno i da je bolje da te rezultate ne vraćamo (ipak na taj node treba da se doda "addr:street" tag).
* Generisani izlaz pamti samo da ima više entiteta za datu ulicu i broj, ali ne pamti ih sve (pamti najviše jedan node i jedan way). Idealno bi bilo da ih pamti sve i da se to prikazuje u generisanom HTML-u.
* Trenutno generisanje traje dan-dva. Kada bi se paralelizovalo, bilo bi brže. Međutim, usko grlo je Overpass, pa više threadova treba da pucaju na različite Overpass instance, nikako na istu!
* Bilo bi dobro kada bi pamtili još neke stvari koje možemo/trebamo imati, kao building:levels i sl., ali tu već ulazimo u teritoriju osmose projekta.
* Ako RGZ da novi dataset i budemo ponovo radili analizu, značilo bi da ne radimo sve, već samo da merge-ujemo postojeće rezultate sa novim (nema potrebe tražiti ponovo node za neku ulicu i broj, dovoljno je proveriti da li dati node ID još uvek postoji i pokazuje na istu ulicu/broj)
* Overpass ima mogućnost da vidimo kada je entitet napravljen. To bi nam omogućilo da vidimo kako je OSM kroz vreme dobijao ove zgrade (i da vidimo da li je ovaj projekat popravio "brzinu" dodavanja zgrada u OSM)
## Analiza
Poslednju analizu možete videti na Jupyter notebook-u:
https://notebooks.azure.com/brankokokanovic/projects/stambene-zajednice/html/StambeneZajednice.ipynb
Tu je i najbolja vizualizacija ovog projekta, pa pogledajte tamo!
## Prikupljeni podaci
Prikupljene podatke ove skripte možete videti ovde:
https://stambenezajednice.z6.web.core.windows.net/avgust2019.html
Ovo je korisno ako želite da se fokusirate na neku konkretnu opštinu/okrug, ili da vidite šta sve fali, pošto ova web strana ima mogućnost filtriranja, sortiranja itd.
This diff is collapsed.
geopy==1.20.0
overpy==0.4
Jinja2==2.8.1
osmium==2.15.2
\ No newline at end of file
# -*- coding: utf-8 -*-
import csv
from operator import itemgetter
from jinja2 import Environment, PackageLoader
def main():
env = Environment(loader=PackageLoader('__main__', '../templates'))
template = env.get_template('index_template.html')
stambene_zajednice = []
districts = {'': 0}
max_district_id = 0
with open('result.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
#if len(stambene_zajednice) > 100:
# break
stambene_zajednice.append(row)
for sz in stambene_zajednice:
if sz['district'] not in districts:
max_district_id += 1
districts[sz['district']] = max_district_id
sz['district_id'] = districts[sz['district']]
sz['street'] = sz['street'].replace('"', '\\"')
sz['found'] = sz['node'] != "" or sz['way'] != ""
sz['multiple_entities_same_housenumber'] = sz['multiple_entities_same_housenumber'] or False
sz['building_tag_present'] = sz['building_tag_present'] or False
sz['building_is_apartments'] = sz['building_is_apartments'] or False
stambene_zajednice.sort(key=itemgetter('district', 'municipality', 'street', 'number'))
output = template.render(stambene_zajednice=stambene_zajednice, districts=districts)
with open('index.html', 'w', encoding='utf-8') as fh:
fh.write(output)
if __name__ == '__main__':
main()
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment