библиотека ogr/gdal для perl - split by column

Ответить
Анна
Завсегдатай
Сообщения: 386
Зарегистрирован: 07 фев 2004, 14:31
Статьи: 15
Проекты: 5
Репутация: 7
Откуда: Лозанна
Контактная информация:

библиотека ogr/gdal для perl - split by column

Сообщение Анна » 15 сен 2009, 17:19

добрый день всем!
три дня ломаю голову - переборовала все варинты, но безуспешно, может быть кто-то подскажет решение следующей задачи.
хочу сделать скрипт, который эдробит шейпфайл на отдельные шейпы по некоторому полю (аналог операции split by column например в arcview). Хотела написать именно через gdal :) но не получается :( из-за банальной вещи - не могу сделать список уникальных значения той колонки, по которой дробить.
Тот код, что ниже - работает, но! он дико неэффективный, т.к. перебирает последовательно все строки таблицы, а хотелось бы, чтобы цикл перебирал только уникальные значения, иначе уже для 10000 записей это удовольствие растягивается на минут 7.
Что делать?
Пробовала уже и просто подключать какую-то дополнительную библиотеку для работы с dbf - так там не работает sql запрос group by. вобщем, друзья, посоветуйте как получить уникальные значения для определенной колонки таблицы шейпфайла?

Код: Выделить всё

# information that we need:
$dsname = ".";          # name of the datasource (in this case a directory)
$lname = "cirsium";     # name of the layer
$field = "SPECIES";     # name of the field whose value we need
$lname2 = "test2";

$datasource = Geo::OGR::Open($dsname);
$layer1 = $datasource->Layer($lname);

$osr = new Geo::OSR::SpatialReference;
$osr->SetWellKnownGeogCS('WGS84');
$schema = Geo::OGR::Layer::Schema ($layer1);

$layer1->ResetReading(); 

$counter = Geo::OGR::Layer::GetFeatureCount($layer1);
print "$count\n";

for ($count = 0; $count <= $counter; $count++) {

   $feature = $layer1->GetFeature($count);
   $value = $feature->GetField($field);
   print "$value\n";
   
   $sql = "select * from cirsium where SPECIES = '$value'";
   $layer1 = $datasource->ExecuteSQL($sql);
   $datasource2 = Geo::OGR::Driver('ESRI Shapefile')->Create($dsname) or die;
   $layer2 = $datasource2->CreateLayer({ Name => $value, SRS => $osr, GeometryType => $layer1->GetLayerDefn->GeometryType, Schema =>$schema});
   #$layer1->ResetReading(); 
   while ($feature = $layer1->GetNextFeature()) {  
		$value = $feature->GetField($field);
		print "$value\n";
        $layer2->InsertFeature($feature);   
}
}

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9038
Зарегистрирован: 06 окт 2003, 20:20
Статьи: 231
Проекты: 12/6
Репутация: 713
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: библиотека ogr/gdal для perl - split by column

Сообщение Максим Дубинин » 15 сен 2009, 17:45

я бы все-таки внимательнее посмотрел на внешнюю библиотеку для работы с dbf, типа dbfpy (питон), построил бы индекс уникальных значений, а потом скормил его OGR. Явно это должно быть быстрее, чем 10 тыс sql запросов.
пристегивайтесь, турбулентность прямо по курсу

Konstantin Tokar
Активный участник
Сообщения: 178
Зарегистрирован: 16 июл 2008, 09:56
Репутация: 0
Откуда: Москва

Re: библиотека ogr/gdal для perl - split by column

Сообщение Konstantin Tokar » 15 сен 2009, 21:37

загрузить всё в postgres не быстрее ли будет?

Анна
Завсегдатай
Сообщения: 386
Зарегистрирован: 07 фев 2004, 14:31
Статьи: 15
Проекты: 5
Репутация: 7
Откуда: Лозанна
Контактная информация:

Re: библиотека ogr/gdal для perl - split by column

Сообщение Анна » 16 сен 2009, 11:46

спасибо за ответы!
to Konstantin Tokar: да, вот и думаю не перелить ли все в базу... пытаюсть соотнести временные затраты\последующее использование.

to sim: да смотрела! (( проблема в том, что можно подключить библиотеку для xls но тогда dbf надо еще и в xls конвертировать, мне кажется это не очень эффективно.
я уж думала, ну ладно - сделаю через доп. скрипт в R - но и там нету функции group by для dbf-ов. замкнутый круг какой-то.

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9038
Зарегистрирован: 06 окт 2003, 20:20
Статьи: 231
Проекты: 12/6
Репутация: 713
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: библиотека ogr/gdal для perl - split by column

Сообщение Максим Дубинин » 17 сен 2009, 03:20

Анна писал(а):я уж думала, ну ладно - сделаю через доп. скрипт в R - но и там нету функции group by для dbf-ов. замкнутый круг какой-то.
Сделать список уникальных значений в R по dbf-файлу? В два счета. В каком виде тебе нужен этот список в итоге? Просто текст?
пристегивайтесь, турбулентность прямо по курсу

Анна
Завсегдатай
Сообщения: 386
Зарегистрирован: 07 фев 2004, 14:31
Статьи: 15
Проекты: 5
Репутация: 7
Откуда: Лозанна
Контактная информация:

Re: библиотека ogr/gdal для perl - split by column

Сообщение Анна » 17 сен 2009, 15:38

Просто список без заголовка и нумерации, но суть в том что у меня все-таки было какое-то ишью со списком уникал значений из дбфа - толи обрезалось название файла после 8 цифр толи еще какая-то ерунда была.

[Сообщение с мобильного устройства] Изображение

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9038
Зарегистрирован: 06 окт 2003, 20:20
Статьи: 231
Проекты: 12/6
Репутация: 713
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: библиотека ogr/gdal для perl - split by column

Сообщение Максим Дубинин » 18 сен 2009, 03:51

как тебе такой вариант?

Код: Выделить всё

x <- c("one","two","three","four","one","three","six")
as.data.frame(table(x))[,1]
> as.data.frame(table(x))[,1]
[1] four one six three two
Levels: four one six three two
пристегивайтесь, турбулентность прямо по курсу

Анна
Завсегдатай
Сообщения: 386
Зарегистрирован: 07 фев 2004, 14:31
Статьи: 15
Проекты: 5
Репутация: 7
Откуда: Лозанна
Контактная информация:

Re: библиотека ogr/gdal для perl - split by column

Сообщение Анна » 21 сен 2009, 15:09

у меня ошибка вылезает
Error in vector("integer", length) : vector size cannot be NA
In addition: Warning messages:
1: In pd * (as.integer(cat) - 1L) : NAs produced by integer overflow
2: In pd * nl : NAs produced by integer overflow
вот мой код (файл в виде dbf приложила вложением

Код: Выделить всё

inputdir = "Y:\\work\\r\\"
outputdir = "Y:\\work\\r\\1\\"

trainingsets = list.files(path=inputdir, pattern="csv")

for (i in 1:length(trainingsets)) {

	afile = paste(inputdir,trainingsets[i],sep="")
	sheetname = substr(trainingsets[i],1,(nchar(trainingsets[i])-4))
	adata = read.csv(afile,header=F,skip=1)
	adata = as.data.frame(table(adata))[,5] # ошибка
        adata = table(adata$V5) # работает, но не утраивает т.к. нужна только первая колонка без заголовков
	write.table(adata,paste(outputdir,sheetname,".txt",sep=""),sep=",",row.names=FALSE)
	
}
и кстати да - с csv это работает, но нужно обращение к dbf напрямую. Библиотека RODBC не работает с именами файлов более 8 символов.
Вложения
froelichia.dbf
(345.77 КБ) 611 скачиваний

Ответить

Вернуться в «GDAL/OGR»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость