Problem in creating raster file using gdal - raster

I use the following code to create a raster file with gdal:
filepath="somefile.tif"
ds = gdal.GetDriverByName("GTiff").Create(filepath, xsize=ny, ysize=nx, bands=1, eType=gdal.GDT_Float64)
ds.GetRasterBand(1).WriteArray(_array)
ds.SetGeoTransform([extent.xMinimum(), pxsize, 0, extent.yMinimum(), 0, pysize])
ds.SetProjection(QgsCoordinateReferenceSystem("EPSG:4326").toWkt())
ds.GetRasterBand(1).FlushCache()
ds = None
del ds
Of course, I checked nx, ny, _array, pxsize, pysize are correct.
This code create a geotiff file which I can visualize in QGIS. My problems are:
the created raster has 2 bands although I created it with only 1 band ;
the created rastre is not recognized as a valid geotiff raster by an other program which deal with geotiff raster format (Serval QGIS plugin).
I try a lots of thing but now stuck on that.

Related

R terra function classify create very large files

I have an habitat classification map from Iceland (https://vistgerdakort.ni.is/) with 72 classes in a tif file of 5m*5m pixel size. I want to simplify it, so that there is only 14 classes. I open the files (a tif file and a text file containing the reclassification rules) and use the function classify in the terra package as follow on a subset of the map.
raster <- rast("habitat_subset.tif")
reclass_table<-read.table("reclass_habitat.txt")
habitat_simple<-classify(raster, reclass_table, othersNA=TRUE)
It does exactly what I need it to do and I am able to save the file back to tif using
writeRaster(habitat_simple, "reclass_hab.tif")
The problem is that my initial tif file was 105MB and my new reclassify tif file is 420MB. Since my goal is to reclassify the whole extent of the country, I can't afford to have the file become so big. Any insights on how to make it smaller? I could not find any comments online in relation to this issue.
You can specify the datatype, in your case you should be able to use "INT1U" (i.e., byte values between 0 and 254 --- 255 is used for NA, at least that is the default). That should give a file that is 4 times smaller than when you write it with the default "FLT4S". Based on your question, the original data come with that datatype. In addition you could use compression; I am not sure how well they work with "INT1U". You could have found out about this in the documentation, see ?writeRaster
writeRaster(habitat_simple, "reclass_hab.tif",
wopt=list(datatype="INT1U", gdal="COMPRESS=LZW"))
You could also skip the writeRaster step and do (with terra >= 1.1-4) you can just do
habitat_simple <- classify(raster, reclass_table, othersNA=TRUE,
datatype="INT1U", gdal="COMPRESS=LZW")

How to edit cells Shapefile in R?

I downloaded a shapefile of the world map from gadm, however, there are typos that happen with importing the shape file. For example "Aland" shows up as "Ã…land" in the shapefile. There are handful of countries I want to make changes to.
world map shapefile, the one that says "You can also download this version as six separate layers (one for each level of subdivision/aggregation), as a geopackage database or as shapefiles" :https://gadm.org/download_world.html
I imported the shapefile using:
worldmap <- readOGR("file/gadm36_0.shp")
I tried using the following code:
levels(wordlmap$NAME_0)[5] <- "Aland"
However I got this message:
Error in `levels<-`(`*tmp*`, value = c(NA, NA, NA, NA, "Aland")) :
factor level [2] is duplicated
Could you suggest how this code can be made better or an alternative.Thanks in advance
Since you did not provide a shapefile, I just worked with a publicly-available shapefile of Indian states. The long and short of it is to use the sf package. It loads shapefiles as (quasi) dataframes--with the longitudes and latitudes stored in the geometry variable. Then, you should be in familiar territory. Here is some code to change a state name variable:
# clear environment
rm(list=ls(all=TRUE))
# let's take admin 1 (states)
# note: already in WGS84 format
library(sf)
india_shape <- st_read("india_shape/gadm36_IND_1.shp", stringsAsFactors=FALSE)
# Let's pick something to change (state name)
> india_shape$NAME_1[1]
[1] "Andaman and Nicobar"
# Now change it
> india_shape$NAME_1[1] <- "New State Name"
> india_shape$NAME_1[1]
[1] "New State Name"
I can tell you a few things about how I manage those shape files downloaded from, www.gadm.org site.
First, a shape file has several other related files that do not have the .shp extension. These files must remain together in the same folder. All these files are included in the shape zip file from the gadm website.
The rgdal package provides the, readOGR() function. This function is normally in the form: readOGR(dsn = " ", layer = " " )
The, dsn is "data source name". Use quotes.
The, layer is the name of shape file without the .shp extension. Use quotes.
Proper file management is required to make things work and to maintain good file management. I already have a USA folder within my dataset folder.
I just downloaded the gadm USA shape file. So first, I will add a new folder, named USA_map, in the USA folder. And also create a new folder named, data in this new USA_map folder.
C:/python/datasets/usa/usa_map/data # usa_map/data are new
Copy the downloaded gadm36_USA_shp.zip from the "download" folder and paste into the new "USA_map" folder. Then, open the GADM zip folder and extract the entire contents of the zip folder into the new "data" folder. Then the zip file can new be deleted because all the files have been copied into the "data" folder. All's done and ready.
Now use the readOGR() function to read the shape file and assign to new variable, called usmap
usmap <- readOGR(dsn = "c:/python/datasets/USA/USA_map/data", layer = "gadm36_USA_1")
The trick is to follow the correct file management so the readOGR() function works as designed.
Next, you need to learn how to navigate through this type of data.
If there is more than one polygon with the same wrong name, you can make like that :
w <- length(wordlmap)
for (i in 1:w){
if (wordlmap$NAME_0[i] == "Ã…land") {
wordlmap$NAME_0[i] <- "Aland"
}}

plot VIIRS raster data (.h5) in R

Im looking into how to handle .h5 (hdf) VIIRS DNB raster data in R. I would like to plot it or export it as a geotiff.
So far I am able to read in the file with
hdf<- h5file("mypath/GDNBO-SVDNB_npp_d20171101_t0110370_e0116174_b31151_c20180208224859630066_nobc_ops.h5", mode = "r")
But I cannot figure out how to access the "radiance" band, let alone plot it. I have read the "h5" package documentation without any progress..
As another option I have tried to export the h5 file to geotiff with
sds <- get_subdatasets("subset_1_d20171101_t0110370.h5")
gdal_translate(sds[17], dst_dataset = "radiance.tif", overwrite=T) #subset 17 is the radiance band i need
however the file has lost its geolocation during the transformation, when the geotiff is opened in e.g. QGIS, it doesnt have any location or projection.
Anyone knows how to deal with these type of files in R?

How to load a geospatial pdf in R?

I am new handling spatial data, and newer doing it in R.
My last attemp was trying to read data in a geographical pdf format. It is information about mexican political bourdaries, so polygons, the file.
I tryied to use the rgdal package to read the data. After typing ogrDrivers()[40:45,], which show the drivers available, I got.
name write
40 PCIDSK TRUE
41 PDF TRUE
42 PDS FALSE
43 PGDump TRUE
44 PGeo FALSE
45 PostgreSQL TRUE
The result show that there is a driver for PDF's, but trying the usual way to read files readOGR(dsn = "data source name", layer = "LAYER") produces:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv, :
Cannot open file
The help of the function does not say the values expected neither for dsn nor for layer when the file is in a geospatial pdf format.
Does anybody knows a way to import data from a pdf? this is from geospatial format; I would appreciate any answer.
By the way, I have Ubuntu 14.04.3 with Qgis installed, and the latest versions of R and rgeos.
The dsn is the file path, and the layer name is internal to the PDF. You can get a list of layers with ogrListLayers on the file name:
> ogrListLayers("foo.pdf")
[1] "polys"
attr(,"driver")
[1] "PDF"
attr(,"nlayers")
[1] 1
Ugly output, but that's one layer called polys. So I can read it like this:
> polys = readOGR("./foo.pdf","polys")
OGR data source with driver: PDF
Source: "./foo.pdf", layer: "polys"
with 9 features
It has 1 fields
Note that this only applies to a special class of PDF files with the map data stored in a particular way. Just because your PDF has a map in it, doesn't make it a Geospatial PDF. Here's the command line test on my Geospatial PDF:
$ ogrinfo Monaco/foo.pdf
Had to open data source read-only.
INFO: Open of `Monaco/foo.pdf'
using driver `PDF' successful.
1: polys (Polygon)
and here's the test on yours:
$ ogrinfo CED06_CARTA_110614.pdf
FAILURE:
Unable to open datasource `CED06_CARTA_110614.pdf' with the following drivers.
-> ESRI Shapefile
-> MapInfo File
[etc etc]
-> PDF
[etc etc]
So you dont have a Geospatial PDF.
Your options are, in possible order of simplicity, something like:
Get the boundary data in a GIS data format (eg shapefile, GeoPDF)
Save as an image, load into a GIS, georeference and trace it (QGIS can do this)
Get the raw PDF vectors out of the PDF, assuming they are vectors (first glance shows me the map isn't an image), then find the right transformation to whatever coordinate system, then possibly rebuild the topology if all you have is line segments...
I've had a little bit of success using pstoedit to convert the PDF to a DXF file which can be loaded into QGIS, but then you have to clean it up and reconstruct the polygons, and then its still not in the right geographical location. It would be much simpler if you can get a shapefile of the regions you are interested in.
If what you want is a raster version of the PDF, then you can either use raster::stack("file.pdf") or readGDAL("file.pdf"). But you'll get an image with no georeferencing (it'll just have a bounding box of the number of pixels) since there's no coordinate system with the PDF.

Creating Shapefiles in R

I'm trying to create a shapefile in R that I will later import to either Fusion Table or some other GIS application.
To start,I imported a blank shapefile containing all the census tracts in Canada. I have attached other data (in tabular format) to the shapefile based on the unique ID of the CTs, and I have mapped my results. At the moment, I only need the ones in Vancouver and I would like to export a shapefile that contains only the Vancouver CTs as well as my newly attached attribute data.
Here is my code (some parts omitted due to privacy reasons):
shape <- readShapePoly('C:/TEST/blank_ct.shp') #Load blank shapefile
shape#data = data.frame(shape#data, data2[match(shape#data$CTUID, data2$CTUID),]) #data2 is my created attributes that I'm attaching to blank file
shape1 <-shape[shape$CMAUID == 933,] #selecting the Vancouver CTs
I've seen other examples using this: writePolyShape to create the shapefile. I tried it, and it worked to an extent. It created the .shp, .dbf, and .shx files. I'm missing the .prj file and I'm not sure how to go about creating it. Are there better methods out there for creating shapefiles?
Any help on this matter would be greatly appreciated.
Use rgdal and writeOGR. rgdal will preserve the projection information
something like
library(rdgal)
shape <- readOGR(dsn = 'C:/TEST', layer = 'blank_ct')
# do your processing
shape#data = data.frame(shape#data, data2[match(shape#data$CTUID, data2$CTUID),]) #data2 is my created attributes that I'm attaching to blank file
shape1 <-shape[shape$CMAUID == 933,]
writeOGR(shape1, dsn = 'C:/TEST', layer ='newstuff', driver = 'ESRI Shapefile')
Note that the dsn is the folder containing the .shp file, and the layer is the name of the shapefile without the .shp extension. It will read (readOGR) and write (writeOGR) all the component files (.dbf, .shp, .prj etc)
Problem solved! Thank you again for those who help!
Here is what I ended up doing:
As Mnel wrote, this line will create the shapefile.
writeOGR(shape1, dsn = 'C:/TEST', layer ='newstuff', driver = 'ESRI Shapefile')
However, when I ran this line, it came back with this error:
Can't convert columns of class: AsIs; column names: ct2,mprop,mlot,mliv
This is because my attribute data was not numeric, but were characters. Luckily, my attribute data is all numbers so I ran transform() to fix this problem.
shape2 <-shape1
shape2#data <- transform(shape1#data, ct2 = as.numeric(ct2),
mprop = as.numeric(mprop),
mlot = as.numeric(mlot),
mliv = as.numeric(mliv))
I tried the writeOGR() command again, but I still didn't get the .prj file that I was looking for. The problem was I didn't specified the coordinate systems for the shapefile when I was importing the file. Since I already know what the coordinate system is, all I had to do was define it when importing.
readShapePoly('C:/TEST/blank_ct.shp',proj4string=CRS("+proj=longlat +datum=WGS84")
After that, I re-ran all the things I wanted to do with the shapefile, and the writeOGR line for exporting. And that's it!

Resources