SASGIS

Веб-картография и навигация

Редактирование тайлов из кеша в berkeley?

Форум для обсуждения деталей разработки программы SAS.Планета

Модераторы: vdemidov, Tolik

Re: Редактирование тайлов из кеша в berkeley?

Сообщение zed » 29 ноя 2014, 23:01

db создаётся с флагами:
Код: Выделить всё
DB_CREATE or DB_AUTO_COMMIT or DB_THREAD

или, если только для чтения:
Код: Выделить всё
DB_RDONLY or DB_THREAD
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение zed » 29 ноя 2014, 23:04

И в FileName у нас передаётся относительный путь: z3/0/0/0.0.sdb
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение lLan » 29 ноя 2014, 23:37

Если открывать только на чтение:
Код: Выделить всё
my $db  = tie %hash, 'BerkeleyDB::Btree',
         -Filename => "/www/sasplanet/sat0/z3/0/0/0.0.sdb",
         -Env => $env,
         -Flags => DB_RDONLY or DB_THREAD
          or die "Could not read file '0.0.sdb': $!\n" ;
foreach $key (keys %hash) {
   print "$key => $hash{$key}\n";
}

Вывод получаю вот такой:
$ perl ./readBDB.pl
=>
untie attempted while 1 inner references still exist at ./readBDB.pl line 60.

То-есть есть одна пустая пара ключ - значение. (или я не правильно смотрю ключи?)
Если на запись открываю (DB_CREATE or DB_AUTO_COMMIT or DB_THREAD), вывод вообще пустой.
И в FileName у нас передаётся относительный путь: z3/0/0/0.0.sdb

Относительный путь передать не получается.
Дело в том, что у меня Home:
Код: Выделить всё
-Home => "/www/sasplanet/sat0/env"

(Если положить home в /www/sasplanet/sat0 то файлы __db.001 создаются там же, в корне)
А отностельные пути с точками (../z3/0/0/0.0.sdb) тоже не проходят. Путь ссылается в никуда.
Поэтому использую абсолютные пути.
lLan
Новичок
 
Сообщения: 8
Зарегистрирован: 29 ноя 2014, 15:36
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение lLan » 30 ноя 2014, 13:29

Нашел, как можно сделать более информативный вывод ошибок при открытии баз данных:
Код: Выделить всё
or die "Could not read file '0.0.sdb': $! $BerkeleyDB::Error\n" ;

Получаю ошибку при попытке открытия базы данных на запись
Код: Выделить всё
files containing multiple databases may only be opened read-only

То-есть файл содержит в себе несколько баз данных. Поясни, как он открывается в sasplanet? И что за несколько баз внутри одного файла?
lLan
Новичок
 
Сообщения: 8
Зарегистрирован: 29 ноя 2014, 15:36
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение zed » 30 ноя 2014, 13:42

У нас одна база, безымянная.

При открытии файла БД, если указать имя базы, можно создавать/открывать несколько баз в одном файле: http://docs.oracle.com/cd/E17076_04/htm ... ensub.html

Но есть важное замечание:
It is an error to attempt to open a second database in a file that was not initially created using a database name, that is, the file must initially be specified as capable of containing multiple databases for a second database to be created in it.

Это именно то, что и произошло - в SAS создана база без указания имени, значит файл БД не может содержать несколько баз и передавать имя базы при открытии sdb уже нельзя.

Как создаётся/открывается база можно посмотреть в исходниках SAS. А все возможные опции хорошо описаны в документации db->open
скрытый текст: показать
file

The file parameter is used as the name of an underlying file that will be used to back the database; see File naming for more information.

In-memory databases never intended to be preserved on disk may be created by setting the file parameter to NULL. Whether other threads of control can access this database is driven entirely by whether the database parameter is set to NULL.

When using a Unicode build on Windows (the default), the file argument will be interpreted as a UTF-8 string, which is equivalent to ASCII for Latin characters.

database

The database parameter is optional, and allows applications to have multiple databases in a single file. Although no database parameter needs to be specified, it is an error to attempt to open a second database in a file that was not initially created using a database name. Further, the database parameter is not supported by the Queue or Heap format. Finally, when opening multiple databases in the same physical file, it is important to consider locking and memory cache issues; see Opening multiple databases in a single file for more information.

If both the database and file parameters are NULL, the database is strictly temporary and cannot be opened by any other thread of control. Thus the database can only be accessed by sharing the single database handle that created it, in circumstances where doing so is safe.

If the database parameter is not set to NULL, the database can be opened by other threads of control and will be replicated to client sites in any replication group, regardless of whether the file parameter is set to NULL.
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение lLan » 30 ноя 2014, 15:25

Ура! Базу открыть получилось. После того, как я добавил выбор базы данных. -Subname => ""
Код вот такой:
Код: Выделить всё
#!/usr/bin/perl
use warnings;
use strict;
use BerkeleyDB;
my %hash;
my $key;
my $env = new BerkeleyDB::Env
         -ErrFile => "/www/sasplanet/sat0/err",
         -Home => "/www/sasplanet/sat0/env",
         -Flags => DB_CREATE or DB_RECOVER or DB_INIT_LOCK or DB_INIT_LOG or DB_INIT_MPOOL or DB_INIT_TXN or DB_REGISTER or DB_THREAD
         #-Config => { DB_DATA_DIR => "/www/sasplanet/sat0",
            #            DB_LOG_DIR  => "/www/sasplanet/sat0/env",
         #         }
                  or die "Could not create ENV: $! $BerkeleyDB::Error\n";
my $db  = tie %hash, 'BerkeleyDB::Btree',
         -Filename => "/www/sasplanet/sat0/z3/0/0/0.0.sdb",
         -Subname => "",
         -Env => $env,
         #-Flags => DB_RDONLY or DB_THREAD
         -Flags => DB_CREATE or DB_AUTO_COMMIT or DB_THREAD
          or die "Could not read file '0.0.sdb': $! $BerkeleyDB::Error\n" ;
open FILES, ">readbDb99.txt";
foreach $key (keys %hash) { 
   print FILES "$key\n";
}
close FILES;
untie %hash;

Однако, получаю ключи в неверной кодировке. Они выглядят вот так:
Код: Выделить всё
NUL NUL NUL NUL NUL NUL NUL NUL
NUL NUL NUL NUL NUL NUL NUL SOH
NUL NUL NUL NUL NUL NUL NUL STX
NUL NUL NUL NUL NUL NUL NUL ETX
NUL NUL NUL NUL NUL NUL NUL EOT
NUL NUL NUL NUL NUL NUL NUL ENO
NUL NUL NUL NUL NUL NUL NUL ACK
NUL NUL NUL NUL NUL NUL NUL BEL
NUL NUL NUL NUL NUL NUL NUL BS
NUL NUL NUL NUL NUL NUL NUL
NUL NUL NUL NUL NUL NUL NUL

NUL NUL NUL NUL NUL NUL NUL VT
NUL NUL NUL NUL NUL NUL NUL FF
NUL NUL NUL NUL NUL NUL NUL
NUL NUL NUL NUL NUL NUL NUL SO
NUL NUL NUL NUL NUL NUL NUL SI

Что это за кодировка? Где можно почитать про формат кеша SAS.Planet?
lLan
Новичок
 
Сообщения: 8
Зарегистрирован: 29 ноя 2014, 15:36
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение zed » 30 ноя 2014, 15:32

lLan писал(а):Где можно почитать про формат кеша SAS.Planet?

Улыбнуло. Обычно, с формата и начинают разбор, ведь он может оказаться слишком сложным.

Почитать можно в сорцах SAS-а: что и как пишется в key и в value

Можно посмотреть на скрипт на питоне, ссылку на который я уже давал: viewtopic.php?f=47&t=2432&start=0#p37448
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение lLan » 01 дек 2014, 22:06

Разобрался с форматом ключей базы данных. Выкладываю код, может кому пригодится:
Код: Выделить всё
sub GetTileFileName {
   my $aX = $_[0];
   my $aY = $_[1];
   my $aZ = $_[2];
   my $str = "z" . ($aZ+1) . "\\" . ($aX >> 10) . "\\" .  ($aY >> 10) . "\\" . ($aX >> 8) . "." . ($aY >> 8) . ".sdb";
   print ("$str\n");
}
sub PointToKey {
   my $PointX = $_[0];
   my $PointY = $_[1];
   my $VkeysX = 0;
   my $VkeysY = 0;
   foreach (0..31) {
      my $VSetX = 0;
      my $VSetY = 0;
      $VSetX = 1 if ((($PointX >> $_) & 1) == 1);
      $VSetY = 1 if ((($PointY >> $_) & 1) == 1);
      if ($_ <= 15) {
         if ($VSetX == 1) { $VkeysY = $VkeysY | (1 << ($_ * 2)); }
         if ($VSetY == 1) { $VkeysY = $VkeysY | (1 << ($_ * 2 + 1)); }
      } else {
         if ($VSetX == 1) { $VkeysX = $VkeysX | (1 << (($_ - 16) * 2)); }
         if ($VSetY == 1) { $VkeysX = $VkeysX | (1 << (($_ - 16) * 2 + 1)); }
      }
   }
   return ($VkeysX, $VkeysY);
}
sub KeyToPoint {
   my $AkeyX = $_[0];
   my $AkeyY = $_[1];
   my $PointX = 0;
   my $PointY = 0;
   ($PointX, $PointY) = ValueToPoint ($AkeyY,0,$PointX,$PointY);
   ($PointX, $PointY) = ValueToPoint ($AkeyX,32,$PointX,$PointY);
   return ($PointX, $PointY);
}
sub ValueToPoint {
   my $AValue = $_[0];
   my $AOffset = $_[1];
   my $APointX = $_[2];
   my $APointY = $_[3];
   
   my $VPointX = $APointX;
   my $VPointY = $APointY;
   foreach (0..31) {
      if ((($AValue >> $_) & 1) == 1) {
         if (($_ % 2) == 0) {
            $VPointX = $VPointX | (1 << int(($_ + $AOffset) / 2));
         } else {
            $VPointY = $VPointY | (1 << int(($_ + $AOffset - 1) / 2));
         }
      }
   }
   $APointX = $VPointX;
   $APointY = $VPointY;
   return ($APointX, $APointY);
}

Вопрос такой: ключ с координатами (-1 -1), подозреваю, что он служебный и в нём хранится информация о базе данных. Какая именно информация в нём хранится? Что в ней меняется в разных файлах базы данных?
lLan
Новичок
 
Сообщения: 8
Зарегистрирован: 29 ноя 2014, 15:36
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение zed » 01 дек 2014, 22:37

Да, это служебный ключ для хранения чего-нибудь полезного. На данный момент там хранится только EPSG код проекции тайлов.
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Редактирование тайлов из кеша в berkeley?

Сообщение lLan » 25 дек 2014, 19:27

Чтоб преобразовать координаты в формате широта/долгота в координаты Х/У Google-проекции тайла нужно вызвать функцию LonLat2TilePosFloat
А что нужно сделать чтоб также преобразовать координаты в проекцию Yandex?
Подскажите название функции. Не могу найти.
lLan
Новичок
 
Сообщения: 8
Зарегистрирован: 29 ноя 2014, 15:36
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Пред.След.

Вернуться в Раздел для разработчиков программы SAS.Планета

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

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