Python для обеспечения географических исследований Лекция 8 Сегодня на повестке дня: Разбираем домашние задачки Что такое shape-файл? Немного разбираемся с модулем GeoVis 2 import numpy as np import matplotlib.pyplot as plt import os def readfile (filename): data = [] f = open (directory + '/' + filename,'r') for line in f: data.append(line) f.close() return data directory = 'E:/python/data/oceans' files = os.listdir(directory) for file in files: if file[0] == 'S': s.append(readfile(file)) if file[0] == 'T': t.append(readfile(file)) s = np.array(s,dtype=float) t = np.array(t,dtype=float) i=0 while i < s.shape[0]: plt.plot(s[i],t[i],'o') print np.corrcoef(s[i],t[i])[0,1] i=i+1 s = [] t = [] plt.show() 3 4 bands = 1 dt = gdal.GDT_Float32 format = "GTiff" driver = gdal.GetDriverByName(format) raster = gdal.Open('E:/python/data/raster/B4B5.tif') outData = driver.Create('E:/python/data/raster/output.tif', cols, rows, bands, dt ) redBand = raster.GetRasterBand(1) outData.SetProjection( projection ) red=redBand.ReadAsArray().astype(np.float32) outData.SetGeoTransform( transform ) import gdal import matplotlib.pyplot as plt import numpy as np nirBand = raster.GetRasterBand(2) nir=nirBand.ReadAsArray().astype(np.float32) projection = raster.GetProjection() transform = raster.GetGeoTransform() cols = raster.RasterXSize rows = raster.RasterYSize AddArray = np.add(nir,red) SubArray = np.subtract(nir,red) np.seterr(divide='ignore') NDVIArray = np.divide(SubArray,AddArray) outData.GetRasterBand( 1 ).WriteArray( NDVIArray ) plt.hist (nir) plt.hist (red) plt.show() 5 6 7 В прошлый раз мы посмотрели на работу с геоизображениями с помощью библиотеки GDAL. Но геоизображения это только один из популярных типов геоданных. Другой тип – векторные геоданные. Векторные геоданные описываются математически – как набор координат, связанных некоторым правилом. Line; 2.4,5.1; 7.4,2.5; 1.3,11.8 Point; 5.3,2.1 8 Векторный объект всегда соответствует объекту реального мира, который имеет дискретный характер (дерево, город, страна, здание, область луга). 9 Векторный объект характеризуется не только пространственным положением, ведь так он совсем условно описывает географическую сущность. Ещё обязательно есть описательные характеристики (атрибуты) 10 В географии повсеместно работают с векторными объектами. Хранить их можно по-разному, но есть стандарты. Среди них наиболее яркий и простой: ESRI shapefile. Все ГИС с ним умеют работать. Почти все наборы геоданных распространяются через него. Shapefile хранит объекты одного класса (с одними свойствами). 1 набор для зданий, 1 для рек, 1 для озер и т.д. Есть три базовых типа геометрии для shapefile: -точка -линия -полигон Все объекты внутри такого файла могут быть только одного конкретного геометрического типа. 11 В Python есть довольно много средств для работы с shape-файлами. Рассмотрим два аспекта. 1. Как читать и писать shape-файлы. (Модуль PyShp) 2. Как визуализировать из них карты на экран или в файлы. (Модуль GeoVis) 12 Читать и писать: модуль pyshp https://code.google.com/p/pyshp/ Скачивается обычный файл .py, который кладется в C:\python\Lib\site-packages Доступны операции чтения и записи геометрии и атрибутов 13 # Импортируем библиотеку import shapefile # Читаем файл sf = shapefile.Reader("E:/python/data/shp/countries.shp") Мы связали переменную sf с внешним файлом, также как и всегда # Выгружаем в переменную геометрию всех объектов shapes = sf.shapes() # Выгружаем в переменную заголовки атрибутов fields = sf.fields # А здесь хранятся сами атрибуты records = sf.records 14 По сути мы полностью прочли shape-файл и теперь владеем в переменных геометрией и семантикой всех объектов! print fields print shapes[4].points 15 Обращение к геометрии всегда происходит по точкам. Точки хранятся как пары координат Линии хранятся как последовательность точек Полигоны хранятся как последовательность точек, замыкающаяся в конце Shapes – массив геометрий всех объектов. У каждого элемента есть свойство points, в котором хранятся пары точек Fields – массив всех заголовков атрибутов (с типами) Records – массив всех значений атрибутов >>> sf.records[3][1:3] ['060750601001', 4715] 16 Пишем файлы тоже очень просто: Запишем точечный слой со своими точками import shapefile w = shapefile.Writer(shapefile.POINT) w.point(90.3, 30) w.point(92, 40) w.point(-122.4, 30) w.point(-90, 35.1) w.field('FIRST_FLD') w.field('SECOND_FLD','C','40') w.record('First','Point') w.record('Second','Point') w.record('Third','Point') w.record('Fourth','Point') w.save('E:/python/data/shp/point_test.shp') 17 Запишем слой со своим полигоном: import shapefile w = shapefile.Writer(shapefile.POINT) w = shapefile.Writer(shapefile.POLYGON) w.poly(parts=[[[1,5],[5,5],[5,1],[3,3],[1,1]]]) w.field('FIRST_FLD','C','40') w.field('SECOND_FLD','C','40') w.record('First','Polygon') w.save('E:/python/data/shp/poly_test.shp') 18 Писать можно любые геометрии. Простой сценарий: читаем gps-трек в виде текстового файла и записываем его в shape-файл. Создаем shape-файлы участков по координатам и т.д. 19 На обычно хочется их ещё и посмотреть, покрасить, экспортировать в картинку и т.д. Одной из неплохих и простых библиотек представляется GeoVis. https://github.com/karimbahgat/GeoVis Визуализация shape-файлов, экспорт в png Установка: скачать архив, поместить папку geovis в C:\python\Lib\site-packages\ Предварительно установив pillow через pip.exe: C:\python\Scripts\pip.exe install pillow Это рендерер для создания изображений. 20 Визуализировать shape-файл очень просто: import geovis geovis.ViewShapefile("E:/python/data/shp/countries.shp") 21 Также очень просто сохранить shape-файл как изображение: geovis.SaveShapefileImage(" E:/python/data/shp/countries.shp ", savepath=«E:/output_picture.png") 22 Без всяких настроек цвета случайные, оформление по умолчание. Обычно карта состоит не из одного слоя, а из многих (из набора shape-файлов). Записываем слои в переменные с помощью geovis.Layer () polylayer = geovis.Layer(“E:/python/data/shp/poly_test.shp”, fillcolor=geovis.Color("red")) pointlayer = geovis.Layer(“E:/python/data/shp/points_test.shp”, fillcolor=geovis.Color(“blue")) Создаем саму карту newmap = geovis.NewMap() Добавляем слои на карту newmap.AddToMap(polylayer) newmap.AddToMap(pointlayer) Сохраняем карту в файл newmap.SaveMap(“E:/map.png") 23 Можно настраивать размеры карты, фон и прочее geovis.SetMapDimensions(width=400, height=200) geovis.SetMapBackground(geovis.Color("blue") newmap = geovis.NewMap() 24 Возможно раскрашивание по атрибутам polylayer = geovis.Layer('E:/python/data/shp/countries.shp', fillcolor=geovis.Color("red")) polylayer.AddClassification(symboltype="fillcolor", valuefield="pop_est", symbolrange=[geovis.Color("#110000"),geovis.Color("#FF0000")], classifytype="natural breaks", nrclasses=5) newmap = geovis.NewMap() newmap.AddToMap(polylayer) newmap.SaveMap('E:/map.png') 25 Можно вставлять тексты newmap.AddText(relx=0.5, rely=0.01, text="Example Map Title", textsize=0.10, textanchor="n") Примитивы: DrawCircle () DrawLine () DrawRectangle () … Что в целом позволяет рисовать, в общем-то, любые несложные карты 26 27 Спасибо за внимание! e.kazakov@spbu.ru ekazakov.info/students 28