Как остановить writeOGR от сокращения имен полей при использовании драйвера «ESRI Shapefile»


18

В настоящее время я использую следующий сценарий для добавления некоторых данных атрибутов из таблицы во множество отдельных шейп-файлов:

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")
}

В конце я получаю следующие предупреждения:

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

При просмотре таблицы атрибутов шейп-файлов после этого процесса имя поля было сокращено до «ENGL_», но я хочу, чтобы оно оставалось «ENGL_NAME». Есть ли способ отключить это сокращение?

Любая помощь высоко ценится.


Есть ли какие-либо из имен полей в шейп-файле> 10 символов? Похоже, ошибка в привязке R для меня.
география

1
Привет, я просто перезапустил скрипт, и теперь он не сокращен. Я не уверен, что изменилось, чтобы вызвать это, хотя ...
JPD

Ответы:


9

Вы не можете, это проблема с шейп-файлом. См. Http://gdal.org/drv_shapefile.html в разделе «Параметры создания».


так это не проблема writeOGR? Это действительно вопрос формата?
Томас

1
Верный. Длина имени столбца dbf ограничена. Другой формат, например sqlite /atialite, не усекает имена (в sqlite есть очень большие ограничения, но на много порядков больше 10).

3
Ну, есть разница между обычным сокращением имен столбцов при записи в dbf и тем, что там делает writeOGR! writeOGR наносит вред даже именам полей короче 10. Мои примеры: имя моего R-столбца "ora_nachweis_id" становится "or_nch_", в то время как writeSpatilaPolygon делает обычное сокращение -> "ora_nachwe". Даже моя переменная "LblColor" (8 символов!) Становится "LblColr".
Бернд В.

Есть ли похожие имена столбцов в структуре БД / данных? Я не мог воспроизвести с ogr2ogr и БД sqlite с этими именами. Если вы можете предоставить образец, я мог бы посмотреть дальше, или, возможно, R-привязки вызывают проблемы.

1
Ссылка не работает, но у меня есть шейп-файлы с именами полей, которые длиннее 10 символов; почему это возможно, если это проблема с шейп-файлом?
Мэтт

7

Ваше 'ENGL_NAME' вообще не должно быть сокращенным (менее 10 символов), но, похоже, writeOGR имеет свою собственную волю.

Вместо того

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

ты можешь попробовать

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

Поскольку writeSpatialShape, похоже, не имеет параметра для места назначения, я нашел этот обходной путь, переключая рабочий каталог назад и вперед.

Другая проблема заключается в том, что он не создает .prj-файл, но это небольшая проблема по сравнению с уничтоженными именами полей.

В ожидании времени, когда формат + * # -! (/ ESRI Shapefile окончательно сдох и заменен на ... хорошо?


Заменен геопакетом?
jsta

3

У меня были похожие проблемы с работой в RStudio. Согласно совету в различных комментариях и ответах выше, мое решение для выжженной земли:

  • в точке, где SpatialWhwhatDataFrame готов для записи в Shape, сделайте копию
  • names(copy@data) <- c('new', 'short', 'names', 'you', 'pickd', 'yrslf')
  • names(copy@data) <- strtrim(names(copy@data), 10) просто чтобы убедиться
  • writeOGR(copy, dsn, layer, driver = 'ESRI Shapefile') но пока не запускайте
  • сохраните сценарий, очистите рабочее пространство, включая скрытые объекты, перезапустите R, перезапустите весь сценарий.

writeOGR () использует base :: abbreviate - вот тест с копией строк 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"  

Вы можете видеть, что на самом деле он вызывает сокращения дважды (возможно, бессмысленно, я не могу понять, как вы вызвали бы этот цикл), и если хотя бы одно имя столбца> 10, то оно укорачивает любое имя столбца с> 7 символами. Я не могу понять, почему нужно очищать рабочее пространство и перезапускать, если writeOGR ранее выполнялся для того же объекта, но, возможно, это как-то связано с тем, что fld_names является именованным символьным вектором. Это могло бы работать лучше, если as.character () был обернут вокруг abbreviate ().


Эй спасибо Я не хотел терять свой файл PRJ, поэтому чтение этого ответа помогло. Я сделал ВСЕ свои имена полей 10 или менее символов до вызова writeOGR, и ни один не был сокращен до 7.
Нова

-1

Как уже упоминалось, шейп-файлы имеют ограничение на количество символов в имени поля 10 символов. writeOGR удовлетворяет этому требованию, изменяя заголовки полей с помощью некоторого алгоритма, который устанавливает приоритеты для символов, которые нужно удалить, когда имя поля превышает предел. Я не уверен, как это работает, но кажется, что он сокращает имена полей странным и непредсказуемым образом и может сократить имена полей таким образом, который уже удовлетворял требованию 10.

Вот моя работа вокруг. Использование strtrim () и установка длины символа в 10 приведет к усечению имен полей до 10 символов более предсказуемо, чем автоматизация writeOGR.

Одна из проблем, с которой вы можете столкнуться, заключается в том, что если у вас есть имена полей, которые идентичны для первых 10 символов, но у меня такая проблема возникает редко.

Я применяю это каждый раз, когда экспортирую шейп-файл, на всякий случай.

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")
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.