SASGIS

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


View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001282SAS.Планета[All Projects] Хотелкаpublic26-04-2012 10:0910-10-2012 12:43
ReporterPapazol 
Assigned ToGarl 
PrioritynormalSeverityminorReproducibilityhave not tried
StatusclosedResolutionfixed 
PlatformWindowsOSXPOS VersionProfessional SP3
Product Version.Nightly 
Target Version120808Fixed in Version120808 
Summary0001282: Экспорт в упакованный формат SAS4WinCE
DescriptionИмеет право быть!
Автор SAS4WinCE как-то давно даже предлагал дать исходники его упаковщика, но внимания на это никто не обратил. Сейчас путь получения упакованного кэша для SAS4WinCE - копировать нужные данные в отдельную папку, а уже из неё собирать кэш. Конечно же, это неудобно: приходится дублировать немалые объёмы информации. Работа с выделенной областью решила бы проблему.
TagsSAS4WinCE, экспорт
Attached Files? file icon SAS4WinCEv16.pas [^] (26,110 bytes) 02-05-2012 13:58
7z file icon SASPlanet.7z [^] (1,899,839 bytes) 02-05-2012 14:13
jpg file icon sas4wince.jpg [^] (72,018 bytes) 02-05-2012 14:38


? file icon SAS4WinCEv17.pas [^] (30,434 bytes) 02-05-2012 19:34
png file icon error.png [^] (97,342 bytes) 03-06-2012 04:32

- Relationships
related to 0001285closedGarl Небольшой глюк в отображении при экспорте в формат SAS4WinCE 
related to 0001301closedDima2000 Ошибка при экспорте в формат SAS4WinCE при нескольких файлах данных и наличии комментария (или названия карты) 
related to 0001322closedvdemidov Не работает экспорт в сжатый формат для SAS4WinCE/SAS4Android 
related to 0001324closedDima2000 Неправильный пакованный кэш после экспорта в формат SAS4WinCE/Sas4Android под Андроидом 

-  Notes
(0006481)
Garl (manager)
26-04-2012 17:45

согласен с тем что получение кэша для SAS4WinCE тот ещё гемор.
как будут исходники конвертера, можно будет и говорить :)
(0006482)
Papazol (reporter)
27-04-2012 08:36

При получении "добра" от наших программеров можно было бы постучаться к v_max за исходниками. Наоборот - как-то невежливо.
(0006483)
Dima2000 (developer)
27-04-2012 08:43

Я уже почти написал упаковщик в тот формат из куска кэша (как сейчас) и из TAR архива (архивов, их можно будет склеивать), который умеет создавать SAS. Дублирование данных это не исключает, но заметно удобнее. И не требует всяких гадостей типа .NET. :) Выложена программа будет на том форуме. Собственно осталось прикрутить лишь чтение TAR, GUI оболочку и обработку ошибок.

Формат хранения там простой, единственная сложность - таблицы по Z,X,Y сортированы, но при обходе области в нужном направлении это получается автоматом. Если заранее (до начала передачи тайлов) передать более-менее точное количество разных X и Y для каждого Z (можно немного завышенное), то создание упакованного кэша достаточно тривиально. У меня 90% программы занимаются "лишними" операциями: обход дерева папок, сортировка, подсчёт количества тайлов.
Если уважаемые разработчики встроят это дело в сам SAS, будет всем счастье. Готов им в этом помочь. Родные исходники были на C# (их у меня нет), я пишу на дельфи.
(0006484)
Dima2000 (developer)
27-04-2012 08:48

Кстати, при наличии TAR можно лишь создать для него индексный файл и смириться с потерей в результате 800 байтов на каждый тайл (накладные расходы TAR архива). Зато можно пользоваться сразу TAR архивом, не перепаковывая его в формат кэша SAS4WinCE, только создав по нему файл *.inx. Для TAR архивов до 2 Гигабайтов моя программа будет это поддерживать.
(0006485)
Garl (manager)
27-04-2012 09:13

так может внедрить таки экспорт внутрь планеты? будет удобнее однозначно.
исходники открыты, энтузиазм есть :)
(0006486)
Papazol (reporter)
27-04-2012 09:48

<можно пользоваться сразу TAR архивом, не перепаковывая его в формат кэша SAS4WinCE, только создав по нему файл *.inx>
Что здесь имеется в виду? Это относится к программе SAS4WinCE?

Надо определиться, что должно являться конечным результатом нашего экспорта.
На мой взгляд, должно быть так:
1. Выделяем область.
2. Указываем нужные карты/снимки/слои.
3. Указываем нужные масштабы.
4. Сливаем тайлы в упакованный кэш, индексируем.
5. Наслаждаемся.
В том смысле, что разные промежуточные результаты не нужны, иначе будет как сейчас есть.
Неплохо было бы ещё считать занимаемое место, причём перед упаковкой, ведь это всё нужно будет положить на флешку, а они не безграничны.
(0006487)
Dima2000 (developer)
27-04-2012 10:28

Я к сожалению не имею возможности встроить что-то сразу в SAS, потому пишу для себя упаковку из кэша SAS (или TAR архивов, что удобнее) в пакованный кэш SAS4WinCE. Авторский упаковщик не нравится требованием .NET и функциональностью. Если разработчики SAS встроят экспорт в саму SAS буду только рад и готов им в этом помочь.

Согласен с описанной последовательностью, именно так и должно быть. Выглядеть должно так же, как и экспорт в TAR, только в формат SAS4WinCE. Конечным значением экспорта должны являться два файла (на каждую карту): *.dat и *.inx. Индексирование производится разумеется сразу в процессе экспорта. Без всяких промежуточных результатов - но только если разработчики встроят в SAS, я встраивать не могу и не буду. Потому и оперирую или как сейчас, или с промежуточным TAR архивом.
Заранее подсчитать место достаточно трудно, это двойной проход по всем тайлам, т.е. двойное время экспорта, а учитывая тормознутость текущего итератора тайлов в SAS и его весьма и весьма приблизительность в оценке объёма заранее для выделений сложной формы - для себя считаю это неприемлимым.

Работа с TAR архивом относится разумеется только к SAS4WinCE. Она может работать с любым неупакованным бинарным форматом, надо лишь построить правильный индекс (*.inx).

Garl, можете потрясти разработчиков на предмет встраивания трёх-четырёх процедур в SAS в диалог экспорта? Насколько мне известно, такой экспорт не однажды хотелся на форуме, но разработчики всегда отказывались от его написания.
(0006488)
Garl (manager)
27-04-2012 10:55

ну экспорт в JNX же сделали.
Если делать по аналогии могу попробовать подвязаться. разработчиков можно сильно не отвлекать а самим писать процедуры, доступ к репозиторию же открыт.
(0006489)
Dima2000 (developer)
27-04-2012 11:11

Я готов написать все нужные процедуры для вывода тайлов в пакованный SAS4WinCE кэш, но вот встраивать их в SAS должен кто-то ещё. Как и согласовывать получаемые/передаваемые аргументы и порядок вызова. Извините, но мне просто некогда разбираться как устроена SAS внутри.
Собственно, процедурок минимум 4: начать экспорт; записать тайл; закончить экспорт; и возможно внешние функции выделения/освобождения памяти.
(0006490)
Garl (manager)
27-04-2012 11:16

та по идее всё уже придумано за нас.
можно подсматривать например вот сюда https://bitbucket.org/azya/sasplanet/src/de5304a25a05/Includes/JNXlib.pas
(0006491)
Dima2000 (developer)
27-04-2012 11:48

Ковырять проще уж TAR https://bitbucket.org/azya/sasplanet/src/de5304a25a05/Includes/LibTar.pas - оставить оттуда лишь создание пустого архива, запись тайла (с разбитием по 2ГБ), закрытие архива. Все фенечки TAR-а ликвидировать. И добавить формирование и запись индекса.
Проблема будет если на вход будут подаваться тайлы не строго сортированно по X,Y, придётся хранить весь индекс в памяти, а это 16 байтов на каждый тайл. Для примера, Москва занимает примерно 35К тайлов на z18, Московская область порядка 220К тайлов.
Ну хорошо, сделаю я unit, даже скомпилю при необходимости - как его SAS подсунуть? Кто это сделает? Для меня проблема именно в этом.
(0006492)
Dima2000 (developer)
27-04-2012 11:53

Собственно такой unit у меня практически готов, только зарыт в недра консольного приложения, в котором плюс ещё и обход дерева папок кэша SAS ... Готов оформить его отдельно, привести к стандарту как в этих двух (каком?) исходниках - и что дальше? Кому отдать для интегрирования в SAS? ;-)
(0006493)
Garl (manager)
27-04-2012 12:12
edited on: 27-04-2012 12:14

привести можно к любому. от него и будем плясать.
сюда прикрепляй, будем пробовать.
ещё бы найти свой CE-девайс, а то после продажи машины он гдето затерялся :)

(0006496)
Dima2000 (developer)
28-04-2012 12:32

Ну что же, приложил файл unit-а ExportCE.0v6.pas. Версия отладочная. В виде класса оформлять не стал, потом. Жду результата по встраиванию его в SAS.
Использовать просто: сначала вызвать TilesBegin (с именем файла), потом для каждого тайла TilesAdd, для завершения экспорта TilesEnd. При желании проверять на ошибки.
Не стоит использовать для десятка миллионов (и более) тайлов, внутренние операции выполнятся за полминуты, но дисковый доступ увеличит время работы до получаса и более! Для миллиона тайлов внутренние операции (без дисковых обращений) занимают пару секунд.
Памяти требуется 16МБ на каждый миллион тайлов! Ошибки выделения памяти и записи файлов не проверяются. Файл индекса занимает порядка 20МБ на миллион тайлов.
(0006499)
Garl (manager)
28-04-2012 17:50

30 как будет свободное время - поковыряюсь.
(0006500)
Papazol (reporter)
29-04-2012 09:14

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

А не проще ли использовать TAR архивы, делая для них индексные файлы? Раз программа их ест, смысла экономить на нескольких мегабайтах нет. Возможно ли индексировать уже созданный архив, или это делается только в процессе?
(0006501)
Dima2000 (developer)
29-04-2012 10:02

Возможно, очень даже, я именно так первоначально и собирался делать. Но размер архива (и пакованного кэша) будет ограничен 2ГБ - WinCE не поддерживает файлы больше 2ГБ, а SAS при экспорте в TAR не бьёт его на volume.
Ну что же, тогда в комплект к unit-у придётся таки писать отдельную прогу для чтения TAR архива и создания по нему индекса. Благо последнее уже реализовано и работает, осталось вынуть из TAR-а инфу о файлах и скормить unit-у. И не забыть переименовать *.tar в *.d00 (это тоже сделаю в самой проге, с подтверждением). ОК, сделаю, как будет желание ковыряться с таром. :)
Скорость обработки TAR-а будет зависеть лишь от скорости чтения файла архива (и скорости записи индексного файла), для миллиона тайлов (а больше и не влезет в 2ГБ) остальные операции займут пару секунд.
PS. Потери в TAR составляют в среднем 800 байтов на тайл, точно меньше килобайта.
(0006502)
Papazol (reporter)
30-04-2012 06:41

Да, задачи множатся. Без разбития архива на части будет плохо, ведь изначально не будет известно, какого размера получится архив, а он во многих случаях может превышать 2 ГБ. Вроде у TAR'а есть ключик, назначающий размер одного файла, но, помнится, когда-то я пытался его задействовать, однако не получилось, возможно, это на винде так.
А SASPack от v_max разбивает кэш на части по 1 ГБ.
(0006503)
zed (manager)
30-04-2012 08:46

>отдельную прогу для чтения TAR архива и создания по нему индекса
Индекс лучше делать во время создания архива внутри САС, тогда и разбить архив на части можно будет без труда.
С другой стороны, если будет экспорт в родной формат SAS4WinCE, то нафига заморачиваться с таром?
(0006504)
zed (manager)
30-04-2012 09:00

>В виде класса оформлять не стал, потом. Жду результата по встраиванию его в SAS.
А чё ждать, оформляйте в виде класса, со встраиванием проблем не будет.
И да, если не лень, добавьте коротенькую шапку с информацией о версией, авторстве и кратким описанием (к примеру, как здесь: https://bitbucket.org/azya/sasplanet/src/ca132b2405d7/Includes/JNXlib.pas ). И название юниту дать более говорящее - то что это будет экспорт, в общем-то и так понятно, а вот кто такой этот CE - загадка. Может быть сойдёт и просто SAS4WinCE.pas?
(0006505)
Garl (manager)
30-04-2012 10:22

я щас чуток начал ковырять не факт что хватит терпения и навыков грамотно перегнать в отдельный класс. но буду делать подглядывая на JNX

и ещё вопрос: структура кэша для CE и для Android одна и та же или они разные?
(0006506)
Papazol (reporter)
30-04-2012 10:27

Кэши у них одинаковые, что неупакованный, что упакованный.
(0006507)
Garl (manager)
30-04-2012 11:00

ну неупакованый == кэш сас, вопрос был про *.d00
(0006508)
Dima2000 (developer)
30-04-2012 11:37

С классом чуток мне доразобраться надо, не готов прям взять и переписать. Сделаю, ничего сложного.
Название unit-а пусть будет именно SAS4WinCE.pas, уже тоже об этом подумал. И классу TSAS4WinCE. Ок? Впрочем, это тоже меняется в исходнике за минуту.
Мне нужна информация о необходимом функционале класса, достаточно трёх функций или надо что-то ещё? Сейчас уже сделал 4-ю (TilesAbort) для прекращения экспорта без завершения создания индекса (к примеру если юзер нажмёт Cancel), немного расширил список параметров в функциях (с default значениями, т.е. необязательных) и добавил выдачу текущей статистики об обработанных тайлах. Надо что-то ещё? Форматы вызовов устраивают? Комментарии на русском нормально или переводить? Ну и вообще, оно работает в SAS-е или нет? И что делать с ошибками выделения памяти (по SetLength()), в обоих классах (и JNXlib и LibTar) эти ошибки вообще не проверяются, это нормально?

Пакованный кэш и для SAS4WinCE и для Android одинаковый.
Автор бьёт по гигабайту, да. Особого смысла в этом нет, файлы до 2ГБ (до 2^31-2 байтов) должны прекрасно работать. Проверю и если проблемы, то уменьшить константу размера дело 5 секунд.

Если делать именно экспорт из SAS, то создаваться будут сразу необходимые файлы *.d00 и *.inx, уже побитые по 2ГБ, т.е. полностью готовые для записи на SD карту.
Ограничение на 2ГБ относится лишь к уже готовому TAR, который надо БЕЗ ПЕРЕУПАКОВКИ превратить в *.d00 и *.inx. Файлы же более 2ГБ просто будут перепаковываться в кучу *.d00, но т.к. это заметно медленнее простого чтения TAR архива, то и хочу предусмотреть использование TAR менее 2ГБ без переупаковки. Замечу, тормоза переупаковки связаны на 95% с тормозами чтения и записи файлов, не с процессом упаковки.

Заморачиваться с TAR-ом я собирался пока не мог надеяться встроить экспорт в сам SAS. Если Вы встроите unit в SAS и в нём появится экспорт сразу в пакованный кэш для SAS4WinCE, то про TAR давайте забудем. Я его для себя потом сделаю в виде отдельной программы и выложу на 4pna рядом с авторским паковщиком.
Объясню почему иногда удобнее не экспорт, а TAR. Экспорт нельзя запустить для нескольких областей выделения, только для одной. А если мне хочется сохранить на SD карту 5 областей (москва в z18, мск область в z15, калуга в z19, владимир в z17, ...), то или делать экспортом 5 пакованных кэшей (что криво! и автор v_max против множества файлов кэшей), или экспортировать все области в промежуточную папку и потом паковать уже эту папку авторским паковщиком (который мне не нравится!), или экспортировать все области в 5 TAR архивов и потом их объединить моей прогой в один пакованный кэш. Последние два способа эквиваленты, но мой лучше тем, что не надо хранить сотни тысяч файлов (только 5 архивов эквивалентного объёма) и не требуется .NET для упаковки.
Но к SASPlanet это уже не относится.
(0006509)
Dima2000 (developer)
30-04-2012 12:13

Приложил последнюю версию (v8). Если ковырять, то лучше её. В конце файла есть история изменений. Пока не классом. Файл ExportCE.0v6.pas можно убить.
(0006510)
Garl (manager)
30-04-2012 12:16

принято
файл лучше обозвать SAS4WinCE.pas а внутри как писал zed в заголовке указывать текущую версию.
ну это не беда. тоже ковыряюсь над кодом.

в интерфейсе оставляем 2 поля название карты и копирайт, затем оба сращиваем и пишем в файл, так пойдёт?
(0006511)
Dima2000 (developer)
30-04-2012 12:51

Файл так и обозвать. Я добавил версию в имя файла лишь тут в момент выкладывания для отличий версий друг от друга, в релизе версия будет лишь внутри файла, конечно. Заголовок напишу, не вопрос.

Не понял зачем название карты? И какое, GUID или NameInCache? И зачем второе класть внутрь файла, если оно обычно явно присутствует в названии файлов? Да и название карты ведь может быть произвольным (я например все карты и папки кэшей у себя переименовываю для удобства). В принципе, GUID можно и добавить, может быть полезным. А можно и NameInCache добавить. :) Да, там где пишется копирайт, он обрамляется символами \r\n (чисто для удобства просмотра файла человеком в блокноте!), вот там и добавить строку про карты. И сделать строки c \0 в конце, для удобства.

Про копирайт спросил v_max не против ли он добавления чужого копирайта в файлы, надеюсь нет. В любом случае unit позволяет выбирать это при запуске экспорта.
(0006512)
Garl (manager)
30-04-2012 12:59

ок.
название и копирайт класть внутрь будем опционально.
но для этого в диалоге надо дать возможность их задать вручную :)
GUID Присутствует только в JNX как идентификатор карты, здесь от него можно и отказаться.

просто у JNX структура позамороченнее http://whiter.brinkster.net/JNX.shtml#coords
(0006513)
Dima2000 (developer)
30-04-2012 13:10

Копирайт нет, должен быт задан жестко в юните, причём const. Если надо, то можно перенести в интерфейс, но всё равно const. Кстати, я планировал его использовать как подпись файла с добавленной дополнительной инфой о тайлах - для обратной распаковки и для восстановления индекса по файлам данных.
В виде класса думаю надо будет возвращать какие-то параметры о классе, типа тот же копирайт, версию, дату компиляции, список возможных галок настроек (с названиями, подсказками и значениями по умолчанию), может ещё что-то.

Что JNX заморочен я в курсе.
(0006514)
Garl (manager)
30-04-2012 13:14

про копирайт ясно, но к нему же можно цеплять доп инфо в виде названия карты или не желательно?
так же туда действительно можно запихать коротко инфу о том какие зумы в файле и сколько тайлов запаковано.
(0006515)
Dima2000 (developer)
30-04-2012 13:15

Наверное удобнее будет получать в TilesBegin ещё строку (по умолчанию пустую) типа коммента, добавляемого сразу за копирайтом. И туда пихать всё что душе угодно в любом формате, от GUID до коммента юзера (добавить поле ввода в диалог). :)
(0006516)
zed (manager)
30-04-2012 13:15

>И что делать с ошибками выделения памяти
Бросать исключение.

>Форматы вызовов устраивают?
procedure TilesAdd(z,x,y:integer; ftile:string; fext:string='');
Лучше юзать TStream/TMemoryStream вместо string-а, и вместо процедуры сделать функцию и в случае неудачи добавления тайла отдавать Result := false; Хотя, можно и так оставить.

Если всё то хозяйство, спрятать в класс, то в идеале у вас должен остаться один метод Add. Всё остальное - глобальные переменные, константы, лишние процы, должно скрыться. TilesBegin будет выполняться в конструкторе класса, TilesEnd - в деструкторе. Тогда можно будет и одновременно запускать несколько процессов экспорта.
(0006517)
Dima2000 (developer)
30-04-2012 13:18

Нет, про зумы нельзя, они могут быть разные в файле, и не полностью, лишнее это. Сколько тайлов ... а нужно ли?
В общем, можно пихать что угодно, кол-во тайлов сообщается, зумы передаются снаружи и тоже известны в любой момент. Но в файлах данных нельзя возвращаться назад и переписывать поля, т.е. вся инфа должна быть известна заранее. Ну лишнее это, возвраты назад. А в .inx вообще нельзя писать поле произвольной длины кроме как в начале записи файла.
(0006518)
Garl (manager)
30-04-2012 13:20

имхо лучше дать возможность вводить произвольный коммент. или оставить поле пустым. ибо по названию файла не всегда понятно что внутри.
(0006519)
Dima2000 (developer)
30-04-2012 13:35

> Если всё то хозяйство, спрятать в класс, то в идеале у вас должен остаться один метод Add.
Да. И метод Cancel для отмены (закрытие открытого файла данных и освобождение памяти). То, что сейчас в TilesAbort.

>TilesBegin будет выполняться в конструкторе класса, TilesEnd - в деструкторе.
А время выполнения деструктора не критично? Ведь сортировка и запись файла индекса может занимать и минуты! В основном запись. (У меня 10М тайлов сортируется за 5с (линейно по количеству), а пишется 20МБ файл аж 10-15с. А если кто-то натравит на 100М тайлов?!) Я думал убрать TilesEnd в отдельный метод, типа .Finalize и пусть шуршит сколько надо. И память не освобождает, вдруг мы захотим пересохранить готовый индекс ещё куда-то. :) А уж после него деструктор с освобождением памяти за микросекунду. И разве деструктор может возвращать ошибки или результат?! А они могут быть (не смогли создать файл индекса). Так что отдельный метод .Finalize имхо нужен.

>вместо процедуры сделать функцию и в случае неудачи добавления тайла отдавать Result := false;
Как скажете.

>>И что делать с ошибками выделения памяти
> Бросать исключение.
Можно ткнуть носом в пример? По идее могу просто ошибку с кодом возвращать, а там уж разбирайтесь что за ошибка произошла... ;-) Но это опять писанины... Исключение думаю проще.

>лучше дать возможность вводить произвольный коммент.
Можно произвольный коммент от юзера (разумной длины, до килобайта к примеру) плюс за ним (или перед ним, как захотите) любую инфу. И всё одной строкой передать в конструктор.

В общем, сейчас набросаю интерфейс класса, будет более предметно.
(0006520)
zed (manager)
30-04-2012 13:58

>А время выполнения деструктора не критично?
Вообще - нет, но юзер может решить что что-то подвисло, если ему пару минут показывать окошко с прогрессом 100%.

>> Бросать исключение.
>Можно ткнуть носом в пример?
Пример того, как бросить исключение? Легко:
raise Exception.Create('Текст_ошибки');
http://www.delphisources.ru/pages/faq/faq_delphi_basics/Raise.php.html

>По идее могу просто ошибку с кодом возвращать, а там уж разбирайтесь что за ошибка произошла... ;-)
Это в процедурном программировании коды ошибок рулят, а в ООП - исключения. И раз уж вы пишете класс, то соблюдайте формат :)
(0006521)
zed (manager)
30-04-2012 14:25

Garl, а пункт Сжатие там зачем? SAS4WinCE вроде бы понимает не только jpeg.

И раз версия для Android имеет тот же формат кэша, то нужно это отразить и в названии экспорта: Cahe for SAS4WinCE/SAS4Android
(0006522)
Garl (manager)
30-04-2012 14:33

про поддержку png запамятовал, хотя для JPEG кэша этот параметр местами необходим.
название щас профикшу.
(0006523)
vasketsov (manager)
30-04-2012 15:02
edited on: 30-04-2012 15:12

>сортируется за 5с (линейно по количеству)
Алгоритм сортировки с линейной сложностью озвучить не сложно?

>raise Exception.Create
Только умоляю, делайте свои классы исключений, при отладке это ой как критично.

>разве деструктор может возвращать ошибки или результат
Нет, деструктор обязан всё смыть безо всяких исключений. Исключение из деструктора - это признак наличия ФГМ у автора такого подхода. Критически важные вещи, которые в принципе могут потребовать вмешательства пользователя или повторного запуска (например поосвободили память на компе, восстановили сеть или закрыли другую прогу, блокирующую операции с файлами), надо обязательно выносить из деструктора.

(0006524)
Dima2000 (developer)
30-04-2012 16:22

Garl, из имени файла нужно убрать расширение! В класс передавать только C:\11, расширения .d00 и .inx класс добавит сам. Потому что ChangeFileExt() может ошибочно принять имя с точкой за имя.расширение, что есть фи. Вот и не стал её применять внутри юнита.
Пункт Сжатие убрать совсем, он неприменим к данному экспорту, юнит не производит ни сжатия, ни пересжатия данных, даже наоборот, суммарный размер данных немного увеличивается за счёт служебных структр (как минимум файла индекса).
Из поля для комментария убрать текст, пусть будет пустое поле для ввода текста. Название поля "Comment" заменить на русское "Комментарий", этого достаточно.
Название экспорта лучше даже "Packed cache for SAS4WinCE/SAS4Android" - подчеркнуть, что кэш именно пакованный будет.

>Алгоритм сортировки с линейной сложностью озвучить не сложно?
Не сложно: http://ru.wikipedia.org/wiki/Цифровая_сортировка (по битам в int64). 56 проходов (эх, достаточно и 51-го) по 56-ти битам общего поля для z+x+y начиная с MSB. Применил именно из-за гарантированного O(n). Видно же в исходнике, по русски коммент написал. :) Писано заново, ни в Кнуте, ни в вики, ни ещё в паре книг простого исходника не нашёл. Да и просто для практики. :)

>Только умоляю, делайте свои классы исключений
Не проблема, только, извините, не понимаю деталей, не писал в терминах классов. Можно носом в пример? И что кидать если исключение не критичное, позволяет продолжать процесс, но сообщить об возникновении надо? Не модальное же окно показывать с кнопками ['Abort','Retry']?
Zed, за ссылку спасибо, поразмышляю.

>И раз уж вы пишете класс, то соблюдайте формат :)
Не вопрос, разумеется. Просто пишу в основном на асме, а там с ООП сложновато. :) Потому не очень уверенно с классами.

>>разве деструктор может возвращать ошибки или результат
>Нет,
Вот потому и нужен отдельный метод для создания файла индекса. Предлагаю .Finalize, вроде название по смыслу подходит. Или лучше таки .SaveINX? А деструктор лишь закроет файлы, освободит память и "смоет всё за собой". :)

Вопрос: деструктор будет вызван в любом случае (даже при генерации исключения в другом методе)? Или может быть ситуация (кроме аварийного снятия процесса SAS) когда деструктор не вызывается? Ведь надо закрыть файлы и освободить память.

>SAS4WinCE вроде бы понимает не только jpeg.
SAS4WinCE понимает много чего (jpg, png, gif, кажется bmp и может ещё что-то), и список этот от экспорта никак не зависит и не должен присутствовать ни явно, ни неявно в коде юнита. Экспорт идёт для файлов произвольного типа - от которого тоже никак не зависит, для экспорта тайл/файл всего лишь последовательность байтов некоей длины - потому и (опционально) передаётся строка расширения исходного файла с тайлом.
(0006525)
Dima2000 (developer)
30-04-2012 16:37

Так, вот что автор (v_max) говорит:
1. Копирайт паковщика добавлять в файлы можно.
2. Другую необходимую информацию при желании тоже можно.
3. Ограничение на 1ГБ связано не только с FAT32, но и с медленным Seek под WinCE (хотя для меня это странно!), потому предлагает добавить пользователю выбор максимального размера файлов данных с значениями 256МБ,512МБ,1024МБ,2048МБ и по умолчанию поставить 1ГБ. Соответственно в юните FDataMaxSize сделать не const и вычислять в момент создания класса по передаваемому параметру. (От себя добавлю, что неплохо бы слегка занизить значение, на пару мег, а то ведь туда будут писаться и строковые данные. Или сделать точный расчёт размера добавляемых данных.)
Ну и его слова: "Если наконец в планету упаковщик удастся встроить то это будет классно." - НАКОНЕЦ. :)
(0006526)
Dima2000 (developer)
30-04-2012 16:43

Да, пункт Сжатие неприменим потому что файлы любых типов пишутся в пакованный кэш в бинарном виде, без распаковки или перепаковки. Хоть jpg, хоть png, хоть exe. Как в архивы (тот же TAR).
(0006527)
Dima2000 (developer)
30-04-2012 16:47

Garl, а галка "Добавлять информацию для восстановления" (info:boolean в юните) считаете не нужна пользователю и писать инфу всегда? Меня убеждали что размеры надо экономить, а 15 байт/тайл для некоторых видов карт может быть заметно. Я бы добавил такую галку в интерфес пользователя с значением по умолчанию =true.
(0006528)
Garl (manager)
30-04-2012 16:50

ок не вопрос. щас прилепим
(0006529)
Dima2000 (developer)
30-04-2012 16:59

Простите, я опять не понял: если при ошибках генерить исключения, то зачем что-то возвращать методу .Add и .SaveINX? Ведь если без ошибок, то вернёт true, а если ошибки, то вылетит по исключению?
(0006530)
Dima2000 (developer)
30-04-2012 17:52

Э, на sas4wince2.jpg небольшая ошибка, не указано имя файла для записи, только путь. AssignFile вылетит по ошибке. В остальном всё нравится (переводом можно и потом заняться), уже облизываюсь на такую ночнушку. :)
(0006531)
Garl (manager)
30-04-2012 17:54

перевод сделается после того как забацаем коммит в исходники.
имя файла без расширения уже есть, скриншот только не сделал.
по умолчанию расширения в диалоге сохранения делаем же .d00 - правильно?
(0006532)
Dima2000 (developer)
30-04-2012 18:07

Нет, по умолчанию никакого расширения не нужно. Не по умолчанию тоже. Вообще никогда никакого расширения не показывать и не передавать.
А то могут быть проблемы если я захочу сохранить кэш в файл c:\1.yandex.d11.d00 - вот как тут понять, .d00 это расширение или имя файла, что в результате экспорта должно быть, yandex.d11.d00.d00 или yandex.d11.d00? И какое тогда будет имя индекса, yandex.d11.d00.inx или yandex.d11.inx? Уж лучше вообще всегда передавать без расширения, юнит сам подставит своё родное. Да и винда обычно не спрашивает про расширение текстовых файлов, а подставляет .txt, иногда даже без возможности сменить. Вот сделать так же.
(0006533)
Garl (manager)
30-04-2012 18:16
edited on: 30-04-2012 18:18

а вот тут давайте поразглагольствуем и на пальцах разберём:
имеем
c:\123.d00
c:\123.inx

я хочу переписать эти 2 файла. что мне нужно отображать в диалоге экспорта?
и что должно быть в поле имени файла при экспорте?

на мой взгляд *.d00 (это базовый файл) .d01 .d02 .. d99 - куски
аля как *.rar и .r01 .r02

так .rar же отображается в списке файлов и в диалогах как расширение...


на мой взгляд логичнее в диалоге отображать только *.d00 а в процедуру будем передавать это же имя без 4х последних символов..
вроде грамотно и просто для неопытных пользователей.

(0006534)
Dima2000 (developer)
30-04-2012 18:26

Согласен, .d00 базовый, можно отображать его.
А теперь вопрос: что будет передано в процедуру если юзер введет руками (а не выбором мышкой) имя файла 123.d01? А если 123.d00? А если 123.dbb? Почему во втором случае Вы предлагаете отрезать часть имени файла, а в первом и третьем не отрезать? И вообще, .d00, введенное руками в строку имени файла - часть имени или расширение? Для рара если ввести 123.dfg, то и архив станет именно 123.dfg, а не 123.dfg.rar.
Я бы предложил отображать файлы по маске *.d00, при выборе мышкой отрезать эти самые .d00, а вот при вводе имени нового файла передавать всё что введено, даже вместе с .d00 (к этому будет добавлено .d00 и .inx). Но разве диалог OpenFile в дельфи позволяет отследить это различие в вводе?
(0006535)
Garl (manager)
30-04-2012 18:31

поэтому из save-диалога мы обрезаем 4 байта и передаём их в форму экспорта, а если ввели имя прям в форму - не делаем ничего.

в общем диалог то можно отшлифовать в процессе отладки, там делов на 5 секунд. ждёмс класс.
(0006536)
Garl (manager)
30-04-2012 18:42

приложил exe чисто для теста интерфейса.
(0006537)
Papazol (reporter)
30-04-2012 18:56

Как видно из приложенного файла, можно выбрать для экспорта только одну карту. Это неправильно, надо чтоб хоть все можно было! Кэш ведь один должен быть на всё про всё.
(0006538)
Garl (manager)
30-04-2012 19:00

тоесть как в диалоге скопировать?

просто у меня отдельно это хозяйство лежит genshtab250m.d00+inx и genshtab500m.d00+inx
(0006539)
Dima2000 (developer)
30-04-2012 19:02

Класс я типа к завтра допилю, уже наполовину сделал (уже компилится, но не работает), вот только ошибки придётся впиливать заново, исключениями.

Интерфейс типа такой будет:
    TSAS4WinCE = class
    public
        constructor Create(fname:string; maxsize:integer=1000000000; cmt:string=''; info:boolean=true); //Начинает процесс экспорта тайлов в файл fname (без расширения!); maxsize - максимально допустимый размер файлов данных; cmt - однократно добавляемый в конец файлов комментарий; info - записывать ли в файлы данных дополнительную информацию об тайле (12-15+ байтов) и копирайт в файлы данных и файл индекса. Копирайт является также сигнатурой наличия дополнительной инфы в файлах данных!
        destructor Destroy(); override; //Закрывает открытые файлы и освобождает память
        procedure Add(z,x,y:integer; ftile:string; fext:string=''); //Добавляет тайл: z,x,y его координаты; ftile содержимое; fext расширение исходного файла с тайлом.
        procedure SaveINX(fname:string=''); //Завершить передачу тайлов, сформировать индекс, записать его в файл fname (без расширения!) (если не указан, то берётся имя файла данных).
        property TilesNum:integer read fTilesNum; //Общее количество принятых тайлов
        property DataNum:integer read fDataNum; //Количество задействованных файлов данных
        property DataLen:int64 read fDataLen; //Общий размер всех файлов данных
        property IndexLen:integer read fIndexLen; //Размер файла индекса (заполняется после завершения экспорта)
        property Comment:string read fComment; //Добавляемый к файлам комментарий
        property WriteTileInfo:boolean read fWriteTileInfo; //Записывать ли в файлы данных дополнительную информацию об тайле (12-15+ байтов) и копирайт в файлы данных и файл индекса
        property MaxFileSize:integer read fMaxSize; //Максимально допустимый размер файлов данных
    end;
(0006540)
Dima2000 (developer)
30-04-2012 19:03

Papazol, нет, пакованный кэш один (или больше) на каждую карту, несколько карт объединять в один пакованный кэш нельзя. Так что тут в диалоге всё верно.
(0006541)
Papazol (reporter)
30-04-2012 19:04

Кстати, и "Название карты" - здесь термин неправильный, так как там может быть не одна карта, а и слои, и снимки разные. Может, надо "Название кэша"?
(0006542)
Papazol (reporter)
30-04-2012 19:08

<пакованный кэш один (или больше) на каждую карту, несколько карт объединять в один пакованный кэш нельзя>

А у v_max в упаковщике можно ставить галки на каждой карте, и все они будут упакованы. Тут надо точно разобраться, будет ли программа работать с несколькими разными упакованными кэшами.
(0006543)
Garl (manager)
30-04-2012 19:08

кстати "название карты" - получается опциональное поле ибо его только внутри файла можно увидеть, и больше нигде оно не фигурирует.
(0006544)
Garl (manager)
30-04-2012 19:09

>в упаковщике можно ставить галки на каждой карте

и все они запакуются в отдельные файлы.
(0006545)
Papazol (reporter)
30-04-2012 19:14
edited on: 30-04-2012 19:17

В таком случае вопрос снимается. Точнее, оба вопроса. Это очень хорошо.

Хотя получается сродни закачке нескольких областей/зумов. Если бы можно было отметить сразу всё нужное, а программа в порядке живой очереди, так сказать, их того...

(0006546)
Papazol (reporter)
30-04-2012 19:23

А названия файлов нужно юзеру указывать, или оно будет даваться по умолчанию? Я бы предпочёл, чтобы оно соответствовало названию NameInCache.
(0006547)
Garl (manager)
30-04-2012 19:27

к сожалению долго и глубоко ковырять названия NameInCache, к тому же юзер может сам задавать их, как в форме, так и в диалоге.

представим: выбрали имя файла а затем передумали и выбрали другой источник карт, получится что программа должна сама поменять данные, которые юзер ввёл вручную - что есть не айс.
(0006548)
Papazol (reporter)
30-04-2012 19:41

Поскольку мы берём данные как раз из папки NameInCache, то это имя нам должно быть заранее известно. Если, конечно, юзер должен указать не только папку, в которую будет положен результат, а и название файлов, то при изменении источника могут быть какие-то несоответствия. А в случае назначения имён программой юзер должен указать только папку назначения. После того, как он нажмёт "Начать", уже ничего не изменить.
А вообще, можно ли переименовывать файлы упакованного кэша?
(0006549)
Garl (manager)
30-04-2012 19:43

можно переименовывать, и поправить в конфиге
там строяка аля
sat=Satellite (Google maps),SphericMercator,6378137,6378137,.jpg

sat - это как имя папки с родным кэшем Планеты, так и sat.d00
(0006550)
Dima2000 (developer)
30-04-2012 19:45

Я бы тоже предпочёл сразу NameInCache иметь в качестве имени файлов. При нажатии кнопки вызова диалога, подставить FileName:=ExtractFileName(строка ввода Куда сохранять);. А при выборе/смене карты заменить в этой строке имя файла на NameInCache. И плевать на то что пользователь туда ввёл раньше, введёт ещё раз.

И ещё. SAS4WinCE сильно привязана к именам пакованных кэшей (там по ним выбираются параметры карт, в том числе расширение файлов и проекция!!), потому менять имена не комильфо. Пусть будут точно по NameInCache, меньше будет путаницы. Тогда можно диалог вообще сделать не выбором файла, а выбором лишь папки! И не будет заморочек с расширениями.

>А вообще, можно ли переименовывать файлы упакованного кэша?
Можно. Но придётся также поменять имя в конфиге SAS4WinCE, иначе она его или не увидит вообще, или не сможет использовать (проекция неизвестна!).
(0006552)
Garl (manager)
30-04-2012 19:48

кстати наверно так и сделаем: выбирать будем только папку, а в класс будет передаваться путь + NameInCache из карты. тогда ничего мельтешить не будет при выборе карты.
(0006553)
Dima2000 (developer)
30-04-2012 19:49

И если не давать вводить имя файла, а разрешать лишь указывать папку куда класть результат, то можно и несколько карт/слоёв выбирать, создадутся правильно все. Передать имя Path+NameInCache одной строкой в юнит не проблема явно.
Только не запускайте экспорт одновременно всех карт! По очереди. А то память не резиновая. Это к Garl, не плодить объекты, а создали, экспортировали, убили, повторили для остальных карт.
(0006555)
Garl (manager)
30-04-2012 20:01

сначала проверим и обкатаем на одной, а затем главное чтоб энтузиазм не угас и руки не опустились :)
(0006556)
Dima2000 (developer)
30-04-2012 20:25

Что-то я не догоняю как в классе в секции interface объявить protected объект типа, который не должен быть виден наружу - т.е. тип нельзя объявлять в интерфейсе, но и сослаться в объявлении класса на тип из implementation нельзя. И что делать? Ткните носом плиз, а?
(0006557)
vdemidov (manager)
30-04-2012 20:27

Объявляй тип в прайвет части класса и всего делов.
(0006558)
Dima2000 (developer)
30-04-2012 20:33

Так?
type TSAS = class
     protected
         type mytype = int64;
         AA:mytype;
     public
     end;
Не компилит. Напишите как именно или скажите где глянуть пример? Ведь наверняка так делали уже.
(0006560)
vasketsov (manager)
30-04-2012 22:07

>деструктор будет вызван в любом случае?
Разумеется нет. Это называется утечка памяти или ресурсов.

>Или может быть ситуация (кроме аварийного снятия процесса SAS) когда деструктор не вызывается?
Легко, опять же к разговорам об утечках:
AObject := TObject.Create;
AObject := TObject.Create;
FreeAndNil(AObject);
FreeAndNil(AObject);
И к слову, при "аварийном снятии процесса" деструктор не вызовется (чтобы он вызвался, надо такой финт исполнить, что тут не тема для описания этого).

>Ведь надо закрыть файлы и освободить память.
Это надо делать в деструкторе.
Соответственно необходимо обеспечить либо убийство интерфейса, либо блок try .. finally .. end, чтобы деструктор вызвался.

>объект типа, который не должен быть виден наружу
Нафига такие сложности?

>скажите где глянуть пример?
Очевидно F1.

>Ведь если без ошибок, то вернёт true
Ну пусть возвращает что-то более полезное типа размера или числа тайлов.
Кроме того, считается ли корректной процедура экспорта, если не экспортировалось ни одного тайла?
(0006561)
Dima2000 (developer)
30-04-2012 22:32

>Нафига такие сложности?
Ну вот хочется чтобы тип данных использовался лишь в данном юните, почему нет?

>Очевидно F1.
Спасибо, догадался, уже замучал help, нету там такого примера.
Пока сделаю как все, с объявлениями типов в interface.

>Кроме того, считается ли корректной процедура экспорта, если не экспортировалось ни одного тайла?
О, спасибо, эту ситуацию не проверял. Формально да, корректно, можно получить файл данных лишь с копирайтом и комментом, файл индекса с таблицами нулевой длины и также копирайтом и комментом. Но смысла в этом мало. Собственно сейчас примерно так и будет: файл данных не создастся, а файл индекса будет с пустой таблицей 96 байтов плюс копирайт плюс коммент. Как к этому отнесётся SAS4WinCE не проверял. Добавлю ошибку для этого случая.
Что-то полезное можно узнать из property класса, там много всякого - и всё read only, "чтобы чего не напортили!"(с). :)
(0006562)
Dima2000 (developer)
01-05-2012 03:14
edited on: 01-05-2012 03:24

Вот Вам для тестов почти готовый класс. У меня с тестовой прогой вроде бы работает. Посмотрите и скажите что не так и что переделать?
Посплю и разберусь с TMemoryStream.
Ну конечно же забыл .SaveINX сделать функцией... У себя уже поправил.
Про свой класс ошибок тоже помню, сделаю.

(0006563)
zed (manager)
01-05-2012 04:49
edited on: 01-05-2012 04:54

Пример приватного объявления типа и констант:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TMyClass = class
  private
    const CPrivateConst = 'Hello World!';
    type
      TPrivateRec = record
        I: Integer;
      end;
  private
    FPrivateVar: TMyClass.TPrivateRec;
    procedure WriteVar(V: TMyClass.TPrivateRec);
  public
    constructor Create;
  end;

{ TMyClass }

constructor TMyClass.Create;
begin
  inherited Create;
  WriteLn('My private const: ' + TMyClass.CPrivateConst);
  FPrivateVar.I := 150;
  WriteVar(FPrivateVar);
end;

procedure TMyClass.WriteVar(V: TMyClass.TPrivateRec);
begin
  WriteLn('My private var: ' + IntToStr(V.I) );
end;


var
  VClass: TMyClass;
begin
  try
    VClass := TMyClass.Create;
    VClass.Free;
    Readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

(0006564)
zed (manager)
01-05-2012 05:04

>Вопрос: деструктор будет вызван в любом случае (даже при генерации исключения в другом методе)? Или может быть ситуация (кроме аварийного снятия процесса SAS) когда деструктор не вызывается? Ведь надо закрыть файлы и освободить память.

В вашем случае деструктор будет вызван в любом случае. Т.е. код вызова будет таким:

VSAS4WinCE := TSAS4WinCE.Create(...);
try
  VSAS4WinCE.Add(...);
  ...
finally
  VSAS4WinCE.Free;
end;

Если деструктор не вызывается при возникновении исключений внутри класса, то это ошибка программиста и её нужно фиксить.
(0006565)
vasketsov (manager)
01-05-2012 07:07
edited on: 01-05-2012 07:09

В порядке занудства:
1. Всё что не меняется в процедрах и функциях - объявляем как const.
2. Save recovery information если инфа сохраняется отдельно, или Add если вместе с данными.
3. Почему GB с пробелами, а MB без?
4. Надеюсь просто размер в байтах можно вбить?
5. Если "Название карты" сделать как Checkbox и обновлять при смене карты если он выключен (по умолчанию), и делать доступным текстовое поле только если checkbox включен - наверное будет вполне доступно для понимания среднестатистическим юзером, что название карты берётся из саса по умолчанию, но в принципе можно и руками поправить.

>Москва занимает примерно 35К тайлов на z18, Московская область порядка 220К тайлов
Странный пример. Вся МО на WinCE для "вот щас возьму и пойду погуляю по всей области" - это идефикс.
Из более реального. Все сервисы подробных снимков вдоль дорог Москва-Пермь (с подробными снимками на зумах 14+16+18 + собственно космоснимки 14 + 15 + все выше 12 + 10 + 8 для всех возможных маршрутов по ширине на каждом зуме на экран ноута + пара тайлов за экраном) занимают полторы карты памяти 32ГБ SDHC в сумме (причём файлами по 1-2 гига, а не мелкой россыпью). Вот на подобные размеры и количества тайлов по порядку величины и стоит ориентироваться, а не на "детские" сотню тыщ тайлов. Для своих любимых маршрутов типа Мурманск-Сочи каждый сам может оценить в зависимости от количества используемых сервисов и наличия снимков. Думаю что нижний предел для всех снимков в сумме - где-то 1 Гиг на 1000 км.

(0006566)
Garl (manager)
01-05-2012 07:18

Размер думаю таки в МегаБайтах будет, а вбивать точно нужно? в принципе можно разрешить.
(0006567)
Garl (manager)
01-05-2012 07:56

блин мну срочно вывозят на природу. класс скомпилился без проблем.

есть вылеты на jpgс размером тайла=0 байт

создание индекса запускаетя вручную? а то у меня создаётся пока только .d00

буду вечером.
(0006568)
Dima2000 (developer)
01-05-2012 09:13

Zed, спасибо, оказывается я всё делал правильно. Наверное дело в дельфи, она у меня 5-я. Потому что Ваш код не компилит (ровно как и мой), говорит ошибку 'END' expected but 'TYPE' found на строку со вторым type. Извините за ламерство.

За занудство спасибо, сам такой, одобряю.

>1. Всё что не меняется в процедрах и функциях - объявляем как const.
Разумеется, так и есть. Куча пропертей объявлена read only - для доступа снаружи к внутренним переменным класса, для контроля, статистики и прочего. Они все совсем не const в самом классе, просто снаружи менять произвольно не дам.

>2. Save recovery information если инфа сохраняется отдельно, или Add если вместе с данными.
Вместе с данными тайла, в процессе экспорта тайлов, прямо перед тайлом, в файлы .d??.
И этот же бит разрешает добавление копирайта (который в свою очередь будет использоваться как сигнатура наличия инфы о тайлах в файле). С сброшенным битом и пустым комментом файлы должны быть похожи на создаваемые родным упаковщиком (от v_max). Индекс я формирую немного по другому, но там всё на прямых указателях, так что работать будет.
Коммент сохраняется вне зависимости от этого бита, если не пуст - добавляется. Для получения "родных" файлов (как от упаковщика v_max) надо передавать коммент пустым.

>4. Надеюсь просто размер в байтах можно вбить?
По желанию, конструктор проверяет переданный размер на интервал 1КБ..2ГБ и выдаёт исключение если не попадает в диапазон. Допустимы отрицательные числа и не передача параметра вообще - тогда возьмётся значение по умолчанию (1ГБ).
Коммент принимает размером до половины ограничения (512Б..1ГБ). Будет беда если тайл вместе с комментом не влезает в ограничение - будут создаваться всё новые и новые файлы данных, дойдёт до .d99 и вылетит по исключению.
Увеличил нижний предел с 1КБ до 1МБ.

>5. Если "Название карты" сделать как Checkbox
Вроде понятно, одобрям-с, сделайте, потестим.

>создание индекса запускаетя вручную?
Простите, но посмотрите же начало исходника, там описано как вызывать. Да, вручную, методом .SaveINX.
Конструктор не создаёт никаких файлов, только иницализация внутренних переменных.
Каждый вызов .Add пишет тайл в файл данных (создавая его), с разбивкой по volume. Файл данных остаётся открытым! Индекс не создаётся.
Для создания индекса вызвать .SaveINX();. Файлы закрываются, память не освобождается.
Деструктор лишь закрывает открытые файлы и отдаёт память. Всё не сохранённое погибает в недрах сборщика мусора. :)

>есть вылеты на jpgс размером тайла=0 байт
Так и должно быть, нулевые тайлы вызывают исключение. Раз уж говорите не надо возвращать коды ошибок, а генерить исключения. В тексте исключения ведь написал его причину: if l=0 then raise Exception.Create('Size of tile is 0.'); //Тайлы нулевой длины не принимаем
Расчитываю что обработкой ошибок займётся вызывающая программа, некоторые исключения не смертельны для продолжения процесса, можно игнорить или копить статистику или показывать вопрос юзеру, по выбору вызывающей программы. Список таких исключений добавлю в описание.

>Размер думаю таки в МегаБайтах будет, а вбивать точно нужно?
Я бы оставил как на картинке, только с пробелом перед МБ. Вбивать точный размер не знаю для чего может пригодиться, ведь файл данных невозможно добить точно до указанного размера, там оставляется запас размером от 300 байтов до максимального размера тайла (если текущий переданный тайл не влезает, то начинается новый файл данных, даже если следующий тайл мог бы и влезть). Т.е. все файлы данных должны быть не больше указанного размера, реально они всегда будут на десяток КБ (ну или один-два КБ если тайлы мелкие) меньше.
(0006569)
Dima2000 (developer)
01-05-2012 09:17

>Будет беда если тайл вместе с комментом не влезает в ограничение
Извините, ошибся, беды не будет, сразу вылетит по исключению raise Exception.Create('Size of tile is too big.'); //Тайлы длиннее предела не принимаем
Во внутреннем пределе размера длина коммента уже учтена.
(0006570)
vasketsov (manager)
01-05-2012 09:37

>дело в дельфи, она у меня 5-я
Так точно. Она не умеет.

>Разумеется, так и есть
Я про квалификатор const перед именем переменной в процедуре.
Сравни:
function MyFunc(const A: String): Boolean;
и
function MyFunc(A: String): Boolean;

>нулевые тайлы вызывают исключение
Почему?

>некоторые исключения не смертельны для продолжения процесса
Исключение прерывает процесс, и в этом его смысл. Если надо просто информацию для юзера выдать - это надо делать лог сообщений.
(0006571)
Dima2000 (developer)
01-05-2012 10:43
edited on: 01-05-2012 10:47

>Я про квалификатор const перед именем переменной в процедуре.
Понял, добавляю.

>>нулевые тайлы вызывают исключение
>Почему?
А нет смысла их добавлять к файлу данных, только место под служебную инфу и индекс занимать. И не уверен как программа v_max отнесётся к файлу нулевой длины. По идее это не исключение, а warning, можно смело игнорить и экспортировать следующий тайл.

>Исключение прерывает процесс, и в этом его смысл. Если надо просто информацию для юзера выдать - это надо делать лог сообщений.
Вообще-то согласен. Так как сделать?
Что делать если встречается не критичная ситуация? Сейчас генерится исключение.
Можно просто возвращать false (но тогда непонятна причина отклонения тайла).
Можно дополнительно к false куда-то в проперти сохранить код ошибки (от чего меня ранее отговаривали).
Вы уж давайте решите, а я сделаю.

Снова приложил юнит, уже 13-й версии. Поглядите что ещё осталось не так?

(0006572)
vasketsov (manager)
01-05-2012 11:12

>нет смысла их добавлять к файлу данных
Ну тогда вернуть false и всё. Соответственно true - добавилось, false - не добавилось и хрен бы с ним, ну а если raise Exception - то }|{опа.

>непонятна причина отклонения тайла
А какие вообще могут быть причины?

>дополнительно к false куда-то в проперти сохранить код ошибки
Ну в общем такое тоже имеет право на существование. Аналог - GetLastError (правда оно НЕ потокобезопасно).
Важно только понимать, зачем этот "GetLastError" нужен и как будет использоваться. Потому что может быть достаточно просто статистику копить, типа число таких "ошибок", число сяких "ошибок".

А можно сделать типа как function MyFunc(...; out AErrorCode: Integer): Boolean или function MyFunc(...): TSomeEnum, а тип TSomeEnum = (seOK, seFail1, seFail2,...) - то есть возвращать результат.
Ещё есть такой подход: тип результата Int, а в случае недобавления устанавливается старший бит. Соответственно добавилось или нет - проверка простая, (Result >= 0), а сопутствующая информация (в том числе и для успеха) - это остальные биты.

Ещё как вариант - вернуть (в 4-х байтах как обычный Int)
TMyResult = packed record
Added: Boolean; // признак добавления
Reserved: Boolean; // для выравнивания
Reason: Word; // полезная нагрузка
end;

В общем методов чуть меньше миллиона.
(0006573)
zed (manager)
01-05-2012 11:22

>Вы уж давайте решите, а я сделаю.
Смело вызывайте исключения, когда что-то у вас там внутри идёт не по плану и не так как надо.

>5. Говорят надо свой класс ошибок сделать. Как и зачем?
Объявляете свой класс, как наследник от базового класса:
  type
    ESAS4WinCEException = class(Exception);

и используете:
  raise ESAS4WinCEException.Create(...)

Зачем это нужно? Ну, как минимум - это правило хорошего тона (раз уж вы в своём классе генерируете исключения вручную). Ещё к примеру, под отладчиком, или в дебажной версии, можно отключить вывод исключений определённого типа.

Но это всё мелочи, и я думаю уже сейчас всё должно работать и экспортироваться как надо. Придёт Garl, соберёт всё до кучи, и думаю завтра уже будем тестировать это в ночнушке.
(0006574)
Dima2000 (developer)
01-05-2012 11:23

Добавил свой класс исключений, vasketsov, Вы его хотели, тогда к Вам и вопрос: достаточно для отладки такого объявления или надо что-то ещё предусмотреть? ESAS4WinCE = class(Exception);

>>непонятна причина отклонения тайла
>А какие вообще могут быть причины?
Неверные координаты (z,x,y), нулевая длина, слишком большой (для заданного ограничения размеров) файл, переполнение ста файлов данных, ect. Посмотрите в начале исходника приведён список исключений.

Если уж делать возврат ошибок, то лучше возвращать boolean, а в проперти .Errors:integer; биты ошибок (или 0 при true). Это безопасно.
Можно и маску ошибок для генерации исключений сделать в проперти, тогда можно будет снаружи выбирать какие некритические исключения пропускать (с выставлением бита в .Errors), а какие генерить.
(0006575)
zed (manager)
01-05-2012 11:24

>В общем методов чуть меньше миллиона.
Ага, но по-моему тут с этим вообще не стоит заморачиваться.
(0006576)
Dima2000 (developer)
01-05-2012 11:26

Упс, уже сделал как надо. :) Имя класса исключений критично? Поменять 10 секунд.

>правило хорошего тона
Да, конечно будем делать "как надо", по правильному. Мы ж не лохи.
(0006577)
zed (manager)
01-05-2012 11:31

>Имя класса исключений критично?
Нет конечно. Что вы, в самом деле :)

И ещё: все эти исключения, ошибки, это ведь только для отладки приложения. Пользователю оно ж всё равно никаким боком не поможет. Единственное, что он сможет сообщить, что у него, вот при таких-то обстоятельствах вот так-то ругалось - почините. Т.е. единственная цель - локализация ошибки, и думаю, у вас там уже более чем достаточно по этому поводу сделано.
(0006578)
Dima2000 (developer)
01-05-2012 11:39

>все эти исключения, ошибки, это ведь только для отладки приложения.
Спорный момент. В отдельных модулях я привык проверять как можно больше разных ошибок и передавать их обработку на уровень выше. Кто вызвал, тот пусть и решает что делать с ошибками: продолжать, пользователя спросить, закрыть прогу или ещё какая заморочка. А модуль должен быть поуниверсальнее. :) Имхо.
(0006579)
vasketsov (manager)
01-05-2012 11:40

>под отладчиком, или в дебажной версии, можно отключить вывод исключений определённого типа
ТАК ТОЧНО!

Кроме того, можно сделать конструктор у исключения и совать туда нужные параметры. И снаружи отлавливать по классу. Тут вряд ли актуально, так что основное - конечно отладка.

>ESAS4WinCE = class(Exception);
Обычно исходя из того, что жизненный цикл программ относительно длительный и они претерпевают изменения, наиболее предпочтительным будет для больших библиотек следующий подход:
1. Объявляется базовый класс своих исключений типа ESAS4WinCEBaseError = class(Exception). Больше это не модифицируется никогда, нигде и никем. Это позволяет в любом остальном месте понять, откуда пришла ошибка. Этакий публичный контракт на исключения из библиотеки.
2. Все остальные исключения наследуются от базового типа, например ESAS4WinCEEmptyTileError = class(ESAS4WinCEBaseError) или ESAS4WinCECannotMakeIndexError = class(ESAS4WinCEBaseError), при необходимости они имеют свои конструкторы, поля и свойства, как обычные классы.

Но тут маленькая простая ситуация, так что может и одного класса хватит.
(0006580)
Dima2000 (developer)
01-05-2012 14:29

Приложил v15.
Разделил ошибки на критичные (с генерацией исключений) и warning (с возвратом false без исключений - можно смело игнорить и продолжать процесс). Сделал исключения потомками базового класса исключений.
С нетерпением жду отзывов о работе... :)
(0006581)
Garl (manager)
01-05-2012 20:09

со стрингами было куда подсматривать, а с TMemoryStream что то не выходит аленький цветочек.
около строки 163 чую что истина где то рядом..
(0006582)
vasketsov (manager)
01-05-2012 20:13
edited on: 01-05-2012 20:22

>было куда подсматривать
а тут TMemoryStream.Memory в виде HexDump в Watches. Или PChar(TMemoryStream.Memory). На самом деле, если разрешить галочкой вызов функций в Watches - можно в любой момент выполнить даже TStream.SaveToFile('c:\mystreamdebug.txt')

>около строки 163
А #0 тоже должен упасть в файл?

(0006583)
Dima2000 (developer)
01-05-2012 21:24
edited on: 01-05-2012 21:25

В чём проблема? я проверяю например так:
var s:sting;
begin
t:=TSAS4WinCE.Create(ParamStr(2),-1,'Comment!');
tile:=TMemoryStream.Create;
for i=1 to N do begin
    s:='dksfjkdsfkdshfjkdshfjdshfjdshgf';
    tile.Clear;
    tile.Write(s[1],length(s));
    t.Add(z,x,y,tile,'jpeg')
end;
t.SaveINX();
t.Destroy;
end.
Или можно в любом месте пересохранить из TMemoryStream в string и уже в нём рассматривать.

(0006584)
Dima2000 (developer)
01-05-2012 21:30

Ну или временно меняете обратно приём на строки в 4-х местах:
два объявления .Add(...; tile:string; ...),
l:=tile.Size; на l:=length(tile); в начале .Add,
Blockwrite(FD,tile.Memory^,l); на Blockwrite(FD,tile[1],l); ближе к концу .Add.
И всё, получаете обратно работу со строками. Остальной код класса от этого не изменится.
(0006585)
vasketsov (manager)
01-05-2012 21:47

>t.Destroy
Либо t.Free, либо FreeAndNil(t)
(0006586)
Dima2000 (developer)
01-05-2012 21:59

Согласен.
Но у меня за этим вся консолькая прога закрывается, так что без разницы, отработает в любом варианте.
(0006587)
Dima2000 (developer)
01-05-2012 22:58
edited on: 01-05-2012 23:26

Простите, а зачем Вы читаете в bitmap (да ещё с кропом), а потом пишете в stream? Нельзя сразу прочитать бинарный файл в stream методом TMemoryStream.LoadFromFile? Ведь никакие преобразования не нужны! Чисто передать бинарное содержимое файла в .Add(). А тут ещё небось и распаковка битмапа будет, из jpeg и png, что совершенно лишнее.
Или это для универсальности кэшей? Не только файловых? Но разве и они не хранят бинарные данные, которые вовсе не обязательно распаковывать для экспорта?

Да, как только итератор выдал тайловые координаты, дальше лишь прочитать бинарные данные тайла из кэша (любого) и передать их без распаковки и преобразований в .Add(). И если расширение файла с тайлом неизвестно, то оставьте пустым, не надо всегда 'jpg' подставлять.

Жуть. Только не говорите, что Вы читаете тайл, перепаковываете его в JPG с качеством 100 и в таком виде передаёте на экспорт! :(

(0006588)
Dima2000 (developer)
01-05-2012 23:07
edited on: 01-05-2012 23:17

Ещё мне кажется там логическая ошибка, метод TSAS4WinCE.SaveINX сидит в блоке finally и вызовется и при отмене операции (exit в строке 159?), что есть неправильно, отмена подразумевает отказ от экспорта и достаточно вызвать деструктор (.Free).
Если не ошибаюсь, то .SaveINX надо вызвать перед finally в строке 175. Т.е. после отработки цикла for по зумам. И именно до finally. И перед вызовом обновить поле прогресса в окне экспорта, .SaveINX может выполнятся заметное время, надо об этом сказать пользователю, остановившиеся цифры обработанных тайлов навевают мысль о подвисании.

(0006589)
Dima2000 (developer)
01-05-2012 23:34

Ну точно, перепаковывается в jpg. В кэше лежит bmp, запаковался jpg. ЖУТЬ!!
(0006590)
Garl (manager)
02-05-2012 04:25

я ж говорю сильно не пинайте :)
расширения вообще обязательно передавать в VSAS4WinCE.Add ?
и что будет если допустим будет передано jpeg содержимое и расширение png?

как и чем прочитать тайл сразу в TMemoryStream ?
(0006591)
zed (manager)
02-05-2012 04:55

Посмотри как сделан экспорт в tar и действуй абсолютно аналогично.

VData := VTileStorage.LoadTile(VTile, VZoom, nil, VTileInfo);
if VData <> nil then begin
  VFileTime := VTileInfo.GetLoadDate;
  VStream := TStreamReadOnlyByBinaryData.Create(VData);
  try
    FTar.AddStream(
      VStream,
      FTileNameGen.GetTileFileName(VTile, VZoom)+ VExt,
      VFileTime
    );
  finally
    VStream.Free;
  end;
end;
(0006592)
Garl (manager)
02-05-2012 05:10

тык а я смотрел на экспорт в jnx :)
щас перепишу
(0006593)
Garl (manager)
02-05-2012 09:38

в таре в примере VStream: TStream;
а нам нужен TMemoryStream.
будет ли корректно:

TileStream.clear;
TileStream.LoadFromStream(VStream);
(0006594)
Garl (manager)
02-05-2012 10:03

ну что , первые 2 карты с 5 зумами заработали :)
сейчас причешу код, и будем внедрять
(0006595)
Dima2000 (developer)
02-05-2012 10:40

>как и чем прочитать тайл сразу в TMemoryStream
Я ж написал, и у TStream, и у TMemoryStream есть метод procedure LoadFromFile(const FileName: string);, им и читать бинарные данные файла для передачи в .Add().

>расширения вообще обязательно передавать в VSAS4WinCE.Add ?
Для работы программы v_max - нет, не обязательно.
Расширения мне понадобятся например для обратной распаковки файлов. Потому что в оригинале автора в пакованном кэше хранятся лишь бинарные данные тайла, без заголовков, и если имя файла можно получить из z,x,y, то расширение так не определить (анализировать содержимое файла можно, так и сделано, но ... с расширением удобнее).

>и что будет если допустим будет передано jpeg содержимое и расширение png?
Ничего не будет. На работе программ v_max это никак не отразится.
Вот если захочешь распаковать пакованный кэш обратно, да ещё и моей пока не написанной программой, то будет небольшая беда - файлы получат .png, а содержать будут JPEG.
Повторю, если расширение неизвестно, то передавать в .Add() лучше пустую строку.
(0006596)
Dima2000 (developer)
02-05-2012 10:45

>сейчас причешу код, и будем внедрять
Можно будет его глянуть? Я б посоветовал что ... ;-)
(0006597)
Garl (manager)
02-05-2012 10:46

с расширениями уже разобрался.

интересно а как оно будет отрабатывать с BerkleyDB ?
сейчас используется
VData := VTileStorage.LoadTile(VTile, VZoom, nil, VTileInfo);
(0006598)
zed (manager)
02-05-2012 10:55

>интересно а как оно будет отрабатывать с BerkleyDB
Будет отрабатывать на ура с любым типом кэша. Это ж универсальный интерфейс загрузки данных из хранилища.
(0006599)
Garl (manager)
02-05-2012 10:56

zed это про LoadFromFile(const FileName: string)?
(0006600)
Dima2000 (developer)
02-05-2012 10:58
edited on: 02-05-2012 10:58

Вот кусок из Вашего .pas выше, как должно выглядеть всё в сумме:
try
    TileStream := TMemoryStream.Create;
    VTilesProcessed := 0;
    ProgressFormUpdateOnProgress(VTilesProcessed, VTilesToProcess);
    for i := 0 to Length(FZooms) - 1 do begin
        VZoom := FZooms[i];
        VTileIterator := VTileIterators[i];
        while VTileIterator.Next(VTile) do begin
            if CancelNotifier.IsOperationCanceled(OperationID) then Exit;
            TileStream.Clear;
            TileStream.LoadFromFile({тут сформировать полное имя файла с расширением и путём});
            VSAS4WinCE.Add(VZoom+1,VTile.X,VTile.Y,TileStream,''{или передать точное расширение прочитанного файла, его кстати можно взять из настроек карты});
            Inc(VTilesProcessed);
            if VTilesProcessed mod 100 = 0 then ProgressFormUpdateOnProgress(VTilesProcessed, VTilesToProcess);
        end;
    end;
    ProgressFormUpdateOnProgress('Создание индкса...');
    VSAS4WinCE.SaveINX(FTargetFile);{Не надо передавать вторым true!!}
finally
    TileStream.Free;
    VSAS4WinCE.Free;
end;

Ой, его обновили, щас погляжу, это код из старого, ночного.

(0006601)
zed (manager)
02-05-2012 10:58

>в таре в примере VStream: TStream;
>а нам нужен TMemoryStream.
Вместо
VStream: TStream;

сделай
VStream: TMemoryStream;

должно работать не хуже. И не нужен будет лишний мемористрим.
(0006602)
zed (manager)
02-05-2012 10:59

>zed это про LoadFromFile(const FileName: string)?
нет, это про:
VData := VTileStorage.LoadTile(VTile, VZoom, nil, VTileInfo);
Прямая загрузка по имени тайла естественно, никуда не годится.
(0006603)
Garl (manager)
02-05-2012 11:01

тогда нужен пример как универсально прочитать содержимое тайла в TMemoryStream
ибо в юните Tar читается в TStream, а в юните JNX в string
(0006604)
Garl (manager)
02-05-2012 11:03

VStream := TStreamReadOnlyByBinaryData.Create(VData);
имеем
[DCC Error] u_ThreadExportToCE.pas(173): E2010 Incompatible types: 'TMemoryStream' and 'TStreamReadOnlyByBinaryData'
(0006605)
Dima2000 (developer)
02-05-2012 11:04

Нет необходимости после .Add() вызывать VStream.Free, достаточно VStream.Clear (перед), а уничтожить объект только перед (или после) .SaveINX, один раз за экспорт, а не для каждого тайла.
(0006606)
Dima2000 (developer)
02-05-2012 11:05
edited on: 02-05-2012 11:09

Блин, ну не заморачивайтесь, TStream и TMemoryStream похожи как близнецы-братья, смените в SAS4WinCE объявление на TStream и всё.
А, нет, не так уж и похожи, извиняюсь.
Записать данные в TMemoryStream можно или из файла - .LoadFromFile(); - или из любого буфера - .Write(s[1],length(s)); для строки. Посмотрите определение .Write, указатель на буфер и длина данных для записи, делов-то.

(0006607)
zed (manager)
02-05-2012 11:05

Кхм, сделай коммит в свой репо, как есть. Я поправлю.
(0006608)
Garl (manager)
02-05-2012 11:08

залил.
(0006609)
Dima2000 (developer)
02-05-2012 11:11

Может мне сделать приём сразу из IBinaryData? Мне ведь в .Add() достаточно лишь указателя и размера данных. Вы скажите как удобнее использовать, сделаем!
(0006610)
Dima2000 (developer)
02-05-2012 11:12

>Кхм, сделай коммит в свой репо, как есть. Я поправлю.
Он публичный? Хочу посмотреть. :)
(0006611)
Garl (manager)
02-05-2012 11:12

5 сек. не торопимся.

нам ещё ловить 'Nothing to export.' в SaveINX :)
(0006612)
Garl (manager)
02-05-2012 11:14

публичный для вышестоящих, регайся на битбукете, сообщи логин , попробую добавить
(0006613)
Dima2000 (developer)
02-05-2012 11:21

>регайся на битбукете
Не люблю я этого дела, регов где не нужно ... Может тогда сюда приложите, или в личку на форуме мне (Dima2000) кинете? Как устаканится?

>нам ещё ловить 'Nothing to export.' в SaveINX :)
Я считаю попытку экспорта 0 тайлов ошибкой, о которой надо информировать пользователя. А ловить не обязательно, деструктор ведь вызовется, этого достаточно. Разве что ловить ради смены сообщения? Это понимаю, это правильно.
(0006614)
Garl (manager)
02-05-2012 11:23

просто скорее всего у меня чтото с этими Stream'ами напутано. ибо делаю экспорт 100% существующих тайлов с 1 по 18 зум, и получаю это сообщение.
в общем будет где ещё ловить глюки :)
щас в личку скину.
(0006615)
Dima2000 (developer)
02-05-2012 11:25
edited on: 02-05-2012 11:27

Ещё пожелание: перед вызовом конструктора сделайте проверку VTilesToProcess на 120млн с выдачей пользователю исключения - более 130млн в индекс физически не влезут, а ждать пока экспорт отработает 130млн тайлов чтобы вылететь по исключению - не комильфо.
Я чуть попозже обновлю юнит, ещё две своих ошибки поправлю.

(0006616)
Dima2000 (developer)
02-05-2012 11:27

>делаю экспорт 100% существующих тайлов с 1 по 18 зум, и получаю это сообщение.
Проверяйте после .Add() или результат (true если тайл принят) или TSAS4WinCE.TilesNum, оно должно быть равно VTilesProcessed.
(0006617)
Dima2000 (developer)
02-05-2012 11:35
edited on: 02-05-2012 11:36

Если не заметили, то в классе есть
        class function Name():string; //Строка с названием модуля (для отображения в диалоге SAS?).
        class function Version():string; //Выдать строку с информацией о версии.
можно для чего-нибудь применить ... Например показывать в диалоге экспорта. :)
И повторно пожелание, сменить имя в диалоге экспорте на 'Packed cache for SAS4WinCE/SAS4Android' - со словом Packed, для подчёркивания, что кэш таки пакованный (в терминах автора, v_max).

Исходники получил, спасибо.

(0006618)
Garl (manager)
02-05-2012 11:42

тем кто знает что такое SAS4WinCE\SAS4Android думаю и так знают что он пакованый.
к тому же слово экспорт подразумавает что он в одну строну.
уже поменял.
(0006619)
zed (manager)
02-05-2012 11:48

Garl, тестируй. Убрал вообще все стримы и подчистил от мусора.
(0006620)
Dima2000 (developer)
02-05-2012 11:56

Вот тут будет возникать исключение если в содержимом некорректное целое число: VMaxSize := Strtoint(FFrame.cbbMaxVolSize.text)*1048576;
Я бы сделал StrToIntDef(.text,-1) shl 20; отрицательные числа обрабатываются конструктором правильно, берётся значение по умолчанию (1ГБ).
А, и ещё будет беда при размере точно 2048МБ, ведь получится -2ГБ! Надо так: VMaxSize := (Strtointdef(FFrame.cbbMaxVolSize.text,-1)-1)*1048576;
Ну или пусть остаётся с исключением... Но с 2ГБ исправить надо, это ошибка. И вообще проверять на превышение 2047 до умножения на 1МБ.

В VComent хотели добавить GUID карты, первой строкой. Типа VComent := GUID+0000013#10+FFrame.EmapName.Text+0000013#10+FFrame.EComent.Text;

VSAS4WinCE.SaveINX лучше вызывать без параметров, это специально предусмотрено. И уж точно не с true вторым параметром!

Сейчас у Вас закомментировано TileStream.LoadFromStream(VStream); - может поэтому в результате тайлов ноль? ;-)

В остальном всё вроде в порядке. Что там с Stream я не знаю, объявлений VData у меня нет, может можно прям его передать в .Add(). Как работать с TMemoryStream я писал тут выше.

Zed, а мне исходничек с вызовом юнита? ;-)
(0006621)
Garl (manager)
02-05-2012 11:58

щас скину
(0006622)
zed (manager)
02-05-2012 12:02

>А, и ещё будет беда при размере точно 2048МБ, ведь получится -2ГБ!
Нужно вместо integer использовать int64, и не будет никаких бед.
(0006624)
Dima2000 (developer)
02-05-2012 12:33

>Нужно вместо integer использовать int64, и не будет никаких бед.
Ага. Но только для вычислений. Передавать в класс int64 нет смысла, WinCE не поддерживает файлы более 2ГБ (именно потому что там везде int32), формат пакованного кэша везде тоже лишь int32, потому и передавать такие числа в класс незачем, я специально всё объявил integer.
(0006625)
Dima2000 (developer)
02-05-2012 12:44

Garl, спасибо.

Метод .Add() подправлен правильно, только забыли tilesize объявить const. У себя изменю так же.

К вызовам класса никаких замечаний нет, всё сделано хорошо.

Всё же напоминаю, перед вызовом VSAS4WinCE.SaveINX(); сказать пользователю в окне прогресса что тайлы переданы, теперь создаём индекс, это не полсекунды.
Ну и с расчётом размера VMaxSize разобраться.
(0006626)
Garl (manager)
02-05-2012 13:17

VMaxSize
сделал VMaxSize := (Strtointdef(FFrame.cbbMaxVolSize.text,-1)-1)*1048576;

но всёравно получается 18 зумов в 58kb!!! не верю :)
(0006627)
Dima2000 (developer)
02-05-2012 14:04

Приложил v16.
Добавил шапку, поправил пару глюков, сменил TMemoryStream на указатель+размер, добавил zed-а в историю изменений. :) Ну и по мелочи ещё.

>но всёравно получается 18 зумов в 58kb!!! не верю :)
Я же предложил, проверяйте результат .Add(), выведите лог результатов .Add(), значений .TilesNum, .DataNum, .DataLen, смотрите что не так.
У меня приложенная версия SASPlanet.exe от 0:13 вполне работает, файлы создаются правильные, правда проверял лишь на десятке тайлов.

Такой расчёт VMaxSize тоже не совсем корректный, к примеру отрицательные числа не надо давать вводить, но уже лучше чем было.
(0006628)
Garl (manager)
02-05-2012 14:08

так мы вообще не даём вводить . пока только жёсткий выбор из списка.
а затем будет RegExpами выбор только чисел без знаков. т.е. только больше ноля.
(0006629)
Dima2000 (developer)
02-05-2012 14:12

Очень долго происходит растеризация полигона в тайлы, при пустом окне прогресса, надо бы написать мол работаю, типа 'Preparing tiles to export...', а?
Запустил в приложенном exe от 0:13 экспорт для 5.9млн тайлов (релаьно в полигоне есть лишь сотня-две тысяч тайлов), часа через два отпишусь о результате, пока .d00 создаётся на вид правильным.
(0006630)
zed (manager)
02-05-2012 14:15

Приложил скомпиленный exe со свежими правками.
(0006631)
Dima2000 (developer)
02-05-2012 14:19
edited on: 02-05-2012 14:20

Оборвал крестиком, из 170К тайлов реально экспортировались 4720 (остальных в кэше SAS просто нет), файл индекса создался, всё в порядке.
Перезапустил для 1.2млн тайлов.

О, здорово, тогда его и запущу.

(0006632)
Dima2000 (developer)
02-05-2012 14:24

Э, а он почему-то при том же выделении разогнался на не 1.2млн, а 1.7млн тайлов. Странно! Ладно, дождёмся завершения. Первое впечатление - работает в несколько раз быстрее. Хорошо. :)
(0006633)
zed (manager)
02-05-2012 14:30

Dima2000, а как насчёт навести марафет в юните согласно стандартам?

http://citforum.ru/programming/delphi/style_delphi/

Так же, нужно заменить табы на символы пробела (один таб = 2 пробела) и ограничить длину строк 80-ю символами (особенно это касается комментариев, которые местами вылазят далеко за пределы экрана).

Код, кроме того что он должен быть рабочим, ещё должен быть и читаем. В вашем юните с читаемостью беда.

Но это так, в плане пожелания. В любом, случае, спасибо за юнит, судя по отзывам, некоторые уже довольно давно ждали этот функционал. И вот, благодаря вам, наконец дождались. :)
(0006634)
Garl (manager)
02-05-2012 14:37

кстати даблклик на зуме в списке зумов выделяет все зумы от 1 до текущего.
вечером из дома причешу ещё чуток GUI.
(0006635)
Dima2000 (developer)
02-05-2012 15:05

Результаты.
Карта спутник яндекс, выделение 2х3 (HxV) квадрата на z8, слева от хабаровска и ниже почти до владивостока (большинство занимает китай, там снимков у яндекса нет), зумы выбраны 1-15,17. На 17-м скачано не всё, остальные должны быть полными.
Галка recovery info стоит, размер файлов 256МБ, название карты и короткий коммент.
Общее количество тайлов 1703942, экспортировано 37706 (по файлу индекса), общий размер тайлов 524524135 (по файлу индекса), размер файлов данных 267381735+257745898=525127633. Где-то непорядок однако! Файлы данных должны быть длиннее, на размер копирайта и комментов и инфы о тайлах.
Ошибок в процессе не произошло, в файле индекса (размером 617713) ошибок также не найдено.
Тайлы передавало 20 минут, сортировка и сохранение индекса менее пары секунд.
Памяти было выделено не пойму сколько, мало, до пары мег явно, точнее не могу увидеть.
В DebugInfo ничего интересного про экспорт не нашёл.
На первый взгляд оба файла данных и файл индекса правильные, копирайт есть, recovery info есть, коммент в конце есть, тайлы очевидно тоже есть. :)
Сейчас буду внимательно разглядывать что получилось в итоге, жаль нельзя посмотреть подробный лог действий класса.

>Dima2000, а как насчёт навести марафет в юните согласно стандартам?
Сугубо положительно. Ознакомлюсь и приведу. Не абсолютно, но близко, некоторые вещи мне не кажутся стоящими. Юнит же не лично для меня писан, пусть будет по стандартам.

Для себя мне удобнее иметь комменты в одну строку прям к команде, пусть вылазят вправо, мониторы широкие, да и уж лучше вправо, чем увеличивать вертикальный размер кода, его вечно не хватает.
Как и begin к примеру предпочитаю не на отдельной строке, а справа (кроме функций и процедур). И табуляцию уважаю. :)
Но это всё лично мне, а юнит приведу как скажете.
(0006636)
Dima2000 (developer)
02-05-2012 15:11
edited on: 02-05-2012 15:27

Маленькое замечание, в .Add(... fext) передаётся '.jpg', можно ведь без точки, зачем она? Впрочем, можно и так.

Та как насчёт добавить в коммент GUID карты перед названием? VComent := {GUID}+\r\n+FFrame.EmapName.Text+\r\n+FFrame.EComent.Text;

(0006637)
Dima2000 (developer)
02-05-2012 15:23

>Где-то непорядок однако! Файлы данных должны быть длиннее, на размер копирайта и комментов и инфы о тайлах.
Я тормоз, всё так и есть, ровно на сколько должно быть, настолько файлы данных и длиннее. Спутал местами два размера.
Тогда считаю всё сформировалось верно.
Сейчас ещё сохраню (средствами SAS)выделенную область в отдельный каталог и сравню файлы данных с ним. Пока сохранение идёт немного медленнее экспорта! Что впрочем ожидаемо, мелкие файлы однако.
(0006638)
Dima2000 (developer)
02-05-2012 15:33
edited on: 02-05-2012 15:36

В выделенной области в кэше SAS есть 37706 файлов общим размером 524524135. Т.е. ровно сколько экспортнулось. Несколько файлов сравнил побайтно из файла данных и из кэша SAS, одинаковы. Экспорт работает.

(0006639)
Garl (manager)
02-05-2012 18:03

>Та как насчёт добавить в коммент GUID карты перед названием?
как лучше: GUID писать постоянно, или только при непустом имени карты?
(0006640)
Dima2000 (developer)
02-05-2012 18:10
edited on: 02-05-2012 18:32

При непустом имени карты. Пусть будет возможность получить "чистые" файлы, без наших добавлений, мало ли что. И предусмотреть чтобы если оба поля в диалоге пустые, то \r\n не передавались в класс, чтобы строка передавалась пустой.

(0006641)
Dima2000 (developer)
02-05-2012 18:42

Немножко оффтопика, потом удалите.
Теперь подумываю как бы сделать тайловое хранилище, чтобы при отсутствии тайла на диске он искался в этом пакованом кэше? Можно будет постоянные области закачать, экспортнуть и пусть себе лежат большими файлами. А если появились новые снимки, то они будут лежать как обычно и дополнять пакованный кэш. И если вдруг какая ошибка в пакованном кэше, то всегда её можно замаскировать перезакачкой новых тайлов. У v_max между прочим именно так и работает, на жалкой WinCE! Значит много ресурсов на это дело не надо.
А при наличии класса экспорта не слишком трудно написать и перепаковщик файлов данных для добавления с заменой в них новых файлов. Даже можно добавить в класс функцию чтения тайла из пакованного кэша, раз уж слова export в названии класса нет. :-)
(0006642)
vasketsov (manager)
02-05-2012 18:47
edited on: 02-05-2012 18:57

>Передавать в класс int64 нет смысла, WinCE не поддерживает файлы более 2ГБ
А андроид поддерживает.

>Такой расчёт VMaxSize тоже не совсем корректный
Ещё бы. Уж что-что, а вводимый размер надо сразу конвертить просто как StrToInt и руками проверка нужного диапазона, если что - сразу юзеру по лицу исключением.

>мне удобнее иметь комменты в одну строку прям к команде
Тут дело в том, что при изменении исходного кода показ различий и все операции разруливания конфликтов и слияния идут построчно. Поэтому на будущее лучше комментарии писать отдельной строкой перед кодом, чтобы корректно всё работало и лишнего не затрагивало.

>как бы сделать тайловое хранилище, чтобы при отсутствии тайла на диске он искался в этом пакованом кэше
Это совершенно отдельная тема вторичного хранилища (secondary tile storage). И не обязательно это должно быть запакованное хранилище.

(0006643)
Dima2000 (developer)
02-05-2012 19:38

>>Передавать в класс int64 нет смысла, WinCE не поддерживает файлы более 2ГБ
>А андроид поддерживает.
Не знал, это прекрасно. Но в файле индекса *.inx все поля 32 бита, и v_max сказал что они типа int (в C). Потому таки 2ГБ.

>на будущее лучше комментарии писать отдельной строкой перед кодом
Может оно и лучше для автоматической обработки, но удвоение вертикального размера кода меня очень сильно напрягает. Гораздо больше, чем выступы вправо на 500 знаков (для которых есть понятие wrap кстати).


Переформатировал исходник "по стандарту" (или очень близко), но идентификаторы не переименовывал, мне названия нравятся, а "стандарты устарели"(с). :-)
Выложил как v17.
По идее изменений в коде нет, но проверить это уже сложновато, отличия в каждой строке. На моих тестах работает идентично. Использовать можно и v16 и v17.
(0006644)
Garl (manager)
02-05-2012 19:41

ок как раз щас собиру на v17
чуток поправил интерфейс и в прогресс бар вывел счётчик DataNum

з.ы.
то что переменные не переименовывал - гуд.
(0006645)
Dima2000 (developer)
02-05-2012 19:53

А предупреждение перед .SaveINX? Ну ведь не сложно же!
И предупреждение перед растеризацией полигона в тайлы?
Я же выше уже говорил, и это всё легко.
(0006646)
Garl (manager)
02-05-2012 19:54
edited on: 02-05-2012 19:55

дык :
      ProgressInfo.FirstLine := 'Making .inx file ..';
      ProgressInfo.SecondLine := '';
      VSAS4WinCE.SaveINX(FTargetFile);

только сильно быстро он у меня 500 Мб кэша индексирует, не успеваю даже увидеть.

(0006647)
Dima2000 (developer)
02-05-2012 20:19

>сильно быстро он у меня 500 Мб кэша индексирует, не успеваю даже увидеть.
Ну да, до полумиллиона тайлов время работы порядка секунды. А вот для пары (а лучше 5-ти) миллионов уже будет пяток секунд, вот и увидим.

>дык
Дык у меня-то исходника нету, Вы не забыли? ;-)
Ещё аналогично перед SetLength(VTileIterators, Length(FZooms)); в u_ThreadExportToCE.pas сделать текст типа 'Preparing tiles to export...' и будет счастье.
(0006648)
Garl (manager)
02-05-2012 20:31

красота.

давно б зарегался на bitbucket.org и делов то :)
хотя можно попробовать и без регистрации https://bitbucket.org/garl/sasplanetgarl
(0006649)
Dima2000 (developer)
02-05-2012 20:58
edited on: 03-05-2012 00:31

Да, дают и без рега, вот точно красота, ща пороюсь! :)

(0006650)
Dima2000 (developer)
02-05-2012 21:08
edited on: 02-05-2012 22:08

Про красоту.
Настоящая красота будет если:
а) прогресс сделать как в окнах закачек, полоска двойным цветом (сколько тайлов обработано и сколько реально экспортировано);
б) как в закачках выводить сколько КБ/МБ/ГБ/ТБ сохранено, сколько ориентировочно осталось, сколько времени ещё надо.
Понимаю что это не совместимо с идеологией экспорта и никто делать не будет, зато красота. :-D

(0006651)
vasketsov (manager)
02-05-2012 22:46

>чего-то не понимаю
Так точно.
(0007283)
DJ VK (manager)
03-06-2012 04:31
edited on: 03-06-2012 04:35

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

(0007284)
Tolik (manager)
03-06-2012 05:26
edited on: 03-06-2012 05:27

Ну и где тут земля?
Подозреваю, что справа не те "02 00 00 00" обведены (д.б. в строке 108).

P.S. неисправность в последних ночнушках обсуждаем в 0001322

(0007289)
DJ VK (manager)
03-06-2012 12:32

да Толик, все верно, ошибочно выделил. Но перед самими данными непойми что. И в результате андроид посылает нахрен с такими картами.

- Users who viewed this issue
User List Anonymous (8545x), kalakotkas (1x)
Total Views 8546
Last View 18-04-2024 08:10

- Issue History
Date Modified Username Field Change
26-04-2012 10:09 Papazol New Issue
26-04-2012 17:45 Garl Note Added: 0006481
26-04-2012 17:45 Garl Tag Attached: экспорт
27-04-2012 08:36 Papazol Note Added: 0006482
27-04-2012 08:43 Dima2000 Note Added: 0006483
27-04-2012 08:48 Dima2000 Note Added: 0006484
27-04-2012 09:13 Garl Note Added: 0006485
27-04-2012 09:48 Papazol Note Added: 0006486
27-04-2012 10:28 Dima2000 Note Added: 0006487
27-04-2012 10:55 Garl Note Added: 0006488
27-04-2012 11:11 Dima2000 Note Added: 0006489
27-04-2012 11:16 Garl Note Added: 0006490
27-04-2012 11:48 Dima2000 Note Added: 0006491
27-04-2012 11:53 Dima2000 Note Added: 0006492
27-04-2012 12:12 Garl Note Added: 0006493
27-04-2012 12:14 Garl Note Edited: 0006493 View Revisions
28-04-2012 12:25 Dima2000 File Added: ExportCE.0v6.pas
28-04-2012 12:32 Dima2000 Note Added: 0006496
28-04-2012 17:50 Garl Note Added: 0006499
29-04-2012 09:14 Papazol Note Added: 0006500
29-04-2012 10:02 Dima2000 Note Added: 0006501
30-04-2012 06:41 Papazol Note Added: 0006502
30-04-2012 08:46 zed Note Added: 0006503
30-04-2012 09:00 zed Note Added: 0006504
30-04-2012 10:22 Garl Note Added: 0006505
30-04-2012 10:27 Papazol Note Added: 0006506
30-04-2012 11:00 Garl Note Added: 0006507
30-04-2012 11:37 Dima2000 Note Added: 0006508
30-04-2012 12:11 Dima2000 File Added: SAS4WinCEv8.pas
30-04-2012 12:13 Dima2000 Note Added: 0006509
30-04-2012 12:13 Garl File Deleted: ExportCE.0v6.pas
30-04-2012 12:16 Garl Note Added: 0006510
30-04-2012 12:51 Dima2000 Note Added: 0006511
30-04-2012 12:59 Garl Note Added: 0006512
30-04-2012 13:10 Dima2000 Note Added: 0006513
30-04-2012 13:14 Garl Note Added: 0006514
30-04-2012 13:15 Dima2000 Note Added: 0006515
30-04-2012 13:15 zed Note Added: 0006516
30-04-2012 13:18 Dima2000 Note Added: 0006517
30-04-2012 13:20 Garl Note Added: 0006518
30-04-2012 13:35 Dima2000 Note Added: 0006519
30-04-2012 13:58 zed Note Added: 0006520
30-04-2012 14:08 Garl File Added: sas4wince.jpg
30-04-2012 14:25 zed Note Added: 0006521
30-04-2012 14:33 Garl Note Added: 0006522
30-04-2012 15:02 vasketsov Note Added: 0006523
30-04-2012 15:04 vasketsov Note Edited: 0006523 View Revisions
30-04-2012 15:12 vasketsov Note Edited: 0006523 View Revisions
30-04-2012 16:22 Dima2000 Note Added: 0006524
30-04-2012 16:37 Dima2000 Note Added: 0006525
30-04-2012 16:43 Dima2000 Note Added: 0006526
30-04-2012 16:47 Dima2000 Note Added: 0006527
30-04-2012 16:50 Garl Note Added: 0006528
30-04-2012 16:59 Dima2000 Note Added: 0006529
30-04-2012 17:13 Garl File Deleted: sas4wince.jpg
30-04-2012 17:13 Garl File Added: sas4wince2.jpg
30-04-2012 17:52 Dima2000 Note Added: 0006530
30-04-2012 17:54 Garl Note Added: 0006531
30-04-2012 18:07 Dima2000 Note Added: 0006532
30-04-2012 18:16 Garl Note Added: 0006533
30-04-2012 18:18 Garl Note Edited: 0006533 View Revisions
30-04-2012 18:26 Dima2000 Note Added: 0006534
30-04-2012 18:31 Garl Note Added: 0006535
30-04-2012 18:42 Garl File Added: SASPlanet.exe
30-04-2012 18:42 Garl Note Added: 0006536
30-04-2012 18:56 Papazol Note Added: 0006537
30-04-2012 19:00 Garl Note Added: 0006538
30-04-2012 19:02 Dima2000 Note Added: 0006539
30-04-2012 19:03 Dima2000 Note Added: 0006540
30-04-2012 19:04 Papazol Note Added: 0006541
30-04-2012 19:08 Papazol Note Added: 0006542
30-04-2012 19:08 Garl Note Added: 0006543
30-04-2012 19:09 Garl Note Added: 0006544
30-04-2012 19:14 Papazol Note Added: 0006545
30-04-2012 19:14 Papazol Note Edited: 0006545 View Revisions
30-04-2012 19:17 Papazol Note Edited: 0006545 View Revisions
30-04-2012 19:23 Papazol Note Added: 0006546
30-04-2012 19:27 Garl Note Added: 0006547
30-04-2012 19:41 Papazol Note Added: 0006548
30-04-2012 19:43 Garl Note Added: 0006549
30-04-2012 19:45 Dima2000 Note Added: 0006550
30-04-2012 19:48 Garl Note Added: 0006552
30-04-2012 19:49 Dima2000 Note Added: 0006553
30-04-2012 20:01 Garl Note Added: 0006555
30-04-2012 20:25 Dima2000 Note Added: 0006556
30-04-2012 20:27 vdemidov Note Added: 0006557
30-04-2012 20:33 Dima2000 Note Added: 0006558
30-04-2012 22:07 vasketsov Note Added: 0006560
30-04-2012 22:32 Dima2000 Note Added: 0006561
01-05-2012 03:12 Dima2000 File Added: SAS4WinCEv12.pas
01-05-2012 03:14 Dima2000 Note Added: 0006562
01-05-2012 03:24 Dima2000 Note Edited: 0006562 View Revisions
01-05-2012 04:49 zed Note Added: 0006563
01-05-2012 04:54 zed Note Edited: 0006563 View Revisions
01-05-2012 05:04 zed Note Added: 0006564
01-05-2012 07:07 vasketsov Note Added: 0006565
01-05-2012 07:09 vasketsov Note Edited: 0006565 View Revisions
01-05-2012 07:18 Garl Note Added: 0006566
01-05-2012 07:56 Garl Note Added: 0006567
01-05-2012 09:13 Dima2000 Note Added: 0006568
01-05-2012 09:17 Dima2000 Note Added: 0006569
01-05-2012 09:37 vasketsov Note Added: 0006570
01-05-2012 10:43 Dima2000 Note Added: 0006571
01-05-2012 10:43 Dima2000 File Added: SAS4WinCEv13.pas
01-05-2012 10:47 Dima2000 Note Edited: 0006571 View Revisions
01-05-2012 11:12 vasketsov Note Added: 0006572
01-05-2012 11:22 zed Note Added: 0006573
01-05-2012 11:23 Dima2000 Note Added: 0006574
01-05-2012 11:24 zed Note Added: 0006575
01-05-2012 11:26 Dima2000 Note Added: 0006576
01-05-2012 11:31 zed Note Added: 0006577
01-05-2012 11:35 Dima2000 File Added: SAS4WinCEv14.pas
01-05-2012 11:39 Dima2000 Note Added: 0006578
01-05-2012 11:40 vasketsov Note Added: 0006579
01-05-2012 14:29 Dima2000 Note Added: 0006580
01-05-2012 14:30 Dima2000 File Added: SAS4WinCEv15.pas
01-05-2012 20:06 Garl File Added: u_ThreadExportToCE.pas
01-05-2012 20:09 Garl Note Added: 0006581
01-05-2012 20:10 Garl File Deleted: SASPlanet.exe
01-05-2012 20:13 Garl File Added: SASPlanet.exe
01-05-2012 20:13 vasketsov Note Added: 0006582
01-05-2012 20:19 vasketsov Note Edited: 0006582 View Revisions
01-05-2012 20:22 vasketsov Note Edited: 0006582 View Revisions
01-05-2012 21:24 Dima2000 Note Added: 0006583
01-05-2012 21:25 Dima2000 Note Edited: 0006583 View Revisions
01-05-2012 21:30 Dima2000 Note Added: 0006584
01-05-2012 21:47 vasketsov Note Added: 0006585
01-05-2012 21:59 Dima2000 Note Added: 0006586
01-05-2012 22:58 Dima2000 Note Added: 0006587
01-05-2012 23:00 Dima2000 Note Edited: 0006587 View Revisions
01-05-2012 23:07 Dima2000 Note Added: 0006588
01-05-2012 23:10 Dima2000 Note Edited: 0006588 View Revisions
01-05-2012 23:14 Dima2000 Note Edited: 0006587 View Revisions
01-05-2012 23:17 Dima2000 Note Edited: 0006588 View Revisions
01-05-2012 23:26 Dima2000 Note Edited: 0006587 View Revisions
01-05-2012 23:34 Dima2000 Note Added: 0006589
02-05-2012 04:25 Garl Note Added: 0006590
02-05-2012 04:55 zed Note Added: 0006591
02-05-2012 05:10 Garl Note Added: 0006592
02-05-2012 09:38 Garl Note Added: 0006593
02-05-2012 10:03 Garl Note Added: 0006594
02-05-2012 10:40 Dima2000 Note Added: 0006595
02-05-2012 10:45 Dima2000 Note Added: 0006596
02-05-2012 10:46 Garl Note Added: 0006597
02-05-2012 10:46 Garl File Deleted: u_ThreadExportToCE.pas
02-05-2012 10:47 Garl File Added: u_ThreadExportToCE.pas
02-05-2012 10:55 zed Note Added: 0006598
02-05-2012 10:56 Garl Note Added: 0006599
02-05-2012 10:58 Dima2000 Note Added: 0006600
02-05-2012 10:58 zed Note Added: 0006601
02-05-2012 10:58 Dima2000 Note Edited: 0006600 View Revisions
02-05-2012 10:59 zed Note Added: 0006602
02-05-2012 11:01 Garl Note Added: 0006603
02-05-2012 11:03 Garl Note Added: 0006604
02-05-2012 11:04 Dima2000 Note Added: 0006605
02-05-2012 11:05 Dima2000 Note Added: 0006606
02-05-2012 11:05 zed Note Added: 0006607
02-05-2012 11:08 Garl Note Added: 0006608
02-05-2012 11:09 Dima2000 Note Edited: 0006606 View Revisions
02-05-2012 11:11 Dima2000 Note Added: 0006609
02-05-2012 11:12 Dima2000 Note Added: 0006610
02-05-2012 11:12 Garl Note Added: 0006611
02-05-2012 11:14 Garl Note Added: 0006612
02-05-2012 11:21 Dima2000 Note Added: 0006613
02-05-2012 11:23 Garl Note Added: 0006614
02-05-2012 11:25 Dima2000 Note Added: 0006615
02-05-2012 11:27 Garl Note Edited: 0006615 View Revisions
02-05-2012 11:27 Dima2000 Note Added: 0006616
02-05-2012 11:35 Dima2000 Note Added: 0006617
02-05-2012 11:36 Dima2000 Note Edited: 0006617 View Revisions
02-05-2012 11:42 Garl Note Added: 0006618
02-05-2012 11:48 zed Note Added: 0006619
02-05-2012 11:56 Dima2000 Note Added: 0006620
02-05-2012 11:58 Garl Note Added: 0006621
02-05-2012 12:02 zed Note Added: 0006622
02-05-2012 12:33 Dima2000 Note Added: 0006624
02-05-2012 12:44 Dima2000 Note Added: 0006625
02-05-2012 13:17 Garl Note Added: 0006626
02-05-2012 13:58 Dima2000 File Added: SAS4WinCEv16.pas
02-05-2012 14:04 Dima2000 Note Added: 0006627
02-05-2012 14:05 zed File Deleted: SAS4WinCEv8.pas
02-05-2012 14:08 Garl Note Added: 0006628
02-05-2012 14:09 zed File Deleted: SAS4WinCEv12.pas
02-05-2012 14:11 zed File Deleted: SASPlanet.exe
02-05-2012 14:12 zed File Deleted: u_ThreadExportToCE.pas
02-05-2012 14:12 Dima2000 Note Added: 0006629
02-05-2012 14:13 zed File Added: SASPlanet.7z
02-05-2012 14:15 zed Note Added: 0006630
02-05-2012 14:16 zed File Deleted: SAS4WinCEv13.pas
02-05-2012 14:16 zed File Deleted: SAS4WinCEv14.pas
02-05-2012 14:17 zed File Deleted: SAS4WinCEv15.pas
02-05-2012 14:19 Dima2000 Note Added: 0006631
02-05-2012 14:20 Dima2000 Note Edited: 0006631 View Revisions
02-05-2012 14:24 Dima2000 Note Added: 0006632
02-05-2012 14:30 zed Note Added: 0006633
02-05-2012 14:37 Garl Note Added: 0006634
02-05-2012 14:38 Garl File Added: sas4wince.jpg
02-05-2012 14:38 Garl File Deleted: sas4wince2.jpg
02-05-2012 15:05 Dima2000 Note Added: 0006635
02-05-2012 15:11 Dima2000 Note Added: 0006636
02-05-2012 15:23 Dima2000 Note Added: 0006637
02-05-2012 15:27 Dima2000 Note Edited: 0006636 View Revisions
02-05-2012 15:33 Dima2000 Note Added: 0006638
02-05-2012 15:36 Dima2000 Note Edited: 0006638 View Revisions
02-05-2012 18:03 Garl Note Added: 0006639
02-05-2012 18:10 Dima2000 Note Added: 0006640
02-05-2012 18:32 Dima2000 Note Edited: 0006640 View Revisions
02-05-2012 18:42 Dima2000 Note Added: 0006641
02-05-2012 18:47 vasketsov Note Added: 0006642
02-05-2012 18:50 vasketsov Note Edited: 0006642 View Revisions
02-05-2012 18:54 vasketsov Note Edited: 0006642 View Revisions
02-05-2012 18:57 vasketsov Note Edited: 0006642 View Revisions
02-05-2012 19:34 Dima2000 File Added: SAS4WinCEv17.pas
02-05-2012 19:38 Dima2000 Note Added: 0006643
02-05-2012 19:41 Garl Note Added: 0006644
02-05-2012 19:53 Dima2000 Note Added: 0006645
02-05-2012 19:54 Garl Note Added: 0006646
02-05-2012 19:55 Garl Note Edited: 0006646 View Revisions
02-05-2012 20:19 Dima2000 Note Added: 0006647
02-05-2012 20:31 Garl Note Added: 0006648
02-05-2012 20:58 Dima2000 Note Added: 0006649
02-05-2012 21:08 Dima2000 Note Added: 0006650
02-05-2012 22:08 Dima2000 Note Edited: 0006650 View Revisions
02-05-2012 22:46 vasketsov Note Added: 0006651
03-05-2012 00:31 Dima2000 Note Edited: 0006649 View Revisions
03-05-2012 07:24 Garl Status new => resolved
03-05-2012 07:24 Garl Fixed in Version => 120808
03-05-2012 07:24 Garl Resolution open => fixed
03-05-2012 07:24 Garl Assigned To => Garl
05-05-2012 10:37 Tolik Target Version => 120808
05-05-2012 10:38 Tolik Relationship added related to 0001285
13-05-2012 09:53 gpsMax Tag Attached: SAS4WinCE
18-05-2012 09:42 Dima2000 Relationship added related to 0001301
03-06-2012 04:31 DJ VK Note Added: 0007283
03-06-2012 04:32 DJ VK File Added: error.png
03-06-2012 04:33 DJ VK Note Edited: 0007283 View Revisions
03-06-2012 04:35 DJ VK Note Edited: 0007283 View Revisions
03-06-2012 05:26 Tolik Note Added: 0007284
03-06-2012 05:27 Tolik Note Edited: 0007284 View Revisions
03-06-2012 11:59 Dima2000 Relationship added related to 0001322
03-06-2012 12:32 DJ VK Note Added: 0007289
04-06-2012 14:42 Dima2000 Relationship added related to 0001324
10-10-2012 11:47 Tolik Status resolved => closed



Copyright © 2007 - 2024 SAS.Planet Team