Грабим WMS сервера с помощью GDAL

denis27
Интересующийся
Сообщения: 39
Зарегистрирован: 18 фев 2008, 10:08
Репутация: 1

Грабим WMS сервера с помощью GDAL

Сообщение denis27 » 04 мар 2008, 09:27

Хочу поделится с общественностью интересным трюком который подсмотрел тут http://crschmidt.net/blog/categories/gdalogr/

С некоторых пор в качестве источников данных для GDAL стало возможным использовать WMS сервера
http://www.gdal.org/frmt_wms.html

Теперь получать с них геопривязанную информацию можно легко и не принужденно.

Описываем в файле параметры сервера

ogc_wms.xml

Код: Выделить всё

<GDAL_WMS>
    <Service name="WMS">
        <Version>1.1.1</Version>
        <ServerUrl>http://onearth.jpl.nasa.gov/wms.cgi?</ServerUrl>
        <SRS>EPSG:4326</SRS>
        <ImageFormat>image/jpeg</ImageFormat>
        <Layers>modis,global_mosaic</Layers>
        <Styles></Styles>
    </Service>
    <DataWindow>
        <UpperLeftX>-180.0</UpperLeftX>
        <UpperLeftY>90.0</UpperLeftY>
        <LowerRightX>180.0</LowerRightX>
        <LowerRightY>-90.0</LowerRightY>
        <SizeX>2666666</SizeX>
        <SizeY>1333333</SizeY>
    </DataWindow>
    <Projection>EPSG:4326</Projection>
    <BandsCount>3</BandsCount>
</GDAL_WMS>
И выполняем команду

Код: Выделить всё

gdal_translate -projwin 131.85 43.15 131.95 43.05 -outsize 500 500 -of GTIFF ogc_wms.xml vladivostok.tif
Получаем привязанный растр нужного участка, в данном случае снимок Владивостока.
Последний раз редактировалось denis27 05 мар 2008, 05:25, всего редактировалось 1 раз.

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9128
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 747
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Сообщение Максим Дубинин » 04 мар 2008, 10:12

забавно, добавлю, в GDAL 1.4.x - не работает, надо 1.5

порадовался исходному размеру OneEarth: 2666666, 1333333 пикселей

пойду попробую сам себя ограбить

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

denis27
Интересующийся
Сообщения: 39
Зарегистрирован: 18 фев 2008, 10:08
Репутация: 1

Сообщение denis27 » 05 мар 2008, 05:32

Под windows особенно удобно пользоваться сборкой FWTools содержащей помимо прочего и GDAL http://fwtools.maptools.org/

Если он установлен то пример выше можно будет запускать из такого BAT файла

Код: Выделить всё

call "C:\Program Files\FWTools2.1.0\setfw.bat"
gdal_translate -projwin 131.85 43.15 131.95 43.05 -outsize 500 500 -of GTIFF ogc_wms.xml vladivostok.tif
И кстати о развитии в рассылке GDAL уже проскакивали сообщения - не плохо бы аналогичным образом сделать провайдер данных для google и подобных сервисов. ;)

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9128
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 747
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Сообщение Максим Дубинин » 05 мар 2008, 05:59

не плохо бы аналогичным образом сделать провайдер данных для google и подобных сервисов.
Это мне тоже сразу пришло в голову, однако, как известно Google не представлет WMS и вообще запрещает доступ к свои данным, кроме как через свой API. Вряд ли Warmerdam со-товарищи пойдет на это, слишком серьезный проект GDAL.
пристегивайтесь, турбулентность прямо по курсу

denis27
Интересующийся
Сообщения: 39
Зарегистрирован: 18 фев 2008, 10:08
Репутация: 1

Сообщение denis27 » 05 мар 2008, 07:40

Тем не менее помимо гугла аналогичную систему разбиения карты на тайлы используют много проектов, например открытые:

STRM relief map - http://srtm.in-ulm.de/zsrtm/info/intro.html
Open Street Map - http://www.openstreetmap.org/

Так что дата провайдер будет универсальный а то что его будут использовать для не легальной скачки гугла уже не проблемы GDAL ;)

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9128
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 747
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Сообщение Максим Дубинин » 06 мар 2008, 06:26

не, это другое

здесь же дело не в разбиении, а в том, что OneEarth поставляет данные по WMS, а Google - нет и вряд ли будет. Вот такой вот строчки вы для него не найдете:

Код: Выделить всё

<ServerUrl>http://onearth.jpl.nasa.gov/wms.cgi?</ServerUrl>
пристегивайтесь, турбулентность прямо по курсу

ericsson
Гуру
Сообщения: 3321
Зарегистрирован: 27 июл 2009, 19:26
Репутация: 748
Ваше звание: Вредитель полей

Re: Грабим WMS сервера с помощью GDAL

Сообщение ericsson » 28 июл 2009, 22:39

Опробовал данный метод.
Сразу, обнаружилось несколько странное поведение GDAL.

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

Во-вторых, есть ощущение, что при увеличении размера запрашиваемого тайла в <BlockSizeX>, <BlockSizeY> число обращений к серверу почти не уменьшается (смотрел по логам своего firewall, число может и не остается постоянным, но остается того же порядка) даже когда -outsize сравним с <BlockSizeX>, <BlockSizeY> и запросов нужно, максимум, четыре (а делается больше десятка, по-моему). Как будто из больших запрашиваемых тайлов берутся только маленькие фрагменты.

Используемая проекция - UTM, зона 32, это нативная проекция для сервера, она же указана в xml-описании источника, и в ней же указывается -projwin.

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9128
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 747
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: Грабим WMS сервера с помощью GDAL

Сообщение Максим Дубинин » 29 июл 2009, 05:59

покажете свой xml?
пристегивайтесь, турбулентность прямо по курсу

ericsson
Гуру
Сообщения: 3321
Зарегистрирован: 27 июл 2009, 19:26
Репутация: 748
Ваше звание: Вредитель полей

Re: Грабим WMS сервера с помощью GDAL

Сообщение ericsson » 29 июл 2009, 08:41

Тут ничего примечательного. Правда, есть одна тонкость - параметр ticket обновляется каждый час, так что тут приведен не валидный на данный момент (с ним сервер выдаст ошибку запроса).

Код: Выделить всё

<GDAL_WMS>
 <Service name="WMS">
  <Name>OGC:WMS</Name>
  <Title>Norge i Bilder</Title>
  <Version>1.1.1</Version>
  <ServerUrl>http://wms.geonorge.no/skwms1/wms.norgeibilder?ticket=8EH55DE&</ServerUrl>
  <Layers>Orto50,Orto20</Layers>
  <SRS>EPSG:32632</SRS>
  <ImageFormat>image/jpg</ImageFormat>
 </Service>
 <DataWindow>
  <UpperLeftX>236000</UpperLeftX>
  <UpperLeftY>8019000</UpperLeftY>
  <LowerRightX>1364000</LowerRightX>
  <LowerRightY>6399000</LowerRightY>
  <SizeX>5640000</SizeX>
  <SizeY>8100000</SizeY>
 </DataWindow>
 <Projection>EPSG:32632</Projection>
 <BlockSizeX>256</BlockSizeX>
 <BlockSizeY>256</BlockSizeY>
 <MaxConnections>3</MaxConnections>
</GDAL_WMS>
Параметры SizeX, SizeY получены путем вычисления (взят размер покрытия в метрах из Capabilities сервера, умножен на 5 в соответствии с разрешением слоя Orto20, 0,2 м/пикс, у слоя Orto50 разрешение 0,5 м/пикс). Смущает именно то, что при конструировании запроса вручную все ОК, полосы вылезают только на выходе GDAL.
Вечером попробую поставить чистый эксперимент, записав чистые логи обращений по HTTP с разным BlockSize.
В принципе, у меня есть идея некого обходного решения, если проблема в запросе двух слоев одновременно, но это тоже надо проверять.

ericsson
Гуру
Сообщения: 3321
Зарегистрирован: 27 июл 2009, 19:26
Репутация: 748
Ваше звание: Вредитель полей

Re: Грабим WMS сервера с помощью GDAL

Сообщение ericsson » 29 июл 2009, 20:39

Начал эксперимент, дано:
Тот же самый WMS, в xml-файле упомянуты два слоя, запрашиваем участок километр на километр, просим сохранить в geotiff 1000х1000 пикс.
Варьирую параметры <BlockSizeX>, <BlockSizeY> в значениях 250, 500, 1000 (тайл - 1/16, 1/4 и 1 от запрашиваемой площади).
Во всех трех случаях получили несжатые GeoTIFF размером 3 004 372 байт. Правда, сами картинки различаются, т.е. упомянутые глючные черные линии в кол-ве двух есть на во втором файле, одна - в третьем и ни одной в первом.
Дальше - забавные факты.
В первом случае было сделано 25 запросов по HTTP, во втором 9 запросов, в третьем - 4 запроса.
Объем скачанного по логам, соответственно, 605 429, 809 526, 1 320 758 байт (формат запрашиваемых файлов - JPEG).
Почешу затылок и напишу скрипт, который нарисует мне квадраты покрытия каждого запрошенного тайла, как будут результаты - изложу.

UPD: Ну с числом запросов все понятно: GDAL начинает запрашивать тайлы не от какого-либо угла указанного прямоугольника, а слегка за его пределами. Т.е. даже при размере тайла, равном размеру окна, вполне могут быть сделаны 4 запроса, покрывающие в сумме куда бОльшую площадь, чем вызван и столь значительный рост общего объема.
Черная же полоса на последнем файле находится как раз на стыке двух тайлов.

Аватара пользователя
Mavka
Гуру
Сообщения: 2060
Зарегистрирован: 14 мар 2008, 17:36
Репутация: 9

Re: Грабим WMS сервера с помощью GDAL

Сообщение Mavka » 03 дек 2009, 11:06

Совет/рецепт

Просто пример из моей работы. Имеется WMS с картой региона. Нужно вырезать из него отдельные участки.
При создании описания сервиса, указываем полный максимальный экстент региона в метрах (т.к. у меня карта в проекции Пулково-1942 зона ...). SizeX/Y указываем исходя из 1 пиксель на метр, т.е. протяженность региона запад-восток / север-юг.

Скрипт, запрашивающий определенный участок (cmd-файл для Windows):

Код: Выделить всё

c:/OSGeo4W/apps/gdal-dev/bin/gdal_translate ^
    -of GTiff ^
    -projwin <координаты углов участка> ^
    -outsize 100%% 100%% ^
    wms.xml ^
    output.tif
(знак крышки "^" - продолжение строки; проценты, как спецсимволы, нужно экранировать).

В projwin указываете координаты нужного участка в метрах. Размер получаемого растра задается параметром outsize. Проценты выбираете экспериментальным путем, он зависит от требуемого масштаба и содержимого слоев. Размер можно задать и в пикселях, но тогда о пропорциях придется позаботиться самому (хотя ГИС-программы растры с разным разрешением по осям x и y должны отображать правильно).

P.S. На счет черных полос. Не знаю какой у вас сервер, но UMN MapServer так реагирует на маленькие (256*256) тайлы при большом количестве одновременных запросов. Т.е. желательно увеличить размер BlockSizeX/Y и уменьшить MaxConnections. В документации GDAL упоминается, что он умеет делать запросы и untiled - можно попробовать, если получаемый растр не слишком большой (кажется, не больше 8000*8000 пикселей).
лангольеры под окном жрали время ом-ном-ном

Landser
Интересующийся
Сообщения: 23
Зарегистрирован: 12 апр 2015, 19:44
Репутация: 1

Re: Грабим WMS сервера с помощью GDAL

Сообщение Landser » 12 апр 2015, 22:46

Приветствую!
Попробовал в ручном режиме получить с WMS-сервера некоторое количество привязанных тайлов, полученным результатом доволен. Стыковка тайлов в объединённом растре получается идеальная, что позволяет полностью избавиться от надоедливого ватермарка, добавляемого сервером в каждый отданный тайл.
Методика следующая:
1. Определяем западную и северную границы нужного участка карты в метрах согласно используемой сервером EPSG. Эти цифры берём за основу. Восточную границу надо взять чуть больше нужного участка, чтобы в строке получилось целое число тайлов. Точное значение получается так: западная граница в метрах + (количество тайлов в строке х разрешение по горизонтали одного тайла в пикселях х масштабный коэффициент карты в метрах на пиксель). Вычисляем южную границу для первой строки тайлов (подразумевается, что для нужного нам участка у нас будет несколько строк тайлов). Северная граница - (разрешение по вертикали одного тайла в пикселях х масштабный коэффициент). Прописываем координаты углов и общее разрешение в пикселях для первой строки в ogc_wms.xml с учётом заранее прописанных параметров WMS-сервера.

Код: Выделить всё

<DataWindow>
        <UpperLeftX>5485000</UpperLeftX>
        <UpperLeftY>5333000</UpperLeftY>
        <LowerRightX>5517768</LowerRightX>
        <LowerRightY>5328904</LowerRightY>
        <SizeX>8192</SizeX>
        <SizeY>1024</SizeY>
    </DataWindow>
В данном примере используюся тайлы разрешением 1024х1024, для уменьшения временных затрат разрешение тайлов выбирается по максимуму из поддерживаемых WMS. Масштабный коэффициент карты - 4 метра на пиксель.
2. Поочерёдно получаем 8 тайлов первой строки:

Код: Выделить всё

gdal_translate -srcwin 0 0 1024 1024 -of GTIFF ogc_wms.xml d:\temp\1.tif
gdal_translate -srcwin 1024 0 1024 1024 -of GTIFF ogc_wms.xml d:\temp\2.tif
..................
gdal_translate -srcwin 7168 0 1024 1024 -of GTIFF ogc_wms.xml d:\temp\8.tif
Как видно, каждый последующий раз меняется значение xoff с 0 до 7168, оно определяет положение каждого тайла в строке по горизонтали (х). Также изменяется имя у выходного файла. Можно попытаться и за один раз взять всю строку тайлов в один выходной файл:

Код: Выделить всё

gdal_translate -srcwin 0 0 8192 1024 -of GTIFF ogc_wms.xml d:\temp\1.tif
Такой вариант проверялся, тоже работает, но не стабильно, gdal_translate часто вылетает без указания ошибки, а выходной файл получается залит чёрным цветом. Иногда по нескольку раз нужно повторять команду, чтобы сработало нормально. Для работы по скрипту не вариант.
Итак, у нас есть 8 привязанных тайлов первой строки. На каждом из них внизу по центру находится надоедливый, и местами просто уродующий карту, ватермарк от WMS-сервера. Решение проблемы:
3.Вторую строку тайлов будем брать не чётко по южной границе первой строки, а с небольшой поправкой на север, дабы затем, при склейке получившийся перехлёст позволил бы закрыть все ватермарки в тайлах предыдущей строки. Опытным путём установлено, что ватермарк занимает на тайле чуть меньше 200 метров с южного края тайла к северу. Запад и восток для всех строк остаются постоянными, определяем север и юг второй строки с учётом поправки в 200 метров. Север второй строки равен югу первой +200. Юг второй строки равен (юг первой строки +200) - (разрешение по вертикали одного тайла в пикселях х масштабный коэффициент). Сохраняем изменённые значения в файл ogc_wms.xml

Код: Выделить всё

<DataWindow>
        <UpperLeftX>5485000</UpperLeftX>
        <UpperLeftY>5329104</UpperLeftY>
        <LowerRightX>5517768</LowerRightX>
        <LowerRightY>5325008</LowerRightY>
        <SizeX>8192</SizeX>
        <SizeY>1024</SizeY>
    </DataWindow>
4. Получаем 8 тайлов второй строки аналогично получению тайлов первой строки. Нумерацию выходных файлов продолжаем 9.tiff - 16tiff.
5. Аналогично определяется север и юг у третьей (с поправкой 200 метров от второй) и последующих строк. Разность между севером и югом у всех строк одинаковая. Последнюю строку берём такой, чтобы ватермарки не попадали в нужный нам участок карты, и их при окончательной склейке можно было бы легко отрезать.

Вот такая логика работы. Повторюсь, что в ручном режиме всё получается на ура. Но очень долго по времени. Хотелось бы автоматизировать процесс получения тайловых строк. Но абсолютно не силён в программировании, помогите пожалуйста со скриптом. И ещё есть вопрос - как заставить gdal_translate работать через прокси (использовать системные настройки прокси-сервера)?

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: Грабим WMS сервера с помощью GDAL

Сообщение Denis Rykov » 13 апр 2015, 04:00

Для работы через прокси надо указать GDAL_HTTP_PROXY, подробнее тут.
Spatial is now, more than ever, just another column- The Geometry Column.

Landser
Интересующийся
Сообщения: 23
Зарегистрирован: 12 апр 2015, 19:44
Репутация: 1

Re: Грабим WMS сервера с помощью GDAL

Сообщение Landser » 15 апр 2015, 17:55

Denis Rykov писал(а):Для работы через прокси надо указать GDAL_HTTP_PROXY, подробнее тут.
Денис, благодарю, вопрос решён.

Мысли по поводу скрипта следующие:
Первая изменяемая величина в скрипте - цифровое имя выходного файла. Принимает значение от 1 до числа общего количества тайлов на весь участок карты. Вторая изменяемая величина - начальный пиксель положения тайла в строке по горизонтали (Х). Первое значение = 0, второе = 1024, третье = 2048 и тд до максимального количества пикселей в строке Х за вычетом пиксельного разрешения одного тайла 1024. Количество отработок равняется количеству тайлов в строке. После отработки строки, скрипт должен вычислять и изменять в ogc_wms.xml северную и южную координаты с учётом поправки в 200 метров от предыдущих значений и запускать отработку последующей строки. Заканчивать работу скрипт должен после того, как достигнуто максимальное цифровое имя выходного файла. Алгоритм работы скрипта мне понятен, мне непонятно, как это можно практически реализовать например на языке командной строки в Виндовс. Прошу помощи. Заранее благодарен.

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: Грабим WMS сервера с помощью GDAL

Сообщение Denis Rykov » 17 апр 2015, 13:57

Можете привести воспроизводимый пример на котором у вас что-то там вылетает?
Spatial is now, more than ever, just another column- The Geometry Column.

Ответить

Вернуться в «GDAL/OGR»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя