Hæ.
Búinn að skrifa póstnúmerascriptuna til að uppfæra póstnúmer inn á OSM
svo þau verði í samræmi við götuskrá Íslandspósts. Það vinnur eingöngu
með relations með götuskrá:id lykli. Einnig athugar það hvort name
lykillinn í relation-inu passar við nafnið í færslu Íslandspósts og
framkvæmir breytingar eingöngu ef svo er.
Var þegar búinn að skrá mestallan Hafnarfjörð með þessu skipulagi og
prufukeyrsla sýnist skila góðu .osc skjali með viðeigandi breytingum.
Var að spá í að prófa að submitta breytingunum og sjá hvernig þær koma út.
Scriptan fylgir í viðhengi og getið þið notað hana sem grunn að frekari
kóða. Kóðinn er gefinn út undir CC0.
- Svavar Kjarrval
#!/usr/bin/env python3.2
# -*- coding: utf-8 -*-
# Copyright 2012, Svavar Kjarrval Lúthersson
# Released under the CC0 license.
# I can be contacted at sva...@kjarrval.is.
# This program performs changes according to pretermined formulas to .osm files
# and outputs a single .osc file which in turn can either be submitted automatically
# by another program (which is not implemented here) or manually with an editor.
# To use it, you must have:
# 1 - An .osm file of the area in question.
# 2 - An Osmosis binary set up and ready to use.
# The reason the script filters instead of working directly on the original file
# is to reduce memory consumption of programs which need to load the complete .osm file into memory.
# If, despite having done proper filtering, the .osm file is still too big to fit into memory,
# please consider splitting the area further.
import os
import xml.etree.cElementTree as etree
# Change the value of DEBUG to 0 when you don't want extra debug messages to appear on screen.
DEBUG = 0
# Get the current working directory
pwd = os.getcwd() + '/'
# Location of the osmosis binary.
osmosis_bin = '/home/kjarrval/bin/osmosis'
# A recently-updated .osm file with an extract of the area of interest from OpenStreetMap.
# This script does not change this file.
original_osm_file = 'iceland.osm'
# Name of the filtered .osm file. It will be completely overwritten each time the script runs.
filtered_osm_file = 'osmosis_filtered.osm'
# Name of the finished .osm file. It will be completely overwritten each time the script runs
finished_osm_file = 'osmosis_finished.osm'
# The finished .osc file. It will be completely overwritten each time the script runs.
finished_osc_file = 'osmosis_finished.osc'
# The filter to use on the original file.
# See https://wiki.openstreetmap.org/wiki/Osmosis/Detailed_Usage#--tag-filter_.28--tf.29 for usage.
# The Osmosis filter is processed in order
osmosis_filter_to_use = ' --tf accept-relations götuskrá:id=*'
osmosis_filter_to_use += ' --tf reject-ways'
osmosis_filter_to_use += ' --tf reject-nodes'
# Run the osmosis command
osmosis_command = osmosis_bin
if DEBUG == 0:
osmosis_command += ' -q'
osmosis_command += ' --read-xml ' + pwd + original_osm_file + ' ' + osmosis_filter_to_use
osmosis_command += ' --write-xml ' + pwd + filtered_osm_file
# Debug
if DEBUG == 1:
print(osmosis_command)
# Let's run the Osmosis command
os.system(osmosis_command)
# Now we should have a filtered .osm file
# Now let's work on running whatever script on the data we want.
# The if condition is to simplify for people where the data processing starts and ends.
# 'götuskrá:id' is a reference to the entry ID in the postcode file from the Icelandic Postal Service.
if 1:
osm_xml = etree.parse(pwd + filtered_osm_file)
postcodes_xml = etree.parse(pwd + 'gotuskra.xml')
# Process the postcodes file into a dictionary
street = {}
for element in postcodes_xml.iter("Gata"):
# print(element[0].text)
street[element[0].text] = [element[1].text,element[2].text,element[3].text]
# print(repr(street))
# Go through every relation
for element in osm_xml.iter("relation"):
tags_arr = {}
tags = element.iterfind('tag')
# All tags put into a dictionary which can be referenced by key name.
for tag in tags:
tags_arr[tag.get('k')] = tag.get('v')
# Check if the relation has the key götuskrá:id.
# If it doesn't have it, skip to the next relation.
if 'götuskrá:id' not in tags_arr:
continue
# Verify that the street names match.
# If they don't, the götuskrá:id has a typo or the streetname.
# In which case, it should be left alone instead of populating
# the relation with potentially wrong data.
if tags_arr['name'] == street[tags_arr['götuskrá:id']][1]:
# The götuskrá:id and streetname match
# Now we only need to check what needs to be changed and change it.
# Check if there is a tag with addr:postcode. If not, add it.
if 'addr:postcode' not in tags_arr:
attrib = {'k':'addr:postcode','v':street[tags_arr['götuskrá:id']][0]}
etree.SubElement(element,'tag',attrib)
else:
# Finds the occurance of the tag where addr:postcode is.
ele = element.find("tag/[@k='addr:postcode']")
# Change the value to the one according to the postcode file.
ele.set('v',street[tags_arr['göt