Страница 2 из 2
PHP MapScript и обработка WMS "на лету"
Добавлено: 16 июл 2013, 09:09
GIS-dev
Сейчас идет разработка ГИС-ресурса на базе Mapserver/MapScript, все данные слоев которого, обычно содержащиеся в мапфайле, хранятся в БД (postgree). Для отображения карт и выдачи информации требуется обеспечить функционал WMS-сервера. Предлагаемая обработка запроса во всех примерах состоит всегда из нескольких строк:
Код: Выделить всё
<?php
$request = ms_newowsrequestobj();
$request->loadparams();
ms_ioinstallstdouttobuffer();
$oMap = ms_newMapobj("../../service/wms.map");
$oMap->owsdispatch($request);
$contenttype = ms_iostripstdoutbuffercontenttype();
if ($contenttype == 'image/png')
header('Content-type: image/png');
ms_iogetStdoutBufferBytes();
ms_ioresethandlers();
?>
Сердце этого кода - метод
owsdispatch(), представляющий собой "черный ящик", выполняющий всю работу. К сожалению, суть его работы туманна. Например, зачем ему вообще нужен объект карты
mapObj, которому он принадлежит? Ведь все данные, включая мапфайл, он получает из
$request. В WMS-запросе есть параметр "
map", перекрывающий аналогичное значение, присваиваемое в момент создания карты конструктором
ms_newMapobj(...); Какой мапфайл будет использоваться при обработке запроса? А главное, как от него вообще избавиться? Все параметры, которые должны быть в мапфайле, для конкретного слоя можно занести прямо в атрибуты соответствующих объектов, подчиненных
mapObj, но они видимо будут затерты при запуске owsdispatch. Примитивный путь - создавать временный мапфайл, заполнять его данными, выполнять запрос и тут же файл удалять, но хотелось-бы обойтись без таких костылей!
Re: PHP MapScript
Добавлено: 17 июл 2013, 05:12
Denis Rykov
GIS-dev писал(а):Ведь все данные, включая мапфайл, он получает из $request.
В общем случае это не так. Вы можете и не передавать имя map-файла в строке запроса, об этом даже написано в
документации. Кроме того, с использованием mapscript вы можете динамически изменять map-файл, формируя его "на лету" и загружая его в mapObj с помощью метода mapscript.fromstring или создавая временные файлы.
GIS-dev писал(а):В WMS-запросе есть параметр "map", перекрывающий аналогичное значение, присваиваемое в момент создания карты конструктором ms_newMapobj(...); Какой мапфайл будет использоваться при обработке запроса? А главное, как от него вообще избавиться? Все параметры, которые должны быть в мапфайле, для конкретного слоя можно занести прямо в атрибуты соответствующих объектов, подчиненных mapObj, но они видимо будут затерты при запуске owsdispatch. Примитивный путь - создавать временный мапфайл, заполнять его данными, выполнять запрос и тут же файл удалять, но хотелось-бы обойтись без таких костылей!
А зачем вы передаете в запросе имя map-файла, если у вас запрос обрабатывается с помощью mapscript и map-файл подставляется на серверной стороне. Я не совсем понял вашу ситуацию, но смысл в том, что если у вас содержимое map-файла статическое, то есть не зависит от запроса, то просто жестко пропишите до него путь (как в вашем примере), если же map-файл нужно изменять динамически (например вы опубликовали по WMS какой-то слой на основе данных PostGIS, а пользователь желает визуализировать только объекты, удовлетворяющие определенному условию, то в этом случае он передает это условие в запросе и в map-файле изменяется SQL-строка запроса данных), то формируйте его при каждом запросе (тут тоже существует несколько вариантов).
Re: PHP MapScript
Добавлено: 19 июл 2013, 09:38
merc
Добрый день! У меня есть вопрос по php mapscript. Пока задача научиться генерить map-файл. У меня есть код (что-то потом добавлю, может что-то выкину)
http://pastebin.com/gGUqUF34. Наверняка кто-нибудь уже делал подобное и есть пример как оптимизировать то что у меня, в частности сделать функцию по layerobj, classobj и тд для разного типа слоев(poi,polygons,lines). Может кто даст дельный совет каким лучше путем пойти? Из выше прочитанного понял, что можно вообще обойтись без map файлов.
Re: PHP MapScript
Добавлено: 19 июл 2013, 12:04
Denis Rykov
А в чем смысл полностью генерировать map-файл? Создайте шаблон и с помощью какого-нибудь шаблонного движка изменяйте необходимые участки, например, стили или строку подключения к базе данных.
[ Сообщение с мобильного устройства ]
Re: PHP MapScript
Добавлено: 19 июл 2013, 12:45
merc
Привет Денис,
Мап файл я генерю (mapserver-utils) на данном этапе и подсовываю ms4w. Но хотелось бы отойти от этого сценария. Можете пояснить что имеется ввиду под созданием шаблона ? mapserver-utils в качестве шаблона подойдет? Там какбы присутствуют шаблоны map-файлов для каждого из типов слоев. Потом в зависимости от zoomlevel подставляются те или иные параметры, меняются классы,стили.
P.S я не программист, что за шаблонные движки?
Re: PHP MapScript
Добавлено: 21 июл 2013, 12:59
Denis Rykov
Опишите задачу, чего вы хотите от mapscript? Может вам статического map-файла хватит.
Re: PHP MapScript
Добавлено: 22 июл 2013, 10:13
merc
Задача,
-автоматизировать процесс создания итогового MAP-файла по mapserver-utils сценарию в WINDOWS,исключив make сценарий и процедуру компиляции,
-в идеале бы получить что то типа maplab (сильно замахнулся:)). Гуглостиль mapserver-utils меня полностью устраивает,
- отдавать стилизированные OSM-данные по WMS\WFS клиенту.
Процесс использования мапсервера связан с постоянной перезаливкой данных разных локаций.
Re: PHP MapScript
Добавлено: 23 июл 2013, 11:18
Denis Rykov
Никогда не пользовался mapserver-utils, поэтому может спрашиваю очевидные вещи - а map-файл, который генерирует mapserver-utils он чем определяется, исходными данными? Если нет, то почему бы его не сгенерировать один раз и использовать.
Re: PHP MapScript
Добавлено: 24 июл 2013, 10:42
merc
как я понимаю, есть набор шаблонизированных Map-файлов highways,borders,places и скрипт generate_style.py, где прописаны данные по стилям. C помощью OptParser в зависимости от зум левела вставляются те или иные данные в шаблоны затем все это компилится в итоговый Map файл.
Re: PHP MapScript
Добавлено: 25 июл 2013, 09:51
Denis Rykov
Ну так скомпилируйте один раз и пользуйтесь, если такой принцип работы.
Re: PHP MapScript
Добавлено: 26 июл 2013, 10:16
merc
Т.к я для каждого нового региона использую отдельную бд(или набор шейпов),то тут у меня несколько путей:
-один раз сгенерировать МАПфайл и потом лазить менять вручную параметры connectiontype,srid,epsg,metadata (18левелов)для каждого нового региона (что довольно муторно);
-импортировать данные нового региона к уже имеющимся в одну базу что несомненно ляжет нагрузкой на перфоманс системы;
-каждый раз генерировать новый МАПфайл для данных нового региона, от чего, как я говорил ранее, хотелось бы уйти.
Re: PHP MapScript
Добавлено: 07 авг 2013, 09:16
GIS-dev
Denis Rykov писал(а):
В общем случае это не так. Вы можете и не передавать имя map-файла в строке запроса, об этом даже написано в
документации. Кроме того, с использованием mapscript вы можете динамически изменять map-файл, формируя его "на лету" и загружая его в mapObj с помощью метода mapscript.fromstring или создавая временные файлы.
А зачем вы передаете в запросе имя map-файла, если у вас запрос обрабатывается с помощью mapscript и map-файл подставляется на серверной стороне. Я не совсем понял вашу ситуацию, но смысл в том, что если у вас содержимое map-файла статическое, то есть не зависит от запроса, то просто жестко пропишите до него путь (как в вашем примере), если же map-файл нужно изменять динамически (например вы опубликовали по WMS какой-то слой на основе данных PostGIS, а пользователь желает визуализировать только объекты, удовлетворяющие определенному условию, то в этом случае он передает это условие в запросе и в map-файле изменяется SQL-строка запроса данных), то формируйте его при каждом запросе (тут тоже существует несколько вариантов).
Да, все параметры динамические, из базы данных. Сомнения были относительно "owsdispatch", что эта функция вытворяет с данными, которые уже загружены в объект карты из мапфайла, или соответствующими вызовами для установки конкретных параметров. А вот вызов метода "ms_newMapObj" без указания мапфайла приводил к странным результатам: получалась карта с параметрами, которые были использованы ранее, при вызове ms_newMapObj с мапфайлом, который их содержал. Это при том, что этот мапфайл был уже физически стерт. Выглядело так, как будто вызов ms_newMapObj без указания мапфайла, вынуждает его использовать кэшированные где-то старые данные. Поэтому пока-что остановился на варианте все-таки создавать временный мапфайл, "скармливать" его ms_newMapObj, а потом удалять.