diff options
author | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-05-23 19:36:55 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-05-23 19:36:55 +0200 |
commit | 4e851d59c8a8dbd227c3699c7982bb07c86c8b9f (patch) | |
tree | bfc5869a91ed92894fab64d70d39343dd8271abf /chimere/utils.py | |
parent | 8135de67b00fa6b1d58c14e54ff3b2830d9255dd (diff) | |
download | Chimère-4e851d59c8a8dbd227c3699c7982bb07c86c8b9f.tar.bz2 Chimère-4e851d59c8a8dbd227c3699c7982bb07c86c8b9f.zip |
Fix OSM route import
Diffstat (limited to 'chimere/utils.py')
-rw-r--r-- | chimere/utils.py | 136 |
1 files changed, 98 insertions, 38 deletions
diff --git a/chimere/utils.py b/chimere/utils.py index 1a63bb5..4b850e3 100644 --- a/chimere/utils.py +++ b/chimere/utils.py @@ -55,6 +55,8 @@ class ImportManager: default_source = None def __init__(self, importer_instance): self.importer_instance = importer_instance + self.default_name = " - ".join([cat.name + for cat in self.importer_instance.categories.order_by('name').all()]) def get(self): pass @@ -62,6 +64,35 @@ class ImportManager: def put(self): pass + def create_or_update_item(self, cls, values, import_key, version=None): + updated, created = False, False + dct_import = { + 'import_key__icontains':'%s:%s;' % ( + self.importer_instance.importer_type, + import_key), + 'import_source':self.importer_instance.source} + try: + item = cls.objects.get(**dct_import) + if version and item.import_version == int(version): + # no update since the last import + return item, None, None + for k in values: + setattr(item, k, values[k]) + item.save() + updated = True + except ObjectDoesNotExist: + values.update({ + 'import_source':self.importer_instance.source}) + values['status'] = 'I' + item = cls.objects.create(**values) + created = True + item.set_key(self.importer_instance.importer_type, + import_key) + item.categories.clear() + for cat in self.importer_instance.categories.all(): + item.categories.add(cat) + return item, updated, created + @classmethod def get_files_inside_zip(cls, zippedfile, suffixes, dest_dir=None): try: @@ -167,7 +198,7 @@ class KMLManager(ImportManager): if self.importer_instance.filtr else self.DEFAULT_XPATH for placemark in tree.xpath(xpath, namespaces={'kml':self.ns}): - name, point, linestring = None, None, None + name, point = None, None pl_id = placemark.attrib.get('id') pl_key = 'kml-%d' % self.importer_instance.pk ns = '{%s}' % self.ns @@ -424,57 +455,86 @@ class OSMManager(ImportManager): - updated items; - error detail on error. """ - from models import Marker - new_item, updated_item = 0 , 0 - items = [] source, msg = self.get_source_file(source, ['.osm'], extra_url=self.importer_instance.filtr) if not source: return (0, 0, msg) + tree = etree.parse(source) + # only import node or ways + if tree.xpath('count(//way)') and tree.xpath('count(//node)'): + return self.import_ways(tree) + elif tree.xpath('count(//node)'): + return self.import_nodes(tree) + return 0, 0, _(u"Nothing to import") + + def import_ways(self, tree): + from chimere.models import Marker, Route + msg, items, new_item, updated_item = "", [], 0 , 0 + nodes = {} for node in tree.xpath('//node'): - name, point, linestring = None, None, None node_id = node.attrib.get('id') + for item in node: + k = item.attrib.get('k') + if node_id: + nodes[node_id] = '%s %s' % (node.get('lon'), + node.get('lat')) + for way in tree.xpath('//way'): + name = None + points = [] + node_id = way.attrib.get('id') + version = way.attrib.get('version') + for item in way: + k = item.attrib.get('k') + if k == 'name': + name = item.attrib.get('v') + if item.tag == 'nd': + points.append(item.get('ref')) + if not name: + name = self.default_name + if not points: + continue + wkt = 'SRID=4326;LINESTRING(%s)' % ",".join([nodes[point_id] + for point_id in points if point_id in nodes]) + dct = {'route':wkt, + 'name':name, + 'import_version':version} + item, updated, created = self.create_or_update_item( + Route, dct, node_id, version) + if updated: + updated_item += 1 + if created: + new_item += 1 + items.append(item) + return new_item, updated_item, msg + + def import_nodes(self, tree): + from chimere.models import Marker + msg, items, new_item, updated_item = "", [], 0 , 0 + for node in tree.xpath('//node'): + name = None + node_id = node.attrib.get('id') + if not node_id: + continue version = node.attrib.get('version') for item in node: k = item.attrib.get('k') if k == 'name': name = item.attrib.get('v') + if not name: + name = self.default_name point = 'SRID=4326;POINT(%s %s)' % (node.get('lon'), node.get('lat')) - if point: - dct = {'point':point, - 'name':name, - 'import_version':version} - m = None - if node_id: - dct_import = { - 'import_key__icontains':'OSM:%s;' % (node_id), - 'import_source':self.importer_instance.source} - try: - m = Marker.objects.get(**dct_import) - items.append(m) - if version and m.import_version == int(version): - # no update since the last import - continue - for k in dct: - setattr(m, k, dct[k]) - m.save() - updated_item += 1 - except ObjectDoesNotExist: - m = None - dct.update({ - 'import_source':self.importer_instance.source}) - if not m: - dct['status'] = 'I' - m = Marker.objects.create(**dct) - new_item += 1 - items.append(m) - if node_id: - m.set_key('OSM', node_id) - m.categories.clear() - for cat in self.importer_instance.categories.all(): - m.categories.add(cat) + dct = {'point':point, + 'name':name, + 'import_version':version} + item, updated, created = self.create_or_update_item( + Marker, dct, node_id, version) + if updated: + updated_item += 1 + if created: + new_item += 1 + items.append(item) return (new_item, updated_item, msg) def put(self): |