[gdal-dev] Re: Best way to test wheter point is contained in Polygon

Jose Gomez-Dans jgomezdans at gmail.com
Tue Sep 23 08:25:40 EDT 2008


I reply to myself, to see if someone has any insights.

2008/9/22 Jose Gomez-Dans <jgomezdans at gmail.com>

> Hi,
> I have a raster file and a vector file. I want to assign to each pixel in
> my raster size a value derived from the vector file (which are polygons). To
> do this, I want to test that the centroid of my pixel lies within a given
> polygon. In the past, I have done this gdal_rasterize-ing the polygon file,
> and going through numpy arrays. It is a bit cumbersome, and the
> rasterization is not really needed with OGR. However, it seems that if my
> pixel centroid is (x,y), I will need to go through all features in my layer,
> extract the geometry and do a Contains() test for my (x,y) point. I can cut
> the number of iterations (I guess, not tried) by using a SpatialFilter on my
> vector layer, so only one (ish) geometry is returned, so I would only need
> to do one Contains test (I do have a _lot_ of polygons in this file)
>

The code I have loops over each pixel, calculates its centroid from the
GeoTransform, and reprojects this to match the OGR's dataset projection. I
then produce a geometry for this centroid, and apply a spatial filter to my
OGR layer so that it encompasses said centroid. It is then a matter of
looping through the geometries until I get a match. The code works, but it
is quite slow. I have speeded it up substantially by creating an spatial
index on my shapefile, but it still takes a long time to go through this
(there are a lot of pixels to go through, and I need to do this for many
raster files!), so I was wondering if anyone has some suggestions on how to
improve this.

here's some relevant snippet of code, just in case someone's interested:
# I am assuming I have a raster_map, it's X and Y size, and its geotransform
# L is my ogr layer
#[...]
 for row in range(g.RasterXSize):
    for col in range(g.RasterYSize):
    if (raster_map[col,row] > 0): #Loop over each pixel, and if the value of
the pixel >0, try to find it's polygon.
        x = geotransform[0] + (row+0.5)*geotransform[1]
        y = geotransform[3] + (col+0.5)*geotransform[5]
        (lon,lat,z) = t.TransformPoint ( x,y ) # I need to transform the
data first.
        geop = ogr.CreateGeometryFromWkt("POINT (%f %f)"%(lon,lat)) # This
is the centroid of my pixel
        feat = L.GetNextFeature()
        filter_layer = L.SetSpatialFilterRect(lon-.5, lat-.5, lon+.5,lat+.5)
# To  minimise searches, do a spatial filter on the layer, so we only have a
handful of geometries to worry about
        while feat is not None:
            geo_grid = feat.GetGeometryRef()
            if geo_grid.Contains( geop ): # Found gridcell
                #Found a match. Do something with it, and stop searching
geometries.
                break
            feat.Destroy()
            feat = L.GetNextFeature()

        L.SetSpatialFilter(None) #Reset the spatial filter
        L.ResetReading() #Go back to the first feature of the layer

Cheers,
Jose

-- 
Centre for Terrestrial Carbon Dynamics
Department of Geography, University College London
Gower Street, London WC1E 6BT, UK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/gdal-dev/attachments/20080923/9a8d9dfb/attachment.html


More information about the gdal-dev mailing list