Контурые карты часто применяются в задачах визуализации, когда нужно отобразить некоторые статистические данные на геопространственных координатах. Для хранения контурных карт наиболее популярными форматами являются форматы shape, geojson и его модификация topojson, позволяющая хранить данные более компактно. Хранить эти форматы можно в базе данных postgtesql, при этом удобно использовать расширение postgis, предоставляющее различные вычислительные функции с географичесими координатами. Для отображения контурных карт в web-приложении используются различные библиотеки, например, d3js.
Карты стран мира в формате shape
Карты очертаний городов России по регионам
Каждый архив содержит 2 типа карт. pop-built-up-a-rostov-gislab более полная, включает следующие полезные поля
- название на латитице и кирилице
- тип объекта (хутор, город,...)
- район
- код по КЛАДР
- еще один код?? напоминающий КЛАДР
- почтовый индекс
- географические координаты
Карты СНГ, России и регионов (подробные с точностью до зданий)
Каждый архив содержит несколько типов карт
- административные границы boundary-polygon.shp
- населенные пункты (в виде точек, не полигонов) settlement-point.shp
- здания building-polygon.shp
- автодороги highway-line.shp
- железные дороги railway-line.shp
может еще копу пригодятся
- землепользование landuse-polygon.shp
- растительность vegetation-polygon.shp
- точки интереса poi-polygon.shp
Карты городов (shape, geojson)
Загрузка карт в базу данных
- Установливаем Postgis
sudo apt-get install postgresql-9.6-postgis-2.3
create extension postgis;
- Загружаем карты
Существует удобная утилита shp2pgsql, позволяющая конвертировать карты в shape-формате в базу данных. Утилита устанавливается с пакетом postgis. Вот пример экспорта shape-файла в БД
shp2pgsql _shapefile_ _schema_._tablename_ > _sqlfilename_
psql -h localhost -d geo -U postgres -f _sqlfilename_
Если напрямую в БД, то можно так
shp2pgsql pop-built-up-a-rostov-gislab rostov1 | psql -h localhost -d geo -U postgres
Если выдает ошибку, связанную с кодировкой при именах, написанных кирилицей, то попробовать добавить ключ -S -W "utf-8"
Описание ключей команды (на русском) можно посмотреть здесь
Для любителей кодить и более гибкой загрузки shape-файлов в БД существует удобная python-библиотека pyshp. Вот пример рабочего кода выполняющий ту же задачу, что и утилита shp2pgsql - экспорт shape-файла в таблицу БД
# -*- coding: utf-8 -*-
import shapefile
import psycopg2
from psycopg2.extensions import QuotedString
import json
filename="ne_10m_admin_0_countries"
dbname='geo'
myshp = open(filename+".shp", "rb")
mydbf = open(filename+".dbf", "rb")
myshx = open(filename+".shx", "rb")
reader = shapefile.Reader(shp=myshp, dbf=mydbf, shx=myshx)
fields = reader.fields[1:]
# подключаемся к БД
conn = psycopg2.connect("dbname='%s' user='postgres' password='qweasd'" % (dbname,))
conn.autocommit=True
cur = conn.cursor()
# собираем имена полей и их типы для создания таблицы
ff='gid serial NOT NULL, '
for f in fields:
typ='smallint'
if f[1]=='C':
typ='character varying(%d)' % (f[2],)
if f[1]=='N' and f[3]:
typ='double precision'
ff+='"%s" %s, ' % (f[0], typ)
# создаем таблицу в БД
sql= "CREATE TABLE IF NOT EXISTS %s (%s)" % (filename,ff[:-2])
cur.execute(sql)
sql="SELECT AddGeometryColumn('public', '%s','geom','0','MULTIPOLYGON',2);" % (filename,)
cur.execute(sql)
# заполняем таблицу
fields=[field[0] for field in fields]
fields.append('geom')
fields=str(tuple(fields)).replace("'", '"')
for sr in reader.shapeRecords():
data=','.join([QuotedString(str(i)).getquoted() for i in sr.record])
geo=sr.shape.__geo_interface__
if geo["type"]=='Polygon':
geo["type"]='MultiPolygon'
geo["coordinates"]=[geo['coordinates']]
sql='INSERT INTO "%(table)s" %(fields)s VALUES (%(val)s, ST_GeomFromGeoJSON(%(geom)s));' % {'table':filename, 'fields':fields, 'val':data, 'geom':QuotedString(json.dumps(geo)).getquoted()}
cur.execute(sql)
Получить контурную карту из базы
Наша карта сохраняется в таблице в специальном сжатом формате postgis. Для ее отрисовки в браузере карту нужно прежде всего преобразовать в формат geojson (о спецификации формата можно прочитать по ссылке вконце статьи). Преобразование выполняется с помощью команды ST_AsGeoJSON, например, так:
select ST_AsGeoJSON(geom) from ne_10m_admin_0_countries where "SOVEREIGNT"='Russia'
Если мы ходим объединить полигоны (все или по некоторому признаку), делаем примерно так
SELECT ST_AsGeoJSON(ST_UNION( ARRAY(select geom from rostov1)));
Так можно объединять по различным признакам, например - показать населенные пункты, находящиеся на одной широте, выделить только города - миллионники и т.д.
При необходимости, если выходной объем получается очень большой для передачи клиенту, геометрию карты можно упрощать с помошью команды ST_Simplify
Проверить отрисовку в браузере
Посмотреть корректность отображения контурной карты можно так. С помошью команды выше выгрузить в формате geojson интересующую нас карту в файл. Файл загрузить на один из сервисов
Кстати, эти онлайн сервисы позволяют сконвертировать формат geojson в topojson - более компактный и адаптированный для работы с библиотекой d3js на стороне клиента.
Полезные ссылки