Exemplo n.º 1
0
def execute_GaussianSmooth(r_flowdir,
                           str_frompoint,
                           r_values,
                           gaussiansigma,
                           nbgaussianpoints,
                           SaveResult,
                           messages,
                           language="FR"):

    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)
    valuesraster = RasterIO(r_values)
    try:
        flowdir.checkMatch(valuesraster)
    except Exception as e:
        messages.addErrorMessage(e.message)

    Result = RasterIO(r_flowdir, SaveResult, float, -255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    count = 0
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "OID@")
    for frompoint in frompointcursor:
        count += 1
    progtext = "Lissage par moyenne mobile"
    if language == "EN":
        progtext = "Processing"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, ["OID@", "SHAPE@"])
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[1].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        listflowpath = []
        listpointsflowpath = []
        listdistance = []
        listelevation = []
        totaldistance = 0
        currentdistance = 0
        confluencedist = 0

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            currentpoint = pointflowpath()
            currentpoint.row = currentrow
            currentpoint.col = currentcol
            listpointsflowpath.append(currentpoint)
            totaldistance = totaldistance + currentdistance

            listflowpath.append(totaldistance)

            # On crée une liste des points d'élévation connue le long de l'écoulement, ainsi qu'une liste associée avec leur distance depuis le point de distance
            if valuesraster.getValue(currentrow,
                                     currentcol) != valuesraster.nodata:
                listdistance.append(totaldistance)
                listelevation.append(
                    valuesraster.getValue(currentrow, currentcol))

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    if confluencedist == 0:
                        confluencedist = totaldistance + currentdistance

                    # On continue encore sur la distance d'extension après le confluent
                    if (totaldistance + currentdistance -
                            confluencedist) > nbgaussianpoints / 2:
                        intheraster = False

        if len(listdistance) <= 1:
            # Avertissement si il n'y a qu'un seul (ou aucun) point de données
            if language == "FR":
                messages.addWarningMessage(
                    "Point source {0}: pas assez de sections transversales".
                    format(frompoint[0]))
            else:
                messages.addWarningMessage(
                    "From point {0}: not enough cross-sections".format(
                        frompoint[0]))

        else:

            currentpointnumber = 0
            # Traitement pour chaque point le long de l'écoulement
            while (currentpointnumber < len(listflowpath)):

                currentpoint = listpointsflowpath[currentpointnumber]
                weights = []
                values = []
                sumwgt = 0
                # On parcourt tous les points d'élévation connue
                for i in range(len(listdistance)):
                    distlocale = abs(listdistance[i] -
                                     listflowpath[currentpointnumber])
                    # ... pour trouver ceux situés à l'intérieur de la fenêtre
                    if distlocale < (nbgaussianpoints - 1) / 2:
                        # On utilise alors la courbe gaussienne pour trouver la pondération de chaque point (et mettre à jour la somme des poids)
                        pointwgt = 1 / (gaussiansigma *
                                        math.sqrt(2 * math.pi)) * math.exp(
                                            -0.5 *
                                            (distlocale / gaussiansigma)**2)

                        sumwgt += pointwgt
                        # Et on enregistre les valeurs dans des listes
                        weights.append(pointwgt)
                        values.append(listelevation[i])

                # Message d'avertissement si la taille de fenêtre est insuffisante
                if len(weights) == 0:
                    if language == "FR":
                        messages.addWarningMessage(
                            "Manque trop important de données à interpoler : "
                            + str(frompoint[0]) + " - " +
                            str(listflowpath[currentpointnumber]))
                    else:
                        messages.addWarningMessage(
                            "Not enough data to interpolate : " +
                            str(frompoint[0]) + " - " +
                            str(listflowpath[currentpointnumber]))

                # On calcul la valeur finale à partir des valeurs et des poids associés
                finalvalue = 0
                for i in range(len(weights)):
                    finalvalue += values[i] * weights[i] / sumwgt

                Result.setValue(currentpoint.row, currentpoint.col, finalvalue)

                currentpointnumber = currentpointnumber + 1

    Result.save()

    return
def execute_CreateZone(r_flowdir, str_lakes, r_slope, minslope, str_frompoint,
                       distance, bufferw, str_zonesfolder, messages):

    str_segments = str_zonesfolder + "\\segments"
    str_linesegments = str_zonesfolder + "\\line_segments.shp"
    str_bufferedsegments = str_zonesfolder + "\\buff_segments.shp"

    save_sourcepoints = str_zonesfolder + "\\sourcepoints.shp"

    str_r_lakes = str_zonesfolder + "\\r_lakes"

    flowdir = RasterIO(r_flowdir)
    if r_slope is not None:
        slope = RasterIO(r_slope)
        try:
            flowdir.checkMatch(slope)

        except Exception as e:
            messages.addErrorMessage(e.message)
    else:
        slope = None

    # Conversion des lacs en raster et copie
    arcpy.env.snapRaster = flowdir.raster
    arcpy.env.outputCoordinateSystem = flowdir.raster.spatialReference
    arcpy.env.extent = flowdir.raster
    arcpy.PolygonToRaster_conversion(str_lakes,
                                     arcpy.Describe(str_lakes).OIDFieldName,
                                     str_r_lakes,
                                     cellsize=flowdir.raster)
    lakes = RasterIO(arcpy.Raster(str_r_lakes))
    arcpy.CopyFeatures_management(str_lakes, str_zonesfolder + "\\lakes.shp")
    str_lakes = str_zonesfolder + "\\lakes.shp"
    arcpy.AddGeometryAttributes_management(str_lakes, "EXTENT")

    ### Début du traitement perrmettant d'identifier les segments (sous forme de raster) ###

    raster_segments = RasterIO(r_flowdir, str_segments, int, -255)

    # numérotation des segments
    segnumber = 0

    lakes_bci = {}
    toclip = {}
    inputpoints = {}

    # Pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, ["SHAPE@", "OID@"])
    for frompoint in frompointcursor:

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Nouvelle rivière : on change de segment
        segnumber += 1

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        intheraster = True
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        listpointsflowpath = []
        totaldistance = 0
        currentdistance = 0
        inlake = True
        # True si la rivière (depuis le point de départ jusqu'au confluent) est composée d'au moins deux segments
        dividedriver = False
        # listtomerged contient la liste des segments trop courts, qui doivent être fusionnés avec segment précédent
        listtomerged = []

        # Pour chaque cellule en suivant l'écoulement
        while (intheraster):

            waslake = inlake

            inlake = False
            lakevalue = lakes.getValue(currentrow, currentcol)

            inlake = (lakevalue != lakes.nodata)

            if not (inlake and waslake):
                # Distance parcourue depuis le début du segment
                totaldistance = totaldistance + currentdistance

            slope_criteria = True
            if slope is not None:
                slope_criteria = slope.getValue(currentrow,
                                                currentcol) > minslope

            # Test si on arrive à un lac
            if inlake and not waslake:
                # Segment trop court si de longueur inférieure à 30% de la distance voullue
                # Le segment doit être alors fusionné avec le segment précédent (qui existe uniquement si dividedriver = True)
                # ajout de l'info de clipper ensuite également
                coordX = flowdir.ColtoX(currentcol)
                coordY = flowdir.RowtoY(currentrow)

                fieldidlakes = arcpy.Describe(str_lakes).OIDFieldName
                shplakes = arcpy.da.SearchCursor(str_lakes, [
                    "SHAPE@", "EXT_MIN_X", "EXT_MAX_X", "EXT_MIN_Y",
                    "EXT_MAX_Y", fieldidlakes
                ])
                for shplake in shplakes:
                    if shplake[0].contains(arcpy.Point(coordX, coordY)):
                        lakes_bci[segnumber] = shplakes[5]
                        distXmin = abs(coordX - shplake[1])
                        distXmax = abs(coordX - shplake[2])
                        distYmin = abs(coordY - shplake[3])
                        distYmax = abs(coordY - shplake[4])
                        mini = min(distXmin, distXmax, distYmin, distYmax)
                        if mini == distXmin:
                            toclip[segnumber] = ["Xmax", shplake[1]]
                            messages.addMessage(
                                str(segnumber) + " Xmax " + str(shplake[1]))
                        if mini == distXmax:
                            toclip[segnumber] = ["Xmin", shplake[2]]
                            messages.addMessage(
                                str(segnumber) + " Xmin " + str(shplake[2]))
                        if mini == distYmin:
                            toclip[segnumber] = ["Ymax", shplake[3]]
                            messages.addMessage(
                                str(segnumber) + " Ymax " + str(shplake[3]))
                        if mini == distYmax:
                            toclip[segnumber] = ["Ymin", shplake[4]]
                            messages.addMessage(
                                str(segnumber) + " Ymin " + str(shplake[4]))
                if totaldistance < 0.3 * distance and dividedriver:
                    if segnumber in toclip:
                        toclip[segnumber - 1] = toclip.pop(segnumber)
                    listtomerged.append(segnumber)
                totaldistance = 0
                segnumber += 1
                dividedriver = False

            elif totaldistance > distance and slope_criteria:
                # Test si on a parcouru la distance voullue
                totaldistance = 0
                segnumber += 1
                dividedriver = True

            if not inlake:
                # On conseerve une liste des points traités, avec leur numéro de segment
                currentpoint = pointflowpath()
                currentpoint.row = currentrow
                currentpoint.col = currentcol
                currentpoint.X = flowdir.ColtoX(currentcol)
                currentpoint.Y = flowdir.RowtoY(currentrow)
                currentpoint.distance = totaldistance
                currentpoint.segnumber = segnumber
                currentpoint.frompointid = frompoint[1]
                listpointsflowpath.append(currentpoint)

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                confluence_seg = raster_segments.getValue(
                    currentrow, currentcol)
                if (confluence_seg != -255):
                    # Atteinte d'un confluent déjà traité

                    # Si le segment dans lequel on arrive est limité par un lac, le confluent peut l'être aussi
                    # On copie l'item toclip pour limiter l'étendu de la zone
                    # par contre on garde l'élévation à -999 (hfix sera le résultat de la simulation du cours d'eau confluent)
                    if confluence_seg in listtomerged:
                        confluence_seg -= 1
                    if confluence_seg in toclip:
                        clipitem = list(toclip[confluence_seg])
                        toclip[segnumber] = clipitem

                    if totaldistance < 0.3 * distance and dividedriver:
                        # Segment trop court si de longueur inférieure à 30% de la distance voullue
                        # Le segment doit être alors fusionné avec le segment précédent (qui existe uniquement si dividedriver = True)
                        listtomerged.append(segnumber)
                        if segnumber in toclip:
                            toclip[segnumber - 1] = toclip.pop(segnumber)

                    intheraster = False

        # Pour chaque point traité le long de l'écoulement
        for currentpoint in listpointsflowpath:
            # Si c'est un point d'un segment trop court, on remplace le numéro du segment par le numéro du segment précédent
            if currentpoint.segnumber in listtomerged:
                currentpoint.segnumber -= 1
            # On enregistre le point
            raster_segments.setValue(currentpoint.row, currentpoint.col,
                                     currentpoint.segnumber)
            if currentpoint.segnumber not in inputpoints:
                newpoint = pointflowpath()
                newpoint.type = "main"
                newpoint.frompointid = currentpoint.frompointid
                # Coordonnées du point source
                newpoint.X = currentpoint.X
                newpoint.Y = currentpoint.Y

                inputpoints[currentpoint.segnumber] = newpoint

    raster_segments.save()

    ### Fin du traitement perrmettant d'identifier les segments ###

    ### Transformation du raster des segments en zones ####

    # Transformation en polyline
    tmp_segments = arcpy.env.scratchWorkspace + "\\tmpsegments.shp"
    arcpy.RasterToPolyline_conversion(str_segments, tmp_segments)
    arcpy.Dissolve_management(tmp_segments, str_linesegments, "GRID_CODE")
    arcpy.Delete_management(tmp_segments)

    # Création de la zone tampon
    # Harcoded : buffer longitudinal de 1/10 de l'extension latérale (obtenue par Euclidienne Allocation)
    tmp_segmentsbuf = arcpy.env.scratchWorkspace + "\\tmpsegments_buf.shp"
    arcpy.Buffer_analysis(str_linesegments, tmp_segmentsbuf, bufferw / 10.)
    segalloc = arcpy.sa.EucAllocation(raster_segments.raster, bufferw)
    arcpy.RasterToPolygon_conversion(segalloc, tmp_segments)
    arcpy.AddField_management(tmp_segments, "GRID_CODE", "LONG")
    arcpy.CalculateField_management(tmp_segments, "GRID_CODE", "!GRIDCODE!",
                                    "PYTHON_9.3")
    tmp_segments2 = arcpy.env.scratchWorkspace + "\\tmpsegments2.shp"
    arcpy.Merge_management([tmp_segmentsbuf, tmp_segments], tmp_segments2)
    arcpy.Dissolve_management(tmp_segments2,
                              str_bufferedsegments, ["GRID_CODE"],
                              multi_part="SINGLE_PART")

    arcpy.Delete_management(tmp_segments)
    arcpy.Delete_management(tmp_segments2)

    arcpy.Delete_management(str_lakes)

    # Création de la zone pour chaque segment
    arcpy.CreateFeatureclass_management(
        str_zonesfolder,
        "polyzones.shp",
        "POLYGON",
        str_bufferedsegments,
        spatial_reference=flowdir.raster.spatialReference)
    polyzones = str_zonesfolder + "\\polyzones.shp"
    arcpy.AddField_management(polyzones, "Lake_ID", "LONG")

    cursor = arcpy.da.InsertCursor(polyzones,
                                   ["GRID_CODE", "SHAPE@", "Lake_ID"])

    segmentscursor = arcpy.da.UpdateCursor(str_bufferedsegments,
                                           ["GRID_CODE", "SHAPE@"])
    for segment in segmentscursor:
        Xmin = segment[1].extent.XMin
        Ymin = segment[1].extent.YMin
        Xmax = segment[1].extent.XMax
        Ymax = segment[1].extent.YMax
        if segment[0] in toclip:

            if toclip[segment[0]][0] == "Xmin":
                Xmin = max(toclip[segment[0]][1], Xmin)
            if toclip[segment[0]][0] == "Xmax":
                Xmax = min(toclip[segment[0]][1], Xmax)
            if toclip[segment[0]][0] == "Ymin":
                Ymin = max(toclip[segment[0]][1], Ymin)
            if toclip[segment[0]][0] == "Ymax":
                Ymax = min(toclip[segment[0]][1], Ymax)

        segmentscursor.updateRow(segment)

        array = arcpy.Array([
            arcpy.Point(Xmin, Ymin),
            arcpy.Point(Xmin, Ymax),
            arcpy.Point(Xmax, Ymax),
            arcpy.Point(Xmax, Ymin)
        ])
        polygon = arcpy.Polygon(array)

        if segment[0] in lakes_bci:
            lakeid = lakes_bci[segment[0]]
        else:
            lakeid = -999

        cursor.insertRow([segment[0], polygon, lakeid])

    del cursor
    del segmentscursor

    arcpy.CreateFeatureclass_management(
        os.path.dirname(save_sourcepoints),
        os.path.basename(save_sourcepoints),
        "POINT",
        spatial_reference=flowdir.raster.spatialReference)
    arcpy.AddField_management(save_sourcepoints, "ZoneID", "LONG")
    arcpy.AddField_management(save_sourcepoints, "fpid", "LONG")

    pointcursor = arcpy.da.InsertCursor(save_sourcepoints,
                                        ["ZoneID", "fpid", "SHAPE@XY"])
    for pointkey in inputpoints:
        pointcursor.insertRow([
            pointkey, inputpoints[pointkey].frompointid,
            (inputpoints[pointkey].X, inputpoints[pointkey].Y)
        ])
    del pointcursor

    return
Exemplo n.º 3
0
def execute_BankfullAtCS(r_dem, r_flowdir, str_frompoints, r_cs, p_detect, thresholdz, increment, str_bkf, messages, language = "FR"):



    # Chargement des fichiers
    dem = RasterIO(r_dem)
    flowdir = RasterIO(r_flowdir)
    cs = RasterIO(r_cs)
    try:
        dem.checkMatch(flowdir)
        dem.checkMatch(cs)
    except Exception as e:
        messages.addErrorMessage(str(e))

    Result = RasterIO(r_dem, str_bkf, float,-255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "OID@")
    count = 0
    for frompoint in frompointcursor:
        count += 1
    progtext= "Calcul des élévations plein-bord aux sections transversales"
    if language == "EN":
        progtext = "Computing elevation at cross-sections"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "SHAPE@")
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol<0 or currentcol>=flowdir.raster.width or currentrow<0 or currentrow>= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and
                      flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and
                      flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and
                      flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            # Traitement effectué sur chaque section transversale
            if cs.getValue(currentrow,currentcol) != cs.nodata:


                zmin = dem.getValue(currentrow,currentcol)
                angle = cs.getValue(currentrow,currentcol)


                MaxHydroH = 0
                HydroH = 0

                stophydroh = False
                previouslisth = []
                previouslisth.append(zmin)
                previousstep = 0
                prevz = zmin
                previouslisth2 = []
                previouslisth2.append(zmin)
                previousstep2 = 0
                prevz2 = zmin
                n = 4
                # itérations, par incrément de 10 cm
                while n < (thresholdz/increment) and not stophydroh :
                    n += 1
                    # currentz : élévation plein-bord testée
                    currentz = zmin + increment*n

                    listh = list(previouslisth)
                    step = previousstep
                    stop = False
                    # Déplacement le long de la section transversale
                    while not stop:
                        step += 1
                        # calcul de la ligne et de la colonne du prochain point dans l'axe de la section transversale
                        if (angle > math.pi / 4 and angle < 3 * math.pi / 4):
                            rowinc = -step
                            colinc = int(math.cos(angle)*step)
                        else:
                            colinc = step
                            rowinc = -int(math.sin(angle)*step)
                        if angle > 3 * math.pi / 4:
                            rowinc = -rowinc
                        # localz : élévation du sol pour le point testé le long de la section transversale
                        localz = dem.getValue(currentrow + rowinc, currentcol + colinc)
                        # on arrête d'avancer le long de la section transversale quand l'élévation devient plus grande que l'élévation plein-bord testée (ou si on sort du raster)
                        if localz != dem.nodata:
                            if localz < prevz:
                                localz = prevz
                            if localz >= currentz:
                                stop = True
                            prevz = localz
                        else:
                            stop = True
                        listh.append(localz)
                    if(len(listh)>2):
                        previousstep = step -1
                        previouslisth = listh[:len(listh)-1]
                    sumh = 0

                    # Pour toutes les élévations sauf la première
                    for i in range(1,len(listh)):
                        if i<len(listh)-1:
                            # Toutes les élévations sauf la dernière.
                            # Aire = panneau trapezoidale
                            sumh+= (currentz-listh[i-1]+currentz-listh[i])/2
                        elif listh[i]!=dem.nodata:
                            # Dernière élévation : plus haute que currentz.
                            # Aire = formule pour le petit triangle
                            sumh += (currentz-listh[i-1])*(currentz-listh[i-1])/(listh[i]-listh[i-1])/2
                            step -= 1
                            step += (currentz - listh[i - 1]) / (listh[i] - listh[i - 1])
                        else:
                            # Dernière élévation : No Data
                            # Pas d'aire calculée pour ce panneau
                            step-=1
                    # on répète les opérations précédentes en progressant dans l'autre sens le long de la section transversale

                    listh = list(previouslisth2)
                    step2 = previousstep2

                    stop = False

                    while not stop:
                        step2 += 1
                        if (angle > math.pi / 4 and angle < 3 * math.pi / 4):
                            rowinc = -step2
                            colinc = int(math.cos(angle) * step2)
                        else:
                            colinc = step2
                            rowinc = -int(math.sin(angle) * step2)
                        if angle > 3 * math.pi / 4:
                            rowinc = -rowinc
                        localz = dem.getValue(currentrow - rowinc, currentcol - colinc)



                        if localz != dem.nodata:
                            if localz < prevz2:
                                localz = prevz2
                            if localz >= currentz:
                                stop = True
                            prevz2 = localz
                        else:
                            stop = True

                        listh.append(localz)
                    if(len(listh)>2):
                        previousstep2 = step2 -1
                        previouslisth2 = listh[:len(listh)-1]
                    sumh2 = 0
                    for i in range(1, len(listh)):
                        if i < len(listh) - 1:
                            sumh2 += (currentz - listh[i - 1] + currentz - listh[i]) / 2
                        elif listh[i] != dem.nodata:
                            sumh2 += (currentz - listh[i - 1]) * (currentz - listh[i - 1]) / (
                            listh[i] - listh[i - 1]) / 2
                            step2 -= 1
                            step2 += (currentz - listh[i - 1]) / (listh[i] - listh[i - 1])
                        else:
                            step2-=1



                    # Calcul de la profondeur moyenne
                    # Note: erreur de +1 au lieu de -1 ds la version EPRI1
                    HydroH = (sumh + sumh2) / (step + step2)

                    # Le critère pour détecter le niveau plein-bord est-il respecté ?
                    if (HydroH < (1-p_detect/100)*MaxHydroH):
                        # si oui, on prends la dernière élévation plein-bord testé, moins 10 cm
                        bkfh = currentz - increment
                        stophydroh = True
                    MaxHydroH = max(HydroH, MaxHydroH)

                # stophydroh est vrai si un niveau plein-bord a été détecté
                if stophydroh:
                    Result.setValue(currentrow,currentcol,bkfh)





            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1

            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1

            if (direction == 4):
                currentrow = currentrow + 1

            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1

            if (direction == 16):
                currentcol = currentcol - 1

            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1

            if (direction == 64):
                currentrow = currentrow - 1

            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and
                          flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and
                          flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and
                          flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    intheraster = False



    Result.save()


    return
def execute_RunSim_prev_2var(str_zonefolder, str_simfolder, str_lisfloodfolder, str_csvq, str_csvz, voutput, simtime, channelmanning, r_zbed, str_log, messages):

    str_inbci = str_zonefolder + "\\inbci.shp"
    str_outbci = str_zonefolder + "\\outbci.shp"
    zbed = RasterIO(r_zbed)



    bcipointcursor = arcpy.da.SearchCursor(str_inbci, ["SHAPE@", "zoneid", "flowacc", "type", "fpid"])
    dictsegmentsin = {}



    for point in bcipointcursor:
        if point[1] not in dictsegmentsin:
            dictsegmentsin[point[1]] = []
        dictsegmentsin[point[1]].append(point)


    allzones = list(dictsegmentsin.keys())
    allzones.sort()


    dictzones_fp = {}

    for zone in allzones:
        if dictsegmentsin[zone][0][4] not in dictzones_fp:
            dictzones_fp[dictsegmentsin[zone][0][4]] = []

        dictzones_fp[dictsegmentsin[zone][0][4]].append(zone)

    sortedzones = []
    listfp = list(dictzones_fp.keys())
    listfp.sort()
    for fp in listfp:
        listzones_fp = dictzones_fp[fp]
        listzones_fp.sort(reverse=True)
        sortedzones.extend(listzones_fp)

    # Ajout des information du fichier outbci.shp
    listzonesout = {}
    bcipointcursor = arcpy.da.SearchCursor(str_outbci, ["zoneid", "side", "lim1", "lim2", "side2", "lim3", "lim4", "SHAPE@"])
    for point in bcipointcursor:
        listzonesout[point[0]] = point


    zones = str_zonefolder + "\\envelopezones.shp"
    # récupération du bci lac
    zonesscursor = arcpy.da.SearchCursor(zones, ["GRID_CODE", "SHAPE@", "Lake_ID"])
    lakeid_byzone = {}
    for zoneshp in zonesscursor:

        if zoneshp[2] != -999:
            lakeid_byzone[zoneshp[0]] = zoneshp[2]




    filelog = open(str_log, 'w')



    csvfilez = open(str_csvz)
    csv_readerz = csv.DictReader(csvfilez)

    ref_raster = None

    for csvzrow in csv_readerz:
        zname = csvzrow["nom"]
        hfix = float(csvzrow["z"])

        csvfileq = open(str_csvq)
        csv_readerq = csv.DictReader(csvfileq)

        for csvqrow in csv_readerq:
            simname = csvqrow["nom"] + "_" + zname
            currentsimfolder = str_simfolder + "\\" + simname
            currentresult = str_simfolder + "\\res_" + simname
            simq = float(csvqrow["q"])

            if not os.path.isdir(currentsimfolder):
                os.makedirs(currentsimfolder)

            for zone in sortedzones:
                segment = dictsegmentsin[zone]
                for point in sorted(segment, key=lambda q: q[2]):

                    if point[3]=="main":
                        try:
                            if not arcpy.Exists(currentsimfolder + "\\elev_zone" + str(point[1])):

                                if ref_raster is None:
                                    ref_raster = arcpy.Raster(str_zonefolder + "\\zone" + str(point[1]))


                                outpointshape = listzonesout[point[1]][7].firstPoint

                                if arcpy.Exists(currentresult):
                                    # dans le cas où un fichier résultat existe avec un résulat valide, on prends les résultats de ce fichier comme limite aval
                                    if arcpy.Exists(currentsimfolder + "\\tmp_zone" + str(point[1])):
                                        arcpy.Delete_management(currentsimfolder + "\\tmp_zone" + str(point[1]))
                                    arcpy.Copy_management(currentresult, currentsimfolder + "\\tmp_zone" + str(point[1]))
                                    res_downstream = RasterIO(arcpy.Raster(currentsimfolder + "\\tmp_zone" + str(point[1])))
                                    hfix_raster = res_downstream.getValue(res_downstream.YtoRow(outpointshape.Y),
                                                                   res_downstream.XtoCol(outpointshape.X))
                                    if hfix_raster != res_downstream.nodata:
                                        hfix_sim = hfix_raster
                                    else:
                                        hfix_sim = hfix
                                    arcpy.Delete_management(currentsimfolder + "\\tmp_zone" + str(point[1]))
                                else:
                                    hfix_sim = hfix

                                # par

                                newfile = str_simfolder + "\\zone" + str(point[1]) + ".par"
                                if os.path.isfile(newfile):
                                    os.remove(newfile)

                                filepar = open(newfile, 'w')
                                filepar.write("DEMfile\tzone" + str(point[1]) + ".txt\n")
                                filepar.write("resroot\tzone" + str(point[1]) + "\n")
                                filepar.write("dirroot\t" + simname + "\n")
                                filepar.write("manningfile\tnzone" + str(point[1]) + ".txt\n")
                                filepar.write("bcifile\tzone" + str(point[1]) + ".bci" + "\n")
                                filepar.write("sim_time\t" + str(simtime) + "\n")
                                filepar.write("saveint\t" + str(simtime) + "\n")
                                filepar.write("bdyfile\t"+ simname +"\\zone" + str(point[1]) + ".bdy" + "\n")
                                filepar.write("SGCwidth\twzone" + str(point[1]) + ".txt\n")
                                filepar.write("SGCbank\tzone" + str(point[1]) + ".txt\n")
                                filepar.write("SGCbed\tdzone" + str(point[1]) + ".txt\n")
                                filepar.write("SGCn\t" + str(channelmanning) + "\n")

                                filepar.write("chanmask\tmzone" + str(point[1]) + ".txt\n")

                                # Vitesses du courant
                                if voutput:
                                    filepar.write("hazard\n")
                                    filepar.write("qoutput\n")
                                filepar.write("cfl\t0.3\n")
                                filepar.write("max_Froude\t1\n")
                                # filepar.write("debug\n")
                                filepar.close()

                                # bdy
                                newfilebdy = currentsimfolder + "\\zone" + str(point[1]) + ".bdy"

                                for point2 in sorted(segment, key=lambda q: q[2]):

                                    q_value = point2[2]*simq*(ref_raster.meanCellHeight*ref_raster.meanCellWidth)/1000000.

                                    if point2[3] == "main":
                                        # Création du fichier bdy


                                        pointdischarge = q_value / (
                                        (ref_raster.meanCellHeight + ref_raster.meanCellWidth) / 2)
                                        lastdischarge = q_value
                                        latnum = 0
                                        filebdy = open(newfilebdy, 'w')
                                        filebdy.write("zone"+str(point[1]) + ".bdy\n")
                                        filebdy.write("zone"+str(point[1]) + "\n")
                                        filebdy.write("3\tseconds\n")
                                        filebdy.write("0\t0\n")
                                        filebdy.write("{0:.3f}".format(pointdischarge) + "\t50000\n")
                                        filebdy.write("{0:.3f}".format(pointdischarge) + "\t" + str(simtime))
                                        filebdy.close()
                                    else:
                                        latnum += 1
                                        pointdischarge = (q_value - lastdischarge) / (
                                        (ref_raster.meanCellHeight + ref_raster.meanCellWidth) / 2)
                                        lastdischarge = q_value
                                        filebdy = open(newfilebdy, 'a')
                                        filebdy.write("\nzone" + str(point[1]) + "_" + str(latnum) + "\n")
                                        filebdy.write("3\tseconds\n")
                                        filebdy.write("0\t0\n")
                                        filebdy.write("{0:.3f}".format(pointdischarge) + "\t50000\n")
                                        filebdy.write("{0:.3f}".format(pointdischarge) + "\t" + str(simtime))
                                        filebdy.close()

                                # condition aval: 30cm au dessus du lit pour commencer
                                zdep = min(zbed.getValue(zbed.YtoRow(outpointshape.Y),
                                                         zbed.XtoCol(outpointshape.X)) + 0.3, hfix_sim)
                                filebdy = open(newfilebdy, 'a')
                                filebdy.write("\nhvar\n")
                                filebdy.write("4\tseconds\n")
                                filebdy.write("{0:.2f}".format(zdep) + "\t0\n")
                                filebdy.write("{0:.2f}".format(zdep) + "\t50000\n")
                                filebdy.write("{0:.2f}".format(hfix_sim) + "\t55000\n")
                                filebdy.write("{0:.2f}".format(hfix_sim) + "\t" + str(simtime))

                                filebdy.close()

                                # calcul pour le -steadytol
                                # Divise le débit par 200 et ne conserve qu'un chiffre significatif
                                steadytol = str(
                                    round(lastdischarge / 200., - int(math.floor(math.log10(abs(lastdischarge / 200.))))))

                                subprocess.check_call([str_lisfloodfolder + "\\lisflood_intelRelease_double.exe", "-steady", "-steadytol", steadytol, str_simfolder + "\\zone" + str(point[1]) + ".par"], shell=True, cwd=str_simfolder)




                                # Conversion des fichiers output

                                # on renomme les fichiers créés (nécessaire pour être acceptés par l'outil de convsersion ASCII vers raster)
                                zonename = "zone"+str(point[1])

                                if os.path.exists(currentsimfolder + "\\"  + zonename + "elev.txt"):
                                    os.remove(currentsimfolder + "\\"   + zonename + "elev.txt")

                                if os.path.exists(currentsimfolder   + "\\" + zonename + "-9999.elev"):
                                    os.rename(currentsimfolder  + "\\"  + zonename + "-9999.elev",
                                              currentsimfolder + "\\" + zonename + "elev.txt")
                                else:
                                    os.rename(currentsimfolder  + "\\" + zonename + "-0001.elev",
                                              currentsimfolder + "\\" + zonename + "elev.txt")
                                    filelog.write("Steady state not reached : " + zonename + ", sim " + simname)
                                    messages.addWarningMessage("Steady state not reached : " + zonename + ", sim " + simname)

                                if os.path.exists(currentsimfolder + "\\" + zonename + "-9999.Vx") or os.path.exists(currentsimfolder + "\\"  + zonename + "-0001.Vx"):
                                    if os.path.exists(currentsimfolder + "\\" + zonename + "Vx.txt"):
                                        os.remove(currentsimfolder + "\\" + zonename + "Vx.txt")

                                    if os.path.exists(currentsimfolder + "\\" + zonename + "Vy.txt"):
                                        os.remove(currentsimfolder + "\\" + zonename + "Vy.txt")
                                    if os.path.exists(currentsimfolder  + "\\" + zonename + "-9999.Vx"):
                                        os.rename(currentsimfolder  + "\\" + zonename + "-9999.Vx",
                                                  currentsimfolder+ "\\" + zonename + "Vx.txt")
                                        os.rename(currentsimfolder  + "\\"  + zonename + "-9999.Vy",
                                                  currentsimfolder  + "\\" + zonename + "Vy.txt")
                                    else:
                                        os.rename(currentsimfolder  + "\\" + zonename + "-0001.Vx",
                                                  currentsimfolder  + "\\" + zonename + "Vx.txt")
                                        os.rename(currentsimfolder  + "\\" + zonename + "-0001.Vy",
                                                  currentsimfolder  + "\\" + zonename + "Vy.txt")
                                    arcpy.ASCIIToRaster_conversion(currentsimfolder  + "\\" + zonename + "Vx.txt",
                                                                   currentsimfolder + "\\Vx_" + zonename,
                                                               "FLOAT")
                                    arcpy.ASCIIToRaster_conversion(currentsimfolder  + "\\" + zonename + "Vy.txt",
                                                                   currentsimfolder + "\\Vy_" + zonename,
                                                               "FLOAT")
                                    arcpy.DefineProjection_management(currentsimfolder + "\\Vx_" + zonename, ref_raster.spatialReference)
                                    arcpy.DefineProjection_management(currentsimfolder + "\\Vy_" + zonename, ref_raster.spatialReference)


                                # Conversion des fichiers de sortie en raster pour ArcGIS
                                str_elev = currentsimfolder + "\\elev_" + zonename
                                arcpy.ASCIIToRaster_conversion(currentsimfolder + "\\"  + zonename + "elev.txt", str_elev, "FLOAT")


                                # Ajout de la projection
                                arcpy.DefineProjection_management(str_elev, ref_raster.spatialReference)



                            if not arcpy.Exists(currentresult):

                                arcpy.Copy_management(currentsimfolder + "\\elev_" + "zone"+str(point[1]), currentresult)
                            else:

                                arcpy.Mosaic_management(currentsimfolder + "\\elev_" + "zone"+str(point[1]), currentresult, mosaic_type="MAXIMUM")
                                #arcpy.Copy_management(str_output + "\\lisflood_res", str_output + "\\tmp_mosaic")
                                #arcpy.Delete_management(str_output + "\\lisflood_res")
                                # arcpy.MosaicToNewRaster_management(';'.join([str_output + "\\tmp_mosaic", str_output + "\\elev_" + point[1]]),
                                #                                    str_output,"lisflood_res",
                                #                                    pixel_type="32_BIT_FLOAT",
                                #                                    number_of_bands=1)

                        except BaseException as e:
                            filelog.write("ERREUR in " + simname + ": sim aborded during zone "+ str(point[1]) + "\n")
                            messages.addWarningMessage("Some simulations skipped. See log file.")
    return
Exemplo n.º 5
0
def execute_RiverWith(r_binary,
                      r_flowdir,
                      str_frompoints,
                      r_cs,
                      oriented,
                      str_width,
                      messages,
                      language="FR"):

    # Chargement des fichiers
    binary = RasterIO(r_binary)
    flowdir = RasterIO(r_flowdir)
    cs = RasterIO(r_cs)
    try:
        flowdir.checkMatch(cs)
    except Exception as e:
        messages.addErrorMessage(e.message)

    Result = RasterIO(r_flowdir, str_width, float, -255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "OID@")
    count = 0
    for frompoint in frompointcursor:
        count += 1

    progtext = "Calcul de la largeur aux sections transversales"
    if language == "EN":
        progtext = "Processing"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "SHAPE@")
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            # On se reprojète dans le système de coordonnées du raster binary
            colbinary = binary.XtoCol(flowdir.ColtoX(currentcol))
            rowbinary = binary.YtoRow(flowdir.RowtoY(currentrow))

            angle = cs.getValue(currentrow, currentcol)
            if angle != cs.nodata:

                if oriented:
                    # calcul de la ligne et de la colonne du prochain point dans l'axe de la section transversale
                    if (angle > math.pi / 4 and angle < 3 * math.pi / 4):
                        rowinc = -1
                        colinc = math.cos(angle)
                    else:
                        colinc = 1
                        rowinc = -math.sin(angle)
                    if angle > 3 * math.pi / 4:
                        rowinc = -rowinc

                    step = 0

                    while binary.getValue(
                            rowbinary + int(rowinc * step),
                            colbinary + int(colinc * step)) != binary.nodata:
                        step += 1

                    # on répète les opérations précédentes en progressant dans l'autre sens le long de la section transversale
                    step2 = 0

                    while binary.getValue(
                            rowbinary - int(rowinc * step2),
                            colbinary - int(colinc * step2)) != binary.nodata:
                        step2 += 1

                    # if the process was not interrupted because an edge was reached
                    if (rowbinary + int(rowinc * step)) >= 0 and (
                            colbinary + int(colinc * step)
                    ) >= 0 and (rowbinary - int(rowinc * step2)) >= 0 and (
                            colbinary - int(colinc * step2)
                    ) and (rowbinary + int(rowinc * step)
                           ) < binary.raster.height and (colbinary + int(
                               colinc * step)) < binary.raster.width and (
                                   rowbinary - int(rowinc * step2)
                               ) < binary.raster.height and (colbinary - int(
                                   colinc * step2)) < binary.raster.width:

                        basedist = math.sqrt(
                            (rowinc * binary.raster.meanCellHeight)**2 +
                            (colinc * binary.raster.meanCellWidth)**2)

                        width = basedist * (step + step2)
                        Result.setValue(currentrow, currentcol, width)

                else:
                    # on teste la largeur sur une étoile à 16 branches et on prend le minimum
                    minwidth = None
                    for star_i in range(1, 9):
                        step = 0
                        step2 = 0
                        if star_i == 1:
                            rowinc = 0
                            colinc = 1
                        if star_i == 2:
                            rowinc = step % 2
                            colinc = 1
                        if star_i == 3:
                            rowinc = 1
                            colinc = 1
                        if star_i == 4:
                            rowinc = 1
                            colinc = step % 2
                        if star_i == 5:
                            rowinc = 1
                            colinc = 0
                        if star_i == 6:
                            rowinc = 1
                            colinc = -step % 2
                        if star_i == 7:
                            rowinc = 1
                            colinc = -1
                        if star_i == 8:
                            rowinc = step % 2
                            colinc = -1

                        while binary.getValue(
                                rowbinary + int(rowinc * step), colbinary +
                                int(colinc * step)) != binary.nodata:
                            step += 1

                        while binary.getValue(
                                rowbinary - int(rowinc * step2), colbinary -
                                int(colinc * step2)) != binary.nodata:
                            step2 += 1

                        width = None
                        # if the process was not interrupted because an edge was reached
                        if (rowbinary + int(rowinc * step)) >= 0 and (
                                colbinary + int(colinc * step)
                        ) >= 0 and (rowbinary - int(rowinc * step2)) >= 0 and (
                                colbinary - int(colinc * step2)
                        ) and (rowbinary +
                               int(rowinc * step)) < binary.raster.height and (
                                   colbinary + int(colinc * step)
                               ) < binary.raster.width and (
                                   rowbinary - int(rowinc * step2)
                               ) < binary.raster.height and (colbinary - int(
                                   colinc * step2)) < binary.raster.width:
                            basedist = math.sqrt(
                                (rowinc * binary.raster.meanCellHeight)**2 +
                                (colinc * binary.raster.meanCellWidth)**2)

                            width = basedist * (step + step2)

                        if minwidth is not None:
                            if width is not None:
                                minwidth = min(minwidth, width)
                        else:
                            minwidth = width

                    if minwidth is not None:
                        Result.setValue(currentrow, currentcol, minwidth)

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1

            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1

            if (direction == 4):
                currentrow = currentrow + 1

            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1

            if (direction == 16):
                currentcol = currentcol - 1

            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1

            if (direction == 64):
                currentrow = currentrow - 1

            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    intheraster = False

    Result.save()

    return
def execute_LinearInterpolation(r_flowdir,
                                str_frompoint,
                                r_values,
                                str_results,
                                messages,
                                language="FR"):

    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)
    bkfatcs = RasterIO(r_values)
    try:
        flowdir.checkMatch(bkfatcs)
    except Exception as e:
        messages.addErrorMessage(e.message)

    Result = RasterIO(r_flowdir, str_results, float, -255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    count = 0
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "OID@")
    for frompoint in frompointcursor:
        count += 1
    progtext = "Traitement"
    if language == "EN":
        progtext = "Processing"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, ["OID@", "SHAPE@"])
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[1].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        listpointsflowpath = []
        listdistance = []
        listelevation = []
        totaldistance = 0
        currentdistance = 0
        confluence = False

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            currentpoint = pointflowpath()
            currentpoint.row = currentrow
            currentpoint.col = currentcol
            totaldistance = totaldistance + currentdistance

            currentpoint.flowlength = totaldistance
            currentpoint.oncs = False

            # On crée une liste des points d'élévation connue le long de l'écoulement, ainsi qu'une liste associée avec leur distance depuis le point de distance
            if bkfatcs.getValue(currentrow, currentcol) != bkfatcs.nodata:
                if confluence:
                    # point après atteinte d'une confluence. On arrête le traitement
                    intheraster = False
                listdistance.append(totaldistance)
                listelevation.append(bkfatcs.getValue(currentrow, currentcol))
                currentpoint.oncs = True

            currentpoint.previouscsid = len(listdistance) - 1
            if not confluence:
                listpointsflowpath.append(currentpoint)

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    # On continue encore jusqu'au prochain point
                    confluence = True

        if len(listdistance) <= 1:
            # Avertissement si il n'y a qu'un seul (ou aucun) point de données
            if language == "FR":
                messages.addWarningMessage(
                    "Point source {0}: pas assez de sections transversales".
                    format(frompoint[0]))
            else:
                messages.addWarningMessage(
                    "From point {0}: not enough cross-sections".format(
                        frompoint[0]))

        else:

            currentpointnumber = 0
            # Traitement pour chaque point le long de l'écoulement
            for currentpoint in listpointsflowpath:

                try:
                    if currentpoint.previouscsid == -1:
                        # cas particulier des premiers points avant une cs
                        # on prends la valeur de la premier cs
                        finalvalue = listelevation[0]
                    else:
                        if currentpoint.oncs:
                            # cas particulier : points sur une section transversale
                            finalvalue = listelevation[
                                currentpoint.previouscsid]
                        else:
                            finalvalue = listelevation[currentpoint.previouscsid]* \
                                         (listdistance[currentpoint.previouscsid + 1] - currentpoint.flowlength)/\
                                         (listdistance[currentpoint.previouscsid+1]-listdistance[currentpoint.previouscsid])\
                                         + listelevation[currentpoint.previouscsid+1]* \
                                         (currentpoint.flowlength - listdistance[currentpoint.previouscsid])/\
                                         (listdistance[currentpoint.previouscsid+1]-listdistance[currentpoint.previouscsid])
                except IndexError:
                    # IndexError lorsque l'on est en aval de la dernière section transversales
                    finalvalue = listelevation[-1]

                Result.setValue(currentpoint.row, currentpoint.col, finalvalue)

                currentpointnumber = currentpointnumber + 1

    Result.save()

    return
def execute_RunSim(str_zonefolder, str_simfolder, str_lisfloodfolder, r_q, str_lakes, field_z, voutput, simtime, channelmanning, r_zbed, messages):

    str_inbci = str_zonefolder + "\\inbci.shp"
    str_outbci = str_zonefolder + "\\outbci.shp"
    zbed = RasterIO(r_zbed)

    discharge = RasterIO(r_q)

    # count est utilisé pour compter le nombre de zones, pour la barre de progression lors des simulations
    count = 0

    bcipointcursor = arcpy.da.SearchCursor(str_inbci, ["SHAPE@", "zoneid", "flowacc", "type", "fpid"])
    dictsegmentsin = {}



    for point in bcipointcursor:
        if point[1] not in dictsegmentsin:
            dictsegmentsin[point[1]] = []
        dictsegmentsin[point[1]].append(point)


    allzones = list(dictsegmentsin.keys())
    allzones.sort()

    dictzones_fp = {}

    for zone in allzones:
        if dictsegmentsin[zone][0][4] not in dictzones_fp:
            dictzones_fp[dictsegmentsin[zone][0][4]] = []

        dictzones_fp[dictsegmentsin[zone][0][4]].append(zone)

    sortedzones = []
    listfp = list(dictzones_fp.keys())
    listfp.sort()
    for fp in listfp:
        listzones_fp = dictzones_fp[fp]
        listzones_fp.sort(reverse=True)
        sortedzones.extend(listzones_fp)

    # Ajout des information du fichier outbci.shp
    listzonesout = {}
    bcipointcursor = arcpy.da.SearchCursor(str_outbci, ["zoneid", "side", "lim1", "lim2", "side2", "lim3", "lim4", "SHAPE@"])
    for point in bcipointcursor:
        listzonesout[point[0]] = point


    zones = str_zonefolder + "\\envelopezones.shp"
    # récupération du bci lac
    zonesscursor = arcpy.da.SearchCursor(zones, ["GRID_CODE", "SHAPE@", "Lake_ID"])
    lakeid_byzone = {}
    for zoneshp in zonesscursor:
        if zoneshp[2] != -999:
            lakeid_byzone[zoneshp[0]] = zoneshp[2]

    # Z BCI
    fieldidlakes = arcpy.Describe(str_lakes).OIDFieldName
    shplakes = arcpy.da.SearchCursor(str_lakes, [fieldidlakes, field_z])
    fieldz_bylakeid = {}
    for shplake in shplakes:
        fieldz_bylakeid[shplake[0]] = shplake[1]

    # Lancement de LISFLOOD-FP
    arcpy.SetProgressor("step", "Simulation 2D", 0, count, 1)
    progres = 0
    arcpy.SetProgressorPosition(progres)

    if os.path.exists(str_simfolder + "\\lisflood_res"):
        arcpy.Delete_management(str_simfolder + "\\lisflood_res")

    for zone in sortedzones:
        segment = dictsegmentsin[zone]

        for point in sorted(segment, key=lambda q: q[2]):
            zonename = "zone" + str(point[1])

            if point[3]=="main":
                if not arcpy.Exists(str_simfolder + "\\elev_zone" + str(point[1])):


                    outpointshape = listzonesout[point[1]][7].firstPoint

                    if point[1] in lakeid_byzone:
                        hfix = fieldz_bylakeid[lakeid_byzone[point[1]]]

                    else:
                        if not os.path.exists(str_simfolder + "\\lisflood_res"):
                            messages.addErrorMessage("Condition limite aval non trouvée : zone " + str(point[1]))
                        else:
                            # issue with Mosaic_management, used later with lisflood_res:
                            # crash sometimes if the file is read here
                            # so we make a tmp copy
                            if arcpy.Exists(str_simfolder + "\\tmp_zone"  + str(point[1])):
                                arcpy.Delete_management(str_simfolder + "\\tmp_zone"  + str(point[1]))
                            arcpy.Copy_management(str_simfolder + "\\lisflood_res", str_simfolder + "\\tmp_zone" + str(point[1]))
                            res_downstream = RasterIO(arcpy.Raster(str_simfolder + "\\tmp_zone"  + str(point[1])))
                            hfix = res_downstream.getValue(res_downstream.YtoRow(outpointshape.Y), res_downstream.XtoCol(outpointshape.X))
                            if hfix == res_downstream.nodata:
                                messages.addErrorMessage("Condition limite aval non trouvée : zone " + str(point[1]))
                            arcpy.Delete_management(str_simfolder + "\\tmp_zone"  + str(point[1]))



                    # par

                    newfile = str_simfolder + "\\zone" + str(point[1]) + ".par"
                    filepar = open(newfile, 'w')
                    filepar.write("DEMfile\tzone" + str(point[1]) + ".txt\n")
                    filepar.write("resroot\tzone" + str(point[1]) + "\n")
                    filepar.write("dirroot\t" + "res\n")
                    filepar.write("manningfile\tnzone" + str(point[1]) + ".txt\n")
                    filepar.write("bcifile\tzone" + str(point[1]) + ".bci" + "\n")
                    filepar.write("sim_time\t" + str(simtime) + "\n")
                    filepar.write("saveint\t" + str(simtime) + "\n")
                    filepar.write("bdyfile\tzone" + str(point[1]) + ".bdy" + "\n")
                    filepar.write("SGCwidth\twzone" + str(point[1]) + ".txt\n")
                    filepar.write("SGCbank\tzone" + str(point[1]) + ".txt\n")
                    filepar.write("SGCbed\tdzone" + str(point[1]) + ".txt\n")
                    filepar.write("SGCn\t" + str(channelmanning) + "\n")

                    filepar.write("chanmask\tmzone" + str(point[1]) + ".txt\n")

                    # Vitesses du courant
                    if voutput:
                        filepar.write("qoutput\n")
                    filepar.write("cfl\t0.5\n")
                    filepar.write("max_Froude\t1\n")
                    # filepar.write("debug\n")
                    filepar.close()

                    # bdy
                    newfilebdy = str_simfolder + "\\zone" + str(point[1]) + ".bdy"

                    for point2 in sorted(segment, key=lambda q: q[2]):

                        raster_q_value = discharge.getValue(discharge.YtoRow(point2[0].firstPoint.Y),
                                                            discharge.XtoCol(point2[0].firstPoint.X))
                        if point2[3] == "main":
                            # Création du fichier bdy

                            pointdischarge = raster_q_value / (
                            (discharge.raster.meanCellHeight + discharge.raster.meanCellWidth) / 2)
                            lastdischarge = raster_q_value
                            latnum = 0
                            filebdy = open(newfilebdy, 'w')
                            filebdy.write("zone"+str(point[1]) + ".bdy\n")
                            filebdy.write("zone"+str(point[1]) + "\n")
                            filebdy.write("3\tseconds\n")
                            filebdy.write("0\t0\n")
                            filebdy.write("{0:.3f}".format(pointdischarge) + "\t50000\n")
                            filebdy.write("{0:.3f}".format(pointdischarge) + "\t" + str(simtime))
                            filebdy.close()
                        else:
                            latnum += 1
                            pointdischarge = (raster_q_value - lastdischarge) / (
                            (discharge.raster.meanCellHeight + discharge.raster.meanCellWidth) / 2)
                            lastdischarge = raster_q_value
                            filebdy = open(newfilebdy, 'a')
                            filebdy.write("\nzone" + str(point[1]) + "_" + str(latnum) + "\n")
                            filebdy.write("3\tseconds\n")
                            filebdy.write("0\t0\n")
                            filebdy.write("{0:.3f}".format(pointdischarge) + "\t50000\n")
                            filebdy.write("{0:.3f}".format(pointdischarge) + "\t" + str(simtime))
                            filebdy.close()

                    # condition aval: 30cm au dessus du lit pour commencer
                    zdep = min(zbed.getValue(zbed.YtoRow(outpointshape.Y),
                                             zbed.XtoCol(outpointshape.X)) + 0.3, hfix)
                    filebdy = open(newfilebdy, 'a')
                    filebdy.write("\nhvar\n")
                    filebdy.write("4\tseconds\n")
                    filebdy.write("{0:.2f}".format(zdep) + "\t0\n")
                    filebdy.write("{0:.2f}".format(zdep) + "\t50000\n")
                    filebdy.write("{0:.2f}".format(hfix) + "\t55000\n")
                    filebdy.write("{0:.2f}".format(hfix) + "\t" + str(simtime))

                    filebdy.close()

                    # calcul pour le -steadytol
                    # Divise le débit par 200 et ne conserve qu'un chiffre significatif
                    steadytol = str(round(lastdischarge / 200., - int(math.floor(math.log10(abs(lastdischarge / 200.))))))

                    subprocess.check_call([str_lisfloodfolder + "\\lisflood_intelRelease_double.exe", "-steady", "-steadytol", steadytol, str_simfolder + "\\zone" + str(point[1]) + ".par"], shell=True, cwd=str_simfolder)
                    progres += 1
                    arcpy.SetProgressorPosition(progres)



                    # Conversion des fichiers output

                    # on renomme les fichiers créés (nécessaire pour être acceptés par l'outil de convsersion ASCII vers raster)

                    if os.path.exists(str_simfolder + "\\res\\"  + zonename + "elev.txt"):
                        os.remove(str_simfolder + "\\res\\"  + zonename + "elev.txt")

                    if os.path.exists(str_simfolder + "\\res\\"  + zonename + "-9999.elev"):
                        os.rename(str_simfolder + "\\res\\"  + zonename + "-9999.elev",
                                  str_simfolder + "\\res\\" + zonename + "elev.txt")
                    else:
                        os.rename(str_simfolder + "\\res\\"  + zonename + "-0001.elev",
                                  str_simfolder + "\\res\\" + zonename + "elev.txt")
                        messages.addWarningMessage("Steady state not reached : " + zonename)

                    # Conversion des fichiers de sortie en raster pour ArcGIS
                    str_elev = str_simfolder + "\\elev_" + zonename
                    arcpy.ASCIIToRaster_conversion(str_simfolder + "\\res\\" + zonename + "elev.txt", str_elev, "FLOAT")


                    # Ajout de la projection
                    arcpy.DefineProjection_management(str_simfolder + "\\elev_" + zonename, r_q.spatialReference)


                    messages.addMessage(str(point[1]) + " done")

                if not arcpy.Exists(str_simfolder + "\\lisflood_res"):

                    arcpy.Copy_management(str_simfolder + "\\elev_" + zonename, str_simfolder + "\\lisflood_res")
                else:

                    arcpy.Mosaic_management(str_simfolder + "\\elev_" + zonename, str_simfolder + "\\lisflood_res", mosaic_type="MAXIMUM")
                    #arcpy.Copy_management(str_output + "\\lisflood_res", str_output + "\\tmp_mosaic")
                    #arcpy.Delete_management(str_output + "\\lisflood_res")
                    # arcpy.MosaicToNewRaster_management(';'.join([str_output + "\\tmp_mosaic", str_output + "\\elev_" + point[1]]),
                    #                                    str_output,"lisflood_res",
                    #                                    pixel_type="32_BIT_FLOAT",
                    #                                    number_of_bands=1)

    return
Exemplo n.º 8
0
def execute_orientedCS(r_flowdir,
                       str_frompoints,
                       str_ptscs,
                       smoothingdistance,
                       str_cs,
                       messages,
                       language="FR"):

    arcpy.env.outputCoordinateSystem = r_flowdir.spatialReference

    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)

    arcpy.env.extent = r_flowdir
    arcpy.env.snapRaster = r_flowdir
    randomname = binascii.hexlify(os.urandom(6)).decode()
    temp_cs2 = arcpy.env.scratchWorkspace + "\\" + str(randomname)
    arcpy.PointToRaster_conversion(str_ptscs,
                                   arcpy.Describe(str_ptscs).OIDFieldName,
                                   temp_cs2,
                                   cellsize=r_flowdir)
    temprastercs = RasterIO(arcpy.Raster(temp_cs2))
    Result = RasterIO(r_flowdir, str_cs, float, -255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "OID@")
    count = 0
    for frompoint in frompointcursor:
        count += 1
    progtext = "Calcul de l'orientation des sections transversales"
    if language == "EN":
        progtext = "Processing"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "SHAPE@")
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        intheraster = True
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        totaldistance = 0
        currentdistance = 0
        confluencedist = 0
        listpointsflowpath = []
        afterconfluence = False
        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            # On stock différentes informations sur le point dans listpointsflowpath
            currentpoint = pointflowpath()
            currentpoint.row = currentrow
            currentpoint.col = currentcol
            currentpoint.X = flowdir.ColtoX(currentcol)
            currentpoint.Y = flowdir.RowtoY(currentrow)
            currentpoint.addeddistance = currentdistance
            totaldistance = totaldistance + currentdistance
            currentpoint.distance = totaldistance
            listpointsflowpath.append(currentpoint)

            # Les points traité sont mis à -999 (cela permet la détection des confluences)
            if not afterconfluence:
                Result.setValue(currentrow, currentcol, -999)

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != Result.nodata):
                    # Atteinte d'un point déjà traité
                    if confluencedist == 0:
                        confluencedist = totaldistance + currentdistance
                        afterconfluence = True

                    # On continue encore sur la moitié de la distance de calcul de la pente après le confluent
                    if (totaldistance + currentdistance -
                            confluencedist) > smoothingdistance / 2:
                        intheraster = False

        currentpointnumber = 0

        # Traitement effectué sur la liste des points le long de l'écoulement
        while (currentpointnumber < len(listpointsflowpath)):

            currentpoint = listpointsflowpath[currentpointnumber]

            if temprastercs.getValue(currentpoint.row,
                                     currentpoint.col) != temprastercs.nodata:
                # Point pour lequel on doit calculer l'orientation de la section transversale

                listXforregression = []
                listYforregression = []
                listXforregression.append(currentpoint.X)
                listYforregression.append(currentpoint.Y)
                distancefromcurrentpoint = 0
                nbcellsfromcurrentpoint = 0
                try:
                    # on ajoute dans listpointforregression les points situés avant le point courant, jusqu'à la distance souhaitée
                    while (distancefromcurrentpoint <= smoothingdistance / 2):
                        nbcellsfromcurrentpoint = nbcellsfromcurrentpoint - 1
                        if (currentpointnumber + nbcellsfromcurrentpoint > 0):
                            distancefromcurrentpoint = distancefromcurrentpoint + listpointsflowpath[
                                currentpointnumber +
                                nbcellsfromcurrentpoint].addeddistance
                            listXforregression.append(
                                listpointsflowpath[currentpointnumber +
                                                   nbcellsfromcurrentpoint].X)
                            listYforregression.append(
                                listpointsflowpath[currentpointnumber +
                                                   nbcellsfromcurrentpoint].Y)
                        else:
                            raise IndexError
                    distancefromcurrentpoint = 0
                    nbcellsfromcurrentpoint = 0
                    # on ajoute également les points situé après le point courant, jusqu'à la distance souhaitée
                    while (distancefromcurrentpoint < smoothingdistance / 2):
                        nbcellsfromcurrentpoint = nbcellsfromcurrentpoint + 1
                        distancefromcurrentpoint = distancefromcurrentpoint + listpointsflowpath[
                            currentpointnumber +
                            nbcellsfromcurrentpoint].addeddistance
                        listXforregression.append(
                            listpointsflowpath[currentpointnumber +
                                               nbcellsfromcurrentpoint].X)
                        listYforregression.append(
                            listpointsflowpath[currentpointnumber +
                                               nbcellsfromcurrentpoint].Y)

                    # Variance et covariance prises avec 0 degrés de liberté
                    varx = numpy.var(listXforregression)
                    vary = numpy.var(listYforregression)
                    covarxy = numpy.cov(listXforregression,
                                        listYforregression,
                                        bias=True)[0][1]

                    slope = 0

                    if (covarxy != 0 and varx > 0 and vary > 0):
                        # Formule pour la régression par axe majeur : Legendre et Legendre, 1998, Numerical Ecology, 2ème édition (p.507)
                        slope = (vary - varx + math.sqrt(
                            (vary - varx)**2 + 4 * covarxy**2)) / (2 * covarxy)
                        angle = math.atan2(slope, 1)
                        # angle perpendiculaire à l'écoulement:
                        angle = angle + math.pi / 2
                        if (angle > math.pi):
                            angle = angle - 2 * math.pi
                    else:
                        if varx == 0:
                            angle = 0
                        elif vary == 0:
                            angle = math.pi / 2
                        else:
                            # la covariance est nulle
                            # on compare l'évolution en x et en y entre le premier et le dernier point
                            if (listXforregression[0] - listXforregression[-1]
                                ) > (listYforregression[0] -
                                     listYforregression[-1]):
                                angle = math.pi / 2
                            else:
                                angle = 0

                    Result.setValue(currentpoint.row, currentpoint.col, angle)

                except IndexError:
                    pass

            currentpointnumber = currentpointnumber + 1

    Result.save()
    # On supprime les -999 du résultat final
    raster_res = arcpy.sa.SetNull(str_cs, str_cs, "VALUE = -999")
    raster_res.save(str_cs)

    # On supprime le fichier temporaire
    arcpy.Delete_management(temp_cs2)

    return
def execute_FloodAndChannel(r_dem,
                            r_elevation,
                            r_flowdir,
                            r_slope,
                            str_frompoints,
                            threshold_slope,
                            threshold_growth,
                            maxiter,
                            str_output,
                            messages,
                            language="FR"):

    # Chargement des fichiers
    dem = RasterIO(r_dem)
    elevation = RasterIO(r_elevation)
    slope = None
    if r_slope is not None:
        slope = RasterIO(r_slope)
    flowdir = RasterIO(r_flowdir)
    try:
        dem.checkMatch(flowdir)
        dem.checkMatch(elevation)
        if slope is not None:
            dem.checkMatch(slope)
    except Exception as e:
        messages.addErrorMessage(e.message)

    # Fichier temporaire créé dans le "Scratch folder"
    randomname = binascii.hexlify(os.urandom(6)).decode()
    temp_flood = arcpy.env.scratchWorkspace + "\\" + str(randomname)
    Result = RasterIO(r_dem, temp_flood, float, -255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "SHAPE@")
    count = 0
    for frompoint in frompointcursor:
        count += 1
    progtext = "Traitement"
    if language == "EN":
        progtext = "Processing"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, ["SHAPE@", "OID@"])
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        listnewcells = []

        # Première itération: on ajoute les cellules pour la rivière, le long de l'écoulement
        while (intheraster):

            point = pointflowpath()
            point.row = currentrow
            point.col = currentcol
            point.elev = elevation.getValue(currentrow, currentcol)
            listnewcells.append(point)
            Result.setValue(currentrow, currentcol, point.elev)

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1

            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1

            if (direction == 4):
                currentrow = currentrow + 1

            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1

            if (direction == 16):
                currentcol = currentcol - 1

            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1

            if (direction == 64):
                currentrow = currentrow - 1

            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != Result.nodata):
                    # Atteinte d'un confluent
                    intheraster = False

        lengthflowpath = len(listnewcells)

        # Itération réalisée jusqu'à atteinte du seuil de croissance négligeable, avec aggrandissement de la largeur d'une cellule à chaque itération
        iteration = 0
        while ((float(len(listnewcells)) / float(lengthflowpath)) >=
               threshold_growth) and iteration < maxiter:

            currentlistnewcells = []

            iteration += 1
            # Pour chaque cellule que l'on a ajoutée à l'itération précédente...
            while (len(listnewcells) > 0):
                currentpoint = listnewcells.pop()
                # ... on test les cellules voisines
                for i in range(1, 5):
                    neighbourcol = currentpoint.col
                    neighbourrow = currentpoint.row
                    if i == 1:
                        neighbourcol += 1
                    elif i == 2:
                        neighbourcol -= 1
                    elif i == 3:
                        neighbourrow += 1
                    elif i == 4:
                        neighbourrow -= 1

                    try:
                        # Si la cellule voisine existe et n'a pas déjà été testée...
                        if (Result.getValue(neighbourrow, neighbourcol)
                                == Result.nodata) and dem.getValue(
                                    neighbourrow, neighbourcol) != dem.nodata:
                            testslope = True
                            if slope is not None:
                                testslope = slope.getValue(
                                    neighbourrow,
                                    neighbourcol) < threshold_slope
                            # ... on teste si la cellule testée est dans le chenal / inondée ...
                            if (dem.getValue(neighbourrow, neighbourcol) <
                                    currentpoint.elev) and testslope:
                                #... auquel cas on mets à jour le fichier de résultat et la liste des cellules ajoutées par l'itération en cours
                                Result.setValue(neighbourrow, neighbourcol,
                                                currentpoint.elev)
                                point = pointflowpath()
                                point.row = neighbourrow
                                point.col = neighbourcol
                                point.elev = currentpoint.elev
                                currentlistnewcells.append(point)

                            else:
                                # Les cellules testées négativement sont mises à -999 pour éviter de les tester à nouveau
                                Result.setValue(neighbourrow, neighbourcol,
                                                -999)
                    except IndexError:
                        # Exception déclenchée et à ignorer lorsque l'on est sur le bord du raster
                        pass
            listnewcells.extend(currentlistnewcells)

    # On supprime les -999 du résultat final
    Result.save()
    raster_res = arcpy.sa.SetNull(temp_flood, temp_flood, "VALUE = -999")
    raster_res.save(str_output)
    arcpy.Delete_management(temp_flood)

    return
Exemplo n.º 10
0
def execute_Slope(r_dem,
                  r_flowdir,
                  str_frompoint,
                  distancesmoothingpath,
                  save_slope,
                  save_newfp,
                  messages,
                  language="FR"):

    # Chargement des fichiers
    DEM = RasterIO(r_dem)
    FlowDir = RasterIO(r_flowdir)
    try:
        DEM.checkMatch(FlowDir)
    except Exception as e:
        messages.addErrorMessage(e.message)

    Result = RasterIO(r_flowdir, save_slope, float, -255)

    # Liste des nouveaux points de départ
    listfirstpoints = []
    # Décompte du nombre de points de départ pour configurer de la barre de progression
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "OID@")
    count = 0
    for frompoint in frompointcursor:
        count += 1
    progtext = "Calcul des pentes"
    if language == "EN":
        progtext = "Processing"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0
    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "SHAPE@")
    for frompoint in frompointcursor:

        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = FlowDir.XtoCol(frompointshape.X)
        currentrow = FlowDir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol < 0 or currentcol >= FlowDir.raster.width or currentrow < 0 or currentrow >= FlowDir.raster.height:
            intheraster = False
        elif (FlowDir.getValue(currentrow, currentcol) != 1
              and FlowDir.getValue(currentrow, currentcol) != 2
              and FlowDir.getValue(currentrow, currentcol) != 4
              and FlowDir.getValue(currentrow, currentcol) != 8
              and FlowDir.getValue(currentrow, currentcol) != 16
              and FlowDir.getValue(currentrow, currentcol) != 32
              and FlowDir.getValue(currentrow, currentcol) != 64
              and FlowDir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        listpointsflowpath = []
        totaldistance = 0
        currentdistance = 0
        confluencedist = 0

        firstpoint = True

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            # On met à jour la liste des points le long de l'écoulement
            currentpoint = pointflowpath()
            currentpoint.row = currentrow
            currentpoint.col = currentcol
            currentpoint.addeddistance = currentdistance
            totaldistance = totaldistance + currentdistance
            currentpoint.distance = totaldistance
            listpointsflowpath.append(currentpoint)

            # les points sont mis à -999 (cela permet la détection des confluences)
            if confluencedist == 0:
                Result.setValue(currentrow, currentcol, -999)

            # On cherche le prochain point à partir du flow direction
            direction = FlowDir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = FlowDir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(FlowDir.raster.meanCellWidth *
                                            FlowDir.raster.meanCellWidth +
                                            FlowDir.raster.meanCellHeight *
                                            FlowDir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = FlowDir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(FlowDir.raster.meanCellWidth *
                                            FlowDir.raster.meanCellWidth +
                                            FlowDir.raster.meanCellHeight *
                                            FlowDir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = FlowDir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(FlowDir.raster.meanCellWidth *
                                            FlowDir.raster.meanCellWidth +
                                            FlowDir.raster.meanCellHeight *
                                            FlowDir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = FlowDir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(FlowDir.raster.meanCellWidth *
                                            FlowDir.raster.meanCellWidth +
                                            FlowDir.raster.meanCellHeight *
                                            FlowDir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= FlowDir.raster.width or currentrow < 0 or currentrow >= FlowDir.raster.height:
                intheraster = False
            elif (FlowDir.getValue(currentrow, currentcol) != 1
                  and FlowDir.getValue(currentrow, currentcol) != 2
                  and FlowDir.getValue(currentrow, currentcol) != 4
                  and FlowDir.getValue(currentrow, currentcol) != 8
                  and FlowDir.getValue(currentrow, currentcol) != 16
                  and FlowDir.getValue(currentrow, currentcol) != 32
                  and FlowDir.getValue(currentrow, currentcol) != 64
                  and FlowDir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    if confluencedist == 0:
                        confluencedist = totaldistance + currentdistance

                    # On continue encore sur la distance de calcul de la pente après le confluent
                    if (totaldistance + currentdistance -
                            confluencedist) > distancesmoothingpath:
                        intheraster = False

        currentpointnumber = 0
        # Pour chaque point le long de l'écoulement
        while (currentpointnumber < len(listpointsflowpath)):

            currentpoint = listpointsflowpath[currentpointnumber]

            listpointforregression = []
            listpointforregression.append(currentpoint)
            distancefromcurrentpoint = 0
            nbcellsfromcurrentpoint = 0
            try:
                # on s'éloigne du point courant, en allant vers l'amont, jusqu'à dépasser la distance de calcul de la pente
                while (distancefromcurrentpoint <= distancesmoothingpath / 2):
                    nbcellsfromcurrentpoint = nbcellsfromcurrentpoint - 1
                    if (currentpointnumber + nbcellsfromcurrentpoint >= 0):
                        # on mets à jour la distance jusqu'au point courant
                        distancefromcurrentpoint = distancefromcurrentpoint + listpointsflowpath[
                            currentpointnumber +
                            nbcellsfromcurrentpoint].addeddistance
                        # on ajoute le point aux points à utiliser pour la régression (calcul de la pente au point courant)
                        listpointforregression.append(
                            listpointsflowpath[currentpointnumber +
                                               nbcellsfromcurrentpoint])
                    else:
                        # la distance à l'extrémité amont est plus petie que la distance de calcul de pente
                        raise IndexError
                distancefromcurrentpoint = 0
                nbcellsfromcurrentpoint = 0
                # même chose en s'éliognant du point courant vers l'aval
                while (distancefromcurrentpoint < distancesmoothingpath / 2):
                    nbcellsfromcurrentpoint = nbcellsfromcurrentpoint + 1
                    if (currentpointnumber + nbcellsfromcurrentpoint <
                            len(listpointsflowpath)):
                        distancefromcurrentpoint = distancefromcurrentpoint + listpointsflowpath[
                            currentpointnumber +
                            nbcellsfromcurrentpoint].addeddistance
                        listpointforregression.append(
                            listpointsflowpath[currentpointnumber +
                                               nbcellsfromcurrentpoint])
                    else:
                        # la distance à l'extrémité aval est plus petite que la distance de calcul de pente
                        raise IndexError

                # Calcul de la régression linéaire
                sumdistance = 0
                sumelevation = 0
                sumdistanceelevation = 0
                sumsquaredistance = 0
                for pointforregression in listpointforregression:
                    sumdistance = sumdistance + pointforregression.distance
                    sumelevation = sumelevation + DEM.getValue(
                        pointforregression.row, pointforregression.col)
                    sumdistanceelevation = sumdistanceelevation + pointforregression.distance * \
                                                                  DEM.getValue(pointforregression.row,
                                                                               pointforregression.col)
                    sumsquaredistance = sumsquaredistance + pointforregression.distance * pointforregression.distance

                slope = -(len(listpointforregression) * sumdistanceelevation -
                          sumdistance * sumelevation) / (
                              len(listpointforregression) * sumsquaredistance -
                              sumdistance * sumdistance)

                Result.setValue(currentpoint.row, currentpoint.col, slope)

                if firstpoint:
                    # S'il s'agit du premier point (pour ce point de départ) pour lequel une valeur de pente est calculée, on enregistre ce point dans la liste des points de départ des pentes
                    newpoint = arcpy.Point(
                        FlowDir.raster.extent.XMin + (currentpoint.col + 0.5) *
                        FlowDir.raster.meanCellWidth,
                        FlowDir.raster.extent.YMax - (currentpoint.row + 0.5) *
                        FlowDir.raster.meanCellHeight)
                    listfirstpoints.append(newpoint)
                    firstpoint = False

            except IndexError:
                # pas de calcul de la pente pour les extrémité amont et aval (il n'y a pas la distance suffisante pour le calcul de la pente)
                pass

            currentpointnumber = currentpointnumber + 1

    Result.save()
    # On supprime les -999 du résultat final
    raster_res = arcpy.sa.SetNull(save_slope, save_slope, "VALUE = -999")
    raster_res.save(save_slope)

    # on enregistre la liste des points de départ des pente
    arcpy.CreateFeatureclass_management(os.path.dirname(save_newfp),
                                        os.path.basename(save_newfp),
                                        "POINT",
                                        spatial_reference=r_flowdir)
    pointcursor = arcpy.da.InsertCursor(save_newfp, "SHAPE@XY")
    for point in listfirstpoints:
        pointcursor.insertRow([(point.X, point.Y)])

    return
Exemplo n.º 11
0
def execute_Breach(r_dem,
                   r_flowdir,
                   str_frompoint,
                   SaveResult,
                   messages,
                   language="FR"):

    # Chargement des fichiers
    dem = RasterIO(r_dem)
    flowdir = RasterIO(r_flowdir)
    try:
        dem.checkMatch(flowdir)
    except Exception as e:
        messages.addErrorMessage(str(e))
    Result = RasterIO(r_flowdir, SaveResult, float, -255)

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "SHAPE@")
    for frompoint in frompointcursor:

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        # prev_z : élévation au point précédent (= élévation du point testé pour le premier point)
        prev_z = dem.getValue(currentrow, currentcol)

        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        intheraster = True
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False
        if dem.getValue(currentrow, currentcol) == dem.nodata:
            intheraster = False

        confluence = False

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            if not confluence:
                # L'élévation finale du point testé (z) est la valeur la plus petite entre son élévation actuelle et l'élévation du point précédent (prev_z)
                newz = dem.getValue(currentrow, currentcol)
            else:
                # Si on a atteint une confluence, on continue jusqu'à ce que qu'on atteingne un point plus bas
                newz = Result.getValue(currentrow, currentcol)
                if newz <= prev_z:
                    intheraster = False

            z = min(prev_z, newz)
            Result.setValue(currentrow, currentcol, z)
            prev_z = z

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1

            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1

            if (direction == 4):
                currentrow = currentrow + 1

            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1

            if (direction == 16):
                currentcol = currentcol - 1

            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1

            if (direction == 64):
                currentrow = currentrow - 1

            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False
            if dem.getValue(currentrow, currentcol) == dem.nodata:
                intheraster = False
            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    confluence = True

    Result.save()

    return
Exemplo n.º 12
0
def execute_D8toD4(r_flowdir,
                   r_dem,
                   str_frompoint,
                   str_result,
                   messages,
                   language="FR"):
    """The source code of the tool."""

    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)
    dem = RasterIO(r_dem)
    try:
        dem.checkMatch(flowdir)
    except Exception as e:
        messages.addErrorMessage(e.message)

    Result = RasterIO(r_flowdir, str_result, float, -255)

    donepoints = __Frompoint_paths()

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, ["SHAPE@", "OID@"])
    for frompoint in frompointcursor:

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        # Traitement effectué sur chaque cellule le long de l'écoulement

        while (intheraster):

            # On regarde la valeur du "flow direction"
            direction = flowdir.getValue(currentrow, currentcol)
            donepoints.add_point(currentrow, currentcol, frompoint[1])
            # Si cette valeur est 1, 4, 16 ou 64, on se déplace sur des cases adjacentes. On garde la valeur.
            # Si cette valeur est 2, 8, 32 ou 128, on se déplace en diagonale. Un traitement est nécesaire.

            if (direction == 1):
                Result.setValue(currentrow, currentcol, direction)
                currentcol = currentcol + 1

            if (direction == 2):

                # on regarde, parmi les deux cellules adjacentes pouvant remplacer le déplacement en diagonale, quelle est celle d'élévation la plus basse, et on passe par celle-ci
                # exemple : direction = 2 -> on se déplace en diagonale, en bas à droite
                # on peut donc remplacer ce déplacement par aller à droite (flow direction = 1) puis aller en bas (flow direction = 4) ou bien aller en bas puis aller à droite
                if dem.getValue(currentrow, currentcol + 1) is None:
                    Result.setValue(currentrow, currentcol, 1)
                    intheraster = False
                elif dem.getValue(currentrow + 1, currentcol) is None:
                    Result.setValue(currentrow, currentcol, 4)
                    intheraster = False
                elif dem.getValue(currentrow, currentcol + 1) < dem.getValue(
                        currentrow + 1, currentcol):
                    # La cellule à droite à une élévation plus basse que la cellule en bas, on choisie donc d'aller à droite puis ensuite en bas
                    # On modifie donc le flow direction pour aller à droite
                    Result.setValue(currentrow, currentcol, 1)
                    # Puis on modifie le flow direction du la cellule à droite pour aller en bas
                    if donepoints.done_previously(currentrow, currentcol + 1,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow, currentcol + 1, 4)
                        donepoints.add_point(currentrow, currentcol + 1,
                                             frompoint[1])
                else:
                    Result.setValue(currentrow, currentcol, 4)
                    if donepoints.done_previously(currentrow + 1, currentcol,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow + 1, currentcol, 1)
                        donepoints.add_point(currentrow + 1, currentcol,
                                             frompoint[1])
                currentcol = currentcol + 1
                currentrow = currentrow + 1

            if (direction == 4):
                Result.setValue(currentrow, currentcol, direction)
                currentrow = currentrow + 1

            if (direction == 8):
                if dem.getValue(currentrow + 1, currentcol) is None:
                    Result.setValue(currentrow, currentcol, 4)
                    intheraster = False
                elif dem.getValue(currentrow, currentcol - 1) is None:
                    Result.setValue(currentrow, currentcol, 16)
                    intheraster = False
                elif dem.getValue(currentrow + 1, currentcol) < dem.getValue(
                        currentrow, currentcol - 1):
                    Result.setValue(currentrow, currentcol, 4)
                    if donepoints.done_previously(currentrow + 1, currentcol,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow + 1, currentcol, 16)
                        donepoints.add_point(currentrow + 1, currentcol,
                                             frompoint[1])
                else:
                    Result.setValue(currentrow, currentcol, 16)
                    if donepoints.done_previously(currentrow, currentcol - 1,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow, currentcol - 1, 4)
                        donepoints.add_point(currentrow, currentcol - 1,
                                             frompoint[1])
                currentcol = currentcol - 1
                currentrow = currentrow + 1

            if (direction == 16):
                Result.setValue(currentrow, currentcol, direction)
                currentcol = currentcol - 1

            if (direction == 32):
                if dem.getValue(currentrow - 1, currentcol) is None:
                    Result.setValue(currentrow, currentcol, 64)
                    intheraster = False
                elif dem.getValue(currentrow, currentcol - 1) is None:
                    Result.setValue(currentrow, currentcol, 16)
                    intheraster = False
                elif dem.getValue(currentrow - 1, currentcol) < dem.getValue(
                        currentrow, currentcol - 1):
                    Result.setValue(currentrow, currentcol, 64)
                    if donepoints.done_previously(currentrow - 1, currentcol,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow - 1, currentcol, 16)
                        donepoints.add_point(currentrow - 1, currentcol,
                                             frompoint[1])
                else:
                    Result.setValue(currentrow, currentcol, 16)
                    if donepoints.done_previously(currentrow, currentcol - 1,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow, currentcol - 1, 64)
                        donepoints.add_point(currentrow, currentcol - 1,
                                             frompoint[1])
                currentcol = currentcol - 1
                currentrow = currentrow - 1

            if (direction == 64):
                Result.setValue(currentrow, currentcol, direction)
                currentrow = currentrow - 1

            if (direction == 128):
                if dem.getValue(currentrow - 1, currentcol) is None:
                    Result.setValue(currentrow, currentcol, 64)
                    intheraster = False
                elif dem.getValue(currentrow, currentcol + 1) is None:
                    Result.setValue(currentrow, currentcol, 1)
                    intheraster = False
                elif dem.getValue(currentrow - 1, currentcol) < dem.getValue(
                        currentrow, currentcol + 1):
                    Result.setValue(currentrow, currentcol, 64)
                    if donepoints.done_previously(currentrow - 1, currentcol,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow - 1, currentcol, 1)
                        donepoints.add_point(currentrow - 1, currentcol,
                                             frompoint[1])
                else:
                    Result.setValue(currentrow, currentcol, 1)
                    if donepoints.done_previously(currentrow, currentcol + 1,
                                                  frompoint[1]):
                        # Atteinte d'un confluent
                        intheraster = False
                    else:
                        Result.setValue(currentrow, currentcol + 1, 64)
                        donepoints.add_point(currentrow, currentcol + 1,
                                             frompoint[1])
                currentcol = currentcol + 1
                currentrow = currentrow - 1

            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if donepoints.done_previously(currentrow, currentcol,
                                              frompoint[1]):
                    # Atteinte d'un confluent
                    intheraster = False

    Result.save()

    return
def execute_FlowLength(r_flowdir,
                       str_frompoint,
                       str_result,
                       riverline,
                       messages,
                       language="FR"):
    """The source code of the tool."""

    flowdir = RasterIO(r_flowdir)

    Result = RasterIO(r_flowdir, str_result, float, -255)

    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "SHAPE@")
    for frompoint in frompointcursor:
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1
              and flowdir.getValue(currentrow, currentcol) != 2
              and flowdir.getValue(currentrow, currentcol) != 4
              and flowdir.getValue(currentrow, currentcol) != 8
              and flowdir.getValue(currentrow, currentcol) != 16
              and flowdir.getValue(currentrow, currentcol) != 32
              and flowdir.getValue(currentrow, currentcol) != 64
              and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        totaldistance = 0
        currentdistance = 0

        while (intheraster):

            totaldistance = totaldistance + currentdistance

            Result.setValue(currentrow, currentcol, totaldistance)

            # looking for the next point
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(flowdir.raster.meanCellWidth *
                                            flowdir.raster.meanCellWidth +
                                            flowdir.raster.meanCellHeight *
                                            flowdir.raster.meanCellHeight)

            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != Result.nodata):
                    # Atteinte d'une confluence
                    intheraster = False

    Result.save()

    if riverline is not None:
        r_rivers = arcpy.sa.SetNull(arcpy.sa.IsNull(Result.raster), 1,
                                    "VALUE = 1")
        arcpy.RasterToPolyline_conversion(r_rivers, riverline)

    return
Exemplo n.º 14
0
def execute_CS(r_flowdir, str_frompoints, distance, str_cs, messages, language = "FR"):

    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)

    # Fichier temporaire créé dans le "Scratch folder"
    temp_cs = arcpy.CreateScratchName("temp_cs", data_type="RasterDataset", workspace=arcpy.env.scratchFolder)
    Result = RasterIO(r_flowdir, temp_cs, float, -255)

    # Décompte du nombre de points de départ pour configurer de la barre de progression
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "OID@")
    count = 0
    for frompoint in frompointcursor:
        count += 1
    progtext = "Calcul de l'emplacement des sections transversales"
    if language == "EN":
        progtext = "Placing cross-sections"
    arcpy.SetProgressor("step", progtext, 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoints, "SHAPE@")
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[0].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        intheraster = True
        if currentcol<0 or currentcol>=flowdir.raster.width or currentrow<0 or currentrow>= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and
                      flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and
                      flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and
                      flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False



        totaldistance = 0
        currentdistance = 0
        lastpointdistance = 0

        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            totaldistance = totaldistance + currentdistance

            # Entre deux sections transversales, les points sont mis à -999 (cela permet la détection des confluences)
            if totaldistance <= lastpointdistance + distance:
                Result.setValue(currentrow, currentcol, -999)
            else:
                Result.setValue(currentrow, currentcol, 1)
                lastpointdistance = totaldistance

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and
                          flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and
                          flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and
                          flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    # Atteinte d'un confluent
                    intheraster = False




    # On supprime les -999 du résultat final
    Result.save()
    raster_res = arcpy.sa.SetNull(temp_cs, temp_cs, "VALUE = -999")
    # randomname = binascii.hexlify(os.urandom(6))
    # temp_cs2 = arcpy.env.scratchWorkspace + "\\" + randomname
    # raster_res.save(temp_cs2)

    arcpy.RasterToPoint_conversion(raster_res, str_cs)


    arcpy.Delete_management(temp_cs)
    #arcpy.Delete_management(temp_cs2)
    return
def execute_DefBCI(r_flowdir, r_flowacc, distoutput, percent, str_zonesfolder,
                   r_dem, r_width, r_zbed, r_manning, r_mask, str_outputfolder,
                   messages):

    save_inbci = str_zonesfolder + "\\inbci.shp"
    save_outbci = str_zonesfolder + "\\outbci.shp"

    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)
    flowacc = RasterIO(r_flowacc)
    dem = RasterIO(r_dem)

    try:
        flowdir.checkMatch(flowacc)
        flowdir.checkMatch(dem)
    except Exception as e:
        messages.addErrorMessage(e.message)

    # Création d'un nouveau fichier de zones en prenant les enveloppes
    zones = str_zonesfolder + "\\envelopezones.shp"
    arcpy.FeatureEnvelopeToPolygon_management(
        str_zonesfolder + "\\polyzones.shp", zones)

    # Clip du DEM

    zonesscursor = arcpy.da.SearchCursor(zones, ["GRID_CODE", "SHAPE@"])
    for zoneshp in zonesscursor:

        Xmin = zoneshp[1].extent.XMin
        Ymin = zoneshp[1].extent.YMin
        Xmax = zoneshp[1].extent.XMax
        Ymax = zoneshp[1].extent.YMax
        envelope = str(Xmin) + " " + str(Ymin) + " " + str(Xmax) + " " + str(
            Ymax)
        arcpy.Clip_management(dem.raster, envelope,
                              str_zonesfolder + "\\zone" + str(zoneshp[0]))

    # Listes des points source et des points de sortie
    listinputpoints = []
    listoutputpoints = []

    # Lectures des points source pour chaque zone
    sourcepointcursor = arcpy.da.SearchCursor(
        str_zonesfolder + "\\sourcepoints.shp", ["SHAPE@", "ZoneID", "fpid"])
    for sourcepoint in sourcepointcursor:
        newpoint = pointflowpath()
        newpoint.type = "main"
        newpoint.frompointid = sourcepoint[2]
        # Coordonnées du point source
        newpoint.X = sourcepoint[0].firstPoint.X
        newpoint.Y = sourcepoint[0].firstPoint.Y
        # Raster de la zone
        newpoint.numzone = sourcepoint[1]
        # Valeur du flow accumulation
        col = flowacc.XtoCol(newpoint.X)
        row = flowacc.YtoRow(newpoint.Y)
        newpoint.flowacc = flowacc.getValue(row, col)

        listinputpoints.append(newpoint)

    ### Début de traitement pour la détection des points de sortie et des points sources latéraux ###

    listlateralinputpoints = []

    # Pour chaque raster, on parcourt l'écoulement à partir du point source
    for mainpoint in listinputpoints:

        # Raster de la zone correspondante au point source
        localraster = RasterIO(
            arcpy.Raster(str_zonesfolder + r"\zone" + str(mainpoint.numzone)))

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(mainpoint.X)
        currentrow = flowdir.YtoRow(mainpoint.Y)
        localcol = localraster.XtoCol(mainpoint.X)
        localrow = localraster.YtoRow(mainpoint.Y)

        currentflowacc = flowacc.getValue(currentrow, currentcol)
        mainpoint.flowacc = currentflowacc
        lastflowacc = currentflowacc

        # Parcours de l'écoulement
        intheraster = True
        while (intheraster):

            prevcol = currentcol
            prevrow = currentrow

            currentflowacc = flowacc.getValue(currentrow, currentcol)

            if 100. * float(currentflowacc -
                            lastflowacc) / float(lastflowacc) >= percent:
                newpoint = pointflowpath()
                newpoint.type = "lateral"
                newpoint.frompointid = mainpoint.frompointid
                # Coordonnées du point source
                newpoint.X = flowdir.ColtoX(currentcol)
                newpoint.Y = flowdir.RowtoY(currentrow)
                # Raster de la zone
                newpoint.numzone = mainpoint.numzone
                # Valeur du flow accumulation
                newpoint.flowacc = currentflowacc
                lastflowacc = currentflowacc

                listlateralinputpoints.append(newpoint)

            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                localcol += 1
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                localcol += 1
                localrow += 1

            if (direction == 4):
                currentrow = currentrow + 1
                localrow += 1

            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                localcol -= 1
                localrow += 1

            if (direction == 16):
                currentcol = currentcol - 1
                localcol -= 1

            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                localcol -= 1
                localrow -= 1

            if (direction == 64):
                currentrow = currentrow - 1
                localrow -= 1

            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                localcol += 1
                localrow -= 1

            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1
                  and flowdir.getValue(currentrow, currentcol) != 2
                  and flowdir.getValue(currentrow, currentcol) != 4
                  and flowdir.getValue(currentrow, currentcol) != 8
                  and flowdir.getValue(currentrow, currentcol) != 16
                  and flowdir.getValue(currentrow, currentcol) != 32
                  and flowdir.getValue(currentrow, currentcol) != 64
                  and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if localcol < 0 or localcol >= localraster.raster.width or localrow < 0 or localrow >= localraster.raster.height:
                intheraster = False
            elif localraster.getValue(localrow,
                                      localcol) == localraster.nodata:
                intheraster = False

        # On enregistre un point de sortie au dernier point traité avant de sortir de la zone
        newpoint = pointflowpath()
        newpoint.numzone = mainpoint.numzone
        newpoint.X = flowdir.ColtoX(prevcol)
        newpoint.Y = flowdir.RowtoY(prevrow)

        # Il est nécessaire d'enregistrer le côté du raster par lequel on sort.
        # Ceci est fait en regardant la distance entre le dernier point traité et les coordonnées maximales de la zone
        # Le côté de sortie est le côté pour lequel cette distance est minimum
        distside = min(newpoint.X - localraster.raster.extent.XMin,
                       localraster.raster.extent.XMax - newpoint.X,
                       newpoint.Y - localraster.raster.extent.YMin,
                       localraster.raster.extent.YMax - newpoint.Y)
        if distside == newpoint.X - localraster.raster.extent.XMin:
            newpoint.side = "W"
        if distside == localraster.raster.extent.XMax - newpoint.X:
            newpoint.side = "E"
        if distside == newpoint.Y - localraster.raster.extent.YMin:
            newpoint.side = "S"
        if distside == localraster.raster.extent.YMax - newpoint.Y:
            newpoint.side = "N"
        listoutputpoints.append(newpoint)

    listinputpoints.extend(listlateralinputpoints)
    ### Fin de traitement pour la détection des points de sortie et des points sources latéraux ###

    ### Début de traitement pour la configuration des fenêtres de sortie ###

    # Pour chaque point de sortie
    for point in listoutputpoints:
        raster = RasterIO(
            arcpy.Raster(str_zonesfolder + r"\zone" + str(point.numzone)))
        colinc = 0
        rowinc = 0
        distinc = 0
        point.side2 = "0"
        point.lim3 = 0
        point.lim4 = 0
        # Selon le coté de sortie, on progressera horizontalement ou verticalement
        if point.side == "W" or point.side == "E":
            rowinc = 1
            distinc = raster.raster.meanCellHeight
        else:
            colinc = 1
            distinc = raster.raster.meanCellWidth
        currentcol = raster.XtoCol(point.X)
        currentrow = raster.YtoRow(point.Y)
        distance = 0
        # On progresse sur dans une direction jusqu'à sortir du raster ou jusqu'à ce que la distance voullue soit attente
        while (not (currentcol < 0 or currentcol >= raster.raster.width or currentrow < 0 or currentrow >= raster.raster.height)) \
                and raster.getValue(currentrow,currentcol) != raster.nodata and distance < distoutput/2:
            distance += distinc
            currentrow += rowinc
            currentcol += colinc
        # On prends les coordonnées avant de sortir du raster
        currentrow -= rowinc
        currentcol -= colinc
        if point.side == "W" or point.side == "E":
            point.lim1 = raster.RowtoY(currentrow)
        else:
            point.lim1 = raster.ColtoX(currentcol)
        # Si la procédure s'est arrêtée parce qu'on est sorti du raster, on tourne de 90 degrés et on continue
        if distance < distoutput / 2:
            distance -= distinc
            if point.side == "W":
                colinc = 1
                rowinc = 0
                distinc = raster.raster.meanCellWidth
                point.lim3 = raster.raster.extent.XMin + (
                    currentcol + 0.5) * raster.raster.meanCellWidth
            elif point.side == "E":
                colinc = -1
                rowinc = 0
                distinc = raster.raster.meanCellWidth
                point.lim3 = raster.raster.extent.XMin + (
                    currentcol + 0.5) * raster.raster.meanCellWidth

            elif point.side == "N":
                rowinc = 1
                colinc = 0
                distinc = raster.raster.meanCellHeight
                point.lim3 = max(
                    raster.raster.extent.YMin, raster.raster.extent.YMax -
                    (currentrow + 1) * raster.raster.meanCellHeight
                ) + 0.5 * raster.raster.meanCellHeight
            elif point.side == "S":
                rowinc = -1
                colinc = 0
                distinc = raster.raster.meanCellHeight
                point.lim3 = max(
                    raster.raster.extent.YMin, raster.raster.extent.YMax -
                    (currentrow + 1) * raster.raster.meanCellHeight
                ) + 0.5 * raster.raster.meanCellHeight
            # On progresse à nouveau jusqu'à sortir du raster ou jusqu'à ce que la distance voullue soit attente
            while (not (currentcol < 0 or currentcol >= raster.raster.width or currentrow < 0 or currentrow >= raster.raster.height)) \
                    and raster.getValue(currentrow, currentcol) != raster.nodata and distance < distoutput / 2:
                distance += distinc
                currentrow += rowinc
                currentcol += colinc
            currentrow -= rowinc
            currentcol -= colinc
            # On cherche sur quel coté on est après avoir tourné de 90 degrés
            if point.side == "W" or point.side == "E":
                point.side2 = "S"
                point.lim4 = raster.raster.extent.XMin + (
                    currentcol + 0.5) * raster.raster.meanCellWidth
            else:
                point.side2 = "E"
                point.lim4 = max(
                    raster.raster.extent.YMin, raster.raster.extent.YMax -
                    (currentrow + 1) * raster.raster.meanCellHeight
                ) + 0.5 * raster.raster.meanCellHeight

        # On recommence toute la procédure de l'autre côté du point de sortie
        colinc = 0
        rowinc = 0
        distinc = 0
        if point.side == "W" or point.side == "E":
            rowinc = -1
            distinc = raster.raster.meanCellHeight
        else:
            colinc = -1
            distinc = raster.raster.meanCellWidth
        currentcol = raster.XtoCol(point.X)
        currentrow = raster.YtoRow(point.Y)
        distance = 0
        while (not (currentcol < 0 or currentcol >= raster.raster.width or currentrow < 0 or currentrow >= raster.raster.height)) \
                and raster.getValue(currentrow, currentcol) != raster.nodata and distance < distoutput / 2:
            distance += distinc
            currentrow += rowinc
            currentcol += colinc
        currentrow -= rowinc
        currentcol -= colinc
        if point.side == "W" or point.side == "E":
            point.lim2 = max(
                raster.raster.extent.YMin, raster.raster.extent.YMax -
                (currentrow + 1) * raster.raster.meanCellHeight
            ) + 0.5 * raster.raster.meanCellHeight
        else:
            point.lim2 = raster.raster.extent.XMin + (
                currentcol + 0.5) * raster.raster.meanCellWidth
        # Si la procédure s'est arrêtée parce qu'on est sorti du raster, on tourne de 90 degrés et on continue
        if distance < distoutput / 2:
            distance -= distinc
            if point.side == "W":
                colinc = 1
                rowinc = 0
                distinc = raster.raster.meanCellWidth
                point.lim3 = raster.raster.extent.XMin + (
                    currentcol + 0.5) * raster.raster.meanCellWidth
            elif point.side == "E":
                colinc = -1
                rowinc = 0
                distinc = raster.raster.meanCellWidth
                point.lim3 = raster.raster.extent.XMin + (
                    currentcol + 0.5) * raster.raster.meanCellWidth
            elif point.side == "N":
                rowinc = 1
                colinc = 0
                distinc = raster.raster.meanCellHeight
                point.lim3 = max(
                    raster.raster.extent.YMin, raster.raster.extent.YMax -
                    (currentrow + 1) * raster.raster.meanCellHeight
                ) + 0.5 * raster.raster.meanCellHeight
            elif point.side == "S":
                rowinc = -1
                colinc = 0
                distinc = raster.raster.meanCellHeight
                point.lim3 = max(
                    raster.raster.extent.YMin, raster.raster.extent.YMax -
                    (currentrow + 1) * raster.raster.meanCellHeight
                ) + 0.5 * raster.raster.meanCellHeight
            while (not (currentcol < 0 or currentcol >= raster.raster.width or currentrow < 0 or currentrow >= raster.raster.height)) \
                and raster.getValue(currentrow, currentcol) != raster.nodata and distance < distoutput / 2:
                distance += distinc
                currentrow += rowinc
                currentcol += colinc
            currentrow -= rowinc
            currentcol -= colinc
            if point.side == "W" or point.side == "E":
                point.side2 = "N"
                point.lim4 = raster.raster.extent.XMin + (
                    currentcol + 0.5) * raster.raster.meanCellWidth
            else:
                point.side2 = "W"
                point.lim4 = max(
                    raster.raster.extent.YMin, raster.raster.extent.YMax -
                    (currentrow + 1) * raster.raster.meanCellHeight
                ) + 0.5 * raster.raster.meanCellHeight

    ### Fin du traitement pour la configuration des fenêtres de sortie ###

    # Création des shapefiles inbci et outbci, avec les champs nécessaires
    arcpy.CreateFeatureclass_management(
        os.path.dirname(save_inbci),
        os.path.basename(save_inbci),
        "POINT",
        spatial_reference=flowdir.raster.spatialReference)
    arcpy.AddField_management(save_inbci, "zoneid", "LONG")
    arcpy.AddField_management(save_inbci, "flowacc", "LONG")
    arcpy.AddField_management(save_inbci, "type", "TEXT")
    arcpy.AddField_management(save_inbci, "fpid", "LONG")
    arcpy.CreateFeatureclass_management(
        os.path.dirname(save_outbci),
        os.path.basename(save_outbci),
        "POINT",
        spatial_reference=flowdir.raster.spatialReference)
    arcpy.AddField_management(save_outbci, "zoneid", "LONG")
    arcpy.AddField_management(save_outbci, "side", "TEXT", field_length=1)
    arcpy.AddField_management(save_outbci, "lim1", "LONG")
    arcpy.AddField_management(save_outbci, "lim2", "LONG")
    arcpy.AddField_management(
        save_outbci,
        "side2",
        "TEXT",
        field_length=1,
    )
    arcpy.AddField_management(save_outbci, "lim3", "LONG")
    arcpy.AddField_management(save_outbci, "lim4", "LONG")

    # Enregistrement dans les shapefiles des informations contenues dans les listes
    pointcursor = arcpy.da.InsertCursor(
        save_inbci, ["zoneid", "flowacc", "type", "fpid", "SHAPE@XY"])
    for point in listinputpoints:
        pointcursor.insertRow([
            point.numzone, point.flowacc, point.type, point.frompointid,
            (point.X, point.Y)
        ])
    pointcursor = arcpy.da.InsertCursor(save_outbci, [
        "zoneid", "side", "lim1", "lim2", "side2", "lim3", "lim4", "SHAPE@XY"
    ])
    for point in listoutputpoints:
        pointcursor.insertRow([
            point.numzone, point.side, point.lim1, point.lim2, point.side2,
            point.lim3, point.lim4, (point.X, point.Y)
        ])

    del pointcursor

    # Création des fichiers .bci à partir des information du fichier inbci.shp

    bcipointcursor = arcpy.da.SearchCursor(
        save_inbci, ["SHAPE@", "zoneid", "flowacc", "type"])
    dictsegmentsin = {}
    for point in bcipointcursor:
        if point[1] not in dictsegmentsin:
            dictsegmentsin[point[1]] = []
        dictsegmentsin[point[1]].append(point)

    for segment in dictsegmentsin.values():
        for point in sorted(segment, key=lambda q: q[2]):
            if point[3] == "main":
                latnum = 0

                pointshape = point[0].firstPoint

                # Création du fichier
                newfile = str_outputfolder + "\\zone" + str(point[1]) + ".bci"

                # Enregistrement des coordonnées pour le point source
                filebci = open(newfile, 'w')
                filebci.write("P\t" + str(int(pointshape.X)) + "\t" +
                              str(int(pointshape.Y)) + "\tQVAR\tzone" +
                              str(point[1]) + "\n")
                filebci.close()

            if point[3] == "lateral":
                pointshape = point[0].firstPoint

                latnum += 1
                newfile = str_outputfolder + "\\zone" + str(point[1]) + ".bci"

                # Enregistrement des coordonnées et du débit pour le point source
                filebci = open(newfile, 'a')
                filebci.write("P\t" + str(int(pointshape.X)) + "\t" +
                              str(int(pointshape.Y)) + "\tQVAR\tzone" +
                              str(point[1]) + "_" + str(latnum) + "\n")
                filebci.close()

    # Ajout de la zone de sortie au .bci
    bcipointcursor = arcpy.da.SearchCursor(
        save_outbci,
        ["zoneid", "side", "lim1", "lim2", "side2", "lim3", "lim4", "SHAPE@"])
    for point in bcipointcursor:
        newfile = str_outputfolder + "\\zone" + str(point[0]) + ".bci"
        filebci = open(newfile, 'a')
        filebci.write(point[1] + "\t" + str(point[2]) + "\t" + str(point[3]) +
                      "\tHVAR\thvar")
        if str(point[4]) != "0":
            filebci.write("\n" + str(point[4]) + "\t" + str(point[5]) + "\t" +
                          str(point[6]) + "\tHVAR\thvar")
        filebci.close()

    # Création des fichiers .par et conversion des rasters en fichiers ASCII (un par point source comme il n'y a qu'un seul point d'entrée par simulation)

    for segment in dictsegmentsin.values():
        for point in sorted(segment, key=lambda q: q[2]):

            if point[3] == "main":

                arcpy.Clip_management(
                    r_width, "#", str_zonesfolder + r"\wzone" + str(point[1]),
                    str_zonesfolder + "\\zone" + str(point[1]), "#", "NONE",
                    "MAINTAIN_EXTENT")
                arcpy.Clip_management(
                    r_zbed, "#", str_zonesfolder + r"\dzone" + str(point[1]),
                    str_zonesfolder + "\\zone" + str(point[1]), "#", "NONE",
                    "MAINTAIN_EXTENT")
                arcpy.Clip_management(
                    r_manning, "#",
                    str_zonesfolder + r"\nzone" + str(point[1]),
                    str_zonesfolder + "\\zone" + str(point[1]), "#", "NONE",
                    "MAINTAIN_EXTENT")

                arcpy.RasterToASCII_conversion(
                    str_zonesfolder + "\\zone" + str(point[1]),
                    str_outputfolder + "\\zone" + str(point[1]) + ".txt")
                arcpy.RasterToASCII_conversion(
                    str_zonesfolder + "\dzone" + str(point[1]),
                    str_outputfolder + "\\dzone" + str(point[1]) + ".txt")
                arcpy.RasterToASCII_conversion(
                    str_zonesfolder + "\wzone" + str(point[1]),
                    str_outputfolder + "\\wzone" + str(point[1]) + ".txt")

                arcpy.RasterToASCII_conversion(
                    str_zonesfolder + "\\nzone" + str(point[1]),
                    str_outputfolder + "\\nzone" + str(point[1]) + ".txt")
                arcpy.Delete_management(str_zonesfolder + r"\wzone" +
                                        str(point[1]))
                arcpy.Delete_management(str_zonesfolder + r"\dzone" +
                                        str(point[1]))
                arcpy.Delete_management(str_zonesfolder + r"\nzone" +
                                        str(point[1]))

                arcpy.Clip_management(
                    r_mask, "#", str_zonesfolder + r"\mzone" + str(point[1]),
                    str_zonesfolder + "\\zone" + str(point[1]), "#", "NONE",
                    "MAINTAIN_EXTENT")
                arcpy.RasterToASCII_conversion(
                    str_zonesfolder + "\mzone" + str(point[1]),
                    str_outputfolder + "\\mzone" + str(point[1]) + ".txt")
                arcpy.Delete_management(str_zonesfolder + r"\mzone" +
                                        str(point[1]))

    return
Exemplo n.º 16
0
def execute_MovingWindowStats(r_flowdir, str_frompoint, r_values, distance, function, SaveResult, messages):


    # Chargement des fichiers
    flowdir = RasterIO(r_flowdir)
    valuesraster = RasterIO(r_values)
    try:
        flowdir.checkMatch(valuesraster)
    except Exception as e:
        messages.addErrorMessage(e.message)

    Result = RasterIO(r_flowdir, SaveResult, float,-255)


    # Décompte du nombre de points de départ pour configurer de la barre de progression
    count = 0
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, "OID@")
    for frompoint in frompointcursor:
        count += 1
    arcpy.SetProgressor("step", "Lissage par moyenne mobile", 0, count, 1)
    progres = 0

    # Traitement effectué pour chaque point de départ
    frompointcursor = arcpy.da.SearchCursor(str_frompoint, ["OID@", "SHAPE@"])
    for frompoint in frompointcursor:
        # Mise à jour de la barre de progression
        arcpy.SetProgressorPosition(progres)
        progres += 1

        # On prend l'objet géométrique (le point) associé à la ligne dans la table
        frompointshape = frompoint[1].firstPoint

        # Conversion des coordonnées
        currentcol = flowdir.XtoCol(frompointshape.X)
        currentrow = flowdir.YtoRow(frompointshape.Y)

        intheraster = True
        # Tests de sécurité pour s'assurer que le point de départ est à l'intérieurs des rasters
        if currentcol<0 or currentcol>=flowdir.raster.width or currentrow<0 or currentrow>= flowdir.raster.height:
            intheraster = False
        elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and
                            flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and
                            flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128):
            intheraster = False

        listflowpath = []
        listpointsflowpath = []
        listdistance = []
        listelevation = []
        totaldistance = 0
        currentdistance = 0


        # Traitement effectué sur chaque cellule le long de l'écoulement
        while (intheraster):

            currentpoint = pointflowpath()
            currentpoint.row = currentrow
            currentpoint.col = currentcol
            listpointsflowpath.append(currentpoint)
            totaldistance = totaldistance + currentdistance

            listflowpath.append(totaldistance)

            # On crée une liste des points d'élévation connue le long de l'écoulement, ainsi qu'une liste associée avec leur distance depuis le point de distance
            if valuesraster.getValue(currentrow, currentcol) != valuesraster.nodata:
                listdistance.append(totaldistance)
                listelevation.append(valuesraster.getValue(currentrow, currentcol))


            # On cherche le prochain point à partir du flow direction
            direction = flowdir.getValue(currentrow, currentcol)
            if (direction == 1):
                currentcol = currentcol + 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 2):
                currentcol = currentcol + 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)
            if (direction == 4):
                currentrow = currentrow + 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 8):
                currentcol = currentcol - 1
                currentrow = currentrow + 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)
            if (direction == 16):
                currentcol = currentcol - 1
                currentdistance = flowdir.raster.meanCellWidth
            if (direction == 32):
                currentcol = currentcol - 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)
            if (direction == 64):
                currentrow = currentrow - 1
                currentdistance = flowdir.raster.meanCellHeight
            if (direction == 128):
                currentcol = currentcol + 1
                currentrow = currentrow - 1
                currentdistance = math.sqrt(
                    flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight)

            # Tests de sécurité pour s'assurer que l'on ne sorte pas des rasters
            if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height:
                intheraster = False
            elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and
                            flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and
                            flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128):
                intheraster = False

            if intheraster:
                if (Result.getValue(currentrow, currentcol) != -255):
                    intheraster = False

        if len(listdistance) <= 1:
            # Avertissement si il n'y a qu'un seul (ou aucun) point de données
            messages.addWarningMessage("Point source {0}: pas assez de sections transversales".format(frompoint[0]))

        else:

            currentpointnumber = 0
            # Traitement pour chaque point le long de l'écoulement
            while (currentpointnumber < len(listflowpath)):

                currentpoint = listpointsflowpath[currentpointnumber]
                weights = []
                values = []
                sumwgt = 0
                # On parcourt tous les points d'élévation connue
                for i in range(len(listdistance)):
                    distlocale = abs(listdistance[i]-listflowpath[currentpointnumber])
                    # ... pour trouver ceux situés à l'intérieur de la fenêtre
                    if distlocale <= distance / 2:
                        values.append(listelevation[i])


                # On calcul la valeur finale à partir des valeurs et des poids associés
                finalvalue = function(values)

                Result.setValue(currentpoint.row, currentpoint.col, finalvalue)

                currentpointnumber = currentpointnumber + 1


    Result.save()

    return