cannot create a geopandas df - projection

I am trying to create a geopandas dataframe using the following code:
# designate coordinate system
crs = {'init':'espc:4326'}
# zip x and y coordinates into single feature
geometry = [Point(xy) for xy in zip(data2['longitude'], data2['latitude'])]
# create GeoPandas dataframe
geo_df = gpd.GeoDataFrame(data, crs = crs, geometry = geometry)
However I'm getting the following error:
Invalid projection: +init=espc:4326 +type=crs: (Internal Proj Error: proj_create: cannot expand +init=espc:4326 +type=crs)
I really don't have a clue of what is happening. Can anyone help me to understand what's going wrong here? This code was not written by me but appears to have worked in the past.

Related

How to resolve spherical geometry failures when joining spatial data

I have a shapefile (with several polygons) and a dataframe with coordinates. I want to assign each coordinate in a dataframe to a polygon in a shapefile. So to add a column in a data frame with a polygon name or id
Here is the link to the data
library(sf)
library(readr)
shape <- read_sf("data/Provinces_v1_2017.shp")
data<- read_csv("data/data.csv")
But when I try to join them, I always get the error
pts = st_as_sf(data, coords = c("dec_lon", "dec_lat"), crs= 4326)
st_join(pts, shape)
i tried over() functions, and other tricks like st_make_valid() but I always get this error:
Error in s2_geography_from_wkb(x, oriented = oriented, check = check) : Evaluation error: Found 30 features with invalid spherical geometry.
It is a recent issue (before my code worked), but now I am unable to use sf package to do this task, I always end up with this error. I updated the libraries to see whether it would help, but I could not make it work.
I would really appreciate your help on this matter
You have two options:
turn off the s2 processing via sf::sf_use_s2(FALSE) in your script; in theory the behaviour should revert to the one before release 1.0
repair the spherical geometry of your polygons object; this will depend on the actual nature of your errors.
I can't access your file & make certain, but this piece of code has helped me in the past:
yer_object$geometry <- yer_object$geometry %>%
s2::s2_rebuild() %>%
sf::st_as_sfc()
I find that this 'invalid spherical geometry' does keep on popping up. If the s2::s2_rebuild() solution above doesn't work, a solution which usually works for me involves projecting and simplifying (reducing the map resolution a little). If your application can work with less resolution try this.
library(tidyverse)
library(sf)
crs_N = 3995 #northern polar projection
# example of FAILING map - with bad spherical geometry.
m_RU <- rnaturalearthdata::countries50 %>%
st_as_sf() %>%
filter((admin %in% c("Russia") )) |>
st_as_s2()
In the example, I chose Russia because it crosses the dateline, which can be one of the challenges. I switch to an Arctic polar projection, and reduce the map to 10km resolution (5km is not enough in this case!).
# with 2 extra lines the problem is gone
m_RU <- rnaturalearthdata::countries50 %>%
st_as_sf() %>%
filter((admin %in% c("Russia") )) |>
st_transform(crs = crs_N) |>
st_simplify(dTolerance = 10000) |> # to get rid of duplicate vertex (reduce to 10km steps)
st_as_s2()

How to calculate the distance of a centroid to a polygon in a shape file? R

I have this, and I am trying to use gDistance to calculate the distance between each centroid and the city of Baghdad. I am trying to do it like this:
gDistance(districts_centroids, districts#data$ADM3NAME %in% c("Baghdad"), byid=TRUE)
Where district_centroids are Formal Class SpatialPoints, and the districts#data... is basically the city of Baghdad in the shp file.
I get an error saying the following:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘is.projected’ for signature ‘"logical"’
In addition: Warning message:
In RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance") :
Spatial object 1 is not projected; GEOS expects planar coordinates
I am completely new to R and I don't really know what's going on.
Any help would be appreciated
Thank you!
This is a great question. After taking a look at things, it was decided the best way to answer this question was using simple feature objects rather than spatial objects.
The map in question looks familiar. I used the IRQ_2_sf.rds map which is probably the same map used and shown above. There are other alternative ways to achieve the solution to this question. Jupyter Lab is the IDE used.
Using the Google API and the geocode function, the coordinates for Baghdad were retrieved.
baghdad <- geocode("Baghdad, Iraq", source = c("google") )
A tibble: 1 × 2
lon lat
<dbl> <dbl>
44.36607 33.31524
Then sf functions were used to create the sf column object.
baghdad.sfg <- st_point(c(lon, lat), dim = "XY")
baghdad.sfc <- st_sfc(baghdad.sfg, crs = 4326)
Then, using the sf map named iraq, the centroids were created.
Note: warning message - st_centroid does not give correct centroids for longitude/latitude data. For this answer, the centroids will be close
enough.
iraq.c <- st_centroid(iraq)
The distance from each centroid to Baghdad gets determined in kilometers.
head(dist <- data.frame(c(st_distance(iraq.c$geom[], baghdad.sfc)/1000)))
Units: [m]
[1] 28.63250 59.61553 215.43354 323.06418 259.14509 113.55356
And then create a date frame that includes the names, the centroid geometry and the distance values. Requires some cleaning and binding.
distance <- c(dist$c.st_distance.iraq.c.geom....baghdad.sfc..1000.)
x <- distance[]
d_Bdad_Km <- as.numeric(str_extract(x, "[0-9]*.[0-9]."))
iraq2 <- iraq[-c(5, 8,9,10,11,12,13)]
df_dist <- cbind(iraq2, d_Bdad_Km) # df as desired
And then the outputs gets plotted.
plot(iraq$geom)
plot(iraq.c$geom, add = TRUE, col = "red")
plot(baghdad.sfc, add = TRUE, pch = 19, col = "blue")
Please ask if there are any follow-up questions. The plot can be viewed at this link:

Failing to assign projection to sp object SpatialPointsDataFrame

I have a SpatialPointsDataFrame called johnny, created from a vanilla dataframe by assigning coordinates. These coordinates are in coordinate system EPSG 4326 (the standard GPS geographic coordinate system), but johnny does not know that. So ,I am trying to assign EPSG 4326 to johnny, essentially as in this earlier question data projection in R using package SP . I, too, am using sp. My ultimate goal is to project johnny to projected_johnny. However, I can't seem to assign the existing projection correctly first. Who sees my mistake?
library(sp)
x <- seq(80,90,by=1)
y <- seq(40,50,by=1)
value <- seq(10,20,by=1)
johnny <- data.frame(cbind(x,y,value))
coordinates(johnny) <- ~x+y
class(johnny)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
proj4string(johnny) <- CRS("+init=epsg:4326")
Error in if (is.na(get("has_proj_def.dat", envir = .RGDAL_CACHE))) { :
argument is of length zero
I have considered and rejected the following possible solutions after trying them out:
Adding library rdgal directly
using CRS("+proj=longlat +datum=WGS84") instead of CRS("+init=epsg:4326")
I am using R 3.6.0 and sp 1.3-1. The rgdal version loaded via sp is 1.5-15. Any ideas are welcome. This should be such a simple action...
I looked over your code and guessed what you are probably trying to accomplish. But the way you are going about things is more different than it needs to be. There is a simple way to accomplished this. By far, the easiest way to accomplish this is by using those tools found in the R, sf package. Know that the sf package is a newer package than the sp package. And the sf package provides easy to use tools for accomplishing these tasks.
The code below is somewhat different from your code. A two column matrix was used instead of your three column data frame.
The simple feature geometry points were created from the matrix. Then the simple feature column object was created from the geometry points. Then the plot was created.
Code:
# Create matrix
x <- seq(80,90,by=1)
y <- seq(40,50,by=1)
# value <- seq(10,20,by=1)
#johnny <- data.frame(cbind(x,y))
jm <- matrix(data = c(x,y), nrow = 11, ncol = 2)
# coordinates(johnny) <- ~x+y
# class(johnny)
# johnny
Create sf multipoint geometry:
jm.sfg <- st_multipoint(jm)
jm.sfg
Create sf column object:
jm.sfc <- st_sfc(jm.sfg, crs = 4326)
jm.sfc
Plot
plot(jm.sfc, axes = TRUE)
The plot can be viewed from link below.

Converting a data frame to a spatial object

I'm trying to publish a map on Shiny, but keep running into this issue.
Let's call the data.frame region. Here are the columns:
library(mapedit)
library(mapview)
library(shiny)
library(leaflet)
library(leaflet.extras)
region$address
region$city
region$state
region$zip
region$county
region$xcol (these are the longitude coordinates)
region$ycol (these are the latitude coordinates)
But when I run the mapview(region)#map it produces the following error:
Error:
oops! Arguments xcol and/or ycol are missing!
You probably expected turf_clean to be a spatial object.
However it is of class data.frame.
Either convert turf_clean to a spatial object or provide xcol and ycol.
I provided the x and y cols, but it's still not producing what I need.
The library sf and its st_as_sf() is a way to convert your data.frame to a spatial object. crs refers to the datum and projection, which I just guessed assuming your lat/long are relative to the WGS84 datum. I believe the projection is what maps.google.com uses - web mercator auxiliary sphere.
library(sf)
turf_clean <- st_as_sf(region, coords = c("xcol", "ycol"), crs = 4326)

How do I import an openstreetmaps shape file in R and extract lat/long centroids?

I am trying to import an openstreetmaps shape file in R using the rgdal package.
The shape file I downloaded has 5 components in it:
places.cpg
places.dbf
places.prj
places.shp
places.shx
The files can be accessed at the following location:
https://drive.google.com/open?id=0B1ITb_7lHh1EUFVfVWc4ekRfSnc
I have to do the following:
1) Import the shape file
2) Extract lat/long of the point or centroid of shape in case of polygon
3) Attach the lat/long pair to the dbf file to do some analysis
I am stuck in the first stage of import itself, I am running the following code:
shape1 <- readOGR(dsn = "try", layer = "places")
Here 'try' is the folder in my working directory where all the 5 'places' file from openstreetmaps mentioned above are located.
I get the following error when doing this:
Error in readOGR(dsn = "try", layer = "places") : no features found
In addition: Warning message:
In ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv =
use_iconv, : ogrInfo: all features NULL
I need help with this import. Alternatively if there is a way to directly extract lat/long from one of the places shape file, I can just open the places.dbf file in excel and add the lat/long.
When you are facing troubles with the readOGR() function: Another possibility is to use the maptools package. It creates SpatialXXXDataFrames so you can use all the functions from rgeosetc.
library(maptools)
setwd("/your/data/path/")
places <- readShapeSpatial("places")
# ... your geospatial functions, like
plot(places)
probably you will have to adjust the projection of the spatial data. For OSM-Data you will need to find the proj4string for WGS84 (or EPSG:4326) at spatialreference.org.
Thus you can adjust your projection in R:
proj4string(places) <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
For the calculation/"extraction" of polygon centroids see this post.
You need to use the shapefile (.shp) as the DSN. Turning the SpatialPointsDataFrame into a "normal" data.frame will give "ugh" column names
for lang & lat, so you can rename them to make them more usable:
library(sp)
library(rgdal)
places <- readOGR("places/places.shp", "places", verbose=FALSE, stringsAsFactors=FALSE)
places_df <- setNames(as.data.frame(places),
c("osm_id", "name", "type", "population", "longitude", "latitude"))
head(places_df)
## osm_id name type population longitude latitude
## 1 25431184 Stockertown village NA -75.26156 40.75446
## 2 25716549 Mechanicsburg village NA -77.00473 40.21020
## 3 25762119 Mansfield hamlet NA -77.07929 41.80569
## 4 25840249 New Columbia hamlet NA -76.87368 41.03368
## 5 25840585 Williamsport town 29381 -77.00277 41.24933
## 6 25930002 Hershey town 14257 -76.65060 40.28549
I couldn't get this package to work but the package "shapefiles" did the work for me. It has a read.shapefile function that imports shapefiles.

Resources