【问题标题】:getKMLcoordinates returns a list of lists instead of a list of segmentsgetKMLcoordinates 返回列表列表而不是段列表
【发布时间】:2012-05-08 05:12:10
【问题描述】:

我曾经通过在 R 中绘制 kml 坐标,并在顶部覆盖物种丰度数据,制作了一张很酷的地图。第一次编写代码时,我使用以下代码调用我的坐标列表:
spa<-getKMLcoordinates('Perimeter_Track.kml', ignoreAltitude=TRUE)

summary(spa) 返回:

 Length Class  Mode   
[1,] 128 -none- numeric

[2,] 242 -none- numeric

[3,] 34 -none- numeric

[4,] 126 -none- numeric

(GPS 坐标是以 4 个块测量的周边轨道,因此每个列表都是这些块之一): 现在,当我再次运行代码时,summary(spa) 返回:

         Length Class  Mode
[1,] 2      -none- list
[2,] 2      -none- list
[3,] 2      -none- list
[4,] 2      -none- list

如果我使用 as.data.frame() 将 spa 转换为数据帧,当我尝试使用 rbind 将 4 个块连接成一个大轨道时仍然会出现此错误:

Error in match.names(clabs, names(xi)) : 
  names do not match previous names

R 似乎没有读取 kml 文件,或者只读取其中的一部分。

列表(或数据框)spa 是

  c..157.80736808..21.4323436..20.324951171875.
1                                    -157.80737
2                                      21.43234
3                                      20.32495
  c..157.80738216..21.43231443..19.36376953125.
1                                    -157.80738
2                                      21.43231
3                                      19.36377
  c..157.80533605..21.43536092..15.9990234375. c..157.8053208..21.43541138..15.9990234375.
1                                   -157.80534                                  -157.80532
2                                     21.43536                                    21.43541
3                                     15.99902                                    15.99902
  c..157.80998348..21.43706806..15.9990234375.
1                                   -157.80998
2                                     21.43707
3                                     15.99902
  c..157.80997007..21.43711106..17.441162109375.
1                                     -157.80997
2                                       21.43711
3                                       17.44116
  c..157.81074733..21.43717535..13.5958251953125.
1                                      -157.81075
2                                        21.43718
3                                        13.59583
  c..157.81071673..21.43718331..14.076416015625.
1                                     -157.81072
2                                       21.43718
3                                       14.07642

这是 maptools 或我的代码错误吗?据我所知,这是将 kml 坐标转换为 R 可以使用的坐标的最简单方法。非常感谢您的帮助。

文件链接在这里:https://www.dropbox.com/s/y8elanjnst6438v/Perimeter_Track.kml

【问题讨论】:

    标签: r gps kml


    【解决方案1】:

    修复已提交给 R-forge,maptools 项目,修订版 232。请在今晚欧洲时间之后试用:

    install.packages("maptools", repos="http://R-Forge.R-project.org")
    

    处理这个问题。但是,我不知道您为什么不使用:

    library(rgdal)
    ogrListLayers(dsn="Perimeter_Track.kml") # to find the layer name
    spa1 <- readOGR(dsn="Perimeter_Track.kml", layer="Perimeter_Track.kml")
    summary(spa1)
    

    这是一个 SpatialLinesData 框架,可以以多种方式使用,无需进一步努力。它还可以毫无困难地处理标签。要将您的输入输入到 ad-hoc maptools 函数返回的表单中,请执行以下操作:

    o0 <- coordinates(spa1)
    o1 <- lapply(o0, function(x) do.call("rbind", x))
    library(maptools) # SVN revision >= 232
    spa <- getKMLcoordinates('Perimeter_Track.kml', ignoreAltitude=TRUE)
    all.equal(o1, spa)
    

    【讨论】:

    • 我没有使用 rgdal,因为没有现成的 Mac OS X 二进制文件可用。无论如何,我一直在努力安装该软件包(请参阅我之前与 .kml 相关的呼救声:stackoverflow.com/questions/7907217/…
    【解决方案2】:

    您的示例文件包含getKMLcoordinates 函数(maptools 版本 0.8-14)不期望的制表符。

    如果您进行小的修改,它会按预期工作。我已将 cmets 放在我的添加位置:

    getKMLcoordinates_01 <- function (kmlfile, ignoreAltitude = FALSE) 
    {
        if (missing(kmlfile)) 
            stop("kmlfile is missing")
        kml <- paste(readLines(kmlfile, encoding = "UTF-8"), collapse = " ")
        re <- "<coordinates> *([^<]+?) *<\\/coordinates>"
    
        ## ++ new code
        ## remove tabs first
        kml <- gsub("\\t", "", kml)
        ##   
    
        mtchs <- gregexpr(re, kml)[[1]]
        coords <- list()
        for (i in 1:(length(mtchs))) {
    
            kmlCoords <- unlist(strsplit(gsub(re, "\\1", substr(kml, 
                mtchs[i], (mtchs[i] + attr(mtchs, "match.length")[i])), 
                perl = TRUE), split = " "))
            m <- t(as.matrix(sapply(kmlCoords, function(x) as.numeric(unlist(strsplit(x, 
                ","))), USE.NAMES = FALSE)))
            if (!ignoreAltitude && dim(m)[2] != 3) 
                message(paste("no altitude values for KML object", 
                    i))
            coords <- append(coords, ifelse(ignoreAltitude, list(m[, 
                1:2]), list(m)))
        }
        coords
    }
    
    spa <- getKMLcoordinates_01("Perimeter_Track.kml")
    summary(spa)
         Length Class  Mode   
    [1,] 192    -none- numeric
    [2,] 363    -none- numeric
    [3,]  51    -none- numeric
    [4,] 189    -none- numeric
    
    R 版本 2.15.0 已修补 (2012-05-05 r59321) 平台:x86_64-pc-mingw32/x64(64位) 语言环境: [1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252 LC_MONETARY=English_Australia.1252 LC_NUMERIC=C [5] LC_TIME=English_Australia.1252 附加的基础包: [1] stats graphics grDevices utils datasets compiler methods base 其他附加包: [1] rgdal_0.7-8 maptools_0.8-14 lattice_0.20-6 sp_0.9-98 foreign_0.8-49 通过命名空间加载(未附加): [1] 网格_2.15.0 工具_2.15.0

    【讨论】:

    • 我现在已将其附加到问题中。我希望它有所帮助。
    猜你喜欢
    • 2020-07-17
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    相关资源
    最近更新 更多