Come posso scorrere tutte le celle in un raster continuo?


13

Vedi questo link per maggiori dettagli.

Il problema:

Voglio passare in rassegna un raster continuo (uno che non ha una tabella di attributi), cella per cella e ottenere il valore della cella. Voglio prendere quei valori ed eseguire i condizionali su di essi, emulando i passaggi di algebra della mappa descritti di seguito senza effettivamente utilizzare il calcolatore raster.

Per richiesta di commenti di seguito, ho aggiunto dettagli che forniscono informazioni di base sul problema e giustificano la necessità di implementare un metodo in quanto tale nella sezione seguente chiamata "L'analisi necessaria:".

L'analisi proposta di seguito, pur essendo pertinente al mio problema fornendo un background, non deve essere implementata in una risposta. L'ambito della domanda riguarda solo l'iterazione attraverso un raster continuo per ottenere / impostare i valori della cella.

L'analisi necessaria:

Se QUALSIASI delle seguenti condizioni sono soddisfatte, assegnare alla cella di output un valore di 1. Assegnare alla cella di output un valore pari a 0 solo se nessuna delle condizioni è soddisfatta.

Condizione 1: se il valore della cella è maggiore delle celle superiore e inferiore, fornire il valore 1:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

Dove il file del kernel è simile al seguente:

3 3 
0 1 0
0 0 0
0 1 0

Condizione 2: se il valore della cella è maggiore delle celle sinistra e destra, fornire il valore 1:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

Dove il file del kernel è simile al seguente:

3 3 
0 0 0
1 0 1
0 0 0  

Condizione 3: se il valore della cella è maggiore delle celle di inizio e di fine, dare il valore di 1:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

Dove il file del kernel è simile al seguente:

3 3 
1 0 0
0 0 0
0 0 1 

Condizione 4: se il valore della cella è maggiore delle celle a fondo e a destra, dare il valore 1:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

Dove il file del kernel è simile al seguente:

3 3 
0 0 1
0 0 0
1 0 0 

Condizione 5: Se qualsiasi una delle celle adiacenti ha un valore uguale alla cella centrale, che invia l'uscita raster valore 1 ( usando varietà focale con due calcoli quartiere più vicine )

Perché non usare l'algebra delle mappe?

È stato notato di seguito che il mio problema potrebbe essere risolto utilizzando l'algebra delle mappe, ma come visto sopra si tratta di un totale di sei calcoli raster, più uno per combinare tutti i raster creati insieme. Mi sembra che sia molto più efficiente andare cella per cella e fare tutti i confronti in una sola volta in ogni cella invece di scorrere ciascuno di essi sette volte e utilizzare un po 'di memoria per creare sette raster.

Come dovrebbe essere attaccato il problema?

Il collegamento sopra consiglia di utilizzare l'interfaccia IPixelBlock, tuttavia non è chiaro dalla documentazione ESRI se si sta effettivamente accedendo a un singolo valore di cella tramite IPixelBlock o se si accede a più valori di cella dalla dimensione di IPixelBlock impostato. Una buona risposta dovrebbe suggerire un metodo per accedere ai valori di cella di un raster continuo e fornire una spiegazione della metodologia alla base del codice, se non apparentemente evidente.

In sintesi:

Qual è il metodo migliore per eseguire il loop attraverso ogni cella in un raster CONTINUOUS (che non ha una tabella di attributi ) per accedere ai suoi valori di cella?

Una buona risposta non deve implementare i passaggi di analisi sopra descritti, deve solo fornire una metodologia per accedere ai valori delle celle di un raster.


4
È quasi sempre necessario passare in rassegna tutte le celle di un raster. Potete fornire ulteriori informazioni su ciò che state cercando di fare?
user2856

2
@Luke è corretto: di gran lunga il modo migliore per eseguire un calcolo raster iterativo in qualsiasi GIS è quello di evitare il loop esplicito attraverso le celle, perché sotto il cofano qualsiasi loop che deve essere fatto è già stato ottimizzato. Cerca invece un modo per utilizzare la funzionalità di algebra delle mappe fornita dal GIS, se possibile. Se dovessi descrivere la tua analisi, potresti ottenere risposte utili che utilizzano tale approccio.
whuber

@Luke Ho aggiunto i dettagli dell'analisi.
Conor,

1
Grazie per il chiarimento, Conor. Concordo sul fatto che se il GIS comporta un notevole sovraccarico per ogni calcolo raster, scrivere il proprio loop potrebbe essere più efficiente. Per curiosità, qual è l'interpretazione intesa di questo (insolito) insieme di condizioni?
whuber

1
@whuber È per le operazioni di rilevamento dei bordi creare poligoni vettoriali dal mio raster. L'applicazione è concettualmente simile all'identificazione di bacini idrologici da un DEM (si pensi alla cellula centrale nelle statistiche di quartiere sopra elencate come il "picco" da cui l'acqua fluirebbe verso il basso) ma è al di fuori del campo dell'idrologia. In precedenza ho utilizzato Flow Direction e Basin Rasters per questo scopo, ma quelli sono inclini a errori nella mia analisi finale a causa delle proprietà di questi metodi che non sono esattamente ciò di cui ho bisogno.
Conor,

Risposte:


11

Vedo che questo è già stato risolto dal Poster originale (OP), ma posterò una semplice soluzione in Python nel caso in cui qualcuno in futuro sia interessato in diversi modi per risolvere questo problema. Sono parziale del software open source, quindi ecco una soluzione che utilizza GDAL in Python:

import gdal

#Set GeoTiff driver
driver = gdal.GetDriverByName("GTiff")
driver.Register()

#Open raster and read number of rows, columns, bands
dataset = gdal.Open(filepath)
cols = dataset.RasterXSize
rows = dataset.RasterYSize
allBands = dataset.RasterCount
band = dataset.GetRasterBand(1)

#Get array of raster cell values.  The two zeros tell the 
#iterator which cell to start on and the 'cols' and 'rows' 
#tell the iterator to iterate through all columns and all rows.
def get_raster_cells(band,cols,rows):
    return band.ReadAsArray(0,0,cols,rows)

Implementa la funzione in questo modo:

#Bind array to a variable
rasterData = get_raster_cells(band,cols,rows)

#The array will look something like this if you print it
print rasterData
> [[ 1, 2, 3 ],
   [ 4, 5, 6 ],
   [ 7, 8, 9 ]]

Quindi, scorrere i dati con un ciclo nidificato:

for row in rasterData:
    for val in row:
        print val
> 1
  2
  3
  4...

O forse vuoi appiattire il tuo array 2-D con una comprensione dell'elenco:

flat = [val for row in rasterData for val in row]

Ad ogni modo, mentre si scorre attraverso i dati cella per cella è possibile gettare alcuni condizionali nel proprio ciclo per cambiare / modificare i valori. Vedi questo script che ho scritto per diversi modi di accedere ai dati: https://github.com/azgs/hazards-viewer/blob/master/python/zonal_stats.py .


Mi piace la semplicità e l'eleganza di questa soluzione. Aspetterò ancora qualche giorno e se nessun altro troverà una soluzione di uguale o maggiore qualità, aggiungerò dei tag per ampliare la portata della domanda a beneficio della comunità e premiarti con la generosità.
Conor,

Grazie, onore! Abbiamo riscontrato un problema simile nel mio posto di lavoro all'inizio di questa settimana e quindi l'ho risolto scrivendo un corso con GDAL / python. In particolare, avevamo bisogno di un metodo lato server per calcolare il valore medio di un'area di un raster dato solo un riquadro di selezione da un utente sulla nostra applicazione lato client. Pensi che sarebbe utile se aggiungessi il resto della classe che ho scritto?
asonnenschein,

Sarebbe utile aggiungere codice che mostri come leggere l'array 2D recuperato e modificarne i valori.
Conor,

9

Aggiornare! La soluzione intorpidita:

import arcpy
import numpy as np

in_ras = path + "/rastername"

raster_Array = arcpy.RasterToNumPyArray(in_ras)
row_num = raster_Array.shape[0]
col_num = raster_Array.shape[1]
cell_count = row_num * row_num

row = 0
col = 0
temp_it = 0

while temp_it < cell_count:
    # Insert conditional statements
    if raster_Array[row, col] > 0:
        # Do something
        val = raster_Array[row, col]
        print val
    row+=1
    if col > col_num - 1:
        row = 0
        col+=1

Quindi, riportare l'array finito su raster usando arcpy è problematico. arcpy.NumPyArrayToRaster è scoiattolo e tende a ridefinire le estensioni anche se le nutri le tue coordinate LL.

Preferisco salvare come testo.

np.savetxt(path + "output.txt", output, fmt='%.10f', delimiter = " ")

Sto eseguendo Python a 64 bit per la velocità - al momento questo significa che non posso alimentare numpy.savetxt un'intestazione. Quindi devo aprire l'output e aggiungere l'intestazione ASCII che Arc vuole prima di convertire ASCII in Raster

File_header = "NCOLS xxx" + '\n'+ "NROWS xxx" + '\n' + "XLLCORNER xxx"+'\n'+"YLLCORNER xxx"+'\n'+"CELLSIZE xxx"+'\n'+"NODATA_VALUE xxx"+'\n'

La versione numpy esegue il mio turno raster, moltiplicazioni e aggiunte molto più velocemente (1000 iterazioni in 2 minuti) rispetto alla versione arcpy (1000 iterazioni in 15 min)

VECCHIA VERSIONE Potrei cancellarla in seguito, ho appena scritto una sceneggiatura simile. Ho provato a convertire in punti e usando il cursore di ricerca. Ho ottenuto solo 5000 iterazioni in 12 ore. Quindi, ho cercato un altro modo.

Il mio modo di farlo è quello di scorrere le coordinate del centro della cella di ogni cella. Comincio nell'angolo in alto a sinistra e mi sposto da destra a sinistra. Alla fine della riga mi sposto di una riga e ricomincio da sinistra. Ho un raster di 240 m con 2603 colonne e 2438 file, quindi un totale di 6111844 celle totali. Uso una variabile iteratore e un ciclo while. Vedi sotto

Alcune note: 1 - è necessario conoscere le coordinate dell'estensione

2 - correre con le coordinate del punto per il centro della cella - spostare di 1/2 la dimensione della cella dai valori di estensione

3 - Il mio script utilizza il valore della cella per estrarre un valore raster specifico, quindi spostare questo raster al centro della cella originale. Ciò si aggiunge a un raster zero per espandere l'estensione prima di aggiungere un raster finale. Questo è solo un esempio. Puoi inserire qui le tue istruzioni condizionali (seconda istruzione if nel ciclo while).

4 - Questo script presuppone che tutti i valori raster possano essere espressi come numeri interi. Ciò significa che è necessario prima sbarazzarsi di nessun dato. Con IsNull.

6 - Non sono ancora contento di questo e sto lavorando per eliminarlo completamente da arcpy. Preferirei lanciare come matrici insensibili e fare la matematica laggiù per poi riportarlo su Arc.

ULx = 959415 ## coordinates for the Upper Left of the entire raster 
ULy = 2044545
x = ULx ## I redefine these if I want to run over a smaller area
y = ULy
temp_it = 0

while temp_it < 6111844: # Total cell count in the data extent
        if x <= 1583895 and y >= 1459474: # Coordinates for the lower right corner of the raster
           # Get the Cell Value
           val_result = arcpy.GetCellValue_management(inraster, str(x)+" " +str(y), "1")
           val = int(val_result.getOutput(0))
        if val > 0: ## Here you could insert your conditional statements
            val_pdf = Raster(path + "pdf_"str(val))
            shift_x  =  ULx - x # This will be a negative value
            shift_y = ULy - y # This will be a positive value
            arcpy.Shift_management(val_pdf, path+ "val_pdf_shift", str(-shift_x), str(-shift_y))
            val_pdf_shift = Raster(path + "val_pdf_shift")
            val_pdf_sh_exp = CellStatistics([zeros, val_pdf_shift], "SUM", "DATA")
            distr_days = Plus(val_pdf_sh_exp, distr_days)
        if temp_it % 20000 == 0: # Just a print statement to tell me how it's going
                print "Iteration number " + str(temp_it) +" completed at " + str(time_it)
        x += 240 # shift x over one column
        if x > 1538295: # if your at the right hand side of a row
            y = y-240 # Shift y down a row
            x = 959415 # Shift x back to the first left hand column
        temp_it+=1

distr_days.save(path + "Final_distr_days")

4

Prova a usare IGridTable, ICursor, IRow. Questo frammento di codice serve per aggiornare i valori delle celle raster, tuttavia mostra le basi dell'iterazione:

Come posso aggiungere un nuovo campo in una tabella di attributi raster e passarci attraverso?

Public Sub CalculateArea(raster As IRaster, areaField As String)
    Dim bandCol As IRasterBandCollection
    Dim band As IRasterBand

    Set bandCol = raster
    Set band = bandCol.Item(0)

    Dim hasTable As Boolean
    band.hasTable hasTable
    If (hasTable = False) Then
        Exit Sub
    End If    

    If (AddVatField(raster, areaField, esriFieldTypeDouble, 38) = True) Then
        ' calculate cell size
        Dim rstProps As IRasterProps
        Set rstProps = raster

        Dim pnt As IPnt
        Set pnt = rstProps.MeanCellSize

        Dim cellSize As Double
        cellSize = (pnt.X + pnt.Y) / 2#

        ' get fields index
        Dim attTable As ITable
        Set attTable = band.AttributeTable

        Dim idxArea As Long, idxCount As Long
        idxArea = attTable.FindField(areaField)
        idxCount = attTable.FindField("COUNT")

        ' using update cursor
        Dim gridTableOp As IGridTableOp
        Set gridTableOp = New gridTableOp

        Dim cellCount As Long, cellArea As Double

        Dim updateCursor As ICursor, updateRow As IRow
        Set updateCursor = gridTableOp.Update(band.RasterDataset, Nothing, False)
        Set updateRow = updateCursor.NextRow()
        Do Until updateRow Is Nothing
            cellCount = CLng(updateRow.Value(idxCount))
            cellArea = cellCount * (cellSize * cellSize)

            updateRow.Value(idxArea) = cellArea
            updateCursor.updateRow updateRow

            Set updateRow = updateCursor.NextRow()
        Loop

    End If
End Sub

Dopo aver attraversato la tabella, è possibile ottenere il valore della riga del campo specifico utilizzando row.get_Value(yourfieldIndex). Se tu Google

arcobjects row.get_Value

dovresti essere in grado di ottenere molti esempi che mostrano questo.

Spero possa aiutare.


1
Purtroppo ho trascurato di notare, e modificherò nella mia domanda originale sopra, che il mio raster ha molti valori continui costituiti da valori doppi grandi, e come tale questo metodo non funzionerà perché il mio raster non ha valori di tabella degli attributi.
Conor,

4

Che ne dici di un'idea radicale, ti richiederebbe di programmare in Python o ArcObjects.

  1. Converti la tua griglia in un punto featureclasss.
  2. Crea campi XY e popola.
  3. Carica i punti in un dizionario in cui la chiave è una stringa di X, Y e l' elemento ha il valore di cella.
  4. Scorri il dizionario e, per ogni punto, risolvi gli 8 XY delle celle circostanti.
  5. Recupera questi dal tuo dizionario e prova con le tue regole, non appena trovi un valore vero puoi saltare il resto dei test.
  6. Scrivi i risultati in un altro dizionario e poi converti nuovamente in una griglia creando prima un FeatureClass punto e poi converti i punti in una griglia.

2
Convertendo in una serie di funzionalità punto, questa idea elimina le due qualità della rappresentazione dei dati basata su raster che la rendono così efficace: (1) trovare i vicini è un'operazione a tempo costante estremamente semplice e (2) perché l'archiviazione esplicita delle posizioni è non necessari, i requisiti di RAM, disco e I / O sono minimi. Pertanto, sebbene questo approccio funzionerà, è difficile trovare motivi per consigliarlo.
whuber

Grazie per la tua risposta Hornbydd. Sono d'accordo con l'implementazione di un metodo come questo, ma sembra che i passaggi 4 e 5 non sarebbero molto efficaci dal punto di vista computazionale. I miei raster avranno un minimo di 62.500 celle (la risoluzione minima per il mio raster che ho impostato è di 250 celle x 250 celle, ma la risoluzione può e di solito consiste in molto di più) e dovrei fare una query spaziale per ogni condizione per eseguire i miei confronti ... Dato che ho 6 condizioni, sarebbe 6 * 62500 = 375000 query spaziali. Starei meglio con l'algebra delle mappe. Ma grazie per questo nuovo modo di vedere il problema. Upvoted.
Conor,

Non puoi semplicemente convertirlo in ASCII e quindi utilizzare un programma come R per fare il calcolo?
Oliver Burdekin,

Inoltre ho un'applet Java che ho scritto che potrebbe essere facilmente modificata per soddisfare le tue condizioni sopra. Era solo un algoritmo di smoothing ma gli aggiornamenti sarebbero stati abbastanza facili da fare.
Oliver Burdekin,

Fintanto che il programma può essere chiamato dalla piattaforma .NET per un utente su cui sono installati solo .NET Framework 3.5 e ArcGIS 10. Il programma è open source e intendo che quelli siano gli unici requisiti software quando consegnati agli utenti finali. Se la tua risposta può essere implementata per soddisfare questi due requisiti, verrà considerata una risposta valida. Aggiungerò anche un tag di versione alla domanda per chiarimenti.
Conor,

2

Una soluzione:

L'ho risolto prima oggi. Il codice è un adattamento di questo metodo . Il concetto alla base di questo non è stato terribilmente difficile una volta che ho capito cosa fanno effettivamente gli oggetti usati per interfacciarsi con il raster. Il metodo seguente accetta due set di dati di input (inRasterDS e outRasterDS). Sono entrambi lo stesso set di dati, ho appena creato una copia di inRasterDS e l'ho passato al metodo come outRasterDS. In questo modo entrambi hanno la stessa estensione, riferimento spaziale, ecc. Il metodo legge i valori da inRasterDS, cella per cella, e fa confronti più vicini su di essi. Utilizza i risultati di questi confronti come valori memorizzati in outRasterDS.

Il processo:

Ho usato IRasterCursor -> IPixelBlock -> SafeArray per ottenere i valori dei pixel e IRasterEdit per scriverne di nuovi sul raster. Quando si crea IPixelBlock, si indica alla macchina le dimensioni e la posizione dell'area in cui si desidera leggere / scrivere. Se si desidera modificare solo la metà inferiore di un raster, impostarlo come parametro IPixelBlock. Se si desidera eseguire il loop su tutto il raster, è necessario impostare IPixelBlock uguale alla dimensione dell'intero raster. Faccio questo nel metodo seguente passando le dimensioni a IRasterCursor (pSize) quindi ottenendo PixelBlock dal cursore raster.

L'altra chiave è che è necessario utilizzare SafeArray per interfacciarsi con i valori in questo metodo. Ottieni IPixelBlock da IRasterCursor, quindi SafeArray da IPixelBlock. Quindi leggi e scrivi a SafeArray. Al termine della lettura / scrittura su SafeArray, riscrivi l'intero SafeArray su IPixelBlock, quindi scrivi il tuo IPixelBlock su IRasterCursor, quindi utilizza IRasterCursor per impostare la posizione in cui avviare la scrittura e IRasterEdit per eseguire la scrittura stessa. Questo passaggio finale è dove si modificano effettivamente i valori del set di dati.

    public static void CreateBoundaryRaster(IRasterDataset2 inRasterDS, IRasterDataset2 outRasterDS)
    {
        try
        {
            //Create a raster. 
            IRaster2 inRaster = inRasterDS.CreateFullRaster() as IRaster2; //Create dataset from input raster
            IRaster2 outRaster = outRasterDS.CreateFullRaster() as IRaster2; //Create dataset from output raster
            IRasterProps pInRasterProps = (IRasterProps)inRaster;
            //Create a raster cursor with a pixel block size matching the extent of the input raster
            IPnt pSize = new DblPnt();
            pSize.SetCoords(pInRasterProps.Width, pInRasterProps.Height); //Give the size of the raster as a IPnt to pass to IRasterCursor
            IRasterCursor inrasterCursor = inRaster.CreateCursorEx(pSize); //Create IRasterCursor to parse input raster 
            IRasterCursor outRasterCursor = outRaster.CreateCursorEx(pSize); //Create IRasterCursor to parse output raster
            //Declare IRasterEdit, used to write the new values to raster
            IRasterEdit rasterEdit = outRaster as IRasterEdit;
            IRasterBandCollection inbands = inRasterDS as IRasterBandCollection;//set input raster as IRasterBandCollection
            IRasterBandCollection outbands = outRasterDS as IRasterBandCollection;//set output raster as IRasterBandCollection
            IPixelBlock3 inpixelblock3 = null; //declare input raster IPixelBlock
            IPixelBlock3 outpixelblock3 = null; //declare output raster IPixelBlock
            long blockwidth = 0; //store # of columns of raster
            long blockheight = 0; //store # of rows of raster

            //create system array for input/output raster. System array is used to interface with values directly. It is a grid that overlays your IPixelBlock which in turn overlays your raster.
            System.Array inpixels; 
            System.Array outpixels; 
            IPnt tlc = null; //set the top left corner

            // define the 3x3 neighborhood objects
            object center;
            object topleft;
            object topmiddle;
            object topright;
            object middleleft;
            object middleright;
            object bottomleft;
            object bottommiddle;
            object bottomright;

            long bandCount = outbands.Count; //use for multiple bands (only one in this case)

            do
            {

                inpixelblock3 = inrasterCursor.PixelBlock as IPixelBlock3; //get the pixel block from raster cursor
                outpixelblock3 = outRasterCursor.PixelBlock as IPixelBlock3;
                blockwidth = inpixelblock3.Width; //set the # of columns in raster
                blockheight = inpixelblock3.Height; //set the # of rows in raster
                outpixelblock3.Mask(255); //set any NoData values

                for (int k = 0; k < bandCount; k++) //for every band in raster (will always be 1 in this case)
                {
                    //Get the pixel array.
                    inpixels = (System.Array)inpixelblock3.get_PixelData(k); //store the raster values in a System Array to read
                    outpixels = (System.Array)outpixelblock3.get_PixelData(k); //store the raster values in a System Array to write
                    for (long i = 1; i < blockwidth - 1; i++) //for every column (except outside columns)
                    {
                        for (long j = 1; j < blockheight - 1; j++) //for every row (except outside rows)
                        {
                            //Get the pixel values of center cell and  neighboring cells

                            center = inpixels.GetValue(i, j);

                            topleft = inpixels.GetValue(i - 1, j + 1);
                            topmiddle = inpixels.GetValue(i, j + 1);
                            topright = inpixels.GetValue(i + 1, j + 1);
                            middleleft = inpixels.GetValue(i - 1, j);
                            middleright = inpixels.GetValue(i + 1, j);
                            bottomleft = inpixels.GetValue(i - 1, j - 1);
                            bottommiddle = inpixels.GetValue(i, j - 1);
                            bottomright = inpixels.GetValue(i - 1, j - 1);


                            //compare center cell value with middle left cell and middle right cell in a 3x3 grid. If true, give output raster value of 1
                            if ((Convert.ToDouble(center) >= Convert.ToDouble(middleleft)) && (Convert.ToDouble(center) >= Convert.ToDouble(middleright)))
                            {
                                outpixels.SetValue(1, i, j);
                            }


                            //compare center cell value with top middle and bottom middle cell in a 3x3 grid. If true, give output raster value of 1
                            else if ((Convert.ToDouble(center) >= Convert.ToDouble(topmiddle)) && (Convert.ToDouble(center) >= Convert.ToDouble(bottommiddle)))
                            {
                                outpixels.SetValue(1, i, j);
                            }

                            //if neither conditions are true, give raster value of 0
                            else
                            {

                                outpixels.SetValue(0, i, j);
                            }
                        }
                    }
                    //Write the pixel array to the pixel block.
                    outpixelblock3.set_PixelData(k, outpixels);
                }
                //Finally, write the pixel block back to the raster.
                tlc = outRasterCursor.TopLeft;
                rasterEdit.Write(tlc, (IPixelBlock)outpixelblock3);
            }
            while (inrasterCursor.Next() == true && outRasterCursor.Next() == true);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);


        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }

1

I dati raster AFAIK possono essere letti in tre modi:

  • per cella (inefficiente);
  • per immagine (abbastanza efficiente);
  • per blocchi (il modo più efficiente).

Senza reinventare la ruota, suggerisco di leggere queste diapositive illuminanti di Chris Garrard.

Quindi il metodo più efficiente è leggere i dati per blocco, tuttavia ciò causerebbe una perdita di dati in corrispondenza dei pixel posizionati oltre i limiti del blocco durante l'applicazione del filtro. Quindi un modo alternativo sicuro dovrebbe consistere nel leggere l'intera immagine in una sola volta e usando l'approccio intorpidito.

Sul lato computazionale, invece, dovrei usare gdalfilter.py e implicitamente l'approccio VRT KernelFilteredSource per applicare i filtri necessari e, soprattutto, evitare calcoli pesanti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.