Skip to content

Commit 7c2a9ff

Browse files
authored
Merge pull request planetlabs#48 from planetlabs/foss4gna
pin base image version to before conda 4.4 to fix kernda bug
2 parents 4669c73 + 7821689 commit 7c2a9ff

File tree

4 files changed

+342
-2354
lines changed

4 files changed

+342
-2354
lines changed
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Inspecting Satellite Imagery using Rasterio\n",
8+
"## A first look at analyzing satellite data with Python\n",
9+
"\n",
10+
"At this point, you've explored different ways of searching for, filtering, and downloading satellite imagery. Now let's use one of these acquired datasets and dig into it a bit with Python.\n",
11+
"\n",
12+
"Here we're going to use a Python library called `rasterio`: you may be familiar with it already, or perhaps with the related C library, `GDAL`."
13+
]
14+
},
15+
{
16+
"cell_type": "code",
17+
"execution_count": 50,
18+
"metadata": {},
19+
"outputs": [],
20+
"source": [
21+
"import rasterio\n",
22+
"satdat = rasterio.open(\"example.tif\")"
23+
]
24+
},
25+
{
26+
"cell_type": "markdown",
27+
"metadata": {},
28+
"source": [
29+
"## Basic details\n",
30+
"What can we learn about this satellite image using just Python?"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": 51,
36+
"metadata": {},
37+
"outputs": [
38+
{
39+
"data": {
40+
"text/plain": [
41+
"BoundingBox(left=540759.0, bottom=3754401.0, right=568047.0, top=3767985.0)"
42+
]
43+
},
44+
"execution_count": 51,
45+
"metadata": {},
46+
"output_type": "execute_result"
47+
}
48+
],
49+
"source": [
50+
"# Get the bounding box of this GeoTIFF\n",
51+
"satdat.bounds"
52+
]
53+
},
54+
{
55+
"cell_type": "code",
56+
"execution_count": 63,
57+
"metadata": {},
58+
"outputs": [
59+
{
60+
"name": "stdout",
61+
"output_type": "stream",
62+
"text": [
63+
"Width: 27288.0, Height: 13584.0\n"
64+
]
65+
}
66+
],
67+
"source": [
68+
"# Get dimensions, in map units (here, that's meters)\n",
69+
"\n",
70+
"width = satdat.bounds.right - satdat.bounds.left\n",
71+
"height = satdat.bounds.top - satdat.bounds.bottom\n",
72+
"\n",
73+
"print(\"Width: {}, Height: {}\".format(width, height))"
74+
]
75+
},
76+
{
77+
"cell_type": "code",
78+
"execution_count": 64,
79+
"metadata": {},
80+
"outputs": [
81+
{
82+
"name": "stdout",
83+
"output_type": "stream",
84+
"text": [
85+
"Width: 9096, Height: 4528\n"
86+
]
87+
}
88+
],
89+
"source": [
90+
"# Get dimensions, in pixels\n",
91+
"px_width = satdat.width\n",
92+
"px_height = satdat.height\n",
93+
"print(\"Width: {}, Height: {}\".format(px_width, px_height))"
94+
]
95+
},
96+
{
97+
"cell_type": "code",
98+
"execution_count": 65,
99+
"metadata": {},
100+
"outputs": [
101+
{
102+
"data": {
103+
"text/plain": [
104+
"(3.0, 3.0)"
105+
]
106+
},
107+
"execution_count": 65,
108+
"metadata": {},
109+
"output_type": "execute_result"
110+
}
111+
],
112+
"source": [
113+
"# How many meters to a pixel?\n",
114+
"\n",
115+
"w = width / px_width\n",
116+
"h = height / px_height\n",
117+
"\n",
118+
"w, h"
119+
]
120+
},
121+
{
122+
"cell_type": "code",
123+
"execution_count": 66,
124+
"metadata": {},
125+
"outputs": [
126+
{
127+
"data": {
128+
"text/plain": [
129+
"CRS({'init': 'epsg:32611'})"
130+
]
131+
},
132+
"execution_count": 66,
133+
"metadata": {},
134+
"output_type": "execute_result"
135+
}
136+
],
137+
"source": [
138+
"# Get coordinate reference system\n",
139+
"satdat.crs"
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": 59,
145+
"metadata": {},
146+
"outputs": [
147+
{
148+
"name": "stdout",
149+
"output_type": "stream",
150+
"text": [
151+
"Top left corner coordinates: (540759.0, 3767985.0)\n",
152+
"Bottom right corner coordinates: (568047.0, 3754401.0)\n"
153+
]
154+
},
155+
{
156+
"name": "stderr",
157+
"output_type": "stream",
158+
"text": [
159+
"/opt/conda/lib/python3.6/site-packages/IPython/core/interactiveshell.py:2910: FutureWarning: The value of this property will change in version 1.0. Please see https://github.com/mapbox/rasterio/issues/86 for details.\n",
160+
" exec(code_obj, self.user_global_ns, self.user_ns)\n"
161+
]
162+
}
163+
],
164+
"source": [
165+
"# Get coordinates of top-left & bottom right corners\n",
166+
"# NOTE: how to do this depends on your Rasterio version:\n",
167+
"# the below example may generate a FutureWarning, which is safe to ignore here\n",
168+
"\n",
169+
"try:\n",
170+
" topleft = satdat.transform * (0, 0)\n",
171+
" botright = satdat.transform * (width, height)\n",
172+
" \n",
173+
"except TypeError:\n",
174+
" topleft = satdat.affine * (0, 0)\n",
175+
" botright = satdat.affine * (width, height)\n",
176+
" \n",
177+
"print(\"Top left corner coordinates: {}\".format(topleft))\n",
178+
"print(\"Bottom right corner coordinates: {}\".format(botright))"
179+
]
180+
},
181+
{
182+
"cell_type": "markdown",
183+
"metadata": {},
184+
"source": [
185+
"## Bands\n",
186+
"So far, we haven't done too much raster-specific work yet. Since we know we're inspecting a multispectral satellite image, let's see what we can learn about its bands."
187+
]
188+
},
189+
{
190+
"cell_type": "code",
191+
"execution_count": null,
192+
"metadata": {},
193+
"outputs": [],
194+
"source": [
195+
"# Get the number of bands by listing their indices\n",
196+
"satdat.indexes"
197+
]
198+
},
199+
{
200+
"cell_type": "markdown",
201+
"metadata": {},
202+
"source": [
203+
"Because we know we're look at a PlanetScope 4-band analytic satellite image, we can define the bands by their order:"
204+
]
205+
},
206+
{
207+
"cell_type": "code",
208+
"execution_count": null,
209+
"metadata": {},
210+
"outputs": [],
211+
"source": [
212+
"# PlanetScope 4-band band order: BGRN\n",
213+
"\n",
214+
"blue = satdat.read(1)\n",
215+
"green = satdat.read(2)\n",
216+
"red = satdat.read(3)\n",
217+
"nir = satdat.read(4)"
218+
]
219+
},
220+
{
221+
"cell_type": "code",
222+
"execution_count": null,
223+
"metadata": {},
224+
"outputs": [],
225+
"source": [
226+
"# bands are stored as numpy arrays\n",
227+
"\n",
228+
"type(blue)"
229+
]
230+
},
231+
{
232+
"cell_type": "code",
233+
"execution_count": null,
234+
"metadata": {},
235+
"outputs": [],
236+
"source": [
237+
"blue"
238+
]
239+
},
240+
{
241+
"cell_type": "code",
242+
"execution_count": null,
243+
"metadata": {},
244+
"outputs": [],
245+
"source": [
246+
"# Output min & max pixel values in each band\n",
247+
"\n",
248+
"print(blue.min(), blue.max())\n",
249+
"print(green.min(), green.max())\n",
250+
"print(red.min(), red.max())\n",
251+
"print(nir.min(), nir.max())"
252+
]
253+
},
254+
{
255+
"cell_type": "markdown",
256+
"metadata": {},
257+
"source": [
258+
"## Pixels"
259+
]
260+
},
261+
{
262+
"cell_type": "code",
263+
"execution_count": 61,
264+
"metadata": {},
265+
"outputs": [
266+
{
267+
"data": {
268+
"text/plain": [
269+
"6382"
270+
]
271+
},
272+
"execution_count": 61,
273+
"metadata": {},
274+
"output_type": "execute_result"
275+
}
276+
],
277+
"source": [
278+
"# Let's grab the pixel 5km east and 5km south of the upper left corner\n",
279+
"\n",
280+
"# get the pixel \n",
281+
"px_x = satdat.bounds.left + 5000\n",
282+
"px_y = satdat.bounds.top - 5000\n",
283+
"\n",
284+
"row, col = satdat.index(px_x, px_y)\n",
285+
"\n",
286+
"# Now let's look at the value of Band1 (\"blue\") at this pixel\n",
287+
"blue[row, col]"
288+
]
289+
},
290+
{
291+
"cell_type": "code",
292+
"execution_count": null,
293+
"metadata": {},
294+
"outputs": [],
295+
"source": []
296+
}
297+
],
298+
"metadata": {
299+
"kernelspec": {
300+
"display_name": "Python 3",
301+
"language": "python",
302+
"name": "python3"
303+
},
304+
"language_info": {
305+
"codemirror_mode": {
306+
"name": "ipython",
307+
"version": 3
308+
},
309+
"file_extension": ".py",
310+
"mimetype": "text/x-python",
311+
"name": "python",
312+
"nbconvert_exporter": "python",
313+
"pygments_lexer": "ipython3",
314+
"version": "3.6.2"
315+
}
316+
},
317+
"nbformat": 4,
318+
"nbformat_minor": 2
319+
}

jupyter-notebooks/mosaicing/basic_compositing_demo.ipynb

Lines changed: 16 additions & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)