summaryrefslogtreecommitdiff
path: root/scripts/import_towns_from_osm.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2016-01-18 18:41:39 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2016-01-19 00:18:02 +0100
commite9c377136b8d0329f464749ea9671874d9dde17e (patch)
tree17e9fbf51fc054d18ddcd7fabc87e8684daf4eb4 /scripts/import_towns_from_osm.py
parent50124308f8f514e0f0120257a7d6a97523edb160 (diff)
downloadIshtar-e9c377136b8d0329f464749ea9671874d9dde17e.tar.bz2
Ishtar-e9c377136b8d0329f464749ea9671874d9dde17e.zip
Configure for publications on pypi, descriptions, etc.
Diffstat (limited to 'scripts/import_towns_from_osm.py')
-rwxr-xr-xscripts/import_towns_from_osm.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/scripts/import_towns_from_osm.py b/scripts/import_towns_from_osm.py
new file mode 100755
index 000000000..fb301f09f
--- /dev/null
+++ b/scripts/import_towns_from_osm.py
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Import towns from OpenStreetMap data.
+Take an OSM xml file for argument.
+
+To get an OSM file (with a bounding box adapted to your needs):
+curl --location --globoff "http://www.informationfreeway.org/api/0.6/node[place=village|town|city][bbox=-5.53711,41.90228,8.96484,51.50874]" -o city.osm
+or from a whole xml/pbf export:
+./osmosis --read-pbf ~/france-20110125.osm.pbf --node-key-value keyValueList="place.village,place.town,place.city" --write-xml city.osm
+"""
+
+import sys
+sys.path.append('.')
+
+from django.core.management import setup_environ
+from django.core.exceptions import ObjectDoesNotExist
+from django.contrib.gis.geos import Point
+import settings
+
+setup_environ(settings)
+
+from optparse import OptionParser
+from xml.parsers import expat
+
+from ishtar_base import models
+
+usage = "usage: %prog osm_file.xml"
+parser = OptionParser(usage=usage)
+
+(options, args) = parser.parse_args()
+
+try:
+ assert len(args) == 1
+except AssertionError:
+ parser.error("You must provide one XML file")
+
+
+ATTRS = [u"lat", u"lon"]
+
+# key : (mandatory, [restraint to keys])
+TAGS = {u"place":(True, [u"village", u"town", u"city"]),
+ u"ref:INSEE":(True, []),
+ u"population":(False, [])
+ }
+
+class TownParser:
+
+ def __init__(self):
+ self._parser = expat.ParserCreate()
+ self._parser.returns_unicode = True
+ self._parser.StartElementHandler = self.start
+ self._parser.EndElementHandler = self.end
+ self._parser.CharacterDataHandler = self.data
+ self.town = {}
+ self.number = 0
+
+ def feed(self, data):
+ self._parser.ParseFile(data)
+
+ def close(self):
+ self._parser.Parse("", 1) # end of data
+ del self._parser # get rid of circular references
+
+ def start(self, tag, attrs):
+ if tag == u"node":
+ self.town = {}
+ for attr in ATTRS:
+ if attr in attrs:
+ self.town[attr] = attrs[attr]
+ if tag == u"tag":
+ if not u"k" in attrs or not u"v" in attrs:
+ return
+ if attrs[u"k"] in TAGS:
+ limit = TAGS[attrs[u"k"]][1]
+ if limit and \
+ (attrs[u"v"] not in limit or \
+ (type(limit) == unicode and limit not in attrs[u"v"])):
+ self.town["DEL"] = True
+ return
+ self.town[attrs[u"k"]] = attrs[u"v"]
+
+ def end(self, tag):
+ if tag == u"node" and self.town and "DEL" not in self.town:
+ for k in TAGS:
+ if TAGS[k][0] and k not in self.town:
+ return
+ self.number += 1
+ try:
+ town = models.Town.objects.get(numero_insee=self.town["ref:INSEE"])
+ except ObjectDoesNotExist:
+ return
+ town.center = Point(float(self.town['lon']), float(self.town['lat']),
+ srid=4326)
+ town.save()
+ print town, "updated"
+
+ def data(self, data):
+ pass
+
+p = TownParser()
+
+try:
+ p.feed(file(args[0]))
+ print u"%d towns updated" % p.number
+except (IOError, expat.ExpatError):
+ parser.error("Incorrect XML file")
+
+