【问题标题】:Reverse geocoding speed反向地理编码速度
【发布时间】:2017-09-17 18:07:13
【问题描述】:

我正在使用 R 从数据框中提取纬度和经度,然后使用反向地理编码获取地址。

我这里有一些玩具数据:

latitude <- c(40.84935,40.76306,40.81423,40.63464,40.71054)
longitude <- c(-73.87119,-73.90235,-73.93443,-73.88090,-73.83765)
x = data.frame(latitude,longitude)

我编写了一个函数来进行实际的地理编码:

require(ggmap)
get_address <- function(df){
      long <- as.numeric(df$longitude)
      lat <- as.numeric(df$latitude)
      revgeocode(c(long,lat))
    }

然后申请:

apply(x,1,get_address)

使用system.time(),这大约需要一秒钟。但是,我计划对具有超过一百万个观察值的数据执行此操作。如果它需要一段时间才能运行,我不介意,但由于我对此相当陌生,我永远不知道长时间运行是否只是获取数据的不可避免的一部分,或者是由于糟糕的功能设计。有没有明显的方法可以显着加快此操作?

编辑:

我从评论者那里得知,我可以提出的免费请求数量(每天 2,500 个)将受到限制。我所有的数据都来自纽约,目的是将纬度/经度坐标与自治市镇名称相匹配。在我发现免费用户的每日限制之前,我计划使用经纬度坐标从 Google 获取地址,从该地址中提取邮政编码,然后将邮政编码与自治市镇匹配。有没有人有关于如何在不使用 Google Maps Geocoding API 的情况下执行此操作的建议?

【问题讨论】:

  • 你有一个更大的问题,你知道的。谷歌很早就会扼杀你。您是为额外的访问付费还是将被限制为免费金额?
  • 没有看到revgeodocde函数的代码,很难说什么。另一方面,您可以轻松地并行化 apply() 调用。
  • 哦,好吧我不知道。
  • 我认为你可以从@SymbolixAU 的回答中获得相当多的信息。对于该分辨率,多边形中的点在sf 中会非常好并且非常快。

标签: r apply ggmap


【解决方案1】:

您可以找到行政区的“空间”数据源,然后使用 sf 库执行几何运算以查找多边形中的点


设置数据

查找空间数据源。这是geojson格式的社区之一

library(sf)

sf <- sf::st_read("https://raw.githubusercontent.com/blackmad/neighborhoods/master/new-york-city-boroughs.geojson")

将您的坐标转换为sf 对象。我已经交换了你的 lat & lon 列顺序。

latitude <- c(40.84935,40.76306,40.81423,40.63464,40.71054)
longitude <- c(-73.87119,-73.90235,-73.93443,-73.88090,-73.83765)
x = data.frame(longitude, latitude)

sf_x <- sf::st_as_sf(x, coords = c("longitude", "latitude"))

要执行空间操作,坐标参考系需要在两个几何之间匹配

## set the cooridnate reference systesm to be the same
st_crs(sf_x) <- st_crs(sf)

使用st_within 查找每个点所在的多边形(邻域)

多边形中的点计算

res <- st_within(sf_x, sf)  ## return the indexes of sf that sf_x are within

这为您提供了每个点所在的多边形索引的稀疏矩阵

## view the results
sapply(res, function(x) as.character(sf$name[x]))
# [1] "Bronx"     "Queens"    "Manhattan" "Brooklyn"  "Queens" 

视觉

用情节确认

library(googleway)

x$neighbourhood <- sapply(res, function(x) as.character(sf$name[x]))

mapKey <- "map_api_key"

google_map(key = mapKey) %>%
  add_markers(data = x, info_window = "neighbourhood")


进一步阅读

【讨论】:

    【解决方案2】:

    据我所知,Google 的免费 API 限制为每天 2,500 个请求。 Nominatim 或者由 OSM 提供,但在 R 中没有任何 API。但是对于这么多的数据,我不会考虑使用 Web 服务。您有 ArcGIS 许可吗?

    也许你也可以通过避免这样的分配来聚合你的函数:

    require(ggmap)
    get_address <- function(df){
      revgeocode(c(as.numeric(df$longitude),as.numeric(df$latitude)))
    }
    

    【讨论】:

    • 我从未使用过 arcGIS,但我相信我可以通过我的大学访问该软件。
    • 我是否正确理解您的编辑,您只是想剪辑位于该特定行政区的点?
    • 就我的数据而言,大多数观测值都有经纬度坐标,但在许多情况下缺少自治市镇的名称。能够从这些坐标中同时获得社区名称和自治市镇名称会很好,但我会很高兴获得自治市镇。
    • 嗯。你从哪里得到关于 Nominatim 没有“R 中的 API”的信息? github.com/hrbrmstr/nominatim不知道自己在说什么的时候,请不要权威。
    • 我很抱歉造成混乱。我真正想说的是,nominatim 没有可以使用 ggmap 之类的包管理器下载的库。
    猜你喜欢
    • 2021-06-02
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多