rworldmap coordinates, how to match NetCDF data to the map? - r

Rworldmap looks like exactly what I need for mapping climate data, but I'm having a problem lining up the base map with the climate data. What I am mapping is ocean temperature data from JAMSTEC for August, 2015 from here:
http://www.jamstec.go.jp/ARGO/argo_web/ancient/MapQ/Mapdataset_e.html
The dataset name is TS_201508_GLB.nc. The R script I'm using is below. The country outlines are fine, but the data is for the oceans only and the data does not show in the oceans it is offset somehow. Can you tell me how to align the data to the map?
I've read lots of articles but I cannot tell how to align the two. The data I have is longitude and latitude. South latitude is negative and west longitude is negative, I don't see how they could be confused. How is the map shown, is there some sort of special convention for the lat/longs?
Thanks for any help you can provide.
The code:
library(RNetCDF)
library(sp)
library(rworldmap)
library(rgeos)
library(RColorBrewer)
library (classInt)
library(grid)
library(spam)
library(maps)
library(maptools)
library(fields)
library(methods)
library(rgdal)
library(rworldxtra)
fname <- "G:/Climate_Change/Ocean_Warming/MOAA_GPV_Jamstec_Temperature/TS_201508_GLB.nc"
moaa <- open.nc(fname)
# moaa
print.nc(moaa)
file.inq.nc(moaa)
#TOI is the temperature array extracted from the NCDF file
TOI = var.get.nc(moaa,"TOI",start=c(1,1,1),count=c(360,132,25))
TOI[1,1,1]
Long = var.get.nc(moaa,"LONGITUDE")
Lat = var.get.nc(moaa, "LATITUDE")
Pres = var.get.nc(moaa,"PRES")
# create grid
offset=c(-179.5,-60.50)
cellsize = c(abs(Long[1]-Long[2]),abs(Lat[1]-Lat[2]))
cells.dim = c(dim(Long), dim(Lat))
# create gt
gt <- GridTopology(cellcentre.offset=offset,cellsize=cellsize,cells.dim=cells.dim)
# create map window
mapDevice()
# Create a color pallette
colourPalette=c('blue','lightblue','white',brewer.pal(9,'YlOrRd'))
# Values at 2000 decibar for August 2015
ncMatrix <- TOI[,,25]
# Gridvalues
gridVals <-data.frame(att=as.vector(ncMatrix))
# create a spatialGridDataFrame
sGDF <-SpatialGridDataFrame(gt,data=gridVals)
# Vector to classify data
catMethod=seq(from=0,to=4,by=.33)
# plotting the map and getting params for legend
mapParams <- mapGriddedData( sGDF, nameColumnToPlot='att',catMethod=catMethod,colourPalette=colourPalette,addLegend=FALSE)

I finally figured it out. rworldmap wants the data organized from the upper left of the map(Northwest corner), that is Long = -180, Lat=90. The NetCDF data starts at Long=0 and Lat=-90(the middle of the map and south edge). So we have to reverse the values in the North-South direction:
#
# Flip the Latitude values so south is last
ncMatrix2 <- ncMatrix[,dim(Lat):1]
Then switch the values for east longitude and west longitude:
#
#Longitude values need to be from -180 to 0 then 0 to 180
# So we divide into East and West, then recombine with rbind
East_Long_values <-ncMatrix2[1:180,]
West_Long_Values <-ncMatrix2[181:360,]
ncMatrix3 <- rbind(West_Long_Values,East_Long_values)
Then everything else works.

Related

Plotting UTM / Coordinates

I am new to R programming, I have a csv/excel file of 20 towns in a country which contains the in the below format,
Towns UTM Cordinates UTM Cordinaetes
xxxxxxxx 1377777 249514
yyyyyyyy 142145 228942
I am unable to plot them into a map, Does anyone have any idea of how t plot these UTM Cordinates.
Is it possible to plot towns in R programming with UTM? If so can anyone help me out here.
I have the shape file for the country with me as well. But I am not sure how to process.
myfilepath <- file.choose()
Cordinates<-read.csv(myfilepath,header=TRUE)
Cordinates
str(Cordinates)
library(rgdal)
library(sp)
library(data.table)
library(ggplot2)
library(tibble)
myfilepath <- file.choose()
Shapefile<-readOGR(myfilepath)
plot(Shapefile)
ggmap(Shapefile)+geom_point(aes(x=Easting,y=Northing,col=Cordinates))
Any help would be appreciated.
Here is a sf-solution, making use of all the hard work from #Dave2e to find the correct coordinate system used...
#convert to simple feature
library( sf )
mysf <- sf::st_as_sf( mydata, coords = c("Easting", "Northing"), crs = 29902)
#plot for visual inspection
mapview::mapview(mysf)
The trick is to determine the grid system used. After much searching the code for standard Republic of Ireland grid is epsg:29902
The first step is to transform the Irish grid coordinates to a standard latitude and longitude. This is accomplished with the "rgdal" library.
library(rgdal)
points <- read.table(header=TRUE, text = "Towns Easting Northing
Belclare 137777 249514
Carnmore 142145 228942")
#Pull out the location columns and rename
point <- points[,2:3]
names(point) <-c('x', 'y')
#convert to corrdinates and define initial coordinates systems
coordinates(point) <- c('x', 'y')
proj4string(point)=CRS("+init=epsg:29902") #29903 is the grid for Ireland
#Transform the Ireland's grid to longitude & latitude
coord<-spTransform(point,CRS("+init=epsg:4326"))
coord
This will transform your list of coordinates, please search this site on how to plot to a map. There are many options available.

Calculate slope over a gridded latitude/longitude coordinate area with corresponding depths in r

I have built a gridded area in the Gulf of Alaska with a resolution of 0.02 decimal degrees (~1nm);
library(sp)
library(rgdal)
# Set interval for grid cells.
my.interval=0.02 #If 1 is 1 degree, which is 60nm, than 0.1 is every 6nm, and 0.05 is every
3nm, so 0.0167 is every 1nm
# Select range of coordinates for grid boundaries (UTM to maintain constant grid cell area regardless of geographic location).
lonmin = -140.5083
lonmax = -131.2889
latmin = 53.83333
latmax = 59.91667
LON = seq(lonmin, lonmax, by=my.interval)
LAT = seq(latmin, latmax, by=my.interval)
# Compile series of points for grid:
mygrd = expand.grid(
Longitude = seq(lonmin, lonmax, by=my.interval),
Latitude = seq(latmin, latmax, by=my.interval)) %>%
#mutate(z=1:n()) %>%
data.frame
I exported that grid as a .csv file and brought it into ArcGIS where I used a few bathymetry rasters to extract the bottom depth at the midpoint of each cell. I then exported that from GIS back into R as a .csv file data frame. So now it has another column called "Depth" on it.
For now, I'll just add a column with random "depth" numbers in it:
mygrd$Depth<-NA
mygrd$Depth<-runif(nrow(mygrd), min=100, max=1000)
I would like to calculate the slope at the midpoint of each cell (between points).
I've been trying to do this with the slope() function in SDMTools package, which requires you to have a SpatialGridDataFrame in the sp package.
I can't get this to work; I am also not sure if this is the easiest way to do that?
I have a data frame with 3 columns: Longitude, Latitude, and Depth. I'd like to calculate slope. If anyone knows any better way to do this, let me know! Any help is much appreciated!
Here is some of the code I've been trying to use:
library(SDMTools)
proj <- CRS('+proj=longlat +datum=WGS84')
coords <- mygrd[,1:2]
t2 <- SpatialPointsDataFrame(coords=coords, data=mgrd proj4string=proj)
t2<-SpatialPixelsDataFrame(points=t2[c("Longitude","Latitude")], data=t1[,c(1,2)])
t3 <- SpatialGridDataFrame(grid=NULL, data=t2, proj4string=CRS("+proj=longlat +datum=WGS84"))
class(t3)
slope.test<-slope(t3, latlon=TRUE)

R - find point farthest from set of points on rasterized USA map

New to spatial analysis on R here. I have a shapefile for the USA that I downloaded from HERE. I also have a set of lat/long points (half a million) that lie within the contiguous USA.
I'd like to find the "most remote spot" -- the spot within the contiguous USA that's farthest from the set of points.
I'm using the rgdal, raster and sp packages. Here's a reproducible example with a random sample of 10 points:
# Set wd to the folder tl_2010_us_state_10
usa <- readOGR(dsn = ".", layer = "tl_2010_us_state10")
# Sample 10 points in USA
sample <- spsample(usa, 10, type = "random")
# Set extent for contiguous united states
ext <- extent(-124.848974, -66.885444, 24.396308, 49.384358)
# Rasterize USA
r <- raster(ext, nrow = 500, ncol = 500)
rr <- rasterize(usa, r)
# Find distance from sample points to cells of USA raster
D <- distanceFromPoints(object = rr, xy = sample)
# Plot distances and points
plot(D)
points(sample)
After the last two lines of code, I get this plot.
However, I'd like it to be over the rasterized map of the USA. And, I'd like it to only consider distances from cells that are in the contiguous USA, not all cells in the bounding box. How do I go about doing this?
I'd also appreciate any other tips regarding the shape file I'm using -- is it the best one? Should I be worried about using the right projection, since my actual dataset is lat/long? Will distanceFromPoints be able to efficiently process such a large dataset, or is there a better function?
To limit raster D to the contiguous USA you could find the elements of rr assigned values of NA (i.e. raster cells within the bounding box but outside of the usa polygons), and assign these same elements of D a value of NA.
D[which(is.na(rr[]))] <- NA
plot(D)
lines(usa)
You can use 'proj4string(usa)' to find the projection info for the usa shapefile. If your coordinates of interest are based on a different projection, you can transform them to match the usa shapefile projection as follows:
my_coords_xform <- spTransform(my_coords, CRS(proj4string(usa)))
Not sure about the relative efficiency of distanceFromPoints, but it only took ~ 1 sec to run on my computer using your example with 10 points.
I think you were looking for the mask function.
library(raster)
usa <- getData('GADM', country='USA', level=1)
# exclude Alaska and Hawaii
usa <- usa[!usa$NAME_1 %in% c( "Alaska" , "Hawaii"), ]
# get the extent and create raster with preferred resolution
r <- raster(floor(extent(usa)), res=1)
# rasterize polygons
rr <- rasterize(usa, r)
set.seed(89)
sample <- spsample(usa, 10, type = "random")
# Find distance from sample points to cells of USA raster
D <- distanceFromPoints(object = rr, xy = sample)
# remove areas outside of polygons
Dm <- mask(D, rr)
# an alternative would be mask(D, usa)
# cell with highest value
mxd <- which.max(Dm)
# coordinates of that cell
pt <- xyFromCell(r, mxd)
plot(Dm)
points(pt)
The distances should be fine, also when using long/lat data. But rasterFromPoints could indeed be a bit slow with a large data set as it uses a brute force algorithm.

Label a point depending on which polygon contains it (NYC civic geospatial data)

I have the longitude and latitude of 5449 trees in NYC, as well as a shapefile for 55 different Neighborhood Tabulation Areas (NTAs). Each NTA has a unique NTACode in the shapefile, and I need to append a third column to the long/lat table telling me which NTA (if any) each tree falls under.
I've made some progress already using other point-in-polygon threads on stackoverflow, especially this one that looks at multiple polygons, but I'm still getting errors when trying to use gContains and don't know how I could check/label each tree for different polygons (I'm guessing some sort of sapply or for loop?).
Below is my code. Data/shapefiles can be found here: http://bit.ly/1BMJubM
library(rgdal)
library(rgeos)
library(ggplot2)
#import data
setwd("< path here >")
xy <- read.csv("lonlat.csv")
#import shapefile
map <- readOGR(dsn="CPI_Zones-NTA", layer="CPI_Zones-NTA", p4s="+init=epsg:25832")
map <- spTransform(map, CRS("+proj=longlat +datum=WGS84"))
#generate the polygons, though this doesn't seem to be generating all of the NTAs
nPolys <- sapply(map#polygons, function(x)length(x#Polygons))
region <- map[which(nPolys==max(nPolys)),]
plot(region, col="lightgreen")
#setting the region and points
region.df <- fortify(region)
points <- data.frame(long=xy$INTPTLON10,
lat =xy$INTPTLAT10,
id =c(1:5449),
stringsAsFactors=F)
#drawing the points / polygon overlay; currently only the points are appearing
ggplot(region.df, aes(x=long,y=lat,group=group))+
geom_polygon(fill="lightgreen")+
geom_path(colour="grey50")+
geom_point(data=points,aes(x=long,y=lat,group=NULL, color=id), size=1)+
xlim(-74.25, -73.7)+
ylim(40.5, 40.92)+
coord_fixed()
#this should check whether each tree falls into **any** of the NTAs, but I need it to specifically return **which** NTA
sapply(1:5449,function(i)
list(id=points[i,]$id, gContains(region,SpatialPoints(points[i,1:2],proj4string=CRS(proj4string(region))))))
#this is something I tried earlier to see if writing a new column using the over() function could work, but I ended up with a column of NAs
pts = SpatialPoints(xy)
nyc <- readShapeSpatial("< path to shapefile here >")
xy$nrow=over(pts,SpatialPolygons(nyc#polygons), returnlist=TRUE)
The NTAs we're checking for are these ones (visualized in GIS): http://bit.ly/1A3jEcE
Try simply:
ShapeFile <- readShapeSpatial("Shapefile.shp")
points <- data.frame(long=xy$INTPTLON10,
lat =xy$INTPTLAT10,
stringsAsFactors=F)
dimnames(points)[[1]] <- seq(1, length(xy$INTPTLON10), 1)
points <- SpatialPoints(points)
df <- over(points, ShapeFile)
I omitted transformation of shapefile because this is not the main subject here.

Can't change the coordinates of a SpatialPolygonsDataFrame in R

This is my program:
library(sp)
library(RColorBrewer)
#get spatial data for Spain on region level
con <- url("http://gadm.org/data/rda/ESP_adm1.RData")
print(load(con))
close(con)
# plot Spain with colors
col = c("blue","blue","blue","blue","blue","blue","blue","blue","blue",
"blue","blue","blue","blue","blue","blue","blue","red","red")
spplot(gadm, "NAME_1", col.regions=col, main="Regiones de EspaƱa",
colorkey=F, lwd=.4, col="black")
What I get when I run is what I am looking for, but I want to change the islands in the south west (Islas Canarias) to be closer to Spain country. I don't know what to do to change the coordinates of the islands. I just know they are here:
gadm[14,]
I try to make changes for example here:
gadm[14,]#polygons[[1]]#Polygons[[1]]#coords
but I get the message: no method for coercing this S4 class to a vector
One could also try the sf package - CRAN link here
The GADM data URL seems deprecated now, but one can manually download the RDS file containing the SpatialPolygonsDataFrame for Spain from http://gadm.org/.
library(sf)
spain <- readRDS(file = "ESP_adm1.rds") # downloaded from http://gadm.org/
# convert from sp to sf object
spain_sf <- st_as_sf(spain)
# Change the coordinates of Canary Islands - the 14th geometry of spain_sf,
# itself with 20 polygons, check str(st_geometry(spain_sf)[[14]])
# Will shift them closer to mainland Spain.
# The added values are degrees because the CRS is unprojected
# (e.g. add 10 to longitudes and 6 to latitudes)
for (i in 1:length(st_geometry(spain_sf)[[14]])) {
st_geometry(spain_sf)[[14]][[i]][[1]][, 1] <- st_geometry(spain_sf)[[14]][[i]][[1]][, 1] + 10
st_geometry(spain_sf)[[14]][[i]][[1]][, 2] <- st_geometry(spain_sf)[[14]][[i]][[1]][, 2] + 6
}
# plot to check
par(omi=c(0,0,0,2)) # make some space to the right for the legend
plot(spain_sf["NAME_1"],
axes = TRUE,
graticule = st_crs(spain_sf))
# dev.off() # resets par()

Resources