diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-05-13 19:44:19 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-05-13 19:44:19 +0200 |
commit | a3a33b79b3cd43535a491c8d9762ebde5b5da9b5 (patch) | |
tree | 44b6cd00a092fd00a6381473265c276b62b34977 /chimere/utils.py | |
parent | 20c8466b3c69f72fd0381cdea633a7ef44707a44 (diff) | |
download | Chimère-a3a33b79b3cd43535a491c8d9762ebde5b5da9b5.tar.bz2 Chimère-a3a33b79b3cd43535a491c8d9762ebde5b5da9b5.zip |
Imports: manage configuration for shapefile - allow import of properties
Diffstat (limited to 'chimere/utils.py')
-rw-r--r-- | chimere/utils.py | 97 |
1 files changed, 70 insertions, 27 deletions
diff --git a/chimere/utils.py b/chimere/utils.py index 1aa639a..20dc99e 100644 --- a/chimere/utils.py +++ b/chimere/utils.py @@ -80,6 +80,7 @@ class ImportManager(object): def create_or_update_item(self, cls, values, import_key, version=None, key='', pk=None, category=None): + from models import PropertyModel updated, created, item = False, False, None import_key = unicode(import_key).replace(':', '^') if not values.get('name'): @@ -87,6 +88,11 @@ class ImportManager(object): if not key: key = self.importer_instance.importer_type item = None + pms = [pm["slug"] for pm in PropertyModel.objects.values('slug').all()] + properties = {} + for k in values.keys(): + if k in pms: + properties[k] = values.pop(k) if import_key or pk: dct_import = { 'import_key__icontains': '%s:%s;' % (key, import_key), @@ -134,6 +140,7 @@ class ImportManager(object): if not self.importer_instance.associate_marker_to_way\ and cls.__name__ == 'Route': values['has_associated_marker'] = False + try: item = cls.objects.create(**values) item.modified_since_import = False @@ -150,6 +157,8 @@ class ImportManager(object): else: for cat in self.importer_instance.categories.all(): item.categories.add(cat) + for prop in properties: + item.setProperty(prop, properties[prop]) return item, updated, created @classmethod @@ -332,6 +341,9 @@ class ShapefileManager(ImportManager): - number of new item ; - number of item updated ; - error detail on error + + The filtr argument allow to specify match between the shapefile cols + and the db. JSON format is used. """ from models import Marker, Route, Polygon new_item, updated_item, msg = 0, 0, '' @@ -366,19 +378,53 @@ class ShapefileManager(ImportManager): shapefilename = tmpdir + os.sep + sources[0] ds = DataSource(shapefilename) lyr = ds[0] - # for this first version it is assumed that the first field is a - # id name and the second field is the name - id_name = lyr.fields[0] if len(lyr.fields) > 0 else None - # test if id_name is well guess - if id_name: - ids = lyr.get_fields(id_name) - if len(ids) != len(set(ids)): - id_name = None - lbl_name = None - if len(lyr.fields) > 1: - lbl_name = lyr.fields[1] - elif id_name: - lbl_name = id_name + default_dct = {} + filtr = self.importer_instance.filtr + if filtr: + try: + filtr = json.JSONDecoder().decode(self.importer_instance.filtr) + except ValueError: + return ( + new_item, updated_item, + _(u"Bad configuration: filter must be a valid " + u"JSON string")) + for k in ('id',): + if k not in filtr: + return ( + new_item, updated_item, + _(u"The key \"%s\" is missing in the " + u"filter.") % k) + for k in filtr: + try: + ids = lyr.get_fields(k) + except: + return ( + new_item, updated_item, + _(u"Config: {} is not an appropriate column name " + u"for this Shapefile. Available columns " + u" are: {}").format(k, u", ".join( + [j for j in lyr.fields]))) + default_dct = {'origin': self.importer_instance.origin, + 'license': self.importer_instance.license} + if 'prefix_name' in filtr: + default_dct['name'] = filtr.pop('prefix_name') + if 'prefix_description' in filtr: + default_dct['description'] = filtr.pop('prefix_description') + else: + # if no filtr it is assumed that the first field is a + # id name and the second field is the name + id_name = lyr.fields[0] if len(lyr.fields) > 0 else None + # test if id_name is well guess + if id_name: + ids = lyr.get_fields(id_name) + if len(ids) != len(set(ids)): + id_name = None + filtr['id'] = id_name + if len(lyr.fields) > 1: + filtr["name"] = lyr.fields[1] + elif id_name: + filtr["name"] = id_name + if lyr.geom_type not in ('Point', 'LineString', 'Polygon'): return (0, 0, _(u"Type of geographic item (%s) of this shapefile " u"is not managed by Chimère.") % lyr.geom_type) @@ -395,32 +441,29 @@ class ShapefileManager(ImportManager): geom_cls = Route # indexes = [] for idx, feat in enumerate(lyr): - name = unicode(idx) - if lbl_name: - name = feat.get(lbl_name) + dct = default_dct.copy() + for k in filtr: + val = feat.get(k) try: - name = unicode(name) + val = unicode(val) except UnicodeDecodeError: try: - name = unicode( - name.decode(settings.CHIMERE_SHAPEFILE_ENCODING)) + val = unicode( + val.decode(settings.CHIMERE_SHAPEFILE_ENCODING)) except: continue + if filtr[k] not in dct: + dct[filtr[k]] = '' + dct[filtr[k]] += val try: geoms = [feat.geom.wkt] except: return (0, 0, _(u"Bad Shapefile")) if feat.geom.geom_type == 'MultiLineString': geoms = [geom.wkt for geom in feat.geom] - import_key = feat.get(id_name) if id_name and len(geoms) == 1 \ - else '' + import_key = dct.pop('id') for geom in geoms: - dct = { - geom_key: 'SRID=%s;%s' % (srid, geom), - 'name': name, - 'origin': self.importer_instance.origin, - 'license': self.importer_instance.license - } + dct[geom_key] = 'SRID=%s;%s' % (srid, geom) item, updated, created = self.create_or_update_item( geom_cls, dct, import_key) if updated: |