I have a set of data strucutured x,y,z running coordinates lon -179.5 to 180 and lat -90 to 90, points are at 5 degree increments and z is temperature. I need to convert this data to a raster and interpolate down to a higher resolution. Additionally, I need to fill in the resultant gap between -179.5 and 180 degrees (error on standard RasterFromXYZ function as this is uneven). I previously converted to Cartesian coordinates and used TPS interpolation; however, this has too large a smoothing effect over the data. The original publication (no script available) also used bi-linear interpolation, so I would like to remain consistent. What is the best method to do this?
Related
From the Velodyne point, how to get pixel coordinate for each camera?
Using pykitti
point_cam0 = data.calib.T_cam0_velo.dot(point_velo)
We can get the projection on the image which is equation 7 of the Kitti Dataset paper:
y = Prect(i) Rrect(0) Tvelocam x
But from there, how to get the actual pixel coordinates on each image?
Update: PyKitti version 0.2.1 exposes projection matrices for all cameras.
I recently faced the same problem. For me, the problem was that pykitty didn't expose Prect and Rrect matrices for all cameras.
For Pykitti > 0.2.1, use Prect and Rrect from calibration data.
For previous versions, you have two options:
Enter the matrices by hand (data is in the .xml calibration file for each sequence).
Use this fork of pykitti: https://github.com/Mi-lo/pykitti/
Then, you can use equation 7 to project a velodyne point into an image. Note that:
You will need 3D points as a 4xN array in homogeneous coordinates. Points returned by pykitti are a Nx4 numpy array, with the reflectance in the 4th column. You can prepare the points with the prepare_velo_points function below, which keeps only points with reflectance > 0, then replaces reflectance values with 1 to get homogeneous coordinates.
The velodyne is 360°. Equation 7 will give you a result even for points that are behind the camera (they will get projected as if they were in front, but vertically mirrored). To avoid this, you should project only points that are in front of the camera. For this, you can use the function project_velo_points_in_img below. It returns 2d points in homogeneous coordinates so you should discard the 3rd row.
Here are the functions I used:
def prepare_velo_points(pts3d_raw):
'''Replaces the reflectance value by 1, and tranposes the array, so
points can be directly multiplied by the camera projection matrix'''
pts3d = pts3d_raw
# Reflectance > 0
pts3d = pts3d[pts3d[:, 3] > 0 ,:]
pts3d[:,3] = 1
return pts3d.transpose()
def project_velo_points_in_img(pts3d, T_cam_velo, Rrect, Prect):
'''Project 3D points into 2D image. Expects pts3d as a 4xN
numpy array. Returns the 2D projection of the points that
are in front of the camera only an the corresponding 3D points.'''
# 3D points in camera reference frame.
pts3d_cam = Rrect.dot(T_cam_velo.dot(pts3d))
# Before projecting, keep only points with z>0
# (points that are in fronto of the camera).
idx = (pts3d_cam[2,:]>=0)
pts2d_cam = Prect.dot(pts3d_cam[:,idx])
return pts3d[:, idx], pts2d_cam/pts2d_cam[2,:]
Hope this helps!
I'm trying to overlay the coastlines and country borders onto the R map I've drawn.
I'm trying the simple worldHires function to do this but it's not scaling correctly to my map. I downloaded my data from https://www.esrl.noaa.gov/psd/data/gridded/data.UDel_AirT_Precip.html and the file name is precip.mon.total.v401
This is my code when I try to plot my map (excluding the first few lines of reading data and variables into R):
>image.plot(lon,lat,precip[,ncol(precip):1,8],
main="Precipitation (August, 2001)",
xlab=expression(paste("Longitude(",degree,"E)")),
ylab=expression(paste("Latitude(",degree,"N)")),
zlim=c(0,15),xlim = c(min(lon),max(lon)),
ylim = c(min(lat),max(lat)),cex=0.5)
> map('world2Hires', fill=FALSE, add=T)
The boundary layer from world2Hires is very small, scaling from -90 to 90 for Latitude and 0 to 360 for Longitude.
My data's range is Latitude -180 to 180 and Longitude 0 to 720. So how do I scale the world2Hires to match my data? Or is that not possible? See image in link
In your question, you seem to be mixing the latitude values (-90:90) degrees with the matrix indices. Since the map is of resolution 0.5 degrees, these run 0:360. The same for the longitudes.
So from your question, I am not sure whether the problem is that your vectors "lon" and "lat" are incorrect (they should probably be something like lon=seq(0,360,by=0.5); lat=seq(-90,90,by=0.5)). Obviously, the map() command expects the co-ordinates to be in degrees.
But the illustration on the link you provided, shows that the data is on longitude [0,360] while the data in worldHires is on [-180,180].
I think the simplest solution is to use "world2Hires", which is the same map but with longitudes shifted to [0,360], which should fit your map.
As a side remark, using worldHires is possibibly not the best choice of world map. The country borders in some parts of the world are outdated, and the high resolution is not so important at a global scale. Just using "world2" (the "2" again is for the shift to [0,360]) would probably look just as good on a global map.
I may add that in the very near future, the next version of "map" will make such shifting of longitudes much easier, whithout the need for an extra data set.
I am using the Spatstat package in R for spatial point analysis. My dataset comprises location coordinates i.e. latitude and longitude of some event upto 6 places of decimal. It has some 9898 observations.
Here`s the output of the summary for the point pattern:
Planar point pattern: 9898 points
Average intensity 149786.3 points per square unit
Coordinates are given to 6 decimal places
units
Window area = 0.0660808 square units
My question is that how can the Average Intensity value be so huge? Or is my approach of creating a point pattern is wrong? Please help!
You are using a geographic coordinate system coordinates which spatstat doesn't support.
The coordinates are simply interpreted as units and since the window area is only 0.0660803 square units the point density is extrapolated to an average intensity of 149786.3 points per square unit.
Have a look at this thread how you convert (project) your coordinates to points on a flat map:
Unit length in spatstat
I have a set of latitudes and longitudes , so this is the data for an animal as it moves in time. what i want to do is to calculate turning angle, that is by what angle it turns between every movement. so say i have point 1, point 2 and point 3 with latitude and longitude value corresponding to each point(animal moves from point 1 to point 2 to point 3 and so on) and i want to calculate the angle between these 3 points, point 2 being the middle point. what should i do? my OS is windows and i am using R for analysis.
so here is my sample data:
longitude latitude
36.89379547 0.290166977
36.89384037 0.290194109
36.88999724 0.286821044
36.88708721 0.288339411
36.88650313 0.29010232
36.88563203 0.289939416
36.88545224 0.290924863
they are in decimal degrees
Using the function trackAzimuth in maptools:
library(maptools)
trackAngle <- function(xy) {
angles <- abs(c(trackAzimuth(xy), 0) -
c(0, rev(trackAzimuth(xy[nrow(xy):1, ]))))
angles <- ifelse(angles > 180, 360 - angles, angles)
angles[is.na(angles)] <- 180
angles[-c(1, length(angles))]
}
The trackAzimuth function is a simple loop wrapper around gzAzimuth. See ?gzAzimuth for references on calculating directions on the sphere.
Using your data:
x <- read.table(text = "longitude latitude
36.89379547 0.290166977
36.89384037 0.290194109
36.88999724 0.286821044
36.88708721 0.288339411
36.88650313 0.29010232
36.88563203 0.289939416
36.88545224 0.290924863", header = TRUE)
trackAngle(as.matrix(x))
[1] 10.12946 111.17211 135.88514 97.73801 89.74684
EDIT: I had to remove first/last angles from the function, something I was doing after the fact with this function elsewhere. Should be right now. :)
Also, the packages adehabitatLT and argosfilter contain functions to calculate track directions and angles.
Your data points vary over only a small range. We can look at one small patch of Earth's surface and pretend it's flat, two dimensional. You have to figure out the scale of how many km, meters, miles, whatever your favorite unit is, corresponds to one degree of latitude, and for one degree of longitude. The latter depends on latitude - it'll be the same as the scale for latitude when near the equator, but if you are standing within arm's length of the north pole, one step will take you through fifty degrees. Set up x,y coordinates where x=0 is at longitude 36.88000, and y=0 is latitude 0.29000.
So, now you have a series of (x,y) points. Take the differences from each point to the next: P2-P1, P3-P2, etc. These could be called "displacement vectors" but other terms may be used in other fields than where i'm from. Call them V1, V2, etc. Use dot products and norms: dot(V1,V2) = magnitude(V1)*magnitude(V2)*cos(a) where a is the angle by which V2 deviates from the direction of V1. Repeat for V3 and V2, and so on.
R has all the tools to do this, but I don't know enough syntax of R to give examples.
Spatialite has a the ability to calculate the distance between 2 geometries with it's Distance() function. There are other functions that work on LINESTRINGs. However I can't find out what units it returns it in. Is it metres? If I have 2 points, how do I calculate the distance between them in a spatialite query?
(For the record I'm using SRID 4326, i.e. WSG 86, i.e. the old traditional degrees of latitude and longitude).
the unit returned by ST_Distance(), ST_Length() and ST_Area()
exactly is the one defined by the corresponding SRID.
consequently, if you are using latitude and longitude (SRID=4326,
WGS 84), any length will be measured in DEGREES, and any area in
SQUARE DEGREES.
if you are interested in giving a more conventional
unit (METERS, SQUARE METERS), you simply have to project
your geometries into some appropriate 'planar' CRS (e.g. UTM)
using ST_Transform()
In version 2.4.4 and higher there is a function PtDistWithin() which returns meters for a distance query. See doc. section "SQL functions for distance relationships":
http://www.gaia-gis.it/spatialite-2.4.0-4/spatialite-sql-2.4-4.html#p13