draw figures on a map with `sf` - r

I am struggling to find a systematic way to convert coordinates and geometries to km.
Let's say I have a .shp file, which I read with st_read. I want to draw a circle of radius 10 kms around a city. I know the coordinates of the city in latitude and longitude, so I can convert to km with:
y = 111.2 * latitude
x = 111.2 * longitude * cos(pi / 130* latitude)
And then define a circle centered in x,y. Now I can easily draw the circle with plot.owin {spatstat.geom}, but, how can I plot is onto the geometry of the .shp file? Can I use st_crs to set the coordinates of the circle to the reference system of the original map (and how)?

Related

Calculating a new lat/long co-ordinate by adding a distance to a starting co-ordinate?

I have an ascii grid of elevation data in 100M cells. I have a lat/long for a starting point and I need to add up these 100m increments and get new lat/long co-ordinate to draw a colored box around.
Im using R and leaflet to draw a map with the elevation data under a series of markers. I want a nice color coded layer in the leaflet map to show elevation.
coords <- function(cells_east, cells_north) {
cells_east =1000
cells_north=1000
start_lat <- 48.922582
start_lng <- -101.497821
kmeast<-cells_east/10 #each cell 100 m
kmnorth<-cells_north/10
#Latitude: 1 deg = 110.574 km
#Longitude: 1 deg = 111.320*cos(latitude) km
lat_east <- kmeast /110.574
lng_north <- kmnorth / (111.32 * cos(start_lat))
elevation <- dem$data[cells_east,cells_north] #elevation from ascii grid
ret <- c(lat_east+start_lat,lng_north+start_lng,elevation) #lat,lng,elev
}
I go the conversion functions off the web near the bottom, but it seems off. This example should be 100 km north and east from the south west starting point but when I punch the coords in google maps its in a way different spot. Not other side of the world wrong but clearly too inaccurate to be useful.

How to plot a extracted raster in proper xy coordinates?

I have a ndvi raster. I had to extract the values using a threshold conditon.When I plot the graph of the extracted raster, the x y coordinated are not lat long.
I have tried the ggplot() , also the used rastertopoints and rasterfromXYZ to plot the raster but in vain.
The code is below.
Unable to plot s. xy coordiantes are not lat long.
library(raster)
library(rgdal)
raster <- ("D:/Project/ndvisoybean.tif")
plot(ndvi)
ndvi[is.na(ndvi)] <-0
s <- ndvi[ndvi#data#values<maxValue(ndvi) & ndvi#data#values>0.3*maxValue(ndvi)]
I want a graph of the extracted raster s with proper lat long coordinates in x y.
As fa as I know there is no appropriate case to plot lon/lat xy coordinate map if the raster is not WGS84 projection.
One way is that converting raster layer to WGS84 projection.So that the plot coordiante is lon/lat. It is only appreciate for small map or world map.
The other way is using coord_map function in ggplot.But the import data must be lon/lat dataframe rather than ohter projection coordinate. So it is low efficiency to plot map. More serous it is very slow when converting data.frame point coordinate to another. this way is only suitable for small width/height raster. Code example:
Primaly you should convert your raster to WGS84 coordiante.
df=rasterToPoint(raster_WGS84)
ggplot(df, aes(y=lon, x=lat, color=values)) +
geom_point(size=2, shape=15) +
theme() +
scale_color_distiller(palette='Spectral') +
coord_map('lambert', lat0=30, lat1=65, xlim=c(-20, 39), ylim=c(19, 75))
Summary: If your raster is projected coordinate,such as Albers,lambert rather than lon/lat WGS84 coordiate, it is inconvenient to plot a map with lon/lat xy coodiate.

Create Grid in R for kriging in gstat

lat long
7.16 124.21
8.6 123.35
8.43 124.28
8.15 125.08
Consider these coordinates, these coordinates correspond to weather stations that measure rainfall data.
The intro to the gstat package in R uses the meuse dataset. At some point in this tutorial: https://rpubs.com/nabilabd/118172, the guys makes use of a "meuse.grid" in this line of code:
data("meuse.grid")
I do not have such a file and I do not know how to create it, can I create one using these coordinates? Or at least point me to material that discusses how to create a custom grid for a custom area (i.e not using administrative boundaries from GADM).
Probably wording this wrong, don't even know if this question makes sense to R savvy people. Still, would love to hear some direction, or at least tips. Thanks a lot!
Total noob at R and statistics.
EDIT: See the sample grid that the tutorial I posted looks like, that's the thing I want to make.
EDIT 2: Would this method be viable? https://rstudio-pubs-static.s3.amazonaws.com/46259_d328295794034414944deea60552a942.html
I am going to share my approach to create a grid for kriging. There are probably more efficient or elegant ways to achieve the same task, but I hope this will be a start to facilitate some discussions.
The original poster was thinking about 1 km for every 10 pixels, but that is probably too much. I am going to create a grid with cell size equals to 1 km * 1 km. In addition, the original poster did not specify an origin of the grid, so I will spend some time determining a good starting point. I also assume that the Spherical Mercator projection coordinate system is the appropriate choice for the projection. This is a common projection for Google Map or Open Street Maps.
1. Load Packages
I am going to use the following packages. sp, rgdal, and raster are packages provide many useful functions for spatial analysis. leaflet and mapview are packages for quick exploratory visualization of spatial data.
# Load packages
library(sp)
library(rgdal)
library(raster)
library(leaflet)
library(mapview)
2. Exploratory Visualization of the station locations
I created an interactive map to inspect the location of the four stations. Because the original poster provided the latitude and longitude of these four stations, I can create a SpatialPointsDataFrame with Latitude/Longitude projection. Notice the EPSG code for Latitude/Longitude projection is 4326. To learn more about EPSG code, please see this tutorial (https://www.nceas.ucsb.edu/~frazier/RSpatialGuides/OverviewCoordinateReferenceSystems.pdf).
# Create a data frame showing the **Latitude/Longitude**
station <- data.frame(lat = c(7.16, 8.6, 8.43, 8.15),
long = c(124.21, 123.35, 124.28, 125.08),
station = 1:4)
# Convert to SpatialPointsDataFrame
coordinates(station) <- ~long + lat
# Set the projection. They were latitude and longitude, so use WGS84 long-lat projection
proj4string(station) <- CRS("+init=epsg:4326")
# View the station location using the mapview function
mapview(station)
The mapview function will create an interactive map. We can use this map to determine what could be a suitable for the origin of the grid.
3. Determine the origin
After inspecting the map, I decided that the origin could be around longitude 123 and latitude 7. This origin will be on the lower left of the grid. Now I need to find the coordinate representing the same point under Spherical Mercator projection.
# Set the origin
ori <- SpatialPoints(cbind(123, 7), proj4string = CRS("+init=epsg:4326"))
# Convert the projection of ori
# Use EPSG: 3857 (Spherical Mercator)
ori_t <- spTransform(ori, CRSobj = CRS("+init=epsg:3857"))
I first created a SpatialPoints object based on the latitude and longitude of the origin. After that I used the spTransform to perform project transformation. The object ori_t now is the origin with Spherical Mercator projection. Notice that the EPSG code for Spherical Mercator is 3857.
To see the value of coordinates, we can use the coordinates function as follows.
coordinates(ori_t)
coords.x1 coords.x2
[1,] 13692297 781182.2
4. Determine the extent of the grid
Now I need to decide the extent of the grid that can cover all the four points and the desired area for kriging, which depends on the cell size and the number of cells. The following code sets up the extent based on the information. I have decided that the cell size is 1 km * 1 km, but I need to experiment on what would be a good cell number for both x- and y-direction.
# The origin has been rounded to the nearest 100
x_ori <- round(coordinates(ori_t)[1, 1]/100) * 100
y_ori <- round(coordinates(ori_t)[1, 2]/100) * 100
# Define how many cells for x and y axis
x_cell <- 250
y_cell <- 200
# Define the resolution to be 1000 meters
cell_size <- 1000
# Create the extent
ext <- extent(x_ori, x_ori + (x_cell * cell_size), y_ori, y_ori + (y_cell * cell_size))
Based on the extent I created, I can create a raster layer with number all equal to 0. Then I can use the mapview function again to see if the raster and the four stations matches well.
# Initialize a raster layer
ras <- raster(ext)
# Set the resolution to be
res(ras) <- c(cell_size, cell_size)
ras[] <- 0
# Project the raster
projection(ras) <- CRS("+init=epsg:3857")
# Create interactive map
mapview(station) + mapview(ras)
I repeated this process several times. Finally I decided that the number of cells is 250 and 200 for x- and y-direction, respectively.
5. Create spatial grid
Now I have created a raster layer with proper extent. I can first save this raster as a GeoTiff for future use.
# Save the raster layer
writeRaster(ras, filename = "ras.tif", format="GTiff")
Finally, to use the kriging functions from the package gstat, I need to convert the raster to SpatialPixels.
# Convert to spatial pixel
st_grid <- rasterToPoints(ras, spatial = TRUE)
gridded(st_grid) <- TRUE
st_grid <- as(st_grid, "SpatialPixels")
The st_grid is a SpatialPixels that can be used in kriging.
This is an iterative process to determine a suitable grid. Throughout the process, users can change the projection, origin, cell size, or cell number depends on the needs of their analysis.
#yzw and #Edzer bring up good points for creating a regular rectangular grid, but sometimes, there is the need to create an irregular grid over a defined polygon, usually for kriging.
This is a sparsely documented topic. One good answer can be found here. I expand on it with code below:
Consider the the built in meuse dataset. meuse.grid is an irregularly shaped grid. How do we make an grid like meuse.grid for our unique study area?
library(sp)
data(meuse.grid)
ggplot(data = meuse.grid) + geom_point(aes(x, y))
Imagine an irregularly shaped SpatialPolygon or SpatialPolygonsDataFrame, called spdf. You first build a regular rectangular grid over it, then subset the points in that regular grid by the irregularly-shaped polygon.
# First, make a rectangular grid over your `SpatialPolygonsDataFrame`
grd <- makegrid(spdf, n = 100)
colnames(grd) <- c("x", "y")
# Next, convert the grid to `SpatialPoints` and subset these points by the polygon.
grd_pts <- SpatialPoints(
coords = grd,
proj4string = CRS(proj4string(spdf))
)
# subset all points in `grd_pts` that fall within `spdf`
grd_pts_in <- grd_pts[spdf, ]
# Then, visualize your clipped grid which can be used for kriging
ggplot(as.data.frame(coordinates(grd_pts_in))) +
geom_point(aes(x, y))
If you have your study area as a polygon, imported as a SpatialPolygons, you could either use package raster to rasterize it, or use sp::spsample to sample it using sampling type regular.
If you don't have such a polygon, you can create points regularly spread over a rectangular long/lat area using expand.grid, using seq to generate a sequence of long and lat values.

polygon to raster with raster as cell size

I have a shapefile and a raster file which I want to merge. Normally I would Extract by mask the rasterfile to obtain delineation of the shapefile. But now the shapefile has sub-delineation inside which I want to keep. One way to do this is Polygon to raster where I choose the raster-file inside cell size. However when I do this the right uppper coordiante is off the chart with values of 10^4 for a WGS 1984 decimal degree georeference. The projection of the two files do not seem to make any difference.
ArcGis 10.1

get longitude and latitude in EPSG:32750

I have mapinfo file and spatial type is point. I want to know longitude and latitude but in this file not include field to specific describe to longitude and latitude.
the CRS is WGS 84/UTM zone 50s (EPSG:32750). I have to export the file (.tab) using ogr but the result is not like a longitude and latitude.
this is the result:
POINT (238339.99924633466 9640080.0006718487)
POINT (238540.00219973351 9640080.0006718487)
POINT (238559.99837215125 9640080.0006718487)
POINT (238580.0027904133 9640080.0006718487)
If I want to get the longitude & latitude from this file is posible?how can?
You will have to run those points through a conversion to get a "normal" (cartesian) latitude and longitude coordinates from them. OSGeo.org has several libraries available to convert these points and translate them to global latitude and longitude points. FreeGIS.org also has a list of tools that you can sort by language. I believe that "Geo" people prefer to use longitude, latitude when describing points.
POINT( longitude latitude )

Resources