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): | 
