计算英国一个点和海岸之间的最小距离

时间:2014-12-09 16:54:03

标签: r gis spatial

我一直在关注显示here的示例,但是对于英国。出于这个原因,我使用EPSG的英国CRS:27700,它具有以下投影字符串:

"+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs"

但是,我不确定要遵循的wgs.84代码。目前我正在使用:

"+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"

也尝试使用datum = OSGB36和+ ellps = airy。

完整代码如下:

library(rgeos)
library(maptools)
library(rgdal)

epsg.27700 <- '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000    +ellps=airy +datum=OSGB36 +units=m +no_defs'
wgs.84    <- '+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0'

coast <- readShapeLines("ne_10m_coastline",CRS(wgs.84)) #have tried other shapefiles with the same issue
MAD   <- readWKT("POINT(-0.1830372 51.1197467)",p4s=CRS(wgs.84)) #Crawley, West Sussex
gDistance(MAD,coast)

[1] 0.28958
Warning messages:
1: In RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance") :
  Spatial object 1 is not projected; GEOS expects planar coordinates
2: In RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance") :
  Spatial object 2 is not projected; GEOS expects planar coordinates
3: In RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance") :
  spgeom1 and spgeom2 have different proj4 strings

尝试完成投影线时会显示错误。

coast.proj <- spTransform(coast,CRS(Epsg.27700))

non finite transformation detected:
 [1] 111.01051  19.68378       Inf       Inf
Error in .spTransform_Line(input[[i]], to_args = to_args, from_args = from_args,  : 
 failure in Lines 22 Line 1 points 1
In addition: Warning message:
In .spTransform_Line(input[[i]], to_args = to_args, from_args = from_args,  :
 671 projected point(s) not finite

我无法理解我在这里做错了什么。

1 个答案:

答案 0 :(得分:4)

AFAICT你没有做错任何事。错误消息告诉您全局海岸线shapefile中的某些坐标映射到Inf。我不确定为什么会发生这种情况,但通常期望特定区域的平面投影在全球范围内工作并不是一个好主意(尽管它确实在另一个问题中起作用......)。一种解决方法是将海岸线shapefile剪切到特定投影的边界框,然后转换剪切的shapefile。可以找到EPSG.27700的边界框here

# use bounding box for epsg.27700
# found here: http://spatialreference.org/ref/epsg/osgb-1936-british-national-grid/
bbx <- readWKT("POLYGON((-7.5600 49.9600, 1.7800 49.9600, 1.7800 60.8400, -7.5600 60.8400, -7.5600 49.9600))",
               p4s=CRS(wgs.84)) 
coast <- gIntersection(coast,bbx)  # just coastlines within bbx
# now transformation works
coast.proj   <- spTransform(coast,CRS(epsg.27700))
MAD.proj     <- spTransform(MAD,CRS(epsg.27700))
dist.27700   <- gDistance(MAD.proj,coast.proj)   # distance in sq.meters
dist.27700
# [1] 32153.23

距离最近的海岸线有32.2公里。我们还可以确定这里的位置

# identify the closest point
th     <- seq(0,2*pi,len=1000)
circle <- cbind(1.00001*dist.wgs84*cos(th)+MAD$x,1.00001*dist.wgs84*sin(th)+MAD$y)
sp.circle <- SpatialLines(list(Lines(list(Line(circle)),ID="1")),proj4string=CRS(wgs.84))
sp.pts <- gIntersection(sp.circle,coast)
sp.pts
# SpatialPoints:
#            x        y
# 1 -0.2019854 50.83079
# 1 -0.1997009 50.83064
# Coordinate Reference System (CRS) arguments: +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 

最后我们可以绘制结果。你应该总是这样做。

# plot the results: plot is in CRS(wgs.84)
plot(coast, asp=1)
plot(bbx,add=T)
plot(MAD,add=T, col="red", pch=20)
plot(sp.circle,add=T, col="blue", lty=2)
lines(c(MAD$x,sp.pts$x),c(MAD$y,sp.pts$y),col="red")