Архив рубрики: Maperitive

Рельеф и дороги

Недавняя запись в ЖЖ-сообществе «Челябинский Челябинск» напомнила, что хотел я как-то собрать рельеф с дорогами на одной карте. Хотел — сделал.

Рельеф и дороги Челябинска

Сделано при помощи Maperitive — он кроссплатформенный (хоть и выглядит по-виндовому), написан на питоне, падает часто. Делаем так:

1. Масштабируем карту, чтоб захватить нужную область.

2. Генерируем фон, с цветом, зависящим от высоты. Если запустить генерацию без дополнительных параметров, то всё зальёт зелёным без заметного контраста, поэтому надо указать свои цвета:

generate-hypsometric ramps=-200:#003399;200:#33cc66;250:#eeee99;350:#993300

Что даст шкалу, где наиболее заметный контраст приходится на высоты от 200 до 350 метров над уровнем моря
Шкала рельефа

3. Для красоты добавляем отмывку: Tools → Generate Hillshading. В меню три подобных пункта — можно выбрать тот, чьи результаты больше нравятся. Если хочется большего контраста, добавлени слоя с отмывкой можно повторить.

4. Скачиваем данные OpenStreetMap для выбранной области: Map → Download Data (Overpass API) Ctrl+Shift+D

5. Создаём стилевой файл с дорогами и границами, но без всего остального, например, такой:

// rendering rules for Maperitive - roads and boundaries
// http://maperitive.net

// Created by Alexander Sapozhnikov, based on style by Igor Brejc
// Released under the Creative Commons Attribution-ShareAlike 3.0 License (http://creativecommons.org/licenses/by-sa/3.0/)

features
	lines
		road major : highway=motorway OR highway=trunk OR highway=primary
		road minor : highway=motorway_link OR highway=trunk_link OR highway=primary_link OR highway=secondary
		boundary country   : relation[type=boundary AND boundary=administrative AND admin_level=2]
		boundary region    : relation[type=boundary AND boundary=administrative AND admin_level=4]
		boundary province  : relation[type=boundary AND boundary=administrative AND admin_level=6]
		boundary municipal : relation[type=boundary AND boundary=administrative AND admin_level=7]

properties
	map-background-color	: #F1EEE8
	map-background-opacity	: 1
	map-sea-color : #B5D0D0
	map.rendering.lflp.min-buffer-space : 5
	map.rendering.lflp.max-allowed-corner-angle : 40

rules

	target : road*
		if : road major
			define
				line-color : #ff9900
				line-width : 2
				border-width : 10%
				border-color : #000000
				border-style : solid
		elseif : road minor
			define
				line-color : #cc6600
				line-width : 1
		draw : line

	target : boundary*
		define
			line-color : #cc3399
			line-style : dash
		if : boundary country
			define
				line-width : 5
		elseif : boundary region
			define
				line-width : 4
		elseif : boundary province
			define
				line-width : 2
		elseif : boundary municipal
			define
				line-width : 1
		draw : line

6. Выбираем этот стиль:

use-ruleset location="/home/as/map/osm/maperitive/rules/road.mrules"

7. Получившуюся карту экспортируем в желаемый формат — см. меню Tools.

Рельеф — в единых цветах

Когда я пробовал рисовать позиционную физическую карту, не сильно парился о точности соответствия цветов тем, что используются на остальных картах — тыкать пипеткой в соседние карты не хотелось. Приблизительно попал — и ладно, потом подправлю. Однако товарищи вики-географы не дремлют, шлют ссылки на правильные палитры. Хорошо, попробуем исправить.

Итак, список высот и соответствующих им цветов такой:

-10   167 223 210
0     172 208 165
100   168 198 143
200   189 204 150
300   209 215 171
400   225 228 181
500   239 235 192
750   232 225 182
1000  222 214 163
1500  211 202 157
2000  202 185 130
2500  195 167 107
3000  185 152  90
3500  170 135  83
4000  172 154 124
5000  186 174 154
6000  202 195 184
7000  224 222 216
8000  245 244 242
9000  245 244 242

Пересчитывать руками для того, чтоб использовать в Маперитиве — не наш метод. Наш метод — автоматизировать:

#!/usr/bin/perl

while (<>) {
    chomp;
    my @data = split;
    printf '%s:#%02x%02x%02x;',
        @data;
}

Ну или можно вообще однострочник написать:

perl -nla -F'\s+' -e 'printf "%s:#%02x%02x%02x;", @F' ramp-colors-above-water.txt

Осталось добавить получившиеся цвета к команде маперитива, рисующей рельеф:

generate-hypsometric ramps=-10:#a7dfd2;0:#acd0a5;100:#a8c68f;200:#bdcc96;300:#d1d7ab;400:#e1e4b5;500:#efebc0;750:#e8e1b6;1000:#ded6a3;1500:#d3ca9d;2000:#cab982;2500:#c3a76b;3000:#b9985a;3500:#aa8753;4000:#ac9a7c;5000:#baae9a;6000:#cac3b8;7000:#e0ded8;8000:#f5f4f2;9000:#f5f4f2

Эти цвета не такие насыщенные как те, что получились сначала. Южный Урал в этой палитре получается таким:

Рельеф Южного Урала

Карта с рельефом

Пару лет назад я пробовал рисовать карты из данных OpenStreetMap при помощи Maperitive — и даже что-то говорил об этом в докладе на UWDC-2013. Что понравилось ещё тогда — возможность «из коробки» отображать рельеф: Маперитив умеет сам ходить в сеть за открытыми данными о рельефе (SRTM) и потом строить из них контуры горизонтали и рисовать отмывку.

В воскресенье, когда гулять не было возможности, а делать что-то полезное не было желания, вспомнил я прошлые свои упражнения и решил сделать хоть что-то полезное — например, позиционную карту для википедии. Позиционными картами там называют такие карты, на которые потом легко можно нанести метки, указав координаты в виде широты и долготы. Подобные карты, как выяснилось, создать достаточно просто: надо лишь взять изображение, и указать для него необходимые данные, чтоб понятен был способ пересчёта координат. Поддерживаются несколько типов проекций карт, по умолчанию используется равноугольная цилиндрическая проекция — как раз такая, как в OpenStreetMap, для карт в этой проекции достаточно указать лишь широту верхнего и нижнего краёв и долготу левого и правого.

У меня не получилось сразу в Маперитиве получить карту такого вида как мне надо: реки текли поверх водохранилищ и водоёмы никак не хотели с административными границами сочетаться. Потратив немного времени на чтение документации и безуспешные эксперименты, пошёл другим путём: сделать пару отдельных карт — с границами и водами — да и собрал их воедино в Inkscape. Маперитив умеет экспортировать карты в SVG. Вот уменьшенный фрагмент того, что вышло:

Север Нязепетровского района

Шаблон с картой лучше делать не по инструкции — там образец неправильный. Лучше взять за образец какой-нибудь существующий шаблон и слегка его поменять: надо изменить координаты границ карты, её названия и имена используемых файлов. Если речь идёт об изготовлении карты актуального состояния существующей местности (то есть, мы рисуем не историческую карту и не карту вымышленного мира), то имеет смысл нарисовать несколько карт одной и той же области, хотя бы две: физическую и политическую/административную — википедия позволяет выбрать нужную карту из шаблона как вручную, так и автоматически: например, в географических статьях (о реках, озёрах, горах) автоматически отображается физическая карта, если она есть.

Пример статьи с этой картой — Шемаха (приток Уфы). В статье Шемаха (Челябинская область) используется тот же самый шаблон, но карта там уже другая — административная.