>ne_110m_admin_1_states_provinces_shp.README.html
>ne_110m_admin_1_states_provinces_shp.sbn
>ne_110m_admin_1_states_provinces_shp.VERSION.txt
>ne_110m_admin_1_states_provinces_shp.sbx
>ne_110m_admin_1_states_provinces_shp.dbf
>ne_110m_admin_1_states_provinces_shp.shp
>ne_110m_admin_1_states_provinces_shp.prj
>ne_110m_admin_1_states_provinces_shp.shx
Мы будем использовать эти файлы в наших примерах.
Для прочтения шейп-файла вам понадобится эта библиотека:
>$ pip install pyshp
Теперь введите текст программы, map1.py, который я модифицировал из статьи в блоге Geospatial Python (http://bit.ly/raster-shape):
>def display_shapefile(name, iwidth=500, iheight=500):
>····import shapefile
>····from PIL import Image, ImageDraw
>····r = shapefile.Reader(name)
>····mleft, mbottom, mright, mtop = r.bbox
>····# map units
>····mwidth = mright — mleft
>····mheight = mtop — mbottom
>····# scale map units to image units
>····hscale = iwidth/mwidth
>····vscale = iheight/mheight
>····img = Image.new("RGB", (iwidth, iheight), "white")
>····draw = ImageDraw.Draw(img)
>····for shape in r.shapes():
>········pixels = [
>············(int(iwidth — ((mright — x) * hscale)), int((mtop — y) * vscale))
>············for x, y in shape.points]
>········if shape.shapeType == shapefile.POLYGON:
>············draw.polygon(pixels, outline='black')
>········elif shape.shapeType == shapefile.POLYLINE:
>············draw.line(pixels, fill='black')
>····img.show()
>if __name__ == '__main__':
>····import sys
>····display_shapefile(sys.argv[1], 700, 700)
Эта программа считывает шейп-файл и проходит по отдельным фигурам. Я ищу только два типа фигур: многоугольник, который соединяет последнюю точку с начальной, и ломаную линию, которая этого не делает. Я строил свою логику на основе оригинальной статьи и беглого просмотра документации pyshp, поэтому вполне уверен в том, что знаю, как работает программа. Иногда вам просто нужно начать и затем справляться с возникающими проблемами.
Запустим наш код. Аргументом станет базовое имя для шейп-файла, не содержащее расширения:
>$ python map1.py ne_110m_admin_1_states_provinces_shp
Вы должны увидеть что-то похожее на рис. Б.1.
Рис. Б.1. Предварительная карта
Что ж, программа нарисовала карту, которая напоминает Соединенные Штаты, но:
• между Аляской и Гавайями видим что-то вроде растрепанных кошкой ниток — это баг;
• страна сплющена, а мне нужна проекция;
• картинка не очень красивая — мне нужно задать стиль.
По поводу первого пункта: в логике программы есть ошибка, но что мне делать? В главе 12 рассматриваются советы для разработчиков, включая информацию об отладке, но мы можем рассмотреть и другие варианты. Я мог бы написать несколько тестов и работать, пока не исправлю ошибку, или же могу применить какую-нибудь другую библиотеку для создания карты. Возможно, более высокоуровневое решение поможет мне справиться со всеми тремя проблемами (лишние линии, сплющенный вид и примитивный стиль).