SASGIS

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


View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0002763SAS.Планета[All Projects] Хотелкаpublic10-07-2015 20:3303-08-2015 08:43
ReporterGunSmoker 
Assigned ToGunSmoker 
PrioritynormalSeverityminorReproducibilityN/A
StatusresolvedResolutionfixed 
PlatformWindowsOS8.1OS Versionx64
Product Version141212 
Target Version150915Fixed in Version150915 
Summary0002763: Добавить возможность наложения слоёв при экспорте/копировании
DescriptionХочется выгрузить карту в PNG тайлы и подсунуть её программе. Нужен спутник (Google) с наложением поверх его гибрида.

В настоящее время возможность наложения есть только для экспорта в sqlite/RMaps ( 0001823 ).

Я посмотрел результат склейки RMaps - там в БД лежат готовые тайлы с уже наложенным поверх слоем. Т.е. код наложения уже есть и работает. Собственно, непонятно, что мешает сделать эту же возможность для всех прочих операций копирования/экспорта.
Additional InformationКогда-то такая задача решалась утилитой SASMerge, которая сегодня мертва и больше не доступна.
TagsSQLite, склейка, экспорт
Attached Files

- Relationships
related to 0000325resolvedGunSmoker При копировании кэша менять тип файлов (jpg->png) 
related to 0001680confirmed экспорт в тайловый кэш с заменой проекции 
related to 0002779assignedGunSmoker Перенести копирование тайлов с изменением со влкадки Скопировать на вкладку Экспорт 

-  Notes
(0016120)
zed (manager)
10-07-2015 20:59

>непонятно, что мешает сделать
Ничего не мешает. Как говорится - бери да делай :)
(0016142)
GunSmoker (developer)
12-07-2015 04:36

Если это, типа, подколка, то лично мне мешает полное незнание предметной области. Есть подозрение, что с какими-нибудь координатами и типами хранилища я так наворочу - мама не горюй. Но пока пытаюсь разобраться.
(0016143)
zed (manager)
12-07-2015 06:40

Это правда жизни - вопрос "что мешает?" можно задать в любом открытом тикете и ответ будет точно таким же. И незнание предметной области не является веской причиной, чтобы ничего не делать. Всё прекрасно познаётся "в процессе", так что велкам.

По поводу "наворочу": глядя на пример того же RMaps, я думаю, будет трудно наворотить. Для комбинирования слоёв с картой используется TBitmapLayerProviderMapWithLayer, который инициализируется картой и слоем (или списком слоёв), а потом у него последовательно запрашиваются тайлы в нужной проекции. Далее, результат конвертируется в нужный формат при помощи IBitmapTileSaver (который возвращает фабрика TBitmapTileSaveLoadFactory) и сохраняется в хранилище или ещё куда угодно. Главное понимать в какой проекции получился ваш тайл и какую проекцию ожидает/поддерживает хранилище или целевой формат, если речь о экспорте.
 
Проекцию вы може взять либо у исходного хранилища из которого читаете тайлы:
VGeoConvert := FTileStorage.CoordConverter;
VProjection := FProjectionFactory.GetByConverterAndZoom(VGeoConvert, FZoom);

Либо создать одну из 3-х доступных:
VGeoConvert := FCoordConverterFactory.GetCoordConverterByCode(
        CGoogleProjectionEPSG,
        CTileSplitQuadrate256x256
      );
VProjection := FProjectionFactory.GetByConverterAndZoom(VGeoConvert, FZoom);

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

Если что-то не понятно, спрашивайте.
(0016144)
zed (manager)
12-07-2015 06:48

Хороший пример создания IBitmapTileUniProvider можно подсмотреть в склейке, в функции TfrMapCombine.GetProvider - там на выбор можно либо наложить все отображаемые слои, либо один конкретный, ну или вообще не накладывать. Правда, в экспорте нужно учитывать, что если мы ничего не накладываем поверх карты и нас устраивает проекция и формат изображений тайлохранилища, то тайлы нужно передавать напрямую из хранилища, без лишней конвертации в битмапку. Т.е. этим провайдером не пользоваться.
(0016145)
vdemidov (manager)
12-07-2015 10:14

Вообще то, я давно планирую перевести экспорты оперирующие тайлами (JNX, сохранение в тайлохранилище и тд) на использование интерфейса ITileInfoUniProvider, у которого экспорт может запросить требуемый тайл с инофрмацией о типе и времени создания. А уже реализация этого провайдера может или напрямую передавать инфу из тайлохранилища, или склеивать и пределывать тайлы налету, или даже просто рендерить тайлы слоя заполнения или меток. Просто все руки никак не доходят сделать.
(0016146)
GunSmoker (developer)
12-07-2015 16:10
edited on: 12-07-2015 16:29

zed, может тогда подскажешь (запишу вопросы в том числе и себе, для упорядочивания в голове):
- Пока вижу так: в TThreadCopyFromStorageToStorage.ProcessTile загрузить тайл в bitmap, слить его с наложением, подсунуть в SaveTile.
- Тайлы всегда одинаковые по размеру (256x256)?
- ITileStorage.SaveTile.AData - передаётся, как я понимаю, содержимое файла. Как узнать, в каком формате нужно передавать (jpg/png)? IContentTypeInfoBasic? По строкам анализировать что-ли? Или по BOM из AData? Как узнать качество сжатия и цветность? Или выносить это как настройку в UI?
- ITileStorage.GetTileInfoEx - аналогичный вопрос: в каком формате возвращает.
- В TThreadCopyFromStorageToStorage.ProcessTile не вижу преобразования форматов (jpg->png;png->jpg). Кто это выполняет?
- Пока нет понимания, что делать с проекциями, как выполнять преобразования, если они нужны.
- В коде для экспорта в RMaps вижу упоминания CGoogleProjectionEPSG. Чем она специальна?
- Количество поясняющих комментариев угнетает :)

(0016147)
GunSmoker (developer)
12-07-2015 16:14

Кстати, с FastMM в FullDebugMode при закрытии вываливаются утечки, иногда - ошибки. Это так и должно быть? :)
(0016148)
zed (manager)
12-07-2015 17:08

>в TThreadCopyFromStorageToStorage.ProcessTile загрузить тайл в bitmap
Копирование из хранилища в хранилище происходит на самом низком уровне и там нету никаких преобразований. Тупо перекидывается бинарь из одного в другое. Чтобы оперировать битмапами и проекциями, нужно подняться на уровень выше, до IMapType - это уже карта, у неё можно запрашивать битмапы в любой известной проекции. А брать из хранилища тайлы и самому пытаться их распаковать в битмап, не стоит. И TBitmapLayerProviderMapWithLayer оперирует как раз картами, его и нужно использовать.

>Тайлы всегда одинаковые по размеру
Пока что да.

>Как узнать, в каком формате нужно передавать (jpg/png)?
Можно взять Saver у карты, а можно спросить и пользователя. См. как это сделано в TfrExportRMapsSQLite.GetBitmapTileSaver, там как раз все варианты присутствуют.

>ITileStorage.GetTileInfoEx - аналогичный вопрос: в каком формате возвращает
Можно узнать какой из интерфейсов поддерживается: IContentTypeInfoBitmap или IContentTypeInfoVectorData и получить Saver/Loader. Далее, можно сравнить свой Saver с полученным. Так можно проверить формат, но не настройки сохранения, они могут отличаться.

>вижу упоминания CGoogleProjectionEPSG. Чем она специальна?
Ничем. Просто RMaps других не понимает, если правильно помню, вот и происходит принудительная конвертация при необходимости.

>при закрытии вываливаются утечки, иногда - ошибки
Возможно это 0002050
(0016149)
zed (manager)
12-07-2015 17:23

Советую сделать свой отдельный экспорт с функцией наложения слоёв и выбором результирующего хранилища, проекции, формата тайлов и т.д. Взять за основу всё тот же RMaps. Из копирования можно взять момент с созданием интерфейса целевого хранилища. Скомбинировать всё это и получится желаемый результат. А вкладка копирования, это всё же отдельная песня и копирование обычно не подразумевает изменения. Так что туда лучше не встревать, особенно учитывая, что там есть возможность копировать сразу пачку хранилищ (и оно копируется не в одно хранилище, а точно в такую же пачку, но уже в другом месте).
(0016150)
GunSmoker (developer)
12-07-2015 18:00

Да-да, уже делаю две вкладки, одна - прямое копирование (как есть), вторая - с преобразованием (моё).
(0016151)
zed (manager)
12-07-2015 18:39

А смысл прямого копирования?
(0016152)
GunSmoker (developer)
12-07-2015 19:32

В смысле? Под "как есть" я имел в виду то, что сейчас делает вкладка "Скопировать". Там же прямое копирование тогда получается, или нет?
(0016153)
GunSmoker (developer)
12-07-2015 19:52

> Возможно это 0002050

Похоже некоторые потоки не закрываются при выходе из программы. Или не успевают завершиться. Возможно не отпускается ссылка на поток?
(0016154)
GunSmoker (developer)
13-07-2015 00:19

> Копирование из хранилища в хранилище происходит на самом низком уровне и там нету никаких преобразований. Тупо перекидывается бинарь из одного в другое.

1. Если источник - png, а сохраняется в jpg? Что тогда? Или получается, что формат хранилища не диктует формат файла?
2. Если не совпадают проекции источника/цели? Надо же конвертацию какую-то выполнить?
(0016155)
GunSmoker (developer)
13-07-2015 01:34

Кажется, что-то получилось.

Сделал новую вкладку, сделал отдельный модуль с новым потоком, на вход - BitmapLayerProviderMapWithLayer, как в RMaps, и TileStorage, как в Copy. Копирует с наложением в выбранный формат хранилища - ОК. Результат такого "модифицирующего" копирования вроде совпадает с "прямым копированием" - по файловой структуре и координатам в тайлах (за исключением самого содержимого рисунков, конечно - но если убрать слой наложения, то совпадает и контент рисунков).

Но, похоже, с преобразованием координат между слоями что-то не то (??). Если копировать гугл+гугл = ОК, если гугл+яндекс = ОК, а если яндекс+гугл = срабатывает Assert в TBitmap32StaticFactory.BuildWithOwnBuffer (FBackEndByStatic.FBitmapStatic = nil). Вроде как цикл в TMapType.LoadBitmap не выполняется ни разу. Сложно отлаживать, т.к. почему-то в этом коде 2007-я виснет постоянно (вместе с ОС).
(0016156)
zed (manager)
13-07-2015 02:05

>Под "как есть" я имел в виду
Ну вот мне и не понятно зачем делать тоже самое, что уже есть на другой вкладке. Разве что чисто потренироваться?

>Если источник - png, а сохраняется в jpg?
Как оно вдруг станет jpeg, если там нету конвертирования?

>Если не совпадают проекции источника/цели?
Источник и цель это кэш одной и той же карты, поэтому проекция там всегда одна. А вот если попытаться скопировать в кэш другой карты, то это уже на свой страх и риск, и нужно понимать что делаешь. Перепроецирования нету.

>а если яндекс+гугл = срабатывает Assert
Не видя кода, сложно сказать. Но "гугл+яндекс" это тоже разные проекции.

>2007-я виснет постоянно (вместе с ОС)
Я обычно использую XE2 при разработке, попробуй её. А D2007 только если приходится на старом железе в XP работать, ну и для проверки, что ночнушка соберётся.
(0016172)
GunSmoker (developer)
18-07-2015 09:43

Я XE в основном использую. Под ней на хостовой машине всё отладил - нашёл у себя в коде ошибку. Теперь вроде всё работает. Пока, правда, особо не тестировал.

Теперь вопрос - эти изменения как и куда заливать?
(0016173)
zed (manager)
18-07-2015 10:00

Порядок принятия изменений в код
(0016174)
GunSmoker (developer)
19-07-2015 04:10

zed, а не подскажешь, вот в 0000780 просили кэш вида <ZOOM>\<Y>\<X>.png. Мне как раз он нужен для экспорта. Вроде как он реализован в u_TileFileNameGM3.pas и обзывается rsGlobalMapperBingCacheName = 'GlobalMapper Bing'. Вопрос: почему он не создаётся в u_TileStorageTypeListSimple.pas?
(0016175)
zed (manager)
19-07-2015 07:58

Похоже, что про него просто забыли. Нужно добавлять.
(0016176)
zed (manager)
19-07-2015 09:22

Пофиксил: https://bitbucket.org/sas_team/sas.planet.src/commits/d271b7d95284db9041580a9865c3569a57eab0d3
(0016177)
GunSmoker (developer)
19-07-2015 15:06

Гы, я его тоже восстановил и думал заливать это или нет :)


Я ещё поиграюсь немного.
(0016191)
GunSmoker (developer)
21-07-2015 04:37

По основным исходникам - создал пул-реквест.

Но не могу сообразить, как правильно сделать внесение изменений в либы (requires)? Мне бы дефайны поправить для поддержки Delphi XE. Делаю форк и клон, вношу изменения, делаю коммит - а там же подхранилища, клиент хочет вносить изменения напрямую в ваши, а не в мой форк.
(0016192)
zed (manager)
21-07-2015 05:22

>По основным исходникам - создал пул-реквест.
Тогда ждём резолюции от vdemidov-а.
Ты, кстати, зачем свой форк приватным сделал? Этот реквест вживую теперь фиг проверишь перед принятием.

>как правильно сделать внесение изменений в либы (requires)
Делаешь клон конкретной либы, делаешь туда пул-реквест, а как их принять в корневой репо (requires) уже наша задача.

В какую либу надо вносить изменения?
(0016193)
GunSmoker (developer)
21-07-2015 05:36

> Ты, кстати, зачем свой форк приватным сделал? Этот реквест вживую теперь фиг проверишь перед принятием.

Я ж не знал :)

Поправил.

> Делаешь клон конкретной либы, делаешь туда пул-реквест, а как их принять в корневой репо (requires) уже наша задача.

Понял. У меня была проблема с поиском. Сейчас сделаю.
(0016199)
vdemidov (manager)
21-07-2015 07:30

Смотрю реквест. Ощущения двойственные. За первых три коммита вообще очень благодарен. Особенно за "Добавлены проверки на наличие указания выходного файла/папки перед началом работ по региону"
А вот к остальным есть претензии.
Во-первых, мне не нравится добавление работы с расширением в ITileFileNameGenerator, так как я его от туда старательно убирал (по факту этот интерфейс нужно было переименовать в ITileNameGenerator). А логика по добавлению '.tile' к именам файлов должна жить внутри соответствующего типа тайлохранилища (отдельный класс или дополнительный параметр в конструктор TTileStorageFileSystem)
Во-вторых, лучше было закладку копирования вообще не трогать, а добавить экспорт в тайлохранилище и там уже выбирать тип тайлохранилища в том числе и добавленный отдельно 'OsmAnd+ Tiles'
Ну и в-третьих, хорошо бы причесывать коммиты перед созданием пул реквеста, что бы по возможности не было некомпилируемых по-отдельности коммитов как получились два предпоследних.

Но, если сильно лень переделывать и так приму, так как пользы от реквеста все-таки гораздо больше чем моих претензий.
(0016201)
GunSmoker (developer)
21-07-2015 08:16

Могу переделать вот это, но, наверное, будет это не ранее след. выходных:

"Во-первых, мне не нравится добавление работы с расширением в ITileFileNameGenerator, так как я его от туда старательно убирал (по факту этот интерфейс нужно было переименовать в ITileNameGenerator). А логика по добавлению '.tile' к именам файлов должна жить внутри соответствующего типа тайлохранилища (отдельный класс или дополнительный параметр в конструктор TTileStorageFileSystem)"
(0016202)
vdemidov (manager)
21-07-2015 08:22

Тогда принимаю как есть, а там разберемся.
(0016206)
zed (manager)
21-07-2015 11:32

Обращаю внимание на:
1. [DCC Warning] u_TileFileNameOsmAnd.pas(101): H2443 Inline function 'SameFileName' has not been expanded because unit 'Windows' is not specified in USES list
2. В dpr файле не отсортированы имена юнитов (нужно запустить Tools\UnitsSort.py см. 0002693)
3. В гуе на вкладке скопировать не вмещаются контролы, окно нужно растянуть по вертикали, чтобы по-умолчанию всё было видно.
(0016207)
zed (manager)
21-07-2015 11:37

И вопрос по поводу пул-реквеста в alcinoe - там точно эти фиксы необходимы?
(0016219)
GunSmoker (developer)
23-07-2015 07:01

Замечания поправлю.

> там точно эти фиксы необходимы?

Да, конечно. В XE же нет namespace-в для стандартных модулей. Они появились только в XE2. Так что для XE2 - "System.AnsiStrings.ЧТОТО", для XE - "AnsiStrings.ЧТОТО".
(0016220)
GunSmoker (developer)
24-07-2015 09:54

Можно вопрос: зачем пишется код вида:

destructor TSomething.Destroy;
var
  I: integer;
begin
  for I := 0 to Length(FItems) - 1 do begin
    FItems[I] := nil;
  end;
  FItems := nil;
  inherited;
end;

Где FItems - динамический массив из интерфейсов.

Это для упрощения отладки? Или остатки от старого не-интерфейсного кода?
(0016221)
vdemidov (manager)
24-07-2015 10:29

Скорее всего остатки старого неинтерфейсного кода, или случая когда FItems было просто указателем, или случая когда FItems было TList
(0016222)
GunSmoker (developer)
24-07-2015 12:24

"мне не нравится добавление работы с расширением в ITileFileNameGenerator, так как я его от туда старательно убирал (по факту этот интерфейс нужно было переименовать в ITileNameGenerator). А логика по добавлению '.tile' к именам файлов должна жить внутри соответствующего типа тайлохранилища (отдельный класс или дополнительный параметр в конструктор TTileStorageFileSystem)"

Как в этом случае быть с экспортом в архив? Для генерации имени файла внутри архива там используется TileNameGenerator, а не хранилище (хранилище идёт только как источник). А расширение там вообще присовокупляется вручную - прямо в цикле. Создавать полноценный ITileStorage только для этого?
(0016223)
GunSmoker (developer)
24-07-2015 12:32

Может сделать так: пусть TileNameGenerator поддерживает (новый) доп. интерфейс, в который вынести формирование имени файла. Пусть дефолтный TileStorage пытается запрашивать у TileNameGenerator этот новый интерфейс. Если он есть - делегировать формирования имени ему. Если нет - добавить расширение самому. Тогда не понадобится два новых класса для OsmAnd (TileStorage и TileStorageType). И экспорт в архив сможет правильно формировать имена файлов, не имея на руках полноценного TileStorage.
(0016224)
vdemidov (manager)
24-07-2015 12:43

> Создавать полноценный ITileStorage только для этого?
Может и не совсем полноценный, а работающий только на запись, но ИМХО это правильней.
Сделать список всех доступных типов тайлохранилищ. У каждого есть набор доступных режимов работы: на импорт (однократный проход итератором), на экспорт (однократная запись), произвольный доступ на чтение, произвольный доступ на запись. И уже из этого списка формировать доступные для разных операций типа экспорта или параметров карты.
Тогда можно будет избавиться от отдельных экспортов в разные архивы. Это будет один экспорт в тайлохранилище с выбором типа этого тайлохранилища.
 
Но это так - мечты. Я пытаюсь постепенно к этом привести всю систему, но времени мало и часто отвлекаюсь на другие задачи. Поэтому и не настаивал на каких либо исправлениях.
(0016225)
vdemidov (manager)
24-07-2015 12:44

>Может сделать так: пусть TileNameGenerator поддерживает (новый) доп. интерфейс, в который вынести формирование имени файла.
Не, оно того не стоит.
(0016229)
zed (manager)
26-07-2015 16:13

Может уже стоит отметить тикет как отработанный? Или там планируется ещё что-то сделать?

- Users who viewed this issue
User List Anonymous (3927x), vdemidov (45x), ingener (2x), GunSmoker (74x), gma (1x), zed (54x), Garl (1x), vasketsov (8x), bk99 (1x)
Total Views 4113
Last View 24-04-2024 23:10

- Issue History
Date Modified Username Field Change
10-07-2015 20:33 GunSmoker New Issue
10-07-2015 20:36 GunSmoker Tag Attached: SQLite
10-07-2015 20:36 GunSmoker Tag Attached: склейка
10-07-2015 20:36 GunSmoker Tag Attached: экспорт
10-07-2015 20:59 zed Note Added: 0016120
12-07-2015 04:36 GunSmoker Note Added: 0016142
12-07-2015 06:40 zed Note Added: 0016143
12-07-2015 06:48 zed Note Added: 0016144
12-07-2015 10:14 vdemidov Note Added: 0016145
12-07-2015 16:10 GunSmoker Note Added: 0016146
12-07-2015 16:14 GunSmoker Note Added: 0016147
12-07-2015 16:24 GunSmoker Note Edited: 0016146 View Revisions
12-07-2015 16:27 GunSmoker Note Edited: 0016146 View Revisions
12-07-2015 16:29 GunSmoker Note Edited: 0016146 View Revisions
12-07-2015 17:08 zed Note Added: 0016148
12-07-2015 17:23 zed Note Added: 0016149
12-07-2015 18:00 GunSmoker Note Added: 0016150
12-07-2015 18:39 zed Note Added: 0016151
12-07-2015 19:32 GunSmoker Note Added: 0016152
12-07-2015 19:52 GunSmoker Note Added: 0016153
13-07-2015 00:19 GunSmoker Note Added: 0016154
13-07-2015 01:34 GunSmoker Note Added: 0016155
13-07-2015 02:05 zed Note Added: 0016156
13-07-2015 02:11 zed Assigned To => GunSmoker
13-07-2015 02:11 zed Status new => assigned
13-07-2015 02:11 zed Product Version .Nightly => 141212
13-07-2015 02:11 zed Target Version => 150915
18-07-2015 09:43 GunSmoker Note Added: 0016172
18-07-2015 10:00 zed Note Added: 0016173
19-07-2015 04:10 GunSmoker Note Added: 0016174
19-07-2015 07:58 zed Note Added: 0016175
19-07-2015 09:22 zed Note Added: 0016176
19-07-2015 15:06 GunSmoker Note Added: 0016177
21-07-2015 04:37 GunSmoker Note Added: 0016191
21-07-2015 05:22 zed Note Added: 0016192
21-07-2015 05:36 GunSmoker Note Added: 0016193
21-07-2015 07:30 vdemidov Note Added: 0016199
21-07-2015 08:16 GunSmoker Note Added: 0016201
21-07-2015 08:22 vdemidov Note Added: 0016202
21-07-2015 11:32 zed Note Added: 0016206
21-07-2015 11:37 zed Note Added: 0016207
23-07-2015 07:01 GunSmoker Note Added: 0016219
24-07-2015 09:54 GunSmoker Note Added: 0016220
24-07-2015 10:29 vdemidov Note Added: 0016221
24-07-2015 12:24 GunSmoker Note Added: 0016222
24-07-2015 12:32 GunSmoker Note Added: 0016223
24-07-2015 12:43 vdemidov Note Added: 0016224
24-07-2015 12:44 vdemidov Note Added: 0016225
26-07-2015 16:13 zed Note Added: 0016229
26-07-2015 17:11 vdemidov Status assigned => resolved
26-07-2015 17:11 vdemidov Fixed in Version => 150915
26-07-2015 17:11 vdemidov Resolution open => fixed
31-07-2015 11:56 vdemidov Relationship added related to 0000325
31-07-2015 12:27 vdemidov Relationship added related to 0001680
03-08-2015 08:43 vdemidov Relationship added related to 0002779



Copyright © 2007 - 2024 SAS.Planet Team