如何可视化具有不确定性的方位角数据?


10

我正在尝试制作一个图,显示在每个点具有不同范围不确定性的方位角数据。这张来自1991年论文的老式人物捕捉了我旨在的“领结情节”构想:

摘自Hillhouse and Wells,1991年。“亚利桑那州,加利福尼亚州和内华达州的中新世下桃桃泉凝灰岩的磁性结构,流动方向和源区”

关于如何制作类似数字的任何建议?我是GIS领域的新手,但是我确实可以通过我的大学使用ArcGIS。我的Arc经验仅限于制作地质图,因此我不必做任何过于奇特的事情。

我在Arc和QGIS中浏览了符号系统选项,但没有看到我认为可以完成此工作的任何设置。注意,这不仅仅是旋转方位角的蝴蝶结形状的问题;每个“领结”的角度范围需要不同。

我将我的Python技能评为“高级中级”,而将我的R技能评为“低级中级”,因此如果有必要,我不反对与matplotlibmpl_toolkits.basemap或类似的库一起破解某些东西。但是我认为在走那条路之前,我会在这里征求建议,以防万一有一个我还没有听说过的GIS领域的简单解决方案。


每个“领结”的数据是什么?我假设纬度/经度/高程,但是弧线是什么?他们反映了这一点吗?
Simbamangu,2012年

是的,每个点都是纬度/经度,方位角(地质学上为“走向”),加上方位角的某些不确定性。例如,如果我的点的az = 110且不确定度为10度,则我想要一个“领结”,其100->120上与180度相距的等效范围之间的角度之间的角度为颜色180->200
侏罗纪

Answers:


10

这需要一种“场计算”,其中计算的值(基于纬度,经度,中心方位角,不确定性和距离)是领结形状而不是数字。由于从ArcView 3.x过渡到ArcGIS 8.x时,这种字段计算功能变得更加困难,并且从未完全恢复,因此,如今,我们使用Python,R或其他语言编写脚本:但是思考过程仍然是相同。

我将用工作R代码进行说明。蝴蝶结形状的核心是计算,因此我们将其封装为一个函数。函数实际上非常简单:要在弓的两端生成两个弧,需要以规则的间隔(方位角)找出一个序列。这需要具有根据起点(经纬度)和所经过的距离查找点的(经纬度)坐标的能力。这是通过子例程完成的goto,其中所有繁重的算术运算都会发生。其余的只是准备要应用的所有内容goto,然后应用它。

bowtie <- function(azimuth, delta, origin=c(0,0), radius=1, eps=1) {
  #
  # On entry:
  #   azimuth and delta are in degrees.
  #   azimuth is east of north; delta should be positive.
  #   origin is (lon, lat) in degrees.
  #   radius is in meters.
  #   eps is in degrees: it is the angular spacing between vertices.
  #
  # On exit:
  #   returns an n by 2 array of (lon, lat) coordinates describing a "bowtie" shape.
  #
  # NB: we work in radians throughout, making conversions from and to degrees at the
  #   entry and exit.
  #--------------------------------------------------------------------------------#
  if (eps <= 0) stop("eps must be positive")
  if (delta <= 0) stop ("delta must be positive")
  if (delta > 90) stop ("delta must be between 0 and 90")
  if (delta >= eps * 10^4) stop("eps is too small compared to delta")
  if (origin[2] > 90 || origin[2] < -90) stop("origin must be in lon-lat")
  a <- azimuth * pi/180; da <- delta * pi/180; de <- eps * pi/180 
  start <- origin * pi/180
  #
  # Precompute values for `goto`.
  #
  lon <- start[1]; lat <- start[2]
  lat.c <- cos(lat); lat.s <- sin(lat)
  radius.radians <- radius/6366710
  radius.c <- cos(radius.radians); radius.s <- sin(radius.radians) * lat.c
  #
  # Find the point at a distance of `radius` from the origin at a bearing of theta.
  # http://williams.best.vwh.net/avform.htm#Math
  #
  goto <- function(theta) {
    lat1 <- asin(lat1.s <- lat.s * radius.c + radius.s * cos(theta))
    dlon <- atan2(-sin(theta) * radius.s, radius.c - lat.s * lat1.s)
    lon1 <- lon - dlon + pi %% (2*pi) - pi
    c(lon1, lat1)
  }
  #
  # Compute the perimeter vertices.
  #
  n.vertices <- ceiling(2*da/de)
  bearings <- seq(from=a-da, to=a+da, length.out=n.vertices)
  t(cbind(start,
        sapply(bearings, goto),
          start,
        sapply(rev(bearings+pi), goto),
          start) * 180/pi)
}

该方法适用于您必须已经以某种形式保存其记录的表:每个记录都提供位置,方位角,不确定性(相对于每一侧的角度),以及(可选)指示要使记录变大的数量。领结。让我们通过在北半球分布1,000个领结来模拟这样的表格:

n <- 1000
input <- data.frame(cbind(
  id = 1:n, 
  lon = runif(n, -180, 180),
  lat = asin(runif(n)) * 180/pi,
  azimuth = runif(n, 0, 360),
  delta = 90 * rbeta(n, 20, 70),
  radius = 10^7/90 * rgamma(n, 10, scale=2/10)
  ))

此时,事情几乎和任何字段计算一样简单。这里是:

  shapes <- as.data.frame(do.call(rbind, 
         by(input, input$id, 
            function(d) cbind(d$id, bowtie(d$azimuth, d$delta, c(d$lon, d$lat), d$radius, 1)))))

(定时测试表明,R每秒可以产生大约25,000个顶点。默认情况下,每个方位角都有一个顶点,用户可以通过设置epsto来设置bowtie。)

您可以对结果R本身做一个简单的绘图作为检查:

colnames(shapes) <- c("id", "x", "y")
plot(shapes$x, shapes$y, type="n", xlab="Longitude", ylab="Latitude", main="Bowties")
temp <- by(shapes, shapes$id, function(d) lines(d$x, d$y, type="l", lwd=2, col=d$id))

在R中绘制

要创建用于导入到GIS的shapefile输出,请使用以下shapefiles软件包:

require(shapefiles)
write.shapefile(convert.to.shapefile(shapes, input, "id", 5), "f:/temp/bowties", arcgis=T)

现在您可以投影结果,等等。本示例使用北半球的立体投影,并且领结由不确定性的分位数着色。(如果您非常仔细地查看经度为180 / -180度,您会发现GIS夹住了跨越这条线的领结。这是GIS的常见缺陷;它并不反映R代码本身的错误。)

在ArcView中绘图

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.