[GIS] Convert raster to a CSV values and lat long based on raster value in QGIS

osgeo4wpointqgisvectorization

I am looking to convert a raster into a csv file (or tab delimited) based on values in the raster (Value > 0).

The csv would have three values, latitude of center of cell, longitude of center of cell, and the raster value where the raster value is greater than 0.

The data in unprojected in geographic coordinate system WGS 1984. It is a GTiff.

I know I can go to point file and then add the latitude and longitude and then go to CSV but I wonder if a direct method exists as I have 130 million points.

Working on going Ras > Point (file Geodatabase) > Query Points > CSV in ArcGIS but it is slow.

I feel I need to build in the query at the Ras > Point section to speed things up as the entire raster has 130 billion cells but only 130 million have values. Rest are 0 or NoData.

Looking for QGIS with processing (Grass, SAGA, etc.). Have OSGEO4W installed but can bring up a Linux box as well.

UPDATE
As per @Luke answer below I am running this GDAL code in OSGEO4w.

E:\temp>gdal_translate -q -of xyz -co ADD_HEADER_LINE=YES -co COLUMN_SEPARATOR="
," mwf2012.tif /vsistdout | findstr /V /C:"65536" > output.csv

I am not getting the usal GDAL Progress bar (is this normal?), everything else looks good so Ill Let you know the final result!

Best Answer

As GDAL supports writing to X,Y,Z (CSV) ascii, you could use gdal_translate:

gdal_translate -of xyz -co ADD_HEADER_LINE=YES -co COLUMN_SEPARATOR="," input_raster output.csv

To avoid writing NoData values to your output you can write the output to stdout then pipe to grep/findstr to filter it before writing to your csv:

gdal_translate -q -of xyz -co ADD_HEADER_LINE=YES -co COLUMN_SEPARATOR="," input_raster /vsistdout | findstr /V /C:"your_nodata_value" > output.csv 

Or in a *Nix OS:

gdal_translate -q -of xyz -co ADD_HEADER_LINE=YES -co COLUMN_SEPARATOR="," input_raster /vsistdout | grep -v "your_nodata_value" > output.csv 

Running the above command (inc. findstr/grep) on a 60 million pixel (7700x7800 Landsat scene) took 2 minutes on my Windows PC and 1min 15 on my slightly more powerful Linux workstation.

Notes:

  1. my nodata_value is negative so I had to escape the negative character on Linux: gdal_translate etc...|grep -v "\-999" > output.csv
  2. if your nodata_value is something really common, i.e "0", you'll need to do something a bit more complex in the grep/findstr expression, like ...|grep -v ",0$" or ...|findstr /V /C:",0$"