GIS-LAB

Географические информационные системы и дистанционное зондирование

Реализация определяющей выборки в Mapserver

Небольшой пример иллюстрирующий построение карты с выборочным показом объектов.

Обсудить в форуме Комментариев — 4

Типичная задача при визуализации пространственной информации - демонстрация некоторого ее подмножества (назовем этот механизм определяющей выборкой), скрыв остальную информацию. Это подмножество может быть определено как пространственно (например ограничением географического охвата или какой-то более сложной формой), так и через атрибутивную таблицу объектов. В данном примере мы иллюстрируем, как можно, с помощью специально сформированного URL карты осуществить выборку и показать только выбранные объекты, скрыв остальные. Данная возможность может пригодится для динамического уменьшения количества информации, показываемой на карте. В терминологии ESRI данные вид выборки называется "definition query" (определяющая выборка).

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

Изменения в map-файле

В конфигурационном файле карты необходимо произвести следующие изменения:

В главный раздел необходимо добавить тэг QUERYMAP, вот так:

QUERYMAP
	STATUS ON
	SIZE 400 300
	STYLE  SELECTED
END

Обращаем внимание, что в STATUS должно стоять именно ON, иначе не будет работать.

В разделе слоя, к которому будет осуществляться запрос (LAYER), так же необходимо установить правило составления запроса:

LAYER
...
	METADATA
		qstring_validation_pattern '.'
	END
...
END

Туда же нужно добавить ссылку на шаблон для вывода атрибутивной информации, несмотря на то, что нас в данном случае интересует выборка с отображением элементов карты, а не атрибутики, это все равно необходимо сделать. Файл шаблона должен существовать, хотя содержимое его не имеет значения. Если этого не сделать, Mapserver будет выдавать следующее сообщение об ошибке:

msQueryByAttributes(): Query error. Requested layer has no templates defined so is not queryable.

Таким образом, к содержимому LAYER добавляется еще несколько строк, указывающих местонахождение главного шаблона (в нашем случае это файл template.html). Содержимое данного раздела представляет собой некоторое ухищрение, если ограничиться просто TEMPLATE "template_subst.html", то будет карта с результатом будет выведена столько раз, сколько объектов попадает в выборку определенную qstring, qitem, qlayer. Данный подход складывает все эти карты в одну, при этом TEMPLATE и FOOTER ссылаются на существующий, но абсолютно пустой файл (само собой для своего проекта это может быть изменено).

LAYER
...
	TEMPLATE 	"template_subst.html"
	FOOTER		"template_subst.html"
	HEADER		"template.html"
...
END

В ту же секцию, возможно сразу после TEMPLATE'ов, необходимо также добавить тэг METADATA со схемой проверки запроса. Так как мы по-умолчанию предполагаем, что запрос наш верен (за это у нас отвечается код на Javascript), то наша строка проверки будет выглядеть таким образом:

LAYER
...
	TEMPLATE 	"template_subst.html"
	...
	METADATA
		qstring_validation_pattern '.'
	END
...
END

Если этого не сделать, получим ошибку от MapServer такого содержания:

mapserv(): Web application error. Metadata qstring_validation_pattern is not set.

Результирующий map-файл целиком будет выглядеть следующим образом:

MAP
  IMAGETYPE      PNG
  EXTENT         -97.238976 41.619778 -82.122902 49.385620
  SIZE           400 300
  SHAPEPATH      "/путь/к/каталогу/c/shape-файлами"
  IMAGECOLOR     255 255 255

  WEB
    TEMPLATE  "template.html"
    IMAGEPATH "/путь/к/каталогу/c/временными файлами"
    IMAGEURL  "/tmp/"
  END

  QUERYMAP
    STATUS ON
    SIZE 400 300
    STYLE  SELECTED
  END

  LAYER
    NAME         states_poly
    DATA         states_ugl
    STATUS       DEFAULT
    TYPE         POLYGON
    CLASSITEM   "CLASS"
	TEMPLATE 	"template_subst.html"
	FOOTER		"template_subst.html"
	HEADER		"template.html"
	METADATA
				qstring_validation_pattern '.'
	END
    CLASS
      NAME 'States'
      EXPRESSION 'land'
      STYLE
        COLOR      232 232 232
      END
    END
    CLASS
      NAME 'Water'
      EXPRESSION 'water'
      STYLE
        COLOR      198 198 255
      END
    END
  END
END

 

Изменения в html

В HTML нашего шаблона нужно добавить параметры запросов:

<input type="hidden" name="qlayer" value="">
<input type="hidden" name="qitem" value="">
<input type="hidden" name="qstring" value="">

И небольшой JavaScript, который будет получить выбранное значение от списка и отправлять его MapServer'у.

<SCRIPT language=JavaScript type=text/javascript>
<!--
function create_query(form) {
vid=form.vid.value;
query="('[State]'=='"+vid+"')";
if (query != "") {
query="("+query+")"
form.qstring.value=query;
form.qitem.value="State";
form.qlayer.value="states_poly";
};
}

function on_submit_form(){
create_query(document.mapserv);
document.mapserv.mode.value="itemnquery"
document.mapserv.target = "_self";
document.mapserv.submit();
}
// -->
</SCRIPT>

Посмотреть пример работающей определяющей выборки реализованной описанным выше образом можно здесь.

Пример результирующего URL, содержащего запрос:

http://gis-lab.info/cgi-bin/mapserv?map=/path/to/example/defquery.map&mode=itemnquery&imgext=-97.238976+39.838907+-82.122902+51.166491&imgxy=200.0+150.0&layer=states_poly&layer=states_line&zoom=0&qlayer=states_poly&qitem=State&qstring='Minnesota'

Обсудить в форуме Комментариев — 4

Последнее обновление: September 09 2021

Дата создания: 02.03.2008
Автор(ы): Максим Дубинин