SASGIS - SAS.Планета
View Issue Details
0001288SAS.Планета[All Projects] Багpublic04-05-2012 21:4319-10-2012 12:44
Dima2000 
vdemidov 
normaltweakalways
resolvedfixed 
WindowsXPProfessional SP3
120808 
131111131111 
0001288: Баг в вызове спирального итератора ("от короеда"?)
Что-то уже довольно давно итератор (от "короеда"?) стал явно тяготеть к правой стороне. До идиотизма доходит, когда правая половина экрана заполнена уже практически полностью, а левая - ни одного тайла. Такое впечатление сложилось после проверки глазками последовательности отображения, что центр экрана считается на 1 тайл правее реального. Раньше было правильнее.
Включаем формирование карты заполнения по гарантированно отсутсвующей карте или слою, выбираем заполнять +7 от текущего зума, центрируем карту двойным щелчком в центр любого тайла, смотрим в каком порядке итератор заполняет экран.
Конкретнее, перебор идёт такой (перед проверкой экран отцентрирован в центр тайла, он 07-й в последовательности перебора):
120503.5485:
35_30_23_24_25_10_11
34_29_22_08_09_02_12
33_28_21_07_01_03_13
32_27_20_06_05_04_14
31_26_19_18_17_16_15
Экран у меня 1680х1050, покрывается тайлами 7х5 с запасом. Видно что перебор смещён вправо на тайл.
Причём между шагами 25 и 26 есть пауза где-то в три тайла, непонятно с какой радости, ведь не отображаемые тайлы не должны проверяться, а тут похоже идёт проверка координаты справа за экраном.
И вот на 18-м шаге практически половина экрана (правая) заполнена, а вся левая пустая. Весьма некрасиво.

Для сравнения, в последнем релизе перебор идёт правильно:
110418:
35_23_24_25_10_11_26
34_22_08_09_02_12_27
33_21_07_01_03_13_28
32_20_06_05_04_14_29
31_19_18_17_16_15_30
Я думал ошибка сидит в самом итераторе, но нет, она выше. О баге писал на форуме (http://sasgis.org/forum/viewtopic.php?f=47&p=28185#p27578).
короед
? u_LocalCoordConverterFactorySimpe.pas (8,751) 10-05-2012 19:39
http://www.sasgis.org/mantis/file_download.php?file_id=794&type=bug
? u_TileIteratorWideSpiralByRect.pas (9,232) 11-05-2012 13:29
http://www.sasgis.org/mantis/file_download.php?file_id=796&type=bug
Issue History
04-05-2012 21:43Dima2000New Issue
04-05-2012 21:45Dima2000Note Added: 0006672
04-05-2012 21:46Dima2000File Added: u_TileIteratorSpiralByRect.zip
04-05-2012 21:55Dima2000Note Edited: 0006672bug_revision_view_page.php?bugnote_id=6672#r3271
04-05-2012 22:10Dima2000Note Added: 0006673
05-05-2012 05:43TolikStatusnew => acknowledged
05-05-2012 07:32vasketsovNote Added: 0006680
05-05-2012 07:34vasketsovNote Edited: 0006680bug_revision_view_page.php?bugnote_id=6680#r3275
05-05-2012 07:35vasketsovNote Edited: 0006680bug_revision_view_page.php?bugnote_id=6680#r3276
05-05-2012 10:05Dima2000Note Added: 0006682
05-05-2012 10:07Dima2000File Added: IteratorTest.zip
05-05-2012 10:42vasketsovNote Added: 0006700
05-05-2012 11:44Dima2000Note Added: 0006737
05-05-2012 11:51vasketsovNote Added: 0006743
05-05-2012 11:58Dima2000Note Added: 0006745
05-05-2012 12:06vasketsovNote Added: 0006751
05-05-2012 12:17Dima2000Note Added: 0006757
06-05-2012 06:26Dima2000Note Added: 0006825
06-05-2012 06:38zedNote Added: 0006826
06-05-2012 07:04Dima2000Note Added: 0006828
06-05-2012 07:05Dima2000Note Edited: 0006828bug_revision_view_page.php?bugnote_id=6828#r3333
06-05-2012 19:49Dima2000File Added: u_TileIteratorSpiralByRect.pas
06-05-2012 19:57Dima2000Note Added: 0006834
06-05-2012 20:07Dima2000Note Added: 0006835
06-05-2012 20:22Dima2000Note Added: 0006836
06-05-2012 20:28Dima2000File Added: u_TileIteratorSpiralByRect..pas
06-05-2012 20:29Dima2000Note Added: 0006837
07-05-2012 06:09GarlFile Deleted: u_TileIteratorSpiralByRect.pas
07-05-2012 06:22vdemidovNote Added: 0006839
07-05-2012 08:55vasketsovNote Added: 0006841
07-05-2012 09:21vdemidovNote Added: 0006842
07-05-2012 09:27vdemidovNote Added: 0006843
07-05-2012 09:28vdemidovNote Added: 0006844
07-05-2012 10:25zedNote Added: 0006845
07-05-2012 11:27Dima2000Note Added: 0006848
07-05-2012 11:30Dima2000Note Edited: 0006848bug_revision_view_page.php?bugnote_id=6848#r3349
07-05-2012 11:36Dima2000Note Edited: 0006848bug_revision_view_page.php?bugnote_id=6848#r3350
07-05-2012 11:43vdemidovNote Added: 0006849
07-05-2012 12:01Dima2000Note Added: 0006850
07-05-2012 12:07Dima2000Note Added: 0006852
07-05-2012 12:19Dima2000Note Added: 0006855
07-05-2012 12:20Dima2000Note Edited: 0006855bug_revision_view_page.php?bugnote_id=6855#r3357
07-05-2012 12:30vasketsovNote Added: 0006856
07-05-2012 12:32vdemidovNote Added: 0006857
07-05-2012 12:35vdemidovNote Added: 0006858
07-05-2012 12:36vdemidovNote Added: 0006859
07-05-2012 12:40Dima2000Note Added: 0006860
07-05-2012 12:43Dima2000Note Added: 0006861
07-05-2012 12:47Dima2000Note Added: 0006862
07-05-2012 12:47vdemidovNote Added: 0006863
07-05-2012 12:49vdemidovNote Added: 0006864
07-05-2012 13:07Dima2000Note Added: 0006865
07-05-2012 13:13vdemidovNote Added: 0006866
07-05-2012 13:16Dima2000Note Added: 0006867
07-05-2012 13:19Dima2000Note Added: 0006868
07-05-2012 13:20vdemidovNote Added: 0006869
07-05-2012 13:23Dima2000Note Edited: 0006867bug_revision_view_page.php?bugnote_id=6867#r3362
07-05-2012 13:23vdemidovNote Added: 0006870
07-05-2012 13:25vdemidovNote Added: 0006871
07-05-2012 13:26vdemidovNote Added: 0006872
07-05-2012 13:31Dima2000Note Added: 0006873
07-05-2012 13:34Dima2000Note Edited: 0006873bug_revision_view_page.php?bugnote_id=6873#r3364
07-05-2012 13:36Dima2000Note Edited: 0006873bug_revision_view_page.php?bugnote_id=6873#r3365
07-05-2012 13:38Dima2000Note Edited: 0006873bug_revision_view_page.php?bugnote_id=6873#r3366
07-05-2012 13:42Dima2000Note Edited: 0006873bug_revision_view_page.php?bugnote_id=6873#r3367
07-05-2012 13:45Dima2000Note Edited: 0006873bug_revision_view_page.php?bugnote_id=6873#r3368
07-05-2012 13:50Dima2000Note Edited: 0006873bug_revision_view_page.php?bugnote_id=6873#r3369
07-05-2012 13:59Dima2000File Added: u_LocalCoordConverterFactorySimpe.pas
07-05-2012 14:02Dima2000Note Added: 0006874
07-05-2012 14:03Dima2000Note Edited: 0006874bug_revision_view_page.php?bugnote_id=6874#r3372
07-05-2012 14:07vdemidovNote Added: 0006875
07-05-2012 14:09Dima2000Note Added: 0006876
07-05-2012 14:10Dima2000Note Edited: 0006876bug_revision_view_page.php?bugnote_id=6876#r3374
07-05-2012 14:11vdemidovNote Added: 0006877
07-05-2012 14:11vdemidovFile Deleted: u_LocalCoordConverterFactorySimpe.pas
07-05-2012 14:12Dima2000File Added: u_LocalCoordConverterFactorySimpe.win.pas
07-05-2012 14:12vdemidovNote Added: 0006878
07-05-2012 14:20Dima2000Note Added: 0006879
07-05-2012 14:50vdemidovNote Added: 0006880
07-05-2012 15:01Dima2000Note Added: 0006881
07-05-2012 16:49vasketsovNote Added: 0006883
07-05-2012 16:51vasketsovNote Edited: 0006883bug_revision_view_page.php?bugnote_id=6883#r3376
07-05-2012 20:14Dima2000File Deleted: u_LocalCoordConverterFactorySimpe.win.pas
07-05-2012 20:14Dima2000File Added: u_LocalCoordConverterFactorySimpe.pas
07-05-2012 20:16Dima2000Note Added: 0006884
07-05-2012 20:27Dima2000Note Edited: 0006884bug_revision_view_page.php?bugnote_id=6884#r3378
07-05-2012 20:36Dima2000Note Added: 0006885
07-05-2012 21:09Dima2000Note Edited: 0006885bug_revision_view_page.php?bugnote_id=6885#r3380
08-05-2012 05:38vdemidovNote Added: 0006886
08-05-2012 10:48Dima2000Note Added: 0006887
08-05-2012 11:01vdemidovNote Added: 0006888
08-05-2012 11:34Dima2000Note Added: 0006889
08-05-2012 11:38Dima2000Note Edited: 0006887bug_revision_view_page.php?bugnote_id=6887#r3389
08-05-2012 12:03Dima2000Note Added: 0006890
08-05-2012 12:05vdemidovNote Added: 0006891
08-05-2012 12:05Dima2000Note Edited: 0006890bug_revision_view_page.php?bugnote_id=6890#r3391
08-05-2012 12:07vdemidovNote Added: 0006892
08-05-2012 12:10Dima2000Note Added: 0006893
08-05-2012 12:13Dima2000Note Added: 0006894
08-05-2012 12:18Dima2000Note Edited: 0006893bug_revision_view_page.php?bugnote_id=6893#r3393
08-05-2012 19:01vdemidovNote Added: 0006897
08-05-2012 20:46Dima2000Note Added: 0006910
09-05-2012 12:14Dima2000File Deleted: u_TileIteratorSpiralByRect.zip
09-05-2012 12:14Dima2000File Deleted: u_TileIteratorSpiralByRect..pas
09-05-2012 12:15Dima2000File Deleted: IteratorTest.zip
09-05-2012 12:16Dima2000File Added: u_TileIteratorWideSpiralByRect.pas
09-05-2012 12:17Dima2000Note Added: 0006913
09-05-2012 19:02vdemidovNote Added: 0006914
09-05-2012 21:24Dima2000Note Added: 0006916
10-05-2012 19:39Dima2000File Deleted: u_LocalCoordConverterFactorySimpe.pas
10-05-2012 19:39Dima2000File Added: u_LocalCoordConverterFactorySimpe.pas
10-05-2012 19:41Dima2000Note Added: 0006927
10-05-2012 19:52Dima2000Note Edited: 0006927bug_revision_view_page.php?bugnote_id=6927#r3406
10-05-2012 19:52Dima2000Note Edited: 0006927bug_revision_view_page.php?bugnote_id=6927#r3407
10-05-2012 20:25vasketsovNote Added: 0006929
10-05-2012 20:36Dima2000Note Added: 0006930
10-05-2012 20:38Dima2000Note Added: 0006931
10-05-2012 20:45Dima2000Note Edited: 0006930bug_revision_view_page.php?bugnote_id=6930#r3409
10-05-2012 21:02vasketsovNote Added: 0006932
10-05-2012 21:17Dima2000Note Added: 0006933
11-05-2012 05:30vdemidovNote Added: 0006937
11-05-2012 11:52Dima2000Note Added: 0006957
11-05-2012 12:10Dima2000Note Edited: 0006957bug_revision_view_page.php?bugnote_id=6957#r3431
11-05-2012 13:29Dima2000File Deleted: u_TileIteratorWideSpiralByRect.pas
11-05-2012 13:29Dima2000File Added: u_TileIteratorWideSpiralByRect.pas
11-05-2012 13:31Dima2000Note Added: 0006961
13-05-2012 09:02gpsMaxTag Attached: короед
09-08-2012 06:54vdemidovProduct Version.Nightly => 120808
19-10-2012 12:44vdemidovNote Added: 0009606
19-10-2012 12:44vdemidovStatusacknowledged => resolved
19-10-2012 12:44vdemidovFixed in Version => 131111
19-10-2012 12:44vdemidovResolutionopen => fixed
19-10-2012 12:44vdemidovAssigned To => vdemidov
19-10-2012 12:44vdemidovTarget Version => 131111

Notes
(0006672)
Dima2000   
04-05-2012 21:45   
(edited on: 04-05-2012 21:55)
Кроме исправления данного глюка со смещением центра, предлагаю сплюснуть спираль до такой:
25_26_27_28_29_30_31
24_09_10_11_12_13_32
23_08_02_01_03_14_33
22_07_06_05_04_15_34
21_20_19_18_17_16_35
Главное отличие в первых 3-х шагах. Да и потом логичнее спираль строится.
На "широких" экранах этот перебор выглядит существенно лучше. На обычных (вообще-то они тоже сплюснуты, ну да ладно) разница непринципиальна. Подробнее есть там же на форуме - http://sasgis.org/forum/viewtopic.php?f=47&p=28185#p28185
Вам ничего писать и исправлять не надо, лишь подменить один файлик в исходниках Планеты. Его сейчас приложу и сюда.
Приложил. Garl-у отдельное спасибо что пересобрал для проверки Планету с бета версией данного класса. Ошибок не обнаружено.

(0006673)
Dima2000   
04-05-2012 22:10   
Кстати, у "короеда" (что сейчас работает в Планете) спираль вообще не совсем правильная, с чего вдруг шаг в следующее кольцо делается по диагонали?! Конкретно, шаги 02, 11 сделаны явно нелогично, они разрывают непрерывную линию спирали, она же должна (и этого достаточно!) двигаться лишь по 4-м направлениям. Это не спираль, а скорее набор колец, со странным выбором начальной точки в каждом.
(0006680)
vasketsov   
05-05-2012 07:32   
(edited on: 05-05-2012 07:35)
Можно пример построения спирали для экранов 9x5 и 9x6 тайлов?

>не отображаемые тайлы не должны проверяться
(голосом Йоды) Есть на эту тему настройка специальная.

(0006682)
Dima2000   
05-05-2012 10:05   
Предлагаемая спираль:
9х5:
40_25_26_27_28_29_30_31_41
39_24_09_10_11_12_13_32_42
38_23_08_02_01_03_14_33_43
37_22_07_06_05_04_15_34_44
36_21_20_19_18_17_16_35_45

9х6:
48_25_26_27_28_29_30_31_49
47_24_09_10_11_12_13_32_50
46_23_08_02_01_03_14_33_51
45_22_07_06_05_04_15_34_52
44_21_20_19_18_17_16_35_53
43_42_41_40_39_38_37_36_54

Для чётных размеров центр сознательно смещён влево/вверх (а не вправо/вниз), мне показалось это более логичным, так заполняет красивее. Хотя для небольших размеров может и кривовато будет. Я уже записал себе в ToDo додумать этот вопрос и возможно для мелких размеров сделать вообще табличку из десятка элементов, уж её можно заполнить как угодно.

Для тестов приложу сюда консольную прогу с исходником, выводящую любую спираль (в консоль!). Запускать с двумя параметрами - размеры по горизонтали и вертикали. Или с четырьмя - координаты углов. Прога чисто тестовая, писалась под себя, лишь для тестов класса, потому стандартам не соответствует.
(0006700)
vasketsov   
05-05-2012 10:42   
>записал себе в ToDo додумать этот вопрос
Тогда ещё хинт для додумывания: построение нескольких спиралей исходя из числа потоков (а не все потоки набрасываются на одну спираль), потом когда поток освобождается - он идёт к соседу за остатком работы по соседовой спирали.
(0006737)
Dima2000   
05-05-2012 11:44   
Oops... Делать интерфейс между потоками, синхронизацию, обмен данными и учёт возможности разных параметров ... Мрак.
Вот делать шаг не только единичный, а любой положительный - это можно. Но будут пропуски.
Но зачем? Спиральный итератор вызывается лишь для показа тайлов (и показа карты заполнения и миникарты), т.е. область никогда не превышает размеров экрана, а это ну пара сотен итераций всего лишь. Зачем городить сложности?

PS. Думаю как было бы красиво при построении карты заполнения для каждого тайла текущего зума запустить отдельный итератор тайлов проверяемого зума... Такие спиральки в каждом тайле ... Красота! Прям почти нирвана. :) Но это можно и сейчас, переделывать не класс итератора, а лишь его вызов.
(0006743)
vasketsov   
05-05-2012 11:51   
Для скачки
(0006745)
Dima2000   
05-05-2012 11:58   
Для скачки кто-то уже предлагал похожее, сделать шаг более 1, чтобы качалось в "псевдослучайном" порядке, очень удобно проверять где есть тайлы. Заглохло.

Ок, добавлю в ToDo хинт сделать проход спирали не подряд, а с заранее заданным шагом и начальным смещением. Этого достаточно чтобы запустить одновременно несколько итераторов с разными начальными значениями. Никакого сообщения между ними не нужно и не будет. Да, не универсально, зато просто.
(0006751)
vasketsov   
05-05-2012 12:06   
>не универсально, зато просто
Ну в общем да, простая арифметическая прогрессия, шаг N, стартовать можно от 0 до (N-1). Когда тайлы уже перенумерованы и развёрнуты в кусок чисел {Z+}.
(0006757)
Dima2000   
05-05-2012 12:17   
Да, именно так. Только всё на лету разумеется, это просто.
(0006825)
Dima2000   
06-05-2012 06:26   
>>не отображаемые тайлы не должны проверяться
>(голосом Йоды) Есть на эту тему настройка специальная.
Если вы про "Кол-во тайлов, загружаемых за границей экрана" в настройках программы, то оно конечно 0. А пауза между шагами есть. Может она по какой другой причине, я не знаю.
(0006826)
zed   
06-05-2012 06:38   
>А пауза между шагами есть
А в параметрах карты пауза установлена? При много-поточной закачке может наблюдаться такой эффект, когда все потоки встают на паузу и не остаётся ни одного активного.
(0006828)
Dima2000   
06-05-2012 07:04   
(edited on: 06-05-2012 07:05)
Я проверял не закачку, а формирование карты заполнения. Всё с диска. Так инет и настройки влиять не должны. Итератор там ипользован тот же.

(0006834)
Dima2000   
06-05-2012 19:57   
Обновил версию итератора до v3.
Теперь поддерживается формирование как сплюснутой спирали, так и квадратной (выбирается в конструкторе). Для малых размеров по любой из осей спираль строится всегда квадратной (так красивее и меньше глюков).
Поддерживается несколько итераторов одной спирали - задаётся в конструкторе количество итераторов и номер каждого. Что будет если им передать разные параметры - не мои проблемы. :) Не вылетят разумеется, но некоторые тайлы не будут выданы, а некоторые выдадут по несколько раз.
Если не использовать дополнительные возможности (как сейчас в Планете), то выдаётся непрерывная сплюснутая спираль. Класс всё так же готов к замене встроенного в Планету...
Пример квадратной спирали 9х5:
45_35_21_22_23_24_25_26_36
44_34_20_07_08_09_10_27_37
43_33_19_06_01_02_11_28_38
42_32_18_05_04_03_12_29_39
41_31_17_16_15_14_13_30_40
(0006835)
Dima2000   
06-05-2012 20:07   
А багу значит так и не хотите искать? Почему в VTileSourceRect (u_MapLayerFillingMap.pas:173) попадает координата на 1 большая по Х? Там какие-то странные вычисления с проекциями, я не понимаю зачем. Но вот что в результате при установке экрана в центр тайла центральным тайлом считается следующий правый - баг! А если это баг в расчёте проекций?! Или пока никто не заметит так и фик с ним? :(
(0006836)
Dima2000   
06-05-2012 20:22   
Ну и конечно забыл поправить класс обратно к стандарту Планеты, сейчас он не потомок более общего итератора, а отдельный класс. :( Надо в 5-ти местах где есть символы '//' совершенно очевидно чуть подправить.
А может и не надо, я не понял зачем итераторы все потомки одного базового класса, насколько я вижу Планета этим нигде не пользуется (по крайней мере для спирального итератора).
(0006837)
Dima2000   
06-05-2012 20:29   
Я понял, проше самому поправить и перевыложить. С тем же именем не дали (дубликат надо удалить сначала, таких прав у меня нет), выложил поправленный с лишней точкой в имени.
(0006839)
vdemidov   
07-05-2012 06:22   
>А багу значит так и не хотите искать?
Это не баг, а фитча. Специально строиться прямоугольник тайлов с запасом покрывающий видимый участок и стабильный по размеру при малых сдвигах.
(0006841)
vasketsov   
07-05-2012 08:55   
>с запасом покрывающий видимый участок
Любой короед с запасом за конечное время покроет любой экран. Вопрос только в числе шагов.

>стабильный по размеру при малых сдвигах
Это что имеется в виду? Априори сдвиги произвольные - думается короед должен быть центральносимметричным прежде всего. Ведь выделенного направления нет. Вот разве что когда едешь с GPSом - тогда оно (выделенное направление) появляется.
(0006842)
vdemidov   
07-05-2012 09:21   
>>с запасом покрывающий видимый участок
>Любой короед с запасом за конечное время покроет любой экран. Вопрос только в числе шагов.
А это тут при чем? Речь идет об подготавливаемой к отображению области.

Имеется в виду то, что сдвиг на произвольное количество пикселей, не приводит к изменению общего размера битмапки. Объясняю на пальцах. Представьте, что у нас отображаемая на экране область 256 пикселов. Размер тайла тоже 256 пиксело. Сколько тайлов по горизонтали нам нужно, что бы покрыть гарантировано экран? Правильный ответ 2 тайла.
(0006843)
vdemidov   
07-05-2012 09:27   
А теперь представьте, что экран у нас 258 пикселов. Сколько нужно тайлов что бы гарантировано покрыть его? Правильный ответ 3 тайла в худшем случае. Это кода от первого и последнего тайлов только по одному столбцу пикселей отображается. Но мы же не хочем каждый раз ресайзить большую битмапку. Поэтому приходится держать битмапку в 3 тайла размером. И при текущем алгоритме расчета этого прямоугольника получается, что остается почти тайл справа от отображаемой области.
А короед просто попадает на результаты этого.
(0006844)
vdemidov   
07-05-2012 09:28   
Кстати. Новый основной слой и новый слой карты заполнения этим уже могут и не страдать. Им не нужно держать полную битмапку как одно целое.
(0006845)
zed   
07-05-2012 10:25   
Кстати, новый основной слой иногда подлагивает - после закачки тайла, слой может забыть перерисовать гуй. Помогает только смена зума.
(0006848)
Dima2000   
07-05-2012 11:27   
(edited on: 07-05-2012 11:36)
Про запас я конечно знаю. Потому и размер у себя 7*5 - это гарантированно покрывает тайлами экран 1680*1050, довольно симметрично по всем сторонам. К запасу претензий нет.

Почему экран отцентрированный ТОЧНО в центр тайла (специально проверял на зуме +16 от текущего!) начинает заполняться правее центра? Имхо это баг.

>при текущем алгоритме расчета этого прямоугольника получается, что остается почти тайл справа от отображаемой области.
Вот-вот, похоже. Плохой алгоритм. Битмапка должна одинаково вылезать вправо/влево/вверх/вниз, тогда и центр будет в центре, и запасы везде будут одинаковы.
Наверное где-то в расчете участвует угол(ы) тайла, а не центр, вот и получается ненужное смещение.

>и стабильный по размеру при малых сдвигах.
Принцип хороший, только запасы надо делать не лишь вправо/вниз, а одинаково во все стороны от центра. И центр останется центром, и сдвиги будут одинаково "безопасны".

А вообще, есть понятие "отображаемые тайлы" - такие, в которые попал хотя бы один пиксель экрана - вот по их границам и надо строить битмапку. Минимально необходимый запас учтётся автоматом. Можно и увеличить размер битмапки на 2*N тайла по горизонтали и вертикали (N тайлов слева/справа и сверху/снизу). И не будет никаких левых смещений.

>должен быть центральносимметричным прежде всего
Да, да! Он сам такой и есть, вот только вызвается похоже ВСЕГДА кривовато. :)

(0006849)
vdemidov   
07-05-2012 11:43   
>А вообще, есть понятие "отображаемые тайлы" - такие, в которые попал хотя бы один пиксель экрана - вот по их границам и надо строить битмапку.
Ага. Только тогда при сдвиге на пару пикселей придется ресайзить битмапку. Потому что в экран будет попадать то 7 то 8 тайлов. А этого нужно избегать. Другое дело, что можно сделать это чуток умнее, что бы лишний тайл был то слева то справа, но мне лень придумвать. Текущий алгоритм меня устраивает на 200% Если сможете поменять алгоритм не потеряв свойства стабильности прямоугольника придумывайте.
(0006850)
Dima2000   
07-05-2012 12:01   
Правильный ответ для размера экрана H пикселей и размера тайла S пикселей: N = (H + 2 * S - 2) div S.
(0006852)
Dima2000   
07-05-2012 12:07   
>Только тогда при сдвиге на пару пикселей придется ресайзить битмапку.
Я же предложил расширить битмапку за границы экрана на 1 отображаемый тайл (уж не такие большие экраны у нас пока). При этом никакой сдвиг до размера тайла не потребует пересчёта битмапки. Уж гораздо проще просчитать битмапку и потом её обрезать по экрану в момент показа.

>умнее, что бы лишний тайл был то слева то справа,
Вот как раз этого и не надо! Надо расширить битмапку СИММЕТРИЧНО! Чтобы центр битмапки остался в центре экрана! Сейчас он смещён вправо (и видимо вниз). А уж куда битмапка будет на несколько пикселей вылезать из экрана при малом сдвиге - дело десятое.
(0006855)
Dima2000   
07-05-2012 12:19   
(edited on: 07-05-2012 12:20)
>Если сможете поменять алгоритм
Скажите, а достаточно ли будет получать на вход положение и размеры экрана в виде TRect((DispLU.X, DispLU.Y), (DispRD.X, DispRD.Y)) и номера обсчитываемого зума и глубины запаса (в тайлах)? И выдавать на выход TRect уже по тому зуму в тайловых координатах? В качестве координат передать координаты углов экрана в виде (Tile.X*256+dX, Tile.Y*256+dY), т.е. тайловые координаты соответствующего тайла на текущем зуме и смещение крайней точки экрана внутри тайла. Вроде для всех зумов это всё влезает в integer. Заморачиваться с географическими преобразованиеями я не вижу никакого смысла, всё должно идти в тайловых и экранных координатах.
И надо ли подерживать размеры тайлов не 256?

Функция то достаточно простая ... И что лично для меня ценно - ни от чего не зависит, не надо лезть в глубины Планеты. :)

(0006856)
vasketsov   
07-05-2012 12:30   
>сдвиг на произвольное количество пикселей, не приводит к изменению общего размера битмапки
Походу это ответ на какой-то другой вопрос. Например зачем обрабатывать тайлы за границей экрана.

>приходится держать битмапку в 3 тайла размером
Однако ситуация остаётся симметричной.

>получается, что остается почти тайл справа от отображаемой области
Как и слева.

Ещё раз:
1. Преимущественное заполнение экрана справа означает наличие выделенного направления (в алгоритме) от центра экрана направо.
2. Сдвиг экрана может быть произвольный (небольшой) в любом направлении.
3. Откуда берётся выделенное направление направо?
4. Почему оно (направление направо) оптимально, как нивелируется несимметричность?
5. Бывает ли ситуация, когда выделенным становится другое направление, или оно пропадает.

>Надо расширить битмапку СИММЕТРИЧНО!
Что само по себе логично.

>Правильный ответ ... N = (H + 2 * S - 2) div S
На какой вопрос? Сколько надо тайлов для покрытия экрана (вдоль одной из границ линейно)?
Вообще говоря отсюда не следует, что размер битмапки будет N*S.
(0006857)
vdemidov   
07-05-2012 12:32   
>Вот как раз этого и не надо! Надо расширить битмапку СИММЕТРИЧНО!
Как симметрично? Вы уже согласились, что для размера 258 пикселей нужно держать 3 тайла в ширину. Но симмитрично оно будет только при одном сдвиге из 256 возможных. Во всех остальных случаях видно будет только 2 тайла. А один будет полностью за границами экрана. Сейчас этот лишний тайл всегда справа. Можно сделать что бы был всегда слева. А идеально, что бы был то справа то слева. А симметрично всегда, просто невозможно без ресайза битмапки.
(0006858)
vdemidov   
07-05-2012 12:35   
>И надо ли подерживать размеры тайлов не 256?
Надо. Более того. Нужно также закладывать, что размеры тайла могут меняться от тайла к тайлу. Тоесть может быть, что с краю карты тайл меньшего размера чем в центре или наоборот. Максимум на что можно положиться, что ширина всех тайлов в столбце равна и высота всех в строке равна.
(0006859)
vdemidov   
07-05-2012 12:36   
>Вообще говоря отсюда не следует, что размер битмапки будет N*S
Это тут при чем? Мы только об одном измерении говорим. Для высоты все точно так же.
(0006860)
Dima2000   
07-05-2012 12:40   
>>И надо ли подерживать размеры тайлов не 256?
>Надо. Более того. Нужно также закладывать, что размеры тайла могут меняться от тайла к тайлу.
Вы уж слишком много хотите, и сразу ... ;-)
Об этом я подумаю потом. Ничего особо сложного нет, надо лишь аккуратно работать со структурами описывающими размеры тайлов по их координатам. И вместо простого арифметического расчёта будут циклы прохода по структурам.

>А идеально, что бы был то справа то слева.
Идеально - и слева, и справа. Всего лишь.

По идее вот такого вызова достаточно для расчёта:
{Пересчитывает положение и размер экрана в тайловые координаты на другом зуме, относительно текущего.}
function GetTilesRect(const tile: TRect; const offset: TRect; const dzoom: integer; const add: integer=0): TRect;
Получает координаты покрывающих тайлов, смещение в левом верхнем тайле левой верхней экранной точки и такое же смещение экрана в правом нижнем тайле, номер зума для расчёта (относительно текущего), запас вокруг отображаемых тайлов (в тайлах текущего зума). Возвращает прямоугольник в тайловых координатах уже на запрошенном зуме.
Уже пишу.
(0006861)
Dima2000   
07-05-2012 12:43   
Правильный ответ был вот на этот вопрос:
>Сколько тайлов по горизонтали нам нужно, что бы покрыть гарантировано экран?

Размеры битмапки при этом Nh*Nv, каждое из Nx считается по той формуле с разным размером H по горизонтали и вертикали.
(0006862)
Dima2000   
07-05-2012 12:47   
>Как симметрично?
Так, чтобы спираль начиналась от того тайла, в который попадает точка центра экрана. Я знаю что для чётных размеров её нет, тогда любая из 4-х центральных. Сейчас это глубоко не так. В этом и есть суть бага. В релизе 110418 было именно так (или ну очень похоже).
(0006863)
vdemidov   
07-05-2012 12:47   
>>А идеально, что бы был то справа то слева.
> Идеально - и слева, и справа. Всего лишь.
То что я пишу кто-то читает? Я конечно понимаю, что чукча не читатель, а писатель, но попробую повторить:
Как симметрично? Вы уже согласились, что для размера 258 пикселей нужно держать 3 тайла в ширину. Но симмитрично оно будет только при одном сдвиге из 256 возможных. Во всех остальных случаях видно будет только 2 тайла. А один будет полностью за границами экрана. Сейчас этот лишний тайл всегда справа. Можно сделать что бы был всегда слева. А идеально, что бы был то справа то слева. А симметрично всегда, просто невозможно без ресайза битмапки.
(0006864)
vdemidov   
07-05-2012 12:49   
>В релизе 110418 было именно так (или ну очень похоже).
Там не было стабильного размера битмапки.
(0006865)
Dima2000   
07-05-2012 13:07   
>То что я пишу кто-то читает?
Читает, не беспокойтесь. Мы просто чуть о разном говорим. Вы про запас, а я про центр. Ок, попробую в ваших терминах.
Размер экрана 258 пикселей, тайлы 256 пикселей, для гарантированного покрытия надо 3 тайла, перенумеруем их 1,2,3. Рассмотрим смещение левой отображаемой точки экрана от границы левого тайла (смещение очевидно всегда вправо):
Смещение 0..126: Отображаются тайлы 1 и 2, центральным считается тайл 2 (?!).
Смещения 127..254: Отображаются тайлы 1 и 2, центральным считается тайл 2 (ок).
Смещение 255: отображаются три тайла, по точке из 1 и 3 и весь 2-й, центральный 2-й (ок).

А теперь вопрос: почему при смещениях 0..126 центральным считается тайл 2 (спираль пойдёт от него), если все 2 центральных точки экрана попали в 1-й тайл?! Вот на это ответьте пожалуйста.

Про запас для защиты от сдвигов это отдельный вопрос. Тоже простой: если Вы хотите добавить запас, то надо расширить битмапку на 2 (ДВА) тайла, слева и справа, с номерами 0 и 4. А не на один. И всё.
(0006866)
vdemidov   
07-05-2012 13:13   
>А теперь вопрос: почему при смещениях 0..126 центральным считается тайл 2 (спираль пойдёт от него), если все 2 центральных точки экрана попали в 1-й тайл?! Вот на это ответьте пожалуйста.
Потому что, при расчете спирали, процедура понятия не имеет о положении центральной точки. У нее есть только информация, что нужно 3 тайла. Менять я это точно не буду и другим менять не дам.
(0006867)
Dima2000   
07-05-2012 13:16   
(edited on: 07-05-2012 13:23)
Да, конечно для экрана 258 пикселей 3-й тайл отображается всегда не более одной точкой и можно его обозвать "запасом", но это лишь при 258 пикселей. А 1024 или 2560? И почему в этих случаях запас лишь справа? Запас на то и запас, что вокруг отображаемых ... Сугубо имхо.

(0006868)
Dima2000   
07-05-2012 13:19   
>при расчете спирали, процедура понятия не имеет о положении центральной точки.
Простите, какая процедура? Итератор спирали? Она и не имеет такой информации, ей и не нужно. Её вызывают не совсем корректно.
О, я кажется понял суть проблемы. Для сдвигов менее половины тайла надо брать на тайл больше слева, 4 тайла вместо 3-х, тогда центр для спирали будет правильным.
(0006869)
vdemidov   
07-05-2012 13:20   
Потому что это не запас. Это минимальный стабильный по размеру прямоугольник тайлов. Тоесть любые сдвиги просматриваемого участка не приводят к изменению размера битмаки. Все. Ни о каком запасе речь не идет.
(0006870)
vdemidov   
07-05-2012 13:23   
>Простите, какая процедура?
Процедура вычисления отображаемого прямоугольника тайлов.
>О, я кажется понял суть проблемы. Для сдвигов менее половины тайла надо брать на тайл больше слева, 4 тайла вместо 3-х, тогда центр для спирали будет правильным.
Не. Вы таки не читаете то что я пишу. КОЛИЧЕСТВО ТАЙЛОВ НЕ ДОЛЖНО ЗАВИСЕТЬ ОТ СДВИГА!!!!!!!
(0006871)
vdemidov   
07-05-2012 13:25   
Но можно что бы при сдвигах меньше полу тайла лишний тайл прибавлялся слева. О чем я и говорил, когда писал про более умное вычисление прямоугольника тайлов.
(0006872)
vdemidov   
07-05-2012 13:26   
Если интересует смотрите юнит u_LocalCoordConverterFactorySimpe.pas метод CreateBySourceWithStableTileRect
(0006873)
Dima2000   
07-05-2012 13:31   
(edited on: 07-05-2012 13:50)
>КОЛИЧЕСТВО ТАЙЛОВ НЕ ДОЛЖНО ЗАВИСЕТЬ ОТ СДВИГА!
Ок, пусть так. Тогда глюк легко лечится виртуальным расширением экрана (только при передаче в процедуру) на ПОЛОВИНУ размеров тайла во все 4 стороны. При этом центр спирали останется в тайле, содержащем центр экрана. И размер обсчёта будет стабильным (при сдвиге до полутайла в любом направлении). Можно расширить и на 1.5 тайла.

Достаточно раздвинуть наружу размеры VSourcePixelRect на полтайла после строки 101 в указанном юните. И убрать часть добавленного далее кода. :)) Оба Inc() и может ещё что вокруг.
PS. Между прочим, это достаточно известный и "стандартный" метод защиты от сдвигов, виртуальным расширением области.
PPS. Собственно насколько раздвигаем область, настолько и появляется "защита от сдвига" в каждом из 4-х направлений. Можно хоть индивидуально выбирать. :) А размеры битмапки и прочих структур остаются постоянными ибо сдвиг в формулу "раздвижки" вообще не входит.

(0006874)
Dima2000   
07-05-2012 14:02   
(edited on: 07-05-2012 14:03)
Поправил (только указанный метод) и приложил сюда указанный юнит. Посмотрите. Модификация простейшая, ничего оптимизировать не стал.

Кстати, вычисление размера VViewSize немного странное, я из школы ещё помню, что разность координат выдаёт размер на 1 меньше фактического. Или у вас VViewSize.X=0 означает размер 1 пиксель? Или передаются координаты правого нижнего угла уже ЗА экраном? Ок.

(0006875)
vdemidov   
07-05-2012 14:07   
>Или передаются координаты правого нижнего угла уже ЗА экраном?
Именно. В VCL везде используется такое правило при работе с координатами. И оно достаточно логично.
(0006876)
Dima2000   
07-05-2012 14:09   
(edited on: 07-05-2012 14:10)
Извините, этого я не знал. Или никогда не обращал внимания.
Ой, ещё извиняюсь, комменты в файл пролезли в DOS кодировке. :(( Сейчас заменю.

(0006877)
vdemidov   
07-05-2012 14:11   
const
  dAll = 256 div 2;
Я ж написал что привязываться к размеру тайла мы не можем. Так что увы.
(0006878)
vdemidov   
07-05-2012 14:12   
И проверьте свое решение. ИМХО размер стабильным не будет.
(0006879)
Dima2000   
07-05-2012 14:20   
А 256 тут вообще говоря не размер тайла!! Вот так вот! В dAll можно любое число (от 1 и до ...) поставить.
Стабильность размера проверю.
(0006880)
vdemidov   
07-05-2012 14:50   
>Стабильность размера проверю.
Сразу говорю, что не будет стабильности. Да и магические константы не очень нравятся. Почему 256 тогда если это не размер тайла?
(0006881)
Dima2000   
07-05-2012 15:01   
Да, нестабильно. Думаю.
256 бралось именно как размер тайла - для стабильности, но промахнулся.
(0006883)
vasketsov   
07-05-2012 16:49   
(edited on: 07-05-2012 16:51)
>Размеры битмапки при этом Nh*Nv
Это если тайлы грузятся только по нулевым координатам по модулю размера тайла (0, 256, 512), если грузить не от нуля - ещё минус тайл по каждой стороне.

Кроме того, это неявно предполагает, что обсуждаемый сдвиг не более 1 тайла (что вообще говоря тоже не универсальная мировая константа).

Впрочем пусть будет тайл: если 258 при тайле 256 - в худшем случае нужно грузануть 3 тайла, но размер битмапки достаточно 512.


>КОЛИЧЕСТВО ТАЙЛОВ НЕ ДОЛЖНО ЗАВИСЕТЬ ОТ СДВИГА!!!!!!!
Количество тайлов или размер битмапки?

(0006884)
Dima2000   
07-05-2012 20:16   
(edited on: 07-05-2012 20:27)
Ура, бага полечилась.
Достаточно разрешить лишь нечетные размеры в тайлах для box-а и аккуратно отцентрировать box относительно центра экрана (из GetRectInMapPixel).
Garl пересобрал Планету, на глаз итератор работает точно как должен, строго из того тайла, в который попадает центр экрана.
Что размеры всегда стабильны (независят от сдвига) я проверял отдельно.
Приложил поправленный файл, посмотрите. Может надо так же поправить ещё где...

На самом деле там ещё можно красоты навести, убрать переменную с из ConvertInterval, неиспользуемые переменные из CreateBySourceWithStableTileRect.

Если надо добавить ещё запас за отображаемыми тайлами, то можно дополнительно увеличить size в строке 102 (size выражается в тайлах).

(0006885)
Dima2000   
07-05-2012 20:36   
(edited on: 07-05-2012 21:09)
Теперь как насчёт сменить итератор? ;-)

(0006886)
vdemidov   
08-05-2012 05:38   
Не катит. Никаких зашитых констант с размером тайла. Вы можете по координатам тайла получить пиксельные координаты углов и по пиксельным координатам получить координаты тайла в который они попадают. И еще ваш метод будет глючить на краях карты со страшной силой.
(0006887)
Dima2000   
08-05-2012 10:48   
(edited on: 08-05-2012 11:38)
Что, заменить константу на ts:=TCoordConverterBasic.GetTileSize(Point(0,0),1)? ;-) Или таки очень хотите тайлы переменного размера?
Ладно, переделаю, самому интересно. Будет не арифметика, а циклы прохода по тайлам.

На краях карты глюк похоже из-за ограничения ASource.GetRectInMapPixel только диапазоном карты.
А также при вычислении центра, его нельзя вычислять полусуммой! Она для отрицательных чисел выдаёт неправильный результат. Я её применил в коде специально для совпадения с вычислениями в итераторе. Правильно: center := (t.X + (t.Y - t.X) div 2) div ts;.
И глюк выражается лишь в смещении центра спирали, ничего не вылетает и не пропускается. Совсем не "страшная сила". :)

(0006888)
vdemidov   
08-05-2012 11:01   
>Или таки очень хотите тайлы переменного размера?
Именно.

>И глюк выражается лишь в смещении центра спирали, ничего не вылетает и не пропускается. Совсем не "страшная сила". :)
Значит ты еще просто не все краевые случаи проверил :) Думай
(0006889)
Dima2000   
08-05-2012 11:34   
Честно говоря не вижу смысла сейчас лишь в одном месте добавлять поддержку тайлов переменного размера. Константы 256/255 (и shl/shr 8) размазаны по коду в u_CoordConverterBasic.pas тонким слоем. Имхо самое разумное сейчас это взять один раз размер тайлов из GetTileSize или аналогичной и смело им пользоваться для всех тайлов. Будет поддержка неквадратных тайлов постоянного размера ...
Я понимаю всё и про задел на будущее, и про переложить работу на другого, и остальное, но хотелось бы СЕЙЧАС получить рабочий код, а не через годы, как с плагинами. :)

Я пока не представляю даже в теории как обеспечить постоянство размера битмапки для тайлов переменного размера. Кстати, размер битмапки должен быть постоянным ведь в терминах тайлов, не пикселей? Симметрично расширить во все стороны от центрального тайла (что собственно и исправляет данный глюк) не проблема, но кол-во тайлов может быть всегда разным.

>Значит ты еще просто не все краевые случаи проверил :) Думай
Пример диапазона координат, когда получается глюк в CorrectInterval?
И текущий расчёт в ночнушке тоже глючит на краях карты.
(0006890)
Dima2000   
08-05-2012 12:03   
(edited on: 08-05-2012 12:05)
Ещё мысль, уже в сторону.
Я бы добивался не стабильного размера битмапки, а чуть расширил (насколько - не принципиально) бы её за пределы экрана и пока экран елозеет не выходя за её границы - не пересчитывать. Ведь идея именно в этом, а не в "всегда одинаковом размере битмапки". А будет ли она при новом расчёте того же размера или нет - дело имхо двадцатое.

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

(0006891)
vdemidov   
08-05-2012 12:05   
> Константы 256/255 (и shl/shr 8) размазаны по коду в u_CoordConverterBasic.pas тонким слоем.
Заметьте. Только по одному юниту. А раньше были по всем юнитам. Знаете сколько мне усилий стоило собрать их там. И работа не закончена. Так что не нужно плодить новых мест с зашитыми константами.
>но хотелось бы СЕЙЧАС получить рабочий код, а не через годы
Код сейчас без ваших изменений вполне рабочий. Легкое визуальное смещение спирали меня совершенно не волнует.

>Я пока не представляю даже в теории как обеспечить постоянство размера битмапки для тайлов переменного размера.
Я этого и не просил никогда. Я просил стабильного размера в тайлах.
(0006892)
vdemidov   
08-05-2012 12:07   
>Ведь идея именно в этом, а не в "всегда одинаковом размере битмапки". А будет ли она при новом расчёте того же размера или нет - дело имхо двадцатое.
Нет. Сдвиг при том же размере выполняется на порядок быстрее. Так что стабильный размер желателен. Хотя как я уже говорил, для новых реализаций основного слоя и карты заполнения это уже не актуально.
(0006893)
Dima2000   
08-05-2012 12:10   
(edited on: 08-05-2012 12:18)
>Я просил стабильного размера в тайлах.
Для тайлов переменного размера (когда два соседних тайла могут иметь разные размеры) - пока на мой взгляд это нереально.

>сколько мне усилий стоило
Догадываюсь.
Я же предложил заменить константу на вызов метода.

>Легкое визуальное смещение спирали меня совершенно не волнует.
Угу. Полэкрана заполнена, а половина пустая. Подумаешь.
Меня бы тоже не волновало при времени построения спирали порядка секунды. А при десятках секунд и минутах - раздражает.

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

(0006894)
Dima2000   
08-05-2012 12:13   
>стабильный размер желателен.
Хм. А если в каком-то месте карты встретится область с тайлами 1*1 пиксель? Не может быть? Ну 10*15? Неужели размер битмапки не изменится? Тогда сделайте его размером с видимую область и всё, она постоянна.
(0006897)
vdemidov   
08-05-2012 19:01   
>Хм. А если в каком-то месте карты встретится область с тайлами 1*1 пиксель? Не может быть? Ну 10*15? Неужели размер битмапки не изменится? Тогда сделайте его размером с видимую область и всё, она постоянна.
Ну пока таких случаев нет, так что не будем оптимизировать заранее. А вот с постоянной областью можно сделать, просто обидно просто выбрасывать на помойку загруженные из файла пиксели или куски построенной карты заполнения и тд.
(0006910)
Dima2000   
08-05-2012 20:46   
А тайлы переменного размера значит уже типа есть?! Простите, не вижу их поддержки в исходнике...

Постоянный размер в тайлах я уже сделал.
Константу легко заменить на вызов GetTileSize или, если он недоступен, то получить размеры тайлов по результату TilePos2PixelRect (как в u_MapType.pas:905-906) для центрального тайла.
(0006913)
Dima2000   
09-05-2012 12:17   
Убрал старые файлы, приложил юнит с новым классом итератора. Изменения лишь в названии юнита и класса.
(0006914)
vdemidov   
09-05-2012 19:02   
Как я уже писал u_LocalCoordConverterFactorySimpe.pas не катит.
(0006916)
Dima2000   
09-05-2012 21:24   
Да он так и остался, его не трогал.
Заменить константу на вызов метода не проблема, это не снимет других возражений.
(0006927)
Dima2000   
10-05-2012 19:41   
(edited on: 10-05-2012 19:52)
Обновил u_LocalCoordConverterFactorySimpe.pas.
Такой расчёт пойдёт? Магических констант нету. Размер постоянный (и в тайлах и в пикселях). На границах карты не глючит. Центральный тайл всегда в центре экрана. Работает только с тайлами постоянного для данного зума размера (но не обязательно квадратными).

(0006929)
vasketsov   
10-05-2012 20:25   
>Работает только с тайлами постоянного для данного зума размера (но не обязательно квадратными).
Вот смотри сам, одно из приложений - это когда на одном конкретном зуме у всех тайлов в мире квазипостоянное значение mpp (metr per pixel) - "разрешение" тайла. Есть картосервисы с такими тайлами. Очевидно, размеры тайлов легко могут быть разными в зависимости от широты (впрочем могут и не быть разными даже при постоянстве mpp, правда в этом случае извращения будут несколько иного порядка).
(0006930)
Dima2000   
10-05-2012 20:36   
(edited on: 10-05-2012 20:45)
Давайте отделим исправление бага со смещением "центрального" тайла от поддержки тайлов переменного размера, а? Поддержки последних я в исходнике Планеты вообще не вижу и добавлять лишь в одно место, да ещё неизвестно как - нафига?
Вопрос: как вы хотя бы в принципе можете обеспечить постоянство размера в тайлах области просмотра если размеры тайлов могут быть разными и их вмещается всегда разное количество?
Я понимаю лишь задав размеры в тайлах с огро-о-о-омным запасом, на самый худший случай, тайлы 1*1. :P Это несерьёзно.

(0006931)
Dima2000   
10-05-2012 20:38   
Можно ещё немного улучшить, заменив:
  {Получим размеры центрального тайла}
  VTileRect := VConverter.TilePos2PixelRect(VCenter, VZoom);
  VTileSize := Point(VTileRect.Right - VTileRect.Left, VTileRect.Bottom - VTileRect.Top);
на:
  {Получим размеры центрального тайла}
  VTileSize := VConverter.GetTileSize(VCenter, VZoom);
И VTileRect становится ненужным.
(0006932)
vasketsov   
10-05-2012 21:02   
>Давайте отделим
Давайте. Я лишь привёл довольно простой пример тайлов разного размера.

>если размеры тайлов могут быть разными
Все известные мне реальные приложения ограничиваются сравнимостью размеров тайлов по широте (кроме удвоения квадратов генштаба на севере, но это не совсем тайлы). То есть между размером тайла сверху экрана и размером тайла снизу экрана всегда можно поставить знак равенства либо сравнения, и он будет справедлив для всего полушария (соответственно северного или южного, экран не вращается). Соответственно покуда на экране не 100500 тайлов - простая оценка сверху выполняется по граничным тайлам (если надо обеспечить постоянство области при смещениях до 1 тайла - соответственно смещаем границу оценки на этот тайл при возможности такого смещения). Точные границы считаются итеративно.
То есть алгоритмически это не сказать что песец как сложно. Другое дело что пока нет реально обкатанных тайлов произвольного постоянного размера, говорить об использовании всюду различных размеров тайлов конечно несерьёзно.
(0006933)
Dima2000   
10-05-2012 21:17   
>То есть алгоритмически это не сказать что песец как сложно.
Ну да, при таких ограничениях да.
Самый простой выход: чуть увеличить запас в тайлах и всё. Уж на интервале экрана разница в два тайла вряд ли набежит. У меня сейчас за размер тайлов принимается размер "центрального" тайла, получится как раз среднее значение. Расширить область на тайл во все стороны и всё, это лишь два числа поменять в процедуре.
(0006937)
vdemidov   
11-05-2012 05:30   
Кстати. Не наследуйтесь вы в итераторе от базового класса. Он был нужен до введения интерфейса. Просто реализуйте интерфейс ITileIterator. Все методы доступные через интерфейс желательно сделать private. И еще. Только сейчас обратил внимание. В проверке попадания точки в прямоугольник правая и нижняя границы не входят в требуемый диапазон.
Вместо
if t.X > fBox.Right then Result := 0;
должно быть
if t.X >= fBox.Right then Result := 0;
(0006957)
Dima2000   
11-05-2012 11:52   
(edited on: 11-05-2012 12:10)
>В проверке попадания точки в прямоугольник правая и нижняя границы не входят в требуемый диапазон.
Да, точно, тогда я этого ещё не знал.

>Не наследуйтесь вы в итераторе от базового класса.
Да я бы с радостью вообще ни от чего не наследовался. :) А это делал по образцу.
С интерфейсом попробую, вроде все методы понятны.

(0006961)
Dima2000   
11-05-2012 13:31   
Приложил v5 версию итератора.
Переделал на интерфейс, поправил TRect. Посмотрите правильно ли. Компилится и работает.
(0009606)
vdemidov   
19-10-2012 12:44   
Так как теперь не используются большие битмапки, то пропала необходимость поддерживать стабильность размера прямоугольника.