nextgis / NextGIS_QGIS

QGIS is a free, open source, cross platform (lin/win/mac) geographical information system (GIS)
http://qgis.org
GNU General Public License v2.0
4 stars 3 forks source link

Ошибка при работе с пирамидальными слоями #30

Open Zeddikus opened 9 years ago

Zeddikus commented 9 years ago

При уменьшении масштаба (меньше чем 1:1, например 1:2) читается оригинальный растр. При масштабе 1:2 это в 4 раза больше пикселей, чем в масштабе 1:1. Это приводит к заметному замедлению перерисовки при небольших уменьшениях масштаба. Хотелось бы, чтобы при масштабе мельче чем 1:1 читался первый пирамидальный слой, а не оригинальный растр.

BishopGIS commented 9 years ago

Мне кажется это не правильно. Растр должен отображается максимально приближенно к выставленному масштабу. Кстати у меня какого либо замедления не проявляется.

Zeddikus commented 9 years ago

А первый пирамидальный слой при уменьшении масштаба в 2 раза (один поворот колёсиком в сторону уменьшения от масштаба 1:1) - это и есть максимально приближённо к выставленному масштабу. Первый пирамидальный слой уже посчитан и нет острой необходимости его для повторно считать при каждом повороте колёсика в сторону уменьшения от масштаба 1:1, жертвуя драгоценными секундами ожидания пользователя. Логично изобразить побыстрее первый уже посчитанный пирамидальный слой.

Обнаружил это когда у моей мозаики рухнули пирамидальные слои. Я мог видеть изображение в масштабе 1:1, а всю картинку не мог видеть (белое поле). Но при уменьшении масштаба на один шаг (один повором колёсиком в сторону уменьшения от масштаба 1:1) QGIS всё-таки продолжал показывать снимок, хотя должен был попытаться изобразить первый пирамидальный слой, испытать неуспех (птмучто пирамидальные слои рухнули) и изобразить белое поле. Мне кажется, что он читал оригинальный растр.

Насчёт замедления - возможно зависит от размера файла. Для небольших файлов это наверно незаметно. Я пробовал на 30-гигабайтовых *.img файлах. При навигации в масштабе 1:2 (один поворот колёсиком в сторону уменьшения от масштаба 1:1) перерисовка раза в два медленнее, чем в масштабе 1:1. Пчму?

BishopGIS commented 9 years ago

При отрисовке пирамидные слои не считаются. Они посчитаны заранее. А скорость чтения одинакового количества пикселей что из пирамиды, что из оригинального растра абсолютно одинакова. При этом размер растра не важен - хоть1 Тб. Одновременно на экран все равно выводится очень ограниченный размер - например при разрешении Full HD 1920×1080 этот размер равен ~6 Мб (!). И этот объем и считывается с диска.

У вас очень специфичная ситуация:

  1. Очень большой растр с "поломанными" пирамидами
  2. Масштабы 2 : 1 и крупнее

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

Zeddikus commented 9 years ago

Для большого (~30 Gb) изображения со "здоровыми" (неполоманными) пирамидальными слоями при навигации в масштабе 1:2 (один поворот колёсиком в сторону уменьшения от масштаба 1:1) перерисовка идёт раза в два медленнее, чем в масштабе 1:1. Пчму?

BishopGIS commented 9 years ago

Я проверил на большом файле (32 Гб):

$ gdalinfo ~/tmp/qqq.tif 
Driver: GTiff/GeoTIFF
Files: /home/bishop/tmp/qqq.tif
Size is 105760, 318478
Coordinate System is:
PROJCS["WGS 84 / UTM zone 39N",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",51],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AUTHORITY["EPSG","32639"]]
Origin = (283649.966729705804028,5249776.087225775234401)
Pixel Size = (0.550000000000000,-0.550000000000000)
Metadata:
  AREA_OR_POINT=Area
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  (  283649.967, 5249776.087) ( 48d 8' 4.36"E, 47d21'56.20"N)
Lower Left  (  283649.967, 5074613.187) ( 48d12'58.94"E, 45d47'28.18"N)
Upper Right (  341817.967, 5249776.087) ( 48d54'15.57"E, 47d22'56.20"N)
Lower Right (  341817.967, 5074613.187) ( 48d57'51.17"E, 45d48'24.99"N)
Center      (  312733.967, 5162194.637) ( 48d33'19.89"E, 46d35'13.89"N)
Band 1 Block=105760x1 Type=Byte, ColorInterp=Gray

Все равно не воспроизводится. Могу предположить, что с данными возможно что-то не то. Но как минимум это уже ваш частный случай, а не система.

simgislab commented 9 years ago

Я дам данные @Zeddikus при встрече, посмотрим более внимательно.

Zeddikus commented 9 years ago

Пирамиды моего растра были посчитаны в Erdas'е. Есть ли разница для QGIS, где были посчитаны пирамиды? Я сегодня на ночь поставлю пересчитать пирамиды в QGIS, возможно это играет какую-то роль.

BishopGIS commented 9 years ago

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

Zeddikus commented 9 years ago

Вот ещё какой эксперимент я поставил. Для одного из своих тайлов (назовём его тайл A) я подменил пирамидальные слои от тайла B. Тайлы одинакового размера, поэтому QGIS не заметил подвоха. Это позволило однозначно определить при каком масштабе происходит переключение на чтение пирамидальных слоёв. То есть, если вижу тайл A, то читается оригинальный растр; если тайл B, то пирамиды.

Оригинальные тайлы находятся в Модисовской проекции: +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs

Если проекция вида совпадает с проекцией растра и перепроецирование на лету не нужно (нету крестика на Enable 'on the fly' CRS transformation), то перерисовка производится корректно, с одинаковой скоростью для всех масштабов. То есть, на масштабе 1:1 я вижу растр А (читается оригинальный растр), на масштабах 1:2 и мельче я вижу тайл B (читаются пирамидальные слои).

Однако, в моей работе критично расширение Send2GE, которое некорректно работает с Модисовской сферой (подробности здесь: https://github.com/nextgis/send2google_earth/issues/3). Поэтому я определил проецию вида как одну из стандартных QGIS'овских (Sphere Sinusoidal): +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs , настроив перепроецирование на лету (крестик Enable 'on the fly' CRS transformation).

При таких настройках на масштабе 1:1 я вижу тайл А, на масштабе 1:2 - тоже тайл A(!), на масштабе 1:4 - тайл B. Это значит что на масштабе 1:2 вместо первого пирамидального слоя тоже читается оригинальный растр, считывая с диска в 4 раза больше пикселей чем необходимо. От этого и торможение.

Таким образом, решив проблему с некорректной работой Send2GE на Модисовской сфере, для меня автоматически отпадёт вопрос о торможении в масштабе 1:2 (чтение оригинального растра вместо пирамидального слоя). Хотя, конечно, мысля более глобально, это два отдельных бага. Возможно другие пользователи тоже страдают от замедления работы в масштабе 1:2 при перепроецировании на лету растровых изображений, но, либо не придают этому большого значения, либо более политкорректные, чем я.

BishopGIS commented 9 years ago

Тут похоже ключевой момент - это перепроецирование. Т.к. я проверял в оригинальной СК изображения. Добавил тэг "баг".