Пример #1
0
def extraction(vectorFill, vectorSource, field, field_val, driversFill,
               driversSource):

    ogrDriversSource = ogr.GetDriverByName(driversSource)
    dataSourceSource = ogrDriversSource.Open(vectorSource, 0)

    layerSource = dataSourceSource.GetLayer()

    print("RECHERCHE DES FIDs")
    All_FID = [(currentFeat.GetField(field), str(currentFeat.GetFID()))
               for currentFeat in layerSource
               if currentFeat.GetField(field) in field_val]
    print("FIDs trouvée")
    layerSource.ResetReading()

    All_FID = fu.sortByFirstElem(All_FID)

    for currentClass, FID in All_FID:
        splits = fu.splitList(FID, len(vectorFill))
        for currentSplit, currentVectorFill in zip(splits, vectorFill):
            cmd = "ogr2ogr -append " + currentVectorFill + " " + vectorSource + " -where \" fid in (" + ",".join(
                currentSplit) + ")\""
            print(cmd)
            print("Ajout de " + str(currentClass) + " dans " +
                  currentVectorFill.split("/")[-1])
            os.system(cmd)
Пример #2
0
def extractFeatureFromShape(shapefile, folds, classf, outpath):

    listid = getFidArea(shapefile, classf)
    statsclasses = getFeaturesFolds(listid, folds)
    lyr = os.path.splitext(os.path.basename(shapefile))[0]
    tomerge = []
    for statsclass in statsclasses:
        for idx, fold in enumerate(statsclass[1]):
            outshape = os.path.join(outpath, \
                                    os.path.splitext(os.path.basename(shapefile))[0] \
                                    +  str(statsclass[0]) + str(idx) + '.shp')

            if len(fold) != 0:
                sublistfid = fu.splitList(fold, 1 + int(len(fold) / 1000))
                filterfid = []
                exp = "FID in "
                for chunk in sublistfid:
                    filterfid.append(
                        "(" +
                        ",".join([str(currentFID[0])
                                  for currentFID in chunk]) + ")")

                exp += " OR FID in ".join(filterfid)

                os.system('ogr2ogr -overwrite -sql "select * from %s where %s" %s %s '%(lyr, \
                                                                                        exp, \
                                                                                        outshape, \
                                                                                        shapefile))
                tomerge.append([idx, outshape])
                print "subfile %s of classe %s has been produced with an total area of %s" % (
                    outshape, statsclass[0], statsclass[2][idx][1])

    listfolds = set(map(lambda x: x[0], tomerge))
    listfilesbyfold = [[x, [y[1] for y in tomerge if y[0] == x]]
                       for x in listfolds]
    for listfiles in listfilesbyfold:
        finalfile = os.path.join(outpath, \
                                 os.path.splitext(os.path.basename(shapefile))[0] \
                                 + str(listfiles[0]) + '.shp')
        mf.mergeVectors(listfiles[1], finalfile)
def get_randomPolyAreaThresh(wd,
                             shapefile,
                             field,
                             classe,
                             thresh,
                             outlistfid="",
                             split=1,
                             outShapefile=None,
                             nolistid=None):

    # Get Id and Area of all features
    driver = ogr.GetDriverByName("ESRI Shapefile")
    dataSource = driver.Open(shapefile, 0)
    layer = dataSource.GetLayer()

    # Field type
    fieldList = vf.getFields(layer)
    try:
        indfield = fieldList.index(field)
    except:
        print "The field {} does not exist in the input shapefile".format(
            field)
        print "You must choose one of these existing fields : {}".format(
            ' / '.join(fieldList))
        sys.exit(-1)

    inLayerDefn = layer.GetLayerDefn()
    fieldTypeCode = inLayerDefn.GetFieldDefn(indfield).GetType()
    fieldType = inLayerDefn.GetFieldDefn(indfield).GetFieldTypeName(
        fieldTypeCode)

    # Filter on given class
    if fieldType != "String":
        layer.SetAttributeFilter(field + "=" + str(classe))
    else:
        layer.SetAttributeFilter(field + '=\"' + classe + '\"')

    print "Get FID and Area values"
    #listid = []
    listiddic = {}
    for feat in layer:
        geom = feat.GetGeometryRef()
        if geom:
            listiddic[feat.GetFID()] = geom.GetArea()

    if nolistid is not None:
        f = open(nolistid, 'r')
        nolistidstr = f.readline()
        nolistidtab = nolistidstr.split(',')
        nofid = set([int(y) for y in nolistidtab])
        listidtokeep = set(list(listiddic.keys())).difference(nofid)
        listidfinal = [(x, listiddic[x]) for x in list(listidtokeep)]
        #listidfinal = [x for x in listid if x[0] in listidtokeep]
        #print listid
        #listid = [x for x in listid if x[0] not in [int(y) for y in nolistidtab]]
        #print listid
    else:
        listidfinal = listiddic.items()

    print "Random selection"
    # random selection based on area sum threshold
    sumarea = 0
    listToChoice = []
    while float(sumarea) <= float(thresh) and len(listidfinal) != 0:
        elt = random.sample(listidfinal, 1)
        listToChoice.append(elt[0][0])
        listidfinal.remove(elt[0])
        sumarea += float(elt[0][1])

    strCondglob = ",".join([str(x) for x in listToChoice])
    if outlistfid != None:
        print "Listid"
        f = open(outlistfid, 'w')
        f.write(strCondglob)
        f.close()

    sqlite3_query_limit = 1000.0
    if outShapefile is not None:
        lyrtmpsqlite = os.path.splitext(os.path.basename(shapefile))[0]
        tmpsqlite = os.path.join(wd, "tmp" + lyrtmpsqlite + '.sqlite')
        os.system('ogr2ogr -preserve_fid -f "SQLite" %s %s' %
                  (tmpsqlite, shapefile))

        conn = db.connect(tmpsqlite)
        cursor = conn.cursor()

        nb_sub_split_SQLITE = int(
            math.ceil(len(listToChoice) / sqlite3_query_limit))
        sub_FID_sqlite = fut.splitList(listToChoice, nb_sub_split_SQLITE)
        subFid_clause = []
        for subFID in sub_FID_sqlite:
            subFid_clause.append("(ogc_fid not in ({}))".format(", ".join(
                map(str, subFID))))
        fid_clause = " AND ".join(subFid_clause)

        sql_clause = "DELETE FROM %s WHERE %s" % (lyrtmpsqlite, fid_clause)

        cursor.execute(sql_clause)
        conn.commit()

        conn = cursor = None

        os.system('ogr2ogr -f "ESRI Shapefile" %s %s' %
                  (outShapefile, tmpsqlite))

        print "Random Selection of polygons with value '{}' of field '{}' done and stored in '{}'".format(
            classe, field, outShapefile)
Пример #4
0
def extraction(shapeE, DriverE, field, field_val, nb_extrac, shapeS, fieldo,
               DriverS):

    driver = ogr.GetDriverByName(DriverE)
    dataSource = driver.Open(shapeE, 0)
    layer = dataSource.GetLayer()

    driver = ogr.GetDriverByName(DriverS)
    dataSourceS = driver.Open(shapeS, 1)
    layerS = dataSourceS.GetLayer()

    print "checking FID"
    All_FID = [(currentFeat.GetField(field), currentFeat.GetFID())
               for currentFeat in layer
               if currentFeat.GetField(field) in field_val]
    All_FID = fu.sortByFirstElem(All_FID)
    print "FIDs found"
    # get Fieldo index

    featureDefnS = layerS.GetLayerDefn()
    indfieldo = featureDefnS.GetFieldIndex(fieldo)

    # Fields Lists
    listFieldIn = fu.getAllFieldsInShape(shapeE, DriverE)
    listFieldOut = fu.getAllFieldsInShape(shapeS, DriverS)

    numberOfFeatures = layerS.GetFIDColumn()

    # in case of not closed layers

    layerS.ResetReading()
    layer.ResetReading()

    i = 0
    fid_ind = layerS
    for val in field_val:
        print "fill up " + str(val) + " values"
        # list of Fid of the current landcover type (val)
        listFid = [x[1] for x in All_FID if x[0] == val][0]
        # Random selection
        print len(listFid)
        nbExtraction = nb_extrac[i]
        if nbExtraction > len(listFid):
            nbExtraction = len(listFid)
            print "Warning : class " + str(val) + " extraction set to " + str(
                nbExtraction)
            sublistFid = random.sample(listFid, nbExtraction)

        chunkSublistFID = fu.splitList(sublistFid,
                                       1 + int(len(sublistFid) / 1000))
        filterFID = []
        for chunk in chunkSublistFID:
            # Filter input shapefile
            filterFID.append("(" + " OR ".join([
                layer.GetFIDColumn() + "=" + str(currentFID)
                for currentFID in chunk
            ]) + ")")

        ffilter = " OR ".join(filterFID)
        layer.SetAttributeFilter(ffilter)
        newfid = max([feat.GetFID() for feat in layerS])
        # filtered input features into output shapefile
        for feature in layer:
            geom = feature.GetGeometryRef()
            dstfeature = ogr.Feature(layerS.GetLayerDefn())
            dstfeature.SetGeometry(geom)
            dstfeature.SetFID(newfid + 1)
            newfid += 1
            indIn = 0
            while indIn < len(listFieldIn):
                dstfeature.SetField(listFieldOut[indIn],
                                    feature.GetField(listFieldIn[indIn]))
                indIn += 1
            layerS.CreateFeature(dstfeature)
            dstfeature.Destroy()
        i += 1

        layerS = layer = None

    print "DONE"
Пример #5
0
def extraction(vectorFill, vectorSource, field, field_val, driversFill,
               driversSource):

    ogrDriversFill = [
        ogr.GetDriverByName(currentDriver) for currentDriver in driversFill
    ]
    ogrDriversSource = ogr.GetDriverByName(driversSource)

    dataSourceFill = [
        currentDriver.Open(currentShape, 1)
        for currentDriver, currentShape in zip(ogrDriversFill, vectorFill)
    ]
    dataSourceSource = ogrDriversSource.Open(vectorSource, 0)

    layerFill = [
        currentDataSource.GetLayer() for currentDataSource in dataSourceFill
    ]
    layerSource = dataSourceSource.GetLayer()
    FIDColumn = layerSource.GetFIDColumn()
    if FIDColumn == "":
        FIDColumn = "FID"

    FIDMAX = [
        max([feat.GetFID() for feat in currentLayerToFill])
        for currentLayerToFill in layerFill
    ]

    listFieldSource = fu.getAllFieldsInShape(vectorSource, driversSource)

    All_FID = [(currentFeat.GetField(field), currentFeat.GetFID())
               for currentFeat in layerSource
               if currentFeat.GetField(field) in field_val]
    layerSource.ResetReading()
    for layerToFill in layerFill:
        layerToFill.ResetReading()
    All_FID = fu.sortByFirstElem(All_FID)

    for currentClass, FID in All_FID:
        splits = fu.splitList(FID, len(vectorFill))
        i = 0
        for currentSplit, layerToFill, fidMax in zip(splits, layerFill,
                                                     FIDMAX):

            chunkSublistFID = fu.splitList(currentSplit,
                                           1 + int(len(currentSplit) / 1000))
            filterFID = "(" + " OR ".join([
                "(" + " OR ".join([
                    FIDColumn + "=" + str(currentFID) for currentFID in chunk
                ]) + ")" for chunk in chunkSublistFID
            ]) + ")"
            layerSource.SetAttributeFilter(filterFID)
            newfid = fidMax
            print "Ajout de " + str(currentClass) + " dans " + vectorFill[
                i] + " filter : " + filterFID
            for feature in layerSource:
                geom = feature.GetGeometryRef()
                print geom
                dstfeature = ogr.Feature(layerSource.GetLayerDefn())
                dstfeature.SetGeometry(geom)
                dstfeature.SetFID(newfid + 1)
                newfid += 1
                indIn = 0
                while indIn < len(listFieldSource):
                    dstfeature.SetField(
                        listFieldSource[indIn],
                        feature.GetField(listFieldSource[indIn]))
                    indIn += 1
                layerToFill.CreateFeature(dstfeature)

                dstfeature.Destroy()
            i += 1

    for layerToFill in layerFill:
        layerToFill = None
    layerSource = None