Anonymous | Login | Signup for a new account | 23-11-24 08:14 UTC |
All Projects | SAS.Планета | Домен, сайт, форум, багтрекер | Доработка карты (ZMP) | Переводы и локализации | Прочее |
My View | View Issues | Change Log | Roadmap | Search |
View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0002763 | SAS.Планета | [All Projects] Хотелка | public | 10-07-2015 20:33 | 03-08-2015 08:43 | ||||
Reporter | GunSmoker | ||||||||
Assigned To | GunSmoker | ||||||||
Priority | normal | Severity | minor | Reproducibility | N/A | ||||
Status | resolved | Resolution | fixed | ||||||
Platform | Windows | OS | 8.1 | OS Version | x64 | ||||
Product Version | 141212 | ||||||||
Target Version | 150915 | Fixed in Version | 150915 | ||||||
Summary | 0002763: Добавить возможность наложения слоёв при экспорте/копировании | ||||||||
Description | Хочется выгрузить карту в PNG тайлы и подсунуть её программе. Нужен спутник (Google) с наложением поверх его гибрида. В настоящее время возможность наложения есть только для экспорта в sqlite/RMaps ( 0001823 ). Я посмотрел результат склейки RMaps - там в БД лежат готовые тайлы с уже наложенным поверх слоем. Т.е. код наложения уже есть и работает. Собственно, непонятно, что мешает сделать эту же возможность для всех прочих операций копирования/экспорта. | ||||||||
Additional Information | Когда-то такая задача решалась утилитой SASMerge, которая сегодня мертва и больше не доступна. | ||||||||
Tags | SQLite, склейка, экспорт | ||||||||
Attached Files | |||||||||
Relationships | ||||||||||||||||
|
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) и сохраняется в хранилище или ещё куда угодно. Главное понимать в какой проекции получился ваш тайл и какую проекцию ожидает/поддерживает хранилище или целевой формат, если речь о экспорте. Проекцию вы може взять либо у исходного хранилища из которого читаете тайлы:
Либо создать одну из 3-х доступных:
И в итоге, с координатами вам вообще не нужно иметь дела, да и тайлохранилища спрятаны за интерфейсами, так что вы даже не почувствуете разницы при записи в разные типы. Если что-то не понятно, спрашивайте. |
(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 (4245x), vdemidov (45x), ingener (2x), GunSmoker (74x), gma (1x), zed (54x), Garl (1x), vasketsov (8x), bk99 (1x) |
Total Views | 4431 |
Last View | 23-11-2024 08:14 |
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 |
My View | View Issues | Change Log | Roadmap | Search |
Copyright © 2007 - 2024 SAS.Planet Team |