summaryrefslogtreecommitdiff
path: root/chimere/utils.py
diff options
context:
space:
mode:
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
commita3a33b79b3cd43535a491c8d9762ebde5b5da9b5 (patch)
tree44b6cd00a092fd00a6381473265c276b62b34977 /chimere/utils.py
parent20c8466b3c69f72fd0381cdea633a7ef44707a44 (diff)
downloadChimè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.py97
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: