def load_shape_dicts(cls, force=False): print 'Loading shapes...' shape_dicts = { FEDERAL_KEYNAME: ('federal_districts.zip', 'Федеральные округа', { FEDERAL_ID_FIELD: 'Идентификатор', FEDERAL_NAME_FIELD: 'Наименование', FEDERAL_SHORT_NAME_FIELD: 'Короткое название', } ), REGIONS_KEYNAME: ('regions.zip', 'Регионы РФ', { REGIONS_ID_FIELD: 'Идентификатор', REGIONS_NAME_FIELD: 'Наименование', } ), DISTRICT_KEYNAME: ('districts.zip', 'Районы', { DISTRICT_ID_FIELD: 'Идентификатор', DISTRICT_NAME_FIELD: 'Наименование', DISTRICT_PARENT_ID_FIELD: 'Ид. родительского региона', DISTRICT_SHORT_NAME_FIELD: 'Короткое название' } ), } # get principals adminusr = User.filter_by(keyname='administrator').one() admingrp = Group.filter_by(keyname='administrators').one() everyone = User.filter_by(keyname='everyone').one() # get root resource try: root_res = ResourceGroup.filter_by(keyname=DICTIONARY_GROUP_KEYNAME).one() except NoResultFound: raise Exception('Need dictionaries group resource!') # create shapes for (dict_keyname, (dict_file, dict_display_name, dict_fields)) in shape_dicts.iteritems(): try: vec_res = VectorLayer.filter_by(keyname=dict_keyname).one() print ' Dictionary "%s" already exists' % dict_keyname if force: print ' Force recreate "%s"' % dict_keyname # try to drop old table try: VectorLayerUpdater.drop_vector_layer_table(vec_res.tbl_uuid) except: pass else: continue except NoResultFound: vec_res = VectorLayer(owner_user=adminusr, display_name=dict_display_name, keyname=dict_keyname, parent=root_res) vec_res.acl.append(ACLRule( principal=admingrp, action='allow')) vec_res.srs = SRS.filter_by(id=3857).one() datafile = path.join(BASE_PATH, dict_file) encoding = 'utf-8' iszip = zipfile.is_zipfile(datafile) try: #open ogr ds if iszip: ogrfn = tempfile.mkdtemp() zipfile.ZipFile(datafile, 'r').extractall(path=ogrfn) else: ogrfn = datafile with _set_encoding(encoding) as sdecode: ogrds = ogr.Open(ogrfn) recode = sdecode if ogrds is None: raise VE("Библиотеке OGR не удалось открыть файл") drivername = ogrds.GetDriver().GetName() if drivername not in ('ESRI Shapefile', ): raise VE("Неподдерживаемый драйвер OGR: %s" % drivername) # check datasource if ogrds.GetLayerCount() < 1: raise VE("Набор данных не содержит слоёв.") if ogrds.GetLayerCount() > 1: raise VE("Набор данных содержит более одного слоя.") # open ogrlayer ogrlayer = ogrds.GetLayer(0) if ogrlayer is None: raise VE("Не удалось открыть слой.") # check layer if ogrlayer.GetSpatialRef() is None: raise VE("Не указана система координат слоя.") feat = ogrlayer.GetNextFeature() while feat: geom = feat.GetGeometryRef() if geom is None: raise VE("Объект %d не содержит геометрии." % feat.GetFID()) feat = ogrlayer.GetNextFeature() ogrlayer.ResetReading() vec_res.tbl_uuid = uuid.uuid4().hex with DBSession.no_autoflush: vec_res.setup_from_ogr(ogrlayer, recode) vec_res.load_from_ogr(ogrlayer, recode) finally: if iszip: shutil.rmtree(ogrfn) # display names for fields for field_keyname, field_dispname in dict_fields.iteritems(): VectorLayerUpdater.change_field_display_name(vec_res, field_keyname, field_dispname) vec_res.persist()