Commits

Anonymous committed 062aee2

Refactored ShpResponse into a working single class and fixed typos

  • Participants
  • Parent commits 03d8926

Comments (0)

Files changed (3)

 
  - Add `shapes` to your INSTALLED APPS
  - Add `(r'^shapes/', include('shapes.urls')),` to your urlpatterns
+ - Until models are implemented add SHP_UPLOAD_DIR = '/some/path' in your setting.py
  
-This application exposed two urls:
+This application exposes two urls:
 
  /shapes/upload/
 
       destination.close()        
 
     def zip_check(self, ext, zip_file):
-      if not True in [info.filename.endswith('shp') for info in zipfile.infolist()]:
+      if not True in [info.filename.endswith('shp') for info in zip_file.infolist()]:
         return False
       return True
       

shapes/views/export.py

 # todo: support multiple querysets == multiple shapefiles
 
 class ShpResponder(object):
-    def __init__(self, queryset,*args, **kwargs):
+    def __init__(self, queryset, proj_transform=None, *args, **kwargs):
         # Available data
         self.queryset = queryset
+        self.mimetype = 'application/zip'
+        self.proj_transform = proj_transform
     
     def __call__(self, request, *args, **kwargs):
         
-        return export(self.queryset, **kwargs)
+        lgdal.OGRRegisterAll()
+        
+        tmp = tempfile.NamedTemporaryFile(suffix='.shp', mode = 'w')
+        path = os.path.dirname(tmp.name)
+        name = tmp.name.split('/')[-1]
+        fullname = tmp.name
+        basename = fullname.strip('.shp')
+        tmp.close()
+        
+        # Todo: contruct download name dynamically from queryset
+        download_name = 'shp_download'
+        
+        fields = self.queryset.model._meta.fields
+        geo_fields = [f for f in fields if isinstance(f, GeometryField)]
+        other_fields = [f for f in fields if not isinstance(f, GeometryField)]
+        
+        if len(geo_fields) > 1:
+            geo_field = geo_fields[0] # no support yet for multiple geometry fields
+        else:
+            geo_field = geo_fields[0]
+        
+        dr = lgdal.OGRGetDriverByName('ESRI Shapefile')
+    
+        # Creating the datasource
+        ds = lgdal.OGR_Dr_CreateDataSource(dr,fullname, None)
+        
+        # Get the right geometry type number for ogr
+        ogr_type = OGRGeomType(geo_field._geom).num
 
-def export(query_set, geom_field=None, proj_transform=4326,mimetype='application/zip'):
+        # Set up the spatial reference with epsg cod
+        srs = SpatialReference(geo_field._srid)
+        # we're going to reproject later on 
+        if self.proj_transform:
+          srs = SpatialReference(self.proj_transform)
+        
+        # Creating the layer
+        layer = lgdal.OGR_DS_CreateLayer(ds,name, srs._ptr, ogr_type, None)
+        #import pdb;pdb.set_trace()
+        
+        for field in other_fields:
+          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.
+        fdefn = lgdal.OGR_L_GetLayerDefn(layer) 
+        
+        for item in self.queryset:
+        
+            feat = lgdal.OGR_F_Create(fdefn)
+            
+            # Setting the fields (for now all as strings)
+            # TODO: catch model types and convert to ogr fields
+            #OFTReal => FloatField DecimalField
+            #OFTInteger => IntegerField
+            #OFTString => CharField
+            #OFTDate => DateField
+            #OFTDateTime => DateTimeField
+            #OFTDate => TimeField
+            
+            idx = 0
+            for field in other_fields:
+              value = getattr(item,field.name)
+              lgdal.OGR_F_SetFieldString(feat, idx, str(value))
+              idx += 1
+              
+            # Transforming & setting the geometry
+            geom = getattr(item,geo_field.name)
+            
+            # reproject is requested so we transform the input
+            # geometry to match the shapefiles projection 'to-be'
+            if self.proj_transform:
+              geom.transform(self.proj_transform)
+            ogr_geom = OGRGeometry(geom.wkt,srs)
+            #if self.proj_transform:
+              #ogr_geom.transform(self.proj_transform)
+            check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr))
+            # Creating the feature in the layer.
+            check_err(lgdal.OGR_L_SetFeature(layer, feat))
+        
+        # Cleaning up
+        check_err(lgdal.OGR_L_SyncToDisk(layer))
+        lgdal.OGR_DS_Destroy(ds)
     
-    lgdal.OGRRegisterAll()
+        buffer = StringIO()
+        zip = zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED)
+        files = ['shp','shx','prj','dbf']
+        for item in files:
+          filename= '%s.%s' % (basename, item)
+          zip.write(filename, '%s.%s' % (download_name, item))
+        zip.close()
+        buffer.flush()
+        ret_zip = buffer.getvalue()
+        buffer.close()     
+        response = HttpResponse()
+        response['Content-Disposition'] = 'filename=%s.zip' % download_name
+        response['Content-length'] = str(len(ret_zip))
+        response['Content-Type'] = self.mimetype
     
-    tmp = tempfile.NamedTemporaryFile(suffix='.shp', mode = 'w')
-    path = os.path.dirname(tmp.name)
-    name = tmp.name.split('/')[-1]
-    fullname = tmp.name
-    basename = fullname.strip('.shp')
-    tmp.close()
-    
-    # Todo: contruct download name dynamically from queryset
-    download_name = 'shp_download'
-    
-    fields = query_set.model._meta.fields
-    geo_fields = [f for f in fields if isinstance(f, GeometryField)]
-    other_fields = [f for f in fields if not isinstance(f, GeometryField)]
-    
-    if len(geo_fields) > 1:
-        geo_field = geo_fields[0] # no support yet for multiple geometry fields
-    else:
-        geo_field = geo_fields[0]
-    
-    srs = SpatialReference(geo_field._srid)
-    dr = lgdal.OGRGetDriverByName('ESRI Shapefile')
-
-    # Creating the datasource
-    ds = lgdal.OGR_Dr_CreateDataSource(dr,fullname, None)
-    
-    # Get the right geometry type number for ogr
-    ogr_type = OGRGeomType(geo_field._geom).num
-    
-    # Creating the layer
-    layer = lgdal.OGR_DS_CreateLayer(ds,name, srs._ptr, ogr_type, None)
-    #import pdb;pdb.set_trace()
-    
-    for field in other_fields:
-      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.
-    fdefn = lgdal.OGR_L_GetLayerDefn(layer) 
-    
-    for item in query_set:
-    
-        feat = lgdal.OGR_F_Create(fdefn)
-        
-        # Setting the fields (for now all as strings)
-        # TODO: catch model types and convert to ogr fields
-        #OFTReal => FloatField DecimalField
-        #OFTInteger => IntegerField
-        #OFTString => CharField
-        #OFTDate => DateField
-        #OFTDateTime => DateTimeField
-        #OFTDate => TimeField
-        
-        idx = 0
-        for field in other_fields:
-          value = getattr(item,field.name)
-          lgdal.OGR_F_SetFieldString(feat, idx, str(value))
-          idx += 1
-          
-        # Transforming & setting the geometry
-        geom = getattr(item,geo_field.name)
-        ogr_geom = OGRGeometry(geom.wkt,srs)
-        ogr_geom.transform(proj_transform)
-        check_err(lgdal.OGR_F_SetGeometry(feat, ogr_geom._ptr))
-        # Creating the feature in the layer.
-        check_err(lgdal.OGR_L_SetFeature(layer, feat))
-    
-    # Cleaning up
-    check_err(lgdal.OGR_L_SyncToDisk(layer))
-    lgdal.OGR_DS_Destroy(ds)
-
-    buffer = StringIO()
-    zip = zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED)
-    files = ['shp','shx','prj','dbf']
-    for item in files:
-      filename= '%s.%s' % (basename, item)
-      if os.path.exists(filename):
-        print 'yes:%s' % filename
-      else:
-        print 'no:%s' % filename
-      zip.write(filename, '%s.%s' % (download_name, item))
-    zip.close()
-    buffer.flush()
-    ret_zip = buffer.getvalue()
-    buffer.close()     
-    response = HttpResponse()
-    response['Content-Disposition'] = 'filename=%s.zip' % download_name
-    response['Content-length'] = str(len(ret_zip))
-    response['Content-Type'] = mimetype
-
-    response.write(ret_zip)
-    lgdal.OGRCleanupAll()
-    return response
+        response.write(ret_zip)
+        lgdal.OGRCleanupAll()
+        return response