Calcul des statistiques focales pour un quartier spécial?

18

Je cherche à calculer des statistiques focales pour chaque cellule d'un raster, dans un voisinage d'un critère spécifié.

Contexte - J'ai trois rasters binaires, chacun représentant un seul type de végétation d'intérêt. J'aimerais calculer le pourcentage de couverture de chaque type de végétation dans (par exemple) 20 km ^ 2 de n'importe quelle cellule de ma zone d'étude (somme / total des cellules dans le voisinage). Le problème est que je ne peux pas utiliser un simple cercle ou voisinage carré autour de chaque cellule parce que, si je le faisais, la zone de recherche utilisée pour calculer la somme incorporerait des zones en dehors de ma zone d'étude. Cette exception est importante car les statistiques seront utilisées comme intrants pour un modèle d'habitat, et les zones à l'extérieur de ma zone d'étude ne peuvent pas être considérées comme un habitat possible - elles sont urbanisées. Les inclure me donnerait des statistiques erronées. Alors, ce que je 'n déterminé par le nombre de cellules nécessaires pour couvrir une zone égale à la taille de quartier souhaitée) qui répondent à mes critères. Les critères étant qu'ils ne relèvent pas d'une zone urbanisée. Je pense qu'une certaine forme d'automates cellulaires devrait être utilisée. Je n'ai cependant jamais travaillé avec CA.

Je suppose que ce que j'aimerais, c'est quelque chose comme du code de démarrage, ou un point dans la bonne direction.


RÉPONSE AU COMMENTAIRE CI-DESSOUS:

Disons que je calcule cette statistique pour une cellule à la limite de mon site d'étude. Si j'attribue à zéro toutes les zones en dehors de ma zone d'étude (ou si j'ignore NoData), j'obtiendrai une statistique qui représente environ la moitié de la couverture surfacique qui m'intéresse. Donc, pourcentage de couverture dans une zone de ~ 10 km ^ 2 , au lieu de 20 km ^ 2. Puisque j'étudie les tailles de domaine domestique, c'est important. Le quartier doit changer de forme, car c'est ainsi que l'animal voit / utilise le paysage. S'ils ont besoin de 20 km ^ 2, ils changeront la forme ou leur territoire d'origine. Si je ne coche pas ignorer NoData, la sortie de la cellule sera NoData - et NoData n'est d'aucune aide.


"PROGRÈS" AU 24/10/2014

Voici le code que j'ai trouvé jusqu'à présent en utilisant Shapely et Fiona:

import numpy as np
import pprint
import shapely
from shapely.geometry import*
import fiona
from fiona import collection
import math

traps = fiona.open('C:/Users/Curtis/Documents/ArcGIS/GIS_Data/occurrence/ss_occ.shp', 'r')

study_area = fiona.open('C:/Users/Curtis/Documents/ArcGIS/GIS_Data/Study_Area.shp', 'r')
for i in study_area: #for every record in 'study_area'
        sa = shape(i['geometry']) #make a variable called 'sa' that is a polygon

grassland = fiona.open('C:/Users/Curtis/Documents/ArcGIS/GIS_Data/land_cover/polys_for_aa/class3_aa.shp', 'r')
pol = grassland.next()
gl = MultiPolygon([shape(pol['geometry']) for pol in grassland])

areaKM2 = 20
with traps as input:
    r = (math.sqrt(areaKM2/math.pi))*1000
    for point in input:
        pt = shape(point['geometry'])
        pt_buff = pt.buffer(r)
        avail_area = pt_buff.intersection(sa).area
        # works to here
        while avail_area < areaKM2:
            r += 10
            pt_buff = pt.buffer(r)
            avail_area = pt_buff.intersection(sa).area

        perc_cov = pt_buff.intersection(gl).area//areaKM2
        print perc_cov

Malheureusement, c'est incroyablement lent.

CSB
la source
1
c'est un problème intéressant. Vous pouvez définir toutes les cellules en dehors de votre zone d'étude sur NoData, mais je ne sais pas comment vous allez obtenir un quartier pour s'adapter et garder la même taille de 20 km2 (il faudrait changer de forme).
jbchurchill
@CSB jbchurchill a raison, la meilleure chose à faire ici est d'attribuer des valeurs NoData en dehors de votre zone d'étude. L'outil Statistiques focales peut traiter ces valeurs de nodata de manière appropriée. Voir «Traitement des cellules de NoData» ici resources.arcgis.com/en/help/main/10.1/index.html#//…
WhiteboxDev
@WhiteboxDev - Votre suggestion ne résoudra pas mon problème. Je vais modifier ce qui précède et expliquer pourquoi cela ne fonctionnera pas.
CSB
Avez-vous vu cet article, qui traite de l'utilisation des statistiques focales avec un rayon variable ( gis.stackexchange.com/questions/34306/… )? Cela semble être votre problème - les cellules sur le bord doivent avoir un grand rayon et ne considérer qu'un voisinage semi-circulaire. Bien sûr, selon la taille de votre cellule, vous devrez peut-être créer de très nombreux rasters parmi lesquels choisir.
phloème
1
@CSB Vous allez rencontrer des effets de bord, que vous utilisiez NoData et un voisinage réduit ou que vous changiez la forme / l'emplacement de votre voisinage pour garantir la taille. Au moins avec le premier, vous ne suréchantillonnerez / ne représenterez pas les données proches du bord de manière non transparente. Cela fait partie du fameux problème des unités de surface modifiables.
WhiteboxDev

Réponses:

0

Le code ci-dessus est la réponse éventuelle et imparfaite que j'ai trouvée pour ce problème. En fin de compte, j'ai pensé que la meilleure approche était d'utiliser un voisinage circulaire et de calculer la zone intersectant ma zone "disponible". (Un voisinage circulaire donnerait de toute façon les n ~ cellules les plus proches - donc, pas besoin de devenir trop sophistiqué avec les automates cellulaires.) Si la zone était trop petite, j'ai simplement agrandi le cercle jusqu'à ce qu'il ne le soit pas.

Cela a bien fonctionné mais, comme je l'ai noté, c'était très lent. Voir ce fil pour des suggestions sur la façon d'accélérer. Optimisation des performances du code pour Shapely . J'ai suivi les suggestions qui ont mené à ce fil Comprendre l'utilisation des index spatiaux . Je n'ai pas fini par appliquer un r-tree à la fin, car je n'ai finalement jamais utilisé le code. J'ai découvert que je pouvais aborder le problème sous un angle entièrement différent et me faire gagner beaucoup de temps / d'énergie, alors je l'ai fait. Je finirai peut-être un jour ...

CSB
la source
En lisant votre code, il semble qu'il y ait de bonnes chances que l'utilisation d'un index spatial accélère le code, souvent de manière spectaculaire. Faire des intersections contre un MultiPolygon comme ça est très lent.
Snorfalorpagus
@Snorfalorpagus Oui, si vous regardez la réponse, je signale deux autres fils liés à cette question. Les deux discutent de l'utilisation d'un index spatial.
CSB