Commit 54cc77d3 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
# Analiza stambenih zajednica (zgrada)
Analiza registra stambenih zajednica - https://data.gov.rs/sr/datasets/registar-stambenikh-zajednitsa-2/
\ No newline at end of file
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 Nominatim i Overpass. 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ć u repozitorijumu kao result.csv (avgust 2019.)
Inače, da bi se skripta pokrenula, potreban je Python 3.5 (ili noviji) i biblioteke pomenute u requirements.txt. Skripti treba oko 5-6 dana 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.
## 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:
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
\ 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:
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.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Stambene zajednice</title>
<meta name="description" content="Stambene zajednice">
<meta name="author" content="Branko Kokanovic">
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
<link type="text/css" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />
</head>
<body>
<h1>Spisak stambenih zajednica i OSM entiteta</h1>
<p>Ova tabela je samo deo projekta <a href="https://gitlab.com/stalker314314/stambene-zajednice-analysis">analize stambenih zajednica u Srbiji</a>.
Sve detalje o projektu, metodologiju, pozadinu i sl. možete naći <a href="https://gitlab.com/stalker314314/stambene-zajednice-analysis">ovde</a>.</p>
<p>Ovde možete videti registar stambenih zajednica i pridruženih OSM entiteta, kao i još neke anotacije:<p>
<ul>
<li>Okrug - okrug kome pripada zgrada</li>
<li>Opština - opština (ili gradska opština) kojoj pripada zgrada</li>
<li>Ulica - ulica zgrade (moguće je kliknuti na nju, pri čemu se otvara Nominatim sa pretragom za datu ulicu u toj opštini)</li>
<li>Broj - broj zgrade (moguće je kliknuti na njega, pri čemu se otvara Nominatim sa pretragom za datu ulicu i broj)</li>
<li>Nađen u OSM-u - štiklirano ako je zgrada nađena u OSM-u (korisno za filtriranje)</li>
<li>Node - ID node-a ako je pronađen, klik vodi na OSM</li>
<li>Way - ID way-a ako je pronađen, klik vodi na OSM</li>
<li>Nađeno više entiteta - u OSM-u je nađeno više od jednog entiteta za datu ulicu i broj</li>
<li>Building tag - way je tagovan kao building=*</li>
<li>building=apartments - way je tagovan pravilno kao building=apartments</li>
</ul>
<div id="jsGrid"></div>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<script>
function transliterate(s) {
return s.toLowerCase()
.replace('а', 'a')
.replace('б', 'b')
.replace('в', 'v')
.replace('г', 'g')
.replace('д', 'd')
.replace('ђ', 'dj')
.replace('е', 'e')
.replace('ж', 'z')
.replace('з', 'z')
.replace('и', 'i')
.replace('ј', 'j')
.replace('к', 'k')
.replace('л', 'l')
.replace('љ', 'lj')
.replace('м', 'm')
.replace('н', 'n')
.replace('њ', 'nj')
.replace('о', 'o')
.replace('п', 'p')
.replace('р', 'r')
.replace('с', 's')
.replace('т', 't')
.replace('ћ', 'c')
.replace('у', 'u')
.replace('ф', 'f')
.replace('х', 'h')
.replace('ц', 'c')
.replace('ч', 'c')
.replace('џ', 'dz')
.replace('ш', 's')
.replace('đ', 'dj')
.replace('ž', 'z')
.replace('ć', 'c')
.replace('č', 'c')
.replace('š', 's');
}
var db = {
loadData: function(filter) {
return $.grep(this.clients, function(client) {
return (!filter.district || client.district === filter.district)
&& (!filter.municipality || client.municipality_latin.toLowerCase().indexOf(transliterate(filter.municipality)) > -1)
&& (!filter.street || client.street_latin.toLowerCase().indexOf(transliterate(filter.street)) > -1)
&& (!filter.number || client.number_latin.toLowerCase().indexOf(transliterate(filter.number)) > -1)
&& (filter.osm_found === undefined || client.osm_found === filter.osm_found)
&& (!filter.node || client.node.toLowerCase().indexOf(filter.node.toLowerCase()) > -1)
&& (!filter.way || client.way.toLowerCase().indexOf(filter.way.toLowerCase()) > -1)
&& (filter.found_muliple === undefined || client.found_muliple === filter.found_muliple)
&& (filter.building === undefined || client.building === filter.building)
&& (filter.apartments === undefined || client.apartments === filter.apartments);
});
},
};
window.db = db;
db.clients = [
{# This is ugly and condensed because it shaves multiple MBs in produced HTML! #}
{% for sz in stambene_zajednice %}{"district": {{ sz.district_id }},"municipality": "{{ sz.municipality }}",
"street": "<a href=\"https://nominatim.openstreetmap.org/search.php?q={{ sz.street }}, {{ sz.municipality }}\" target=\"_blank\">{{ sz.street }}</a>",
"number": "<a href=\"https://nominatim.openstreetmap.org/search.php?q={{ sz.street }} {{ sz.number }}\" target=\"_blank\">{{ sz.number }}</a>","osm_found": {{ sz.found|lower }},
"node": {% if sz.node|length %}"<a href=\"https://www.openstreetmap.org/node/{{ sz.node }}\" target=\"_blank\">{{ sz.node }}</a>" {% else %}""{% endif %},
"way": {% if sz.way|length %}"<a href=\"https://www.openstreetmap.org/way/{{ sz.way }}\" target=\"_blank\">{{ sz.way }}</a>" {% else %}""{% endif %},
"found_muliple": {{ sz.multiple_entities_same_housenumber|lower }},"building": {{ sz.building_tag_present|lower }},"apartments": {{ sz.building_is_apartments|lower }} },
{% endfor %}
];
db.districts = [
{% for key, value in districts.items() %}{ Name: "{{ key }}", Id: {{ value }} },{% endfor %}
];
db.clients.forEach(element => {
element['municipality_latin'] = transliterate(element['municipality']);
element['street_latin'] = transliterate(element['street']);
element['number_latin'] = transliterate(element['number']);
});
$("#jsGrid").jsGrid({
width: "100%",
height: "auto",
pageSize: 200,
filtering: true,
inserting: false,
editing: false,
heading: true,
sorting: true,
paging: true,
selecting: false,
autoload: true,
controller: db,
fields: [
{ name: "district", type: "select", items: db.districts, valueField: "Id", textField: "Name", title: "Okrug", width: 200, filtering: true },
{ name: "municipality", type: "text", width: 200, title: "Opština" },
{ name: "street", type: "text", width: 200, title: "Ulica" },
{ name: "number", type: "text", width: 50, title: "Broj" },
{ name: "osm_found", type: "checkbox", width: 50, title: "Nađen u OSM-u" },
{ name: "node", type: "text", width: 50, title: "Node" },
{ name: "way", type: "text", width: 50, title: "Way" },
{ name: "found_muliple", type: "checkbox", title: "Nađeno više entiteta" },
{ name: "building", type: "checkbox", title: "Building tag" },
{ name: "apartments", type: "checkbox", title: "building=apartments" },
/*{ type: "control", editButton: false, deleteButton: false }*/
]
});
</script>
</body>
</html>
\ No newline at end of file
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