def add_aois_to_shapefile(self, ds, job_object): aois = job_object.aois.all() if len(aois) == 0: return geo_field = aois[0].polygon # Get the right geometry type number for ogr ogr_type = OGRGeomType(geo_field.geom_type).num # Set up the native spatial reference of the geometry field using the srid native_srs = SpatialReference(geo_field.srid) # create the AOI layer layer = lgdal.OGR_DS_CreateLayer(ds, 'lyr', native_srs._ptr, ogr_type, None) # Create the fields that each feature will have fields = AOI._meta.fields attributes = [] for field in fields: if field.name in 'id, active, name, created_at, updated_at, analyst, priority, status, properties': attributes.append(field) for field in attributes: data_type = 4 if field.name == 'id': data_type = 0 fld = lgdal.OGR_Fld_Create(str(field.name), data_type) added = lgdal.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = lgdal.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in aois: feat = lgdal.OGR_F_Create(feature_def) for idx, field in enumerate(attributes): if field.name == 'properties': value = json.dumps(item.properties) else: value = getattr(item, field.name) string_value = str(value)[:80] lgdal.OGR_F_SetFieldString(feat, idx, string_value) # Transforming & setting the geometry geom = item.polygon ogr_geom = OGRGeometry(geom.wkt, native_srs) check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr)) # create the feature in the layer. check_err(lgdal.OGR_L_CreateFeature(layer, feat)) check_err(lgdal.OGR_L_SyncToDisk(layer))
def add_features_subset_to_shapefile(self, ds, features, layer_name): if len(features) == 0: return geo_field = features[0].the_geom # Get the right geometry type number for ogr ogr_type = OGRGeomType(geo_field.geom_type).num # Set up the native spatial reference of the geometry field using the srid native_srs = SpatialReference(geo_field.srid) # create the Feature layer layer = lgdal.OGR_DS_CreateLayer(ds, layer_name, native_srs._ptr, ogr_type, None) # Create the fields that each feature will have fields = Feature._meta.fields attributes = [] for field in fields: if field.name in 'id, analyst, template, created_at, updated_at, job, project': attributes.append(field) for field in attributes: data_type = 4 if field.name == 'id': data_type = 0 fld = lgdal.OGR_Fld_Create(str(field.name), data_type) added = lgdal.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = lgdal.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in features: feat = lgdal.OGR_F_Create(feature_def) for idx, field in enumerate(attributes): value = getattr(item, field.name) # if field.name == 'template': # value = value.name string_value = str(value) lgdal.OGR_F_SetFieldString(feat, idx, string_value) # Transforming & setting the geometry geom = item.the_geom ogr_geom = OGRGeometry(geom.wkt, native_srs) check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr)) # create the feature in the layer. check_err(lgdal.OGR_L_CreateFeature(layer, feat)) check_err(lgdal.OGR_L_SyncToDisk(layer))
def write_with_ctypes_bindings(self, tmp_name, queryset, geo_field): """ Scrive un file in un formato geografico da un geoqueryset; questa funzione usa le librerie Python di GeoDjangos. """ # Get the shapefile driver dr = Driver(self.out_format) # Creating the datasource ds = lgdal.OGR_Dr_CreateDataSource(dr._ptr, tmp_name, None) if ds is None: raise Exception('Could not create file!') # Get the right geometry type number for ogr if hasattr(geo_field, 'geom_type'): ogr_type = OGRGeomType(geo_field.geom_type).num else: ogr_type = OGRGeomType(geo_field._geom).num # Set up the native spatial reference of geometry field using the srid if hasattr(geo_field, 'srid'): native_srs = SpatialReference(geo_field.srid) else: native_srs = SpatialReference(geo_field._srid) if self.proj_transform: output_srs = SpatialReference(self.proj_transform) else: output_srs = native_srs # create the layer # this is crashing python26 on osx and ubuntu layer = lgdal.OGR_DS_CreateLayer(ds, 'lyr', output_srs._ptr, ogr_type, None) # Create the fields attributes = self.get_attributes() for field in attributes: fld = lgdal.OGR_Fld_Create(str(field.name), 4) added = lgdal.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = lgdal.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in self.queryset: feat = lgdal.OGR_F_Create(feature_def) # For now, set all fields as strings # TODO: catch model types and convert to ogr fields # http://www.gdal.org/ogr/classOGRFeature.html # OGR_F_SetFieldDouble #OFTReal => FloatField DecimalField # OGR_F_SetFieldInteger #OFTInteger => IntegerField #OGR_F_SetFieldStrin #OFTString => CharField # OGR_F_SetFieldDateTime() #OFTDateTime => DateTimeField #OFTDate => TimeField #OFTDate => DateField for idx, field in enumerate(attributes): value = getattr(item, field.name) try: string_value = str(value) except UnicodeEncodeError, E: # pass for now.... # http://trac.osgeo.org/gdal/ticket/882 string_value = '' lgdal.OGR_F_SetFieldString(feat, idx, string_value) # Transforming & setting the geometry geom = getattr(item, geo_field.name) # if requested we transform the input geometry # to match the shapefiles projection 'to-be' if geom: ogr_geom = OGRGeometry(geom.wkt, output_srs) if self.proj_transform: ct = CoordTransform(native_srs, output_srs) ogr_geom.transform(ct) # create the geometry check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr)) else: # Case where geometry object is not found because of null # value for field effectively looses whole record in shapefile # if geometry does not exist pass # creat the feature in the layer. check_err(lgdal.OGR_L_SetFeature(layer, feat))
def __call__(self): """ """ fields = self.queryset.model._meta.fields geo_fields = [f for f in fields if isinstance(f, GeometryField)] geo_fields_names = ', '.join([f.name for f in geo_fields]) attributes = [f for f in fields if not isinstance(f, GeometryField)] if len(geo_fields) > 1: if not self.geo_field: raise ValueError("More than one geodjango geometry field found, please specify which to use by name. Available fields are: '%s'" % geo_fields_names) else: geo_field_by_name = [fld for fld in geo_fields if fld.name == self.geo_field] if not geo_field_by_name: raise ValueError("Geodjango geometry field not found with the name '%s', fields available are: '%s'" % (self.geo_field,geo_fields_names)) else: geo_field = geo_field_by_name[0] elif geo_fields: geo_field = geo_fields[0] else: raise ValueError('No geodjango geometry fields found in this model queryset') ogr.OGRRegisterAll() # Get the shapefile driver dr = ogr.OGRGetDriverByName('ESRI Shapefile') # create a temporary file to write the shapefile to # since we are ultimately going to zip it up tmp = tempfile.NamedTemporaryFile(suffix='.shp', mode = 'w+b') # we must close the file for GDAL to be able to open and write to it tmp.close() # Creating the datasource ds = ogr.OGR_Dr_CreateDataSource(dr,tmp.name, None) # Get the right geometry type number for ogr ogr_type = OGRGeomType(geo_field._geom).num # Set up the spatial reference with epsg code srs = SpatialReference(geo_field._srid) # If true we're going to reproject later on if self.proj_transform: srs = SpatialReference(self.proj_transform) # Creating the layer layer = ogr.OGR_DS_CreateLayer(ds,os.path.basename(tmp.name), srs._ptr, ogr_type, None) # Create the fields # Todo: control field order as param for field in attributes: fld = ogr.OGR_Fld_Create(str(field.name), 4) added = ogr.OGR_L_CreateField(layer, fld, 0) check_err(added) # Getting the Layer feature definition. feature_def = ogr.OGR_L_GetLayerDefn(layer) # Loop through queryset creating features for item in self.queryset: feat = ogr.OGR_F_Create(feature_def) # For now, set all fields as strings # TODO: catch model types and convert to ogr fields # http://www.gdal.org/ogr/classOGRFeature.html # OGR_F_SetFieldDouble #OFTReal => FloatField DecimalField # OGR_F_SetFieldInteger #OFTInteger => IntegerField #OGR_F_SetFieldStrin #OFTString => CharField # OGR_F_SetFieldDateTime() #OFTDateTime => DateTimeField #OFTDate => TimeField #OFTDate => DateField idx = 0 for field in attributes: value = getattr(item,field.name) try: string_value = str(value) except UnicodeEncodeError, E: # pass for now.... # http://trac.osgeo.org/gdal/ticket/882 string_value = '' ogr.OGR_F_SetFieldString(feat, idx, string_value) idx += 1 # Transforming & setting the geometry geom = getattr(item,geo_field.name) #import pdb;pdb.set_trace() # if requested we transform the input geometry # to match the shapefiles projection 'to-be' if geom: if self.proj_transform: geom.transform(self.proj_transform) ogr_geom = OGRGeometry(geom.wkt,srs) # create the geometry check_err(ogr.OGR_F_SetGeometry(feat, ogr_geom._ptr)) else: # Case where geometry object is not found because of null value for field # effectively looses whole record in shapefile if geometry does not exist pass # creat the feature in the layer. check_err(ogr.OGR_L_SetFeature(layer, feat))