Applying d3.js Density map of homicides example to own data fails - r

We tried to reproduce the beautiful example of bl.ocks.org/diegovalle/5166482, using d3.js and leaflet, but with our own data, which is on a regular lon-lat grid.
In R, we first retrieve the data from a mysql table, and write them to a shapefile:
lonmin <- -10; lonmax <- 10
latmin <- 30; latmax <- 50
dlon <- dlat <- 0.5
lon <- seq(from=lonmin, to=lonmax, by=dlon)
lat <- seq(from=latmin, to=latmax, by=dlat)
nlon <- length(lon); nlat <- length(lat)
# cl <- a mysql request
solRad <- matrix(cl$solRad, ncol=nlon, nrow=nlat)
# Plot the data
levels=seq(from=-40, to=1000, by=40)
filled.contour(solRad, x=lon, y=lat, levels=levels, col=col)
# Write a shapefile
require(maptools); require(rgdal)
writeOGR(ContourLines2SLDF(contourLines(lon, lat, solRad, levels=levels)),
"solRad.shp", "contours", "ESRI Shapefile")
You can look at the filled.contour output ![here] http://www.jonxion.ch/5166482/solRad.png. We then transform the shape file to a topojson file, which you can find by replacing the .png in the above link by .json.
Finally, we render it with D3.js and Leaflet, leading to this faulty result [here] http://www.jonxion.ch/5166482/
We browsed many tutorials and other examples without finding the cue to our problem. What are we doing wrong?
Might it be a d3.js limitation? We recognise that our data is more complex, but Diegovalle's data contains unclosed contours too (see its upper left corner). Would writing ContourPolygones instead of ContourLines solve our problem? Does such routines exist? Or, is there an alternative technique to d3.js? Thank's in advance for your help!

Related

Plotting netcdf file with raster package leads to distorted representation, R

I want to properly plot this netcdf file: http://www.filedropper.com/sshgridsv16092015060412nc (Downloaded originally from here: https://opendap.jpl.nasa.gov/opendap/allData/merged_alt/L4/cdr_grid/contents.html)
But run into issues:
I should be able to just plot the raster (the SLA variable):
library(RNetCDF)
library(raster)
library(maptools)
d <- raster("ssh_grids_v1609_2015060412.nc.nc4", varname = "SLA")
plot(d)
#plot SLA
But the result is very weird as you can see with the provided file.
Especially when plotting a world map on top:
data(wrld_simpl)
plot(wrld_simpl, add = T)
They don't match at all :/
So I thought maybe the problem is with the longitude (ranging from 4.839944e-09 to 360)
Then I read that raster::rotate(d)
should be perfect for that (to get longitude to -180 to 180), but it won't let me. I get this warning message:
Warning message:
In .local(x, ...) :
this does not look like an appropriate object for this function
and
plot(d)
still looks the same.
Any advice would be greatly appreciated!
Cheers
The Netcdf file is not only "rotated" in longitude but x and y are also at the wrong position. The way it has been entered in the netcdf is not usual apparently.
I downloaded the netcdf directly on the OpenDap server because your filedropper link seems to be corrupt.
Anyway, here is my proposition:
library(raster)
library(maptools)
d <- raster("ssh_grids_v1609_2015060412.nc.nc4", varname = "SLA")
# transpose x to y and double flip the map
m.r <- flip(flip(t(d), direction = "y"), direction = "x")
# then rotate from 0:360 to -180:180
rm.r <- rotate(m.r)
data(wrld_simpl)
plot(rm.r)
plot(wrld_simpl, add = T)

NetCDF - converting into raster and projection issues

I have the following NetCDF file - I am trying to convert into raster but something is not right. The projection of the NetCDF file is not given but based on the software I received it from it should LatLong but might be cylindrical equal area. I tried both, but I keep getting this distortion which makes it impossible to query for the values at the right locations. I know the spacing of the grid is not even, not sure if that affects the end result (here visual from ArcGIS but in R it is the same problem unless plotted with levelplot function).
library(raster)
library(ncdf4)
library(lattice)
library(RColorBrewer)
setwd("D:/Results")
climexncdf <- nc_open("ResultsSO_month.nc")
lon <- ncvar_get(climexncdf,"Longitude")
nlon <- dim(lon)
head(lon)
lat <- ncvar_get(climexncdf,"Latitude")
nlat <- dim(lat)
head(lat)
dname <- "Weekly Growth Index"
t <- ncvar_get(climexncdf,"Step")
tmp_array <- ncvar_get(climexncdf,dname)
tmp_stack <- vector("list",length(t))
for (i in 1:length(t)) {
tmp_stack[[i]] <- tmp_array[,,i]
}
YearData <- vector("list",52)
for (i in 1:4) {
YearData[[i]] <- tmp_array[,,i]
}
Month1 <- YearData[c(1,2,3,4)]
# Calculate monthly averages
M1Avg <- Reduce("+",Month1)/length(Month1)
# Replace 0's with NA's
M1Avg[M1Avg==0] <- NA
# Piece of code that gives me what I need:
grid <- expand.grid(lon=lon, lat=lat)
cutpts <- seq(0,1,0.1)
# Convert to raster - work to include lat and long
M1Avg_reorder <- M1Avg[ ,order(lat) ]
M1Avg_reorder <- apply(t(M1Avg_reorder),2,rev)
M1AvgRaster <- raster(M1Avg_reorder,
xmn=min(lon),xmx=max(lon),
ymn=min(lat),ymx=max(lat),
crs=CRS("+proj=longlat +datum=WGS84"))
#crs=CRS("+proj=cea +lat_0=0 +lon_0=0"))
r <- projectRaster(M1AvgRaster,crs=CRS("+proj=longlat +datum=WSG84"))
plot(M1AvgRaster)
# Location file not included but any locations can be entered
locations <- read.csv("Locations.csv", header=T)
coordinates(locations) <- c("y","x")
data <- extract(M1AvgRaster,locations)
writeRaster(M1AvgRaster, "M1AvgRaster_Globe_projWGSTest", format = "GTiff")
the python version shows that after reordering at least the location of data seems correct. However, the data file seems strange, I saw data actually getting corrupted in the python netcdf library, which I've never seen before with quite a lot of different NetCDF files. Also, the chunking and compression settings are strange, better not to apply them at all.
But minimal python example to get the plot is here:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from netCDF4 import Dataset
ff = Dataset('ResultsSO_month.nc')
test_var = np.copy(ff.variables['Maximum Temperature'][:])
## reorder latitudes
latindex = np.argsort(ff.variables['Latitude'][:])
## Set up map and compute map coordinates
m = Basemap(projection='cea', llcrnrlat=-90, urcrnrlat=90,
llcrnrlon=-180, urcrnrlon=180, resolution='c')
grid_coords = np.meshgrid(ff.variables['Longitude'[:],ff.variables['Latitude'][latindex])
X,Y = m(grid_coords[0],grid_coords[1])
## Plot
m.pcolormesh(X,Y,test_var[0,latindex,:])
m.drawcoastlines()
plt.colorbar()
plt.show()

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.

Dealing with unordered XY points to create a polygon shapefile in R

I've inherited a geodatabase of polygons of lakes for which I am trying to create sampling grids on each lake. My current strategy is to export spatial data to CSV, use R to run a loop to create the grids on each lake, and then write to a new shapefile. However, here is my problem, when exporting to a CSV the WKT strings get messed up and put onto different lines. Okay, no problem, I moved on to exporting just the geometry to CSV so that I get X-Y values. When I simply plot the points they look perfect (using plot(y~x)), but the points are not in order. So, when I transform the data to a SpatialPolygon in the sp package in R using the following sequence:
XY-points -> Polygon -> Polygons -> SpatialPolygon
and then plot the SpatialPolygon I get this:
I know this is an artifact of incorrectly ordered points, because when I order the points by X and then by Y and run the same procedure here is what I get:
This is what the correct plotting is supposed to look like (X-Y data plotted with open circles):
Here is a short reproducible example of what I am trying to deal with:
library(sp)
# correct polygon
data <- data.frame(x=c(1:10, 10:1), y=c(5:1, 1:10, 10:6))
# plot(y~x, data=data)
correct.data.points <- rbind(data, data[1,]) # to close the ring for a polygon
correct.data.coords <- as.matrix(cbind(correct.data.points))
correct.data.poly <- Polygon(correct.data.coords, hole=F)
correct.data.poly <- Polygons(list(correct.data.poly), ID=0)
correct.data.poly.sp <- SpatialPolygons(list(correct.data.poly))
plot(correct.data.poly.sp)
# incorrect polygon
scr.data <- data[c(sample(1:20)),]
# plot(y~x, data=scr.data)
scr.data.points <- rbind(scr.data, scr.data[1,]) # to close the ring for a polygon
scr.data.coords <- as.matrix(cbind(scr.data.points))
scr.data.poly <- Polygon(scr.data.coords, hole=F)
scr.data.poly <- Polygons(list(scr.data.poly), ID=0)
scr.data.poly.sp <- SpatialPolygons(list(scr.data.poly))
plot(scr.data.poly.sp)
Any thoughts? Thanks for any help or insight anyone can provide. Also, for reference I am using QGIS 2.6.0 and the MMQGIS Python plugin to do the geometry exporting.

How to properly project and plot raster in R

I have a raster in an equal area Behrmann projection and I would like to project it to the Mollweide projection and plot.
When I do this with the following code, however, the plotting doesn't seem right, as the map extends to the sides, and there are outlines of various landmasses where I wouldn't expect them.Also, the map extends beyond the plot window.
Can anyone please help me get this to plot nicely?
Thanks!
The data file used can be downloaded from this link.
Here is the code I have so far:
require(rgdal)
require(maptools)
require(raster)
data(wrld_simpl)
mollCRS <- CRS('+proj=moll')
behrmannCRS <- CRS('+proj=cea +lat_ts=30')
sst <- raster("~/Dropbox/Public/sst.tif", crs=behrmannCRS)
sst_moll <- projectRaster(sst, crs=mollCRS)
wrld <- spTransform(wrld_simpl, mollCRS)
plot(sst_moll)
plot(wrld, add=TRUE)
Alright, since the example at this page seems to work, I tried to mimic it as much as possible. I think problems arise because the far left and far right side of the raster image overlap. Cropping and an intermediate reprojection to Lat-Lon as in the example seem to solve your problem.
Perhaps this workaround can be a basis for a more elegant solution that directly addresses the problem, as it is not benificial to reproject a raster twice.
# packages
library(rgdal)
library(maptools)
library(raster)
# define projections
mollCRS <- CRS('+proj=moll')
behrmannCRS <- CRS('+proj=cea +lat_ts=30')
# read data
data(wrld_simpl)
sst <- raster("~/Downloads/sst.tif", crs=behrmannCRS)
# crop sst to extent of world to avoid overlap on the seam
world_ext = projectExtent(wrld_simpl, crs = behrmannCRS)
sst_crop = crop(x = sst, y=world_ext, snap='in')
# convert sst to longlat (similar to test file)
# somehow this gets rid of the unwanted pixels outside the ellipse
sst_longlat = projectRaster(sst_crop, crs = ('+proj=longlat'))
# then convert to mollweide
sst_moll <- projectRaster(sst_longlat, crs=mollCRS, over=T)
wrld <- spTransform(wrld_simpl, mollCRS)
# plot results
plot(sst_moll)
plot(wrld, add=TRUE)

Resources