如何在R中读取.MAP文件扩展名?

问题描述 投票:0回答:1

是否有一种简单的方法来读取R中.MAP扩展名的文件?我在下面尝试了一些选项,但没有成功。 Here is a .MAP file for a reproducible example

context:出于某种奇怪的原因,巴西的卫生计划政策中使用的空间区域划分仅以这种格式提供。我想将其转换为.MAP,因此我们可以将其添加到geopackage包中。

geobr

ps。 # none of these options work mp <- sf::st_read("./se_mapas_2013/se_regsaud.MAP") mp <- rgdal::readGDAL("./se_mapas_2013/se_regsaud.MAP") mp <- rgdal::readOGR("./se_mapas_2013/se_regsaud.MAP") mp <- raster::raster("./se_mapas_2013/se_regsaud.MAP") mp <- stars::read_stars("./se_mapas_2013/se_regsaud.MAP")

更新

我们已经发现there is a similar question on SO focused on Python, unfortunately unanswered使用了读取a publication文件的自定义函数。请参见下面的示例。但是,它返回一个.MAP对象。有没有简单的方法可以将其转换为"polylist"

原始自定义功能

simple feature

使用原始自定义功能

read.map = function(filename){
  zz=file(filename,"rb")
  #
  # header of .map
  #
  versao = readBin(zz,"integer",1,size=2)  # 100 = versao 1.00
  #Bounding Box
  Leste = readBin(zz,"numeric",1,size=4)
  Norte = readBin(zz,"numeric",1,size=4)
  Oeste = readBin(zz,"numeric",1,size=4)
  Sul   = readBin(zz,"numeric",1,size=4)

  geocodigo = ""
  nome = ""
  xleg = 0
  yleg = 0
  sede = FALSE
  poli = list()
  i = 0

  #
  # repeat of each object in file
  #
  repeat{  
    tipoobj = readBin(zz,"integer",1,size=1) # 0=Poligono, 1=PoligonoComSede, 2=Linha, 3=Ponto

    if (length(tipoobj) == 0) break
    i = i + 1

    Len = readBin(zz,"integer",1,size=1)  # length byte da string Pascal
    geocodigo[i] = readChar(zz,10)
    Len = readBin(zz,"integer",1,size=1)  # length byte da string Pascal
    nome[i] = substr(readChar(zz,25),1,Len)
    xleg[i] = readBin(zz,"numeric",1,size=4)
    yleg[i] = readBin(zz,"numeric",1,size=4)
    numpontos = readBin(zz,"integer",1,size=2)

    sede = sede || (tipoobj = 1)

    x=0
    y=0   
    for (j in 1:numpontos){
      x[j] = readBin(zz,"numeric",1,size=4)
      y[j] = readBin(zz,"numeric",1,size=4)
    }


    # separate polygons
    xInic = x[1]
    yInic = y[1]  
    for (j in 2:numpontos){
      if (x[j] == xInic & y[j] == yInic) {x[j]=NA; y[j] = NA}
    }

    poli[[i]] = c(x,y)
    dim(poli[[i]]) = c(numpontos,2)
  }

  class(poli) = "polylist"
  attr(poli,"region.id") = geocodigo
  attr(poli,"region.name") = nome
  attr(poli,"centroid") = list(x=xleg,y=yleg)
  attr(poli,"sede") = sede
  attr(poli,"maplim") = list(x=c(Oeste,Leste),y=c(Sul,Norte))

  close(zz)
  return(poli)
}

mp <- read.map("./se_mapas_2013/se_regsaud.MAP") class(mp) >[1] "polylist" # plot plot(attributes(mp)$maplim, type='n', asp=1, xlab=NA, ylab=NA) title('Map') lapply(mp, polygon, asp=T, col=3)

r geospatial spatial sf rgdal
1个回答
0
投票

编辑:看起来这通常不适用于所有文件,因此正确转换为sf需要更深入的了解。

这是复活的快速刺杀。我用enter image description here测试了累积总和以获得多个线串的方法可能是不正确的,并且每个环的结尾行仅包含NA。如果它可能具有未连接的多环(multipolygon),则此方法将无法完全起作用。

se_municip.MAP

有趣的是您遇到了被遗忘的遗产的正式版本!

(顺便说一句,我可以将数据集发布到包中吗?]

x <- read.map("se_municip.MAP") df <- setNames(as.data.frame(do.call(rbind, x)), c("x", "y")) df$region.name <- rep(attr(x, "region.name"), unlist(lapply(x, nrow))) ## in case there are multi-rings df$linestring_id <- cumsum(c(0, diff(is.na(df$x)))) df$polygon_id <- as.integer(factor(df$region.name)) df <- df[!is.na(df$x), ] sfx <- sfheaders::sf_polygon(df, x = "x", y = "y", linestring_id = "linestring_id", polygon_id = "polygon_id", keep = TRUE) #sf::st_crs(sfx) <- sf::st_crs(<whatever it is probably 4326>) plot(sf::st_geometry(sfx), reset = FALSE) maps::map(add = TRUE)

© www.soinside.com 2019 - 2024. All rights reserved.