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

如何在R中读取.MAP文件扩展名?,r,geospatial,spatial,sf,rgdal,R,Geospatial,Spatial,Sf,Rgdal,有没有一种简单的方法可以读取R中扩展名为.MAP的文件?我尝试了以下几种选择,但没有成功 背景:出于某种奇怪的原因,巴西卫生规划政策中使用的空间区域化仅以这种格式提供。我想将其转换为geopackage,以便我们可以将其添加到包中 使用原始自定义函数 mp[1]“多段列表” #密谋 绘图(属性(mp)$maplim,type='n',asp=1,xlab=NA,ylab=NA) 标题(“地图”) lappy(mp,多边形,asp=T,col=3) 编辑:看起来这并不能在所有文件中正常工作,因此

有没有一种简单的方法可以读取R中扩展名为
.MAP
的文件?我尝试了以下几种选择,但没有成功

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

使用原始自定义函数
mp[1]“多段列表”
#密谋
绘图(属性(mp)$maplim,type='n',asp=1,xlab=NA,ylab=NA)
标题(“地图”)
lappy(mp,多边形,asp=T,col=3)

编辑:看起来这并不能在所有文件中正常工作,因此正确转换为sf需要更深入的研究

这里有一个关于复活的快速尝试。累积求和以获得多行字符串可能是不正确的,我使用
se_municip.MAP
进行了测试,它只有NAs作为每个环的结束行。如果它可能具有非连接的多环(multipolygon),那么这种方法将无法完全工作

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)

x问题是:使用带有尾随nul字节的
readChar
——更改为
readBin()
rawToChar()
无法接受的8位字符(在我的UTF-8系统上);某些文件中的多个碎片需要删除;还有其他一些。我将上面编辑的
read.map()
函数添加到maptools,但名称不同,没有导出。现在(使用maptoolsrev 370,从构建完成时开始):

库(maptools)

哦,嗨,夏天。谢谢这看起来很有希望。尽管如此,我们只需要
se_regsaud.MAP
文件。请随意将该zip文件中的数据以包的形式发布。啊,太酷了,我把我所做的放在这里:(它不适用于“se_regsaud.MAP”因此,上面的代码不正确,需要仔细查看罗杰,这真的很好。谢谢。有没有办法编辑函数传递和
编码
参数?这非常重要,我们可以正确检索
区域。name
属性。我已尝试替换
readBin()
带有
读线
但它不起作用。再次感谢您的响应。但是,当我运行
maptools:::.polylist2sp(oo..)
处理此文件时,我收到一条奇怪的错误消息
在.ringcentradèu 2d(xy)中出错:NA/NaN/Inf em chamada de funèèo externa(argumento 2)
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)

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)
library(maptools)
o <- maptools:::readMAP2polylist("se_regsaud.MAP")
oo <- maptools:::.makePolylistValid(o)
ooo <- maptools:::.polylist2SpP(oo, tol=.Machine$double.eps^(1/4))
rn <- row.names(ooo)
df <- data.frame(ID=rn, row.names=rn, stringsAsFactors=FALSE)
res <- SpatialPolygonsDataFrame(ooo, data=df)
library(sf)
res_sf <- st_as_sf(res)
res_sf
plot(st_geometry(res_sf))