geopandasgdalgeotiffrasterio

From numpy to geotif having a georeferenced box


I created a numpy array by calculating the density of dwellings within an area through the following code:

def myplot(x, y, z, s, bins=10000):
    heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins, weights=z)
    heatmap = gaussian_filter(heatmap, sigma=s)

    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    return heatmap.T, extent


fig, axs = plt.subplots(2, 2)

# Generate some test data
x = buildings["x"]
y = buildings["y"]
weights = buildings["Area"]

sigmas = [0, 16, 32, 64]

for ax, s in zip(axs.flatten(), sigmas):
    if s == 0:
        ax.plot(x, y, weights, 'k.', markersize=5)
        ax.set_title("Scatter plot")
    else:
        img, extent = myplot(x, y, weights, s)
        ax.imshow(img, extent=extent, origin='lower', cmap=cm.jet)
        ax.set_title("Smoothing with  $\sigma$ = %d" % s)

    plt.savefig('export_'+str(s)+'.png', dpi=150, bbox_inches='tight')

plt.show()

This is the result and works fine: enter image description here

Now I need to save it as a geotif and I know the extreme coordinates of the box angles. I tried to do that using the following code:

# create a georeferenced box
transform = from_bounds(extent[0], extent[1],extent[2], extent[3], 10000, 10000)

# save the georeferenced tif
with rio.open('data.tif', 'w', driver='GTiff', height=10000, width=10000, count=1, dtype='float64', nodata=0, crs=32632, transform=transform) as dst:
    dst.write(img, 1)

The problem is that the result is transpose and not on the right position. Could you help me to find the solution?

I tried to develop the code but did not work


Solution

  • You should simply use numpy.transpose on your array - it is a very fast operation that does not copy the array.

    GDAL uses traditional C style raster coordinates. In numpy an array with shape (x, y) is x lines of y pixels, while in GDAL it is the other way around.

    # save the georeferenced tif
    with rio.open('data.tif', 'w', driver='GTiff', height=10000, width=10000, count=1, dtype='float64', nodata=0, crs=32632, transform=transform) as dst:
        dst.write(img.tranpose(), 1)