21 votos

Cómo evitar que writeOGR abrevie los nombres de los campos cuando se utiliza el controlador "ESRI Shapefile

Actualmente estoy usando el siguiente script para añadir algunos datos de atributos de una tabla a muchos shapefiles individuales:

library(rgdal)
specieslist <- read.csv("SpeciesList1.txt", header=F)
attdata <- read.table("TestAtt.csv", sep = ",", header=T)
for (n in 1:dim(specieslist)[1]) 
{
speciesname <- specieslist[n,1]
shp <- readOGR("Mesoamerica_modified_polygons", speciesname)
shp$ENGL_NAME<-attdata[n,2]
writeOGR(shp, "PolygonsV2", speciesname, driver="ESRI Shapefile")
}

Al final me aparecen las siguientes advertencias:

1: In writeOGR(shp, "PolygonsV2", speciesname, driver = "ESRI Shapefile") :
Field names abbreviated for ESRI Shapefile driver

Al ver la tabla de atributos de los shapefiles después de este proceso, el nombre del campo se ha acortado a 'ENGL_', pero quiero que siga siendo 'ENGL_NAME'. ¿Hay alguna forma de desactivar esta abreviación?

Se agradece cualquier ayuda.

10voto

No se puede, es un problema de shapefile. Véase http://gdal.org/drv_shapefile.html en "Opciones de creación

7voto

Gdalya Puntos 409

Tu 'ENGL_NAME' no debería ser abreviado en absoluto (menos de 10 caracteres), pero parece que writeOGR tiene su propia voluntad.

En lugar de

writeOGR(shp, "PolygonsV2", speciesname, driver="ESRI Shapefile")

puedes probar

library(maptools)
currdir <- getwd() #store your current working directory
setwd(paste(currdir,"PolygonsV2",sep="/")) #switch to your desired folder

writeSpatialShape(shp, speciesname) # write shapefile

setwd(currdir) #switch back to parent folder

Como writeSpatialShape parece no tener un parámetro para el destino, encontré esta solución cambiando el directorio de trabajo de un lado a otro.

El otro problema es que no produce un archivo .prj, pero eso es un problema menor, comparado con los nombres de los campos destruidos.

Esperando los tiempos en que el formato +*#-!(/ ESRI Shapefile esté finalmente muerto y sea reemplazado por ... ¿bien?

3voto

obrl_soil Puntos 53

He tenido problemas similares trabajando en RStudio. De acuerdo con los consejos de varios comentarios y respuestas anteriores, mi solución de tierra quemada es:

  • en el momento en que el SpatialWhateverDataFrame esté listo para ser escrito en Shape, haga una copia
  • names(copy@data) <- c('new', 'short', 'names', 'you', 'pickd', 'yrslf')
  • names(copy@data) <- strtrim(names(copy@data), 10) sólo para estar seguros
  • writeOGR(copy, dsn, layer, driver = 'ESRI Shapefile') pero no lo ejecutes todavía
  • guarde el script, borre el espacio de trabajo incluyendo los objetos ocultos, reinicie R, vuelva a ejecutar todo el script.

writeOGR() utiliza base::abreviar - aquí hay una prueba con una copia de las líneas 158-164:

fld_names <- c('short', 'longlonglong', 'middle_1')
if (any(nchar(fld_names) > 10)) {
    fld_names <- abbreviate(fld_names, minlength = 7)
    warning("Field names abbreviated for ESRI Shapefile driver")
    if (any(nchar(fld_names) > 10)) 
      fld_names <- abbreviate(fld_names, minlength = 5)
  }

> fld_names
       short longlonglong     middle_1 
     "short"    "lnglngl"    "middl_1" 
> names(fld_names)
[1] "short"        "longlonglong" "middle_1"  

Puedes ver que en realidad llama a abreviar dos veces (posiblemente sin sentido, no puedo entender cómo activarías ese sub-bucle), y si incluso un nombre de columna > 10 entonces acortará cualquier nombre de columna con > 7 caracteres. No puedo entender por qué uno tiene que borrar el espacio de trabajo y reiniciar si writeOGR se ha ejecutado en el mismo objeto antes, pero tal vez es algo que ver con fld_names siendo un vector de caracteres con nombre. Podría funcionar mejor si as.character() se envolviera alrededor de abbreviate().

0voto

sambler Puntos 211

Es posible abreviar a 10 caracteres sobrescribiendo el código original de writeOGR (ver https://rdrr.io/cran/rgdal/src/R/ogr_write.R ) en su propia función también llamada writeOGR (o utilizar un nuevo nombre de función). Quizás quieras añadir una nota en tu script para mencionar esto.

Reemplace en su función (busque "abb"):

fld_names <- abbreviate(fld_names, minlength=7) o fld_names <- abbreviate(fld_names, minlength=5) por fld_names <- abbreviate(fld_names, minlength=**10**)

-1voto

Jack Puntos 28

Como ya se ha mencionado, los shapefiles tienen un límite de caracteres para los nombres de campo de 10. writeOGR cumple este requisito cambiando los encabezados de los campos mediante algún algoritmo que prioriza qué caracteres eliminar cuando hay un nombre de campo que supera el límite. No estoy seguro de cómo funciona, pero parece que acorta los nombres de campo de forma extraña e impredecible, y puede acortar de esta forma nombres de campo que ya cumplían el requisito de los 10.

Esta es mi solución. Usando strtrim() y estableciendo la longitud de los caracteres a 10 se truncarán los nombres de los campos a 10 caracteres de forma más predecible que la automatización de writeOGR.

Un problema que podría tener es si tiene nombres de campo que son idénticos para los primeros 10 caracteres, pero rara vez tengo este problema.

Lo aplico cada vez que exporto un shapefile, por si acaso.

library(sp)
library(rgdal)

table <- data.frame(X_Coordinates = runif(10)*1000, 
                    Y_Coordinates = runif(10)*1000, 
                    LongFieldNameForData = runif(10))

p <- SpatialPointsDataFrame(SpatialPoints(table), data = table)

names(p) <- strtrim(names(points),10)

writeOGR(p, "OutputDirectory", "Points", "ESRI Shapefile")

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X