Перевод статьи Justin Palk «Serving and styling maps with Geoserver».
Google Maps открыл целый мир карт в Сети, делая проще помещение данных на карту для компаний и частных лиц. Но если вы хотите большего контроля над тем, как должны выглядеть ваши карты, или у вас есть данные, которые не очень хорошо работают с Google Maps, есть и другие возможности, включая обслуживание ваших данных с помощью Geoserver.
Geoserver реализует спецификации Web Feature Server и Web Coverage Server консорциума Open Geospatial, с интегрированным Web Map Server. Текущая стабильная версия — 1.6.5, хотя разработчики недавно выпустили 1.7.0-RC2. Написанный на Java, он доступен под Linux и Unix, а также для Windows и требует для своей работы исполняющую систему Java (Java Runtime Environment), например Sun JRE 6.
Geoserver может быть установлен в сервлет, такой, как Tomcat или Jetty, но разработчики также предоставляют отдельные бинарные пакеты. Установить Geoserver в Ubuntu, также просто, как набрать sudo unzip geoserver-1.6.4-bin.zip-d /usr/local/.
Прежде чем вы запустите Geoserver, вам необходимо определить $GEOSERVER_HOME в вашем командном интерпретаторе. Если вы используете bash, вы можете сделать это, добавив export GEOSERVER_HOME=/usr/local/geoserver в конец файла .bashrc или .bash_profile, по вашему выбору.
Чтобы запустить Geoserver, выполните $GEOSERVER_HOME/bin/startup.sh. Когда процесс запуска, который может занять минуту, завершиться, откройте браузер и зайдите на http://127.0.0.1:8080/geoserver, чтобы получить доступ к настройке и демонстрационным страницам.
Нажатие на ссылку «Admin» даст некоторую информацию о статусе сервера, а нажатие на «Config» позволит вам зайти в панель настроек. Блок левой верхней части страницы, с кнопками «Apply», «Save» и «Load» представляет собой большинство страниц настройки Geoserver. Когда вы измените часть конфигурации сервера, вам необходимо нажать «Apply» до того, как сервер их отменит. Нажатие на «Save» запишет изменения на диск, а «Load» перезагрузит ваши настройки с диска, отменяя примененные, но не сохраненные изменения.
Подготовка ваших данных
Когда вы установили и запустили Geoserver, вам потребуются некоторые данные, с которыми необходимо работать. Geoserver может получать данные из другого Web Feature Server или из базы данных PostgreSQL с расширениями PostGIS, но для того, чтобы все работало быстро, вы можете использовать хранимые локально шейпфайлы. Хорошим ресурсом, на котором находятся в свободном доступе данные GIS — это US Census Bureau и их шейпфайлы TIGER/Line. Эти файлы содержат автомобильные и железные дороги, границы воды, штатов и стран. Для нашего упражнения, покажем и зададим определенный внешний вид для данных дорог округа Фредерик, штат Мэриленд. Если вы хотите рассмотреть их поближе, прежде чем продолжить, вам понадобится такая программа, как Qgis.
Разархивируйте шейпфайлы с помощью команды unzip fe_2007_24021_edges.zip -d $GEOSERVER_HOME/data_dir/data/shapefiles/, а затем отправляйтесь в контрольную панель Geoserver. Войдя в неё, нажмите на «Data». Чтобы начать, вам надо создать Namespace, который сможет хранить несколько связанных наборов данных. Нажмите на «Namespace», а затем на «New». Так как мы работаем с данными, описывающими округ Фредерик, дайте Namespace префикс FrCo. Нажмите на «New», затем заполните поле URI для Namespace — наиболее подходящее имя домена, где данные будут обрабатываться — с добавленным префиксом Namespace'а. Для этого примера просто используйте адрес http://127.0.0.1/FrCo. Наконец, нажмите «Submit».
Когда у вас будет Namespace с вашими данными, вам надо будет добавить DataStore, — в данном случае, шейпфайл TIGER. Вернитесь к странице конфигурации данных и нажмите на «DataStores». И снова, нажмите «New», введите имя в Feature Data Set ID, такое, как «FrederickCountyLines» и выберите «Shapefile» из предоставленного выпадающего меню. Убедитесь, что отмечено поле «Enabled», чтобы сервер сделал данными доступными из сети, установите Namespace в FrCo, если ещё этого не сделали и введите в строке адреса file:data/shapefile/fe_2007_24021_edges.shp. Внизу выберите «create spatial index -> true» и нажмите «Submit».
Geoserver незамедлительно перенаправит вас на страницу FeatureType Configuration, где вы дадите ему больше деталей о тех данных, на которые вы указали. Так как имя шейпфайла не описывает его в нужной степени, задайте функции алиас: FrederickCountyLines. Так как вы не создали стиль для этой функции, который указал бы Geoserver'у, как она должна отображаться, выберите стиль линий из выпадающего меню сейчас.
Затем, вам нужно сообщить Geoserver'у информацию о геометрической модели или пространственной системе ссылок, на которой основаны данные. SRS описывает систему координат, модель образа Земли и проекцию, которую использует карта. У группы European Petroleum Survey Group есть каталог SRS, на которые можно ссылаться по их номеру EPSG. В данном случае, SRS для данных TIGER, с которыми вы работаете в каталоге EPSG, находится под номером 4269, поэтому поместите его в поле SRS и нажмите «Lookup SRS».
Geoserver может автоматически установить значение границ для ваших данных, поэтому нажмите кнопку «Generate», чтобы это сделать, а затем опуститесь вниз по странице и нажмите «Submit».
Примените произведенные изменения, чтобы увидеть, что у вас есть в итоге, вернитесь на экран приветствия, нажмите ссылку «Demo», а затем «Map Preview». В списке FeatureTypes пункт FrCo:FrederickCountyLines должен находится наверху. Нажмите на него, и Geoserver выдаст вам карту OpenLayers, используя введенные вами данные.
Мы получили всего лишь комок неразличимых линий, не несущих каких-либо значений, до тех пор, пока вам не посчастливится угадать, какую область вы показываете. Это произошло потому, что шейпфайл содержит данные о разных типах объектов, включая автомобильные и железные дороги и реки, а тот стиль, что вы выбрали несколько раньше, просто сообщает Geoserver'у вырисовывать все в виде простых линий. Чтобы исправить это, вам нужно создать стиль для карты.
Создание стиля карты
Для контроля над внешним видом карты, которую он отображает, Geoserver использует Styled Layer Descriptor от консорциума Open Geospatial. SLD — это XML-документы, которые содержат правила, управляющие тем, как должны отрисовываться объекты. Вот простой SLD:
<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NamedLayer>
<Name>Округ Фредерик</Name>
<UserStyle>
<Title>Стиль дорог Фредерик</Title>
<Abstract>Стиль для карты дорог округа Фредерик</Abstract>
<FeatureTypeStyle>
<Rule>
<Name>Highways</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>MTFCC</ogc:PropertyName>
<ogc:Literal>S1100</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<!-- черная внешняя линия -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">5</CssParameter>
</Stroke>
</LineSymbolizer>
<!-- красная центральная линия -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FF0000</CssParameter>
<CssParameter name="stroke-width">3</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
Этот файл содержит одно правило по отрисовке шоссейных дорог красным цветом с черной внешней линией. Он состоит из двух частей: фильр и пара LineSymbolizer.
Фильтры позволяют вам указать, к каким классам данных в FeatureType вы хотите применить правило. В этом случае, вы ищете главные дороги. В шейпфайле они классифицируются с кодом класса MAF/Tiger Feature, или MTFCC из S1100. Учтите, что имена свойств в фильтрах чувствительны к регистру.
LineSymbolizer сообщает Geoserver'у, как должны выглядеть линии. Когда вы их соединяете вместе, думайте, как будто вы рисуете картину — то, что должно быть наверху должно быть последним помещено. В данном случае, чтобы получить красную линию с черной внешней, сначала рисуется 5-пиксельная черная линия, а затем поверх неё кладется 3-пиксельная красная линия.
SLD также содержит PolygonSymbolizer для рисования многоугольников и других геометрических фигур, обладающих площадью; PointSymbolizer для данных о точках; TextSymbolizer для форматирования текста надписи; RasterSymbolizer для использования при отображении растровых данных, таких, как снимки со спутника или моделей возвышенностей. Вы можете скачать полную спецификацию SLD.
Скопируйте ваш SLD и сохраните его, где пожелаете. Вернитесь к настройке Geoserver и нажмите «Style», затем «New». Вы увидете диалоговый блок, где вы можете ввести новое имя стиля. Введите «FrederickCountyRoads» и нажмите «Submit». Geoserver покажет текстовое поле, куда вы можете ввести ваш новый стиль. Либо скопируйте и вставьте стиль в текстовое поле, либо, если вы сделали локальную копию, загрузите её с помощью элементов ниже текстового поля, а затем нажмите «Submit». По умолчанию Geoserver произведет валидацию вашего SLD по отношению к схеме SLD, и, если будут ошибки, выдаст страницу, на которой они будут отмечены, чтобы вы смогли их исправить.
Вернитесь к настройке FeatureTypes для FrCo:FrederickCountyLines, поменяйте SLD со строк на FrederickCountyRoads, нажмите «Submit», а затем кнопку «Apply», чтобы сервер зарегистрировал изменения в SLD. Когда вы вернетесь к просмотру карты, масса тонких линий исчезнет, и вы должны будете увидеть только шоссейные дороги, — l-79 лежит с востока на запад, а l-270 пролегает по окружности из центра карты вниз на юго-восток. Сейчас все продвинулись немного дальше, и теперь скелет отображает данные, но вы начали видеть, как Geoserver позволяет вам брать контроль над картой.
Вот более сложный SLD, который делает возможным отображение разных типов дорог, каждый в своем стиле:
<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NamedLayer>
<Name>Frederick County</Name>
<UserStyle>
<Title>Стиль дорог округа Фредерик</Title>
<Abstract>Стиль для карты дорог округа Фредерик</Abstract>
<FeatureTypeStyle>
<Rule>
<Name>Дороги местного значения</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>MTFCC</ogc:PropertyName>
<ogc:Literal>S1200</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<MinScaleDenominator>15000</MinScaleDenominator>
<!-- черная линия (2 px.) -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
<Rule>
<Name>Дороги местного значения
высокого разрешения</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>MTFCC</ogc:PropertyName>
<ogc:Literal>S1200</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<MaxScaleDenominator>14999</MaxScaleDenominator>
<!-- черная граница -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">5</CssParameter>
</Stroke>
</LineSymbolizer>
<!-- белая полоса -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FFFFFF</CssParameter>
<CssParameter name="stroke-width">3</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
<Rule>
<Name>Скоростные шоссе</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>MTFCC</ogc:PropertyName>
<ogc:Literal>S1100</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<!-- черная внешняя линия -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">5</CssParameter>
</Stroke>
</LineSymbolizer>
<!-- красная центральная линия -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FF0000</CssParameter>
<CssParameter name="stroke-width">3</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
В этой SLD есть правила для скоростных шоссе и дорог местного значения. Если вы посмотрите внимательнее, то заметите, что есть два правила для дорог местного значения, каждое из которых предназначено для разных уровней разрешения карты. Вернитесь и отредактируйте SLD FrederickCountyRoads, внеся туда этот файл взамен тому, что вы установили первым, примените изменения и перейдите к просмотру карты. Теперь вы увидете скоростные шоссе и дороги местного значения, а когда вы приблизите изображение, увидете, что отображение дорог местного значения изменится.
Соответствующие теги — MinScaleDenominator и MaxScaleDenominator. В то время, как филтры позволяют контролировать то, к каким данным применять правило, эти два тега контролируют, на каком масштабе их применять. Они позволяют управлять уровнем детализации на вашей карте, чтобы люди не были ошеломлены массой спагетти, когда они приблизят изображение. Когда вы приближаете карту, и уровень детализации возрастает, знаменатель масштаба карты уменьшается. MinScaleDenominator устанавливает самый высокий уровень приближения, к которому будет применяться правило, а MaxScaleDenominator устанавливает его нижнюю границу. В данном случае, вы установили одно правило для показа дорог местного значения, когда знаменатель масштаба равен 15000, или выше, для карт, отображающих большую площадь, и другое правило для тех случаев, когда знаменатель масштаба карты равен 14999, или ниже, для карт, которые при приближении отображают меньшую площадь.
Обозначения
Следующей вещью, которую предстоит сделать, будет поместить обозначения на дороги. Чтобы избежать путаницы на карте, добавьте следующий код для правил отображения дорог местного значения в высоком разрешении, сразу над первым LineSymbolizer:
<TextSymbolizer>
<Label>
<ogc:PropertyName>FULLNAME</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Times New Roman</CssParameter>
<CssParameter name="font-style">Normal</CssParameter>
<CssParameter name="font-size">10</CssParameter>
</Font>
<LabelPlacement>
<LinePlacement>
<PerpendicularOffset>10</PerpendicularOffset>
</LinePlacement>
</LabelPlacement>
<Halo>
<Radius>
<ogc:Literal>2</ogc:Literal>
</Radius>
<Fill>
<CssParameter name="fill">#FFFFFF</CssParameter>
<CssParameter name="fill-opacity">0.85</CssParameter>
</Fill>
</Halo>
<Fill>
<CssParameter name="fill">#000000</CssParameter>
</Fill>
<VendorOption name="group">yes</VendorOption>
</TextSymbolizer>
TextSymbolizer расширяет некоторые возможности с помощью LineSymbolizer, но также имеет и некоторые новые возможности. Тег Label определяет, какое поле в шейпфайле Geoserver должен искать для будущего имени. Тег LabelPlacement и его дочерние теги указывают, что обозначения должны быть помещены перпендикулярно линии, к которой они добавляются, и сдвинуты на 10 пикселов. Тег Halo создает белые ореолы в 2 пикселя вокруг обозначений, чтобы повысить их видимость. Наконец, тег VendorOption устанавливает специальное правило Geoserver, чтобы отображать одно и то же любое определенное обозначение, даже если оно относится к разным объектам, как, например, сегменты дороги. Загрузите и примените изменения, вернитесь к просмотру карты и приблизьте изображение на некоторых дорогах, чтобы увидеть результат.
Шаблоны GetFeatureInfo
Это ещё одна вещь, которую позволяет делать Geoserver для контроля над тем, как данные о ваших FeatureTypes будут представлены в соответствии с запросами. Просмотр карты устроен таким образом, что когда вы кликните на таком объекте, как дорога, он выполнит запрос WFS GetFeatureInfo для получения информации о том объекте, по которому вы кликнули. Стандартный ответ Geoserver на такой запрос — отправка таблицы, содержащей все поля данных, связанных с этим объектом. Вы можете использовать шаблоны Freemarker для перезаписи стандартного ответа. Помимо других возможностей, Freemarker позволяет вам считывать данные об объекте и поддерживает простые циклы и условные выражения.
Вот простой шаблон Freemarker для FeatureType, настроенного на отображение имени дороги. Он MTFCC и показывает, является ли дорога разделенной:
<#list features as feature>
<#if feature.MTFCC.value = "S1200" || feature.MTFCC.value = "S1100">
<p><b>Имя дороги:</b> ${feature.FULLNAME.value}</p>
<p><b>Код класса MAF/TIGER Feature:</b> ${feature.MTFCC.value}</p>
<#if feature.DIVROAD.value = "Y">
<p>Это разделенная дорога.</p>
</#if>
</#if>
</#list>
Для использования этого шаблона, скопируйте его в файл и сохраните как $GEOSERVER_HOME/data_dir/featureTypes/FrederickCountyLines_fe_2007_24021_edges/content.ftl. В данном случае, вам не надо применять изменения, так как Geoserver автоматически будет использовать новый шаблон при следующем обращении к объекту в этом FeatureType.
При поступлении запроса, Geoserver прогонит объект (или набор объектов, в случае пересечения, наложения и т.п.) через этот шаблон в виде списка, по которому проходит директива <#list>. Пример содержит данные для объекта, который вы запросили, к которым вы можете получить доступ через точку, как показано выше. Или, в более общем виде: feature.ИмяПоля.Значение. Как и в случае с фильтрами, ссылки к полям данных в FeatureType чувствительны к регистры, поэтому feature.FULLNAME будет отличаться от feature.fullname.
С этим шаблоном, при нажатии на дорогу, вместо таблицы данных, вы просто получите информацию, которую вы указали и отформатировали, как хотели.
Заключение
Это было только небольшое вступление к тому, как Geoserver может помочь вам в представлении ваших данных. Документация Geoserver содержит больше информации о внешнем виде карт, сложностей размещения обозначений и других возможностей, не затронутых в этой статье, включая и то, как обработать растровые данные, такие, как изображения со спутника, сделать ваши данные столь же доступными для скачивания, как и для отображения и кеширование FeatureTyoe для лучшей производительности.
|