def editFeature(request, shapefile_id, feature_id=None):
    if request.method == "POST" and "delete" in request.POST:
        return HttpResponseRedirect("/shape-editor/deleteFeature/"
                                    +shapefile_id+"/"+feature_id)
    try:
        shapefile = Shapefile.objects.get(id=shapefile_id)
    except ShapeFile.DoesNotExist:
        raise Http404
    if feature_id == None:
        feature = Feature(shapefile=shapefile)
    else:
        try:
            feature = Feature.objects.get(id=feature_id)
        except Feature.DoesNotExist:
            raise Http404
    attributes = []
    for attrValue in feature.attributevalue_set.all():
        attributes.append([attrValue.attribute.name,
                          attrValue.value])
    attributes.sort()
    geometryField = utils.calcGeometryField(shapefile.geom_type)
    formType = utils.getMapForm(shapefile)
    if request.method == "GET":
        wkt = getattr(feature, geometryField)
        form = formType({'geometry' : wkt})
        return render_to_response("editFeature.html",
                                  {'shapefile': shapefile,
                                  'form': form,
                                  'attributes': attributes})
    elif request.method == "POST":
        form = formType(request.POST)
        try:
            if form.is_valid():
                wkt = form.clean_data['geometry']
                setattr(feature, geometryField, wkt)
                feature.save()
                return HttpResponseRedirect("/shape-editor/edit/" +
                                            shapefile_id)
        except ValueError:
            pass
        return render_to_response("editFeature.html",
                                  {'shapefile' : shapefile,
                                  'form': form,
                                  'attributes': attributes})
def importData(shapefile, characterEncoding):
    fd,fname = tempfile.mkstemp(suffix=".zip")
    os.close(fd)
    f = open(fname, "wb")
    for chunk in shapefile.chunks():
        f.write(chunk)
    f.close()

    if not zipfile.is_zipfile(fname):
        os.remove(fname)
        return "Not a valid zip archive."

    zip = zipfile.ZipFile(fname)
    required_suffixes = [".shp", ".shx", ".dbf", ".prj"]
    hasSuffix = {}
    for suffix in required_suffixes:
        hasSuffix[suffix] = False
    for info in zip.infolist():
        extension = os.path.splitext(info.filename)[1].lower()
        if extension in required_suffixes:
            hasSuffix[extension] = True
    for suffix in required_suffixes:
        if not hasSuffix[suffix]:
            zip.close()
            os.remove(fname)
            return "Archive missing required "+suffix+" file."
    zip = zipfile.ZipFile(fname)
    shapefileName = None
    dirname = tempfile.mkdtemp()
    for info in zip.infolist():
        if info.filename.endswith(".shp"):
            shapefileName = info.filename
        dstFile = os.path.join(dirname, info.filename)
        f = open(dstFile, "wb")
        f.write(zip.read(info.filename))
        f.close()
    zip.close()

    try:
        datasource = ogr.Open(os.path.join(dirname, shapefileName))
        layer = datasource.GetLayer(0)
        shapefileOK = True
    except:
        traceback.print_exc()
        shapefileOK = False
        if not shapefileOK:
            os.remove(fname)
            shutil.rmtree(dirname)
            return "Not a valid shapefile."

    srcSpatialRef = layer.GetSpatialRef()
    geometryType = layer.GetLayerDefn().GetGeomType()
    geometryName = utils.ogrTypeToGeometryName(geometryType)
    shapefile = Shapefile(
            filename=shapefileName,
            srs_wkt=srcSpatialRef.ExportToWkt(),
            geom_type=geometryName,
            encoding=characterEncoding
            )
    shapefile.save()

    attributes = []
    layerDef = layer.GetLayerDefn()
    for i in range(layerDef.GetFieldCount()):
        fieldDef = layerDef.GetFieldDefn(i)
        attr = Attribute(
                shapefile=shapefile,
                name=fieldDef.GetName(),
                type=fieldDef.GetType(),
                width=fieldDef.GetWidth(),
                precision=fieldDef.GetPrecision()
                )
        attr.save()
        attributes.append(attr)

    dstSpatialRef = osr.SpatialReference()
    dstSpatialRef.ImportFromEPSG(4326)
    coordTransform = osr.CoordinateTransformation(srcSpatialRef,
            dstSpatialRef)
    for i in range(layer.GetFeatureCount()):
        srcFeature = layer.GetFeature(i)
        srcGeometry = srcFeature.GetGeometryRef()
        srcGeometry.Transform(coordTransform)
        geometry = GEOSGeometry(srcGeometry.ExportToWkt())
        geometry = utils.wrapGEOSGeometry(geometry)
        geometryField = utils.calcGeometryField(geometryName)
        args = {}
        args['shapefile'] = shapefile
        args[geometryField] = geometry
        feature = Feature(**args)
        feature.save()

    for attr in attributes:
        success,result = utils.getOGRFeatureAttribute(
                attr,
                srcFeature,
                characterEncoding
                )
        if not success:
            os.remove(fname)
            shutil.rmtree(dirname)
            shapefile.delete()
            return result
        attrValue = AttributeValue(
                feature=feature,
                attribute=attr,
                value=result
                )
        attrValue.save()

    os.remove(fname)
    shutil.rmtree(dirname)

    return "Data imported!"