_This is a slightly modified version of "gis-course/course.ipynb" from Jonathan Feinberg's gis-course github repo as of Jan 20 2019. The repo is cloned in gis_jonathanfeinberg/gis-course/ . - Jim M
import rasterio # I/O raster data (netcdf, height, geotiff, ...)
import rasterio.warp # Reproject raster samples
import fiona # I/O vector data (shape, geojson, ...)
import pyproj # Change coordinate reference system
import numpy as np # numerical array manipulation
import matplotlib.pyplot as plt # plotting tools
%matplotlib inline
import warnings # ignore annoying warnings
warnings.filterwarnings("ignore")
# Jim M : path to data in github epo clone
data_home = "gis_jonathan_feinberg/gis-course/"
rasterio
¶Read more on: https://github.com/mapbox/rasterio
# Map of Norway
with rasterio.open(data_home + "nc/etopo180.nc", "r") as src_nc:
left, bottom, right, top = src_nc.bounds
height, width = src_nc.shape
# raster information
print("left: %s, right: %s, bottom: %s, top: %s" % (left, right, bottom, top))
print("height: %s, width: %s" % (height, width))
# 1D vectors
x_1d = np.linspace(left, right, width)
y_1d = np.linspace(top, bottom, height)
# 2D vectors trough meshing
x, y = np.meshgrid(x_1d, y_1d)
z = src_nc.read()[0]
print("shapes:", x.shape, y.shape, z.shape)
matplotlib
library¶Read more on: http://matplotlib.org/
# altitude colors
colors = range(0, 2500, 100)
# plot in summer greens
plt.contourf(x, y, z, colors, cmap="summer")
# labels and colorbar
plt.xlabel("longditude")
plt.ylabel("latitude")
plt.colorbar().set_label("altitude")
numpy
¶index = np.argwhere(z == np.max(z))
i, j = index.T
x_max = x[i, j]
y_max = y[i, j]
z_max = z[i, j]
plt.contourf(x, y, z, colors, cmap="summer")
plt.colorbar()
plt.plot(x_max, y_max, "r^")
plt.title("Norway's top %d meters above sea level" % z_max)
pyproj
¶Read more on: http://jswhit.github.io/pyproj/
print("coordinate reference system:", src_nc.crs)
# no info typically means WGS84/EPSG:4326
wgs84 = pyproj.Proj(init="epsg:4326")
utm33n = pyproj.Proj(init="epsg:32633")
x_utm33n, y_utm33n, z_utm33n = pyproj.transform(wgs84, utm33n, x, y, z)
plt.contourf(x_utm33n, y_utm33n, z_utm33n, colors, cmap="summer")
plt.colorbar()
# lon/lat bounding box for Telemark
left, right, bottom, top = 6.9, 10.0, 58.6, 60.2
# closest indices on mesh
i_left = np.argmin( (x_1d - left)**2 )
i_right = np.argmin( (x_1d - right)**2 )
i_top = np.argmin( (y_1d - top)**2 )
i_bottom = np.argmin( (y_1d - bottom)**2 )
print("Bounding box on grid:")
print(x_1d[i_left], x_1d[i_right], y_1d[i_bottom], y_1d[i_top])
# subset to box thorugh slicing
x_telemark = x[i_top:i_bottom, i_left:i_right]
y_telemark = y[i_top:i_bottom, i_left:i_right]
z_telemark = z[i_top:i_bottom, i_left:i_right]
# transform to projection
x_telemark_utm33n, y_telemark_utm33n, z_telemark_utm33n = \
pyproj.transform(wgs84, utm33n, x_telemark, y_telemark, z_telemark)
plt.contourf(x_telemark_utm33n, y_telemark_utm33n, z_telemark_utm33n, colors, cmap="summer")
plt.colorbar()
plt.contourf(x_utm33n, y_utm33n, z_utm33n, colors, cmap="summer")
plt.colorbar()
# zoom box
left_utm33n, top_utm33n = pyproj.transform(wgs84, utm33n, left, top)
right_utm33n, bottom_utm33n = pyproj.transform(wgs84, utm33n, right, bottom)
plt.axis([left_utm33n, right_utm33n, bottom_utm33n, top_utm33n])
rasterio.warp
¶# Source information
west, east = x_1d[0], x_1d[-1]
north, south = y_1d[0], y_1d[-1]
src_transform = rasterio.transform.from_bounds(
west, south, east, north,
width, height)
src_crs = {"init": "epsg:4326"}
print(z.shape)
# Destination information
height_telemark = i_bottom-i_top
width_telemark = i_right-i_left
dst_transform = rasterio.transform.from_bounds(
left_utm33n, bottom_utm33n,
right_utm33n, top_utm33n,
width_telemark, height_telemark)
dst_crs = {"init": "epsg:32633"}
# container for output
z_reproject = np.empty((height_telemark, width_telemark), z.dtype)
print(z_reproject.shape)
#rasterio.warp.reproject(z, z_reproject,
# src_transform=src_transform, src_crs=src_crs,
# dst_transform=dst_transform, dst_crs=dst_crs,
# resampling=rasterio.warp.RESAMPLING.nearest)
# Jim M :
# AttributeError: module 'rasterio.warp' has no attribute 'RESAMPLING'
# ... probably a feature difference in this version of the software.
rasterio.warp.reproject(z, z_reproject,
src_transform=src_transform, src_crs=src_crs,
dst_transform=dst_transform, dst_crs=dst_crs)
x_reproject = np.linspace(left_utm33n, right_utm33n, width_telemark)
y_reproject = np.linspace(top_utm33n, bottom_utm33n, height_telemark)
x_reproject, y_reproject = np.meshgrid(x_reproject, y_reproject)
plt.contourf(x_reproject, y_reproject, z_reproject, colors, cmap="summer")
plt.colorbar()
#with rasterio.open(data_home + "telemark.nc", "w",
# driver="netCDF",
# crs={"init":"epsg:32633"}, transform=dst_transform,
# width=width, height=height,
# count=1, dtype=z_reproject.dtype
# ) as dst:
# dst.write_band(1, z_reproject)
# Jim M
# Error: RasterioIOError: Blacklisted: file cannot be opened by driver 'netCDF' in 'w' mode
# Didn't try to debug.
Save as raster file type without meta-info:
# rescale and recast
z_rescaled = (z_reproject - z_reproject.min()) / (z_reproject.max() - z_reproject.min()) * 255
z_rescaled = z_rescaled.astype(np.uint8)
# save as gif
with rasterio.open(data_home + "telemark.gif", "w",
driver="gif", transform=dst_transform,
width=width, height=height,
count=1, dtype=np.uint8
) as dst:
dst.write_band(1, z_rescaled)
fiona
¶Read more on: https://github.com/Toblerity/Fiona
Data from Norges vassdrags- og energidirektorat: http://nedlasting.nve.no/gis/
src_shp = fiona.open(data_home + "shp/Innsjo_InnsjoInformasjon.shp", "r")
print("File data type:")
print(src_shp.driver)
print()
print("Information about data:")
print(src_shp.schema)
print()
print("Coordinate reference system:")
print(src_shp.crs)
# Create local projection
proj_innsjo = pyproj.Proj(**src_shp.crs)
print("Number of entries: %d" % len(src_shp))
print("First entry:")
print(src_shp[0])
Cleaning up formating:
{
'geometry' : {
'type' : 'Point',
'coordinates' : (120430.72499999963, 6592609.6603125, 0.0)
},
'properties' : {
'objType' : 'Innsjø',
'vatnLnr' : 14290.0,
'navn' : 'Skredstøyltjørnan',
'areal_km2' : 0.0607,
'arealNO' : 0.06,
'hoyde_moh' : 801.0,
'magasinNr' : None,
'vassdragNr' : '019.F42AZ',
'hierarki' : 'GRIMDALSÃ…I/HORGEVIKÃ…I/ARENDALSVASSDRAGET',
'dybdekart' : None,
'grensesjo' : None,
'land1' : 'NO',
'land2' : None,
'vassOmrNr' : '019',
'uttakDato' : '2016-01-19',
'ekspType' : 'NVEs nedlastningsløsning'
}
'type' : 'Feature',
'id' : '0'
}
innsjo_large = []
for entry in src_shp:
area = entry["properties"]["areal_km2"]
if area > 20:
innsjo_large.append(entry)
print("Antall innsjøer totalt: %d" % len(src_shp))
print("Antall store innsjøer: %d" % len(innsjo_large))
innsjo_coords = []
for entry in innsjo_large:
# retrieve polygon
x, y, z = entry["geometry"]["coordinates"]
# map sample to correct projection
x, y = pyproj.transform(proj_innsjo, utm33n, x, y)
innsjo_coords.append((x, y))
innsjo_coords = np.array(innsjo_coords)
print(innsjo_coords.shape)
plt.contourf(x_reproject, y_reproject, z_reproject, colors, cmap="summer")
plt.colorbar()
for x,y in innsjo_coords:
plt.plot(x, y, "wo")
with fiona.open(data_home + "innsjo_large.shp", "w",
driver=src_shp.driver,
schema=src_shp.schema,
crs=src_shp.crs
) as dst:
for entry in innsjo_large:
dst.write(entry)
Statens Kartverk provides data in geojson
format fra:
http://data.kartverket.no/
src_gj = fiona.open(data_home + "geojson/fylker.geojson", "r")
print("File data type:")
print(repr(src_gj.driver))
print()
print("Information about data:")
print(src_gj.schema)
print()
print("Coordinate reference system:")
print(src_gj.crs)
Clearning up schema entry:
{
'geometry' : 'Polygon',
'properties' : {
'y' : 'float',
'poly_id' : 'float',
'area' : 'float',
'malemetode' : 'int',
'oppr' : 'int',
'objtype' : 'str',
'koordh' : 'float',
'h_malemeto' : 'int',
'max_avvik' : 'int',
'fylkenr' : 'int',
'poly_' : 'float',
'x' : 'float',
'synbarhet' : 'int',
'noyaktifhe' : 'int',
'navn' : 'str',
'parimeter' : 'float',
'h_noyaktig' : 'int'
}
}
# Same as above, but faster and no meta info
import json
with open(data_home + "geojson/fylker.geojson", "r") as f:
raw = f.read()
src_alt = json.loads(raw)["features"]
for feature in src_gj:
if feature["properties"]["navn"] == "Telemark":
break
border_coords = feature["geometry"]["coordinates"]
print("Number of polygons:")
print(len(border_coords))
border_coords = np.array(border_coords[0])
print("Polygon shape:")
print(border_coords.shape)
x_border, y_border = border_coords.T
x_border, y_border = pyproj.transform(wgs84, utm33n, x_border, y_border)
plt.contourf(x_reproject, y_reproject, z_reproject, colors, cmap="summer")
plt.colorbar()
plt.fill(x_border, y_border, "r", alpha=0.3)
plt.plot(x_border, y_border, "r")
for x,y in innsjo_coords:
plt.plot(x, y, "wo")
For example: Find the large lake closest to fylke border.
x_innsjo, y_innsjo = innsjo_coords.T
print(x_border.shape, x_innsjo.shape)
x_innsjo_mesh, x_border_mesh = np.meshgrid(x_innsjo, x_border)
y_innsjo_mesh, y_border_mesh = np.meshgrid(y_innsjo, y_border)
print(x_innsjo_mesh.shape, x_border_mesh.shape)
def distance(x1, y1, x2, y2):
return np.sqrt( (x1-x2)**2 + (y1-y2)**2 )
dist = distance(x_innsjo_mesh, y_innsjo_mesh, x_border_mesh, y_border_mesh)
dist_min = np.min(dist, 0)
print(dist_min)
index = np.argmin(dist_min)
print(index)
plt.contourf(x_reproject, y_reproject, z_reproject, colors, cmap="summer")
plt.colorbar()
plt.fill(x_border, y_border, "r", alpha=0.3)
plt.plot(x_border, y_border, "r")
for x,y in innsjo_coords:
plt.plot(x, y, "wo")
plt.plot(innsjo_coords[index, 0], innsjo_coords[index, 1], "bo")