Skip to content

Commit abc5d7c

Browse files
committed
added geojson snippet
1 parent ab08e42 commit abc5d7c

File tree

2 files changed

+262
-1
lines changed

2 files changed

+262
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ pip install -r requirements.txt
1616
```
1717

1818
## The snippets...
19-
tbd
19+
20+
__GeoJSON__
21+
- [GeoJSON Example - Stations](geojson/geojson_stations.ipynb)

geojson_stations.ipynb

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"## GeoJSON Example - Stations\n",
8+
"\n",
9+
"In this Python snippet we use stations (geographic) from the Swiss public transportation and convert the data to a GeoJSON (http://geojson.org/) file.\n",
10+
"\n",
11+
"\n",
12+
"- Donwload the _'bfkoordgeo.csv'_ file, https://opentransportdata.swiss/en/dataset/bhlist/resource/b92a372f-7843-4ddd-b1c6-c9c6397e1097\n",
13+
"- Convert the file from ISO-8859-1 to UTF-8\n",
14+
"\n",
15+
"```\n",
16+
"iconv -f ISO-8859-1 -t UTF-8 bfkoordgeo.csv > out.csv\n",
17+
"```\n",
18+
"\n",
19+
"\n",
20+
"> __Note:__ The data is from the _Open Data Platform Swiss Public Transport_, https://opentransportdata.swiss/en/\n",
21+
"\n",
22+
"\n",
23+
"### Required libraries\n",
24+
"- pandas, http://pandas.pydata.org/\n",
25+
"- geojson, https://pypi.python.org/pypi/geojson/\n"
26+
]
27+
},
28+
{
29+
"cell_type": "markdown",
30+
"metadata": {},
31+
"source": [
32+
"### Load the data\n",
33+
"First let's load the data with pandas. The data frame contains the stations from the public transportations from Switzerland and some from adjoining countries. We have the columns:\n",
34+
"- StationID\n",
35+
"- Longitude\n",
36+
"- Latitude\n",
37+
"- Height\n",
38+
"- Remark\n",
39+
"\n",
40+
"Longitude and Latitude should be _WGS 84_ coordinates."
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": 4,
46+
"metadata": {
47+
"collapsed": false
48+
},
49+
"outputs": [
50+
{
51+
"data": {
52+
"text/html": [
53+
"<div>\n",
54+
"<table border=\"1\" class=\"dataframe\">\n",
55+
" <thead>\n",
56+
" <tr style=\"text-align: right;\">\n",
57+
" <th></th>\n",
58+
" <th>StationID</th>\n",
59+
" <th>Longitude</th>\n",
60+
" <th>Latitude</th>\n",
61+
" <th>Height</th>\n",
62+
" <th>Remark</th>\n",
63+
" </tr>\n",
64+
" </thead>\n",
65+
" <tbody>\n",
66+
" <tr>\n",
67+
" <th>0</th>\n",
68+
" <td>6</td>\n",
69+
" <td>7.549783</td>\n",
70+
" <td>47.216111</td>\n",
71+
" <td>441</td>\n",
72+
" <td>St. Katharinen</td>\n",
73+
" </tr>\n",
74+
" <tr>\n",
75+
" <th>1</th>\n",
76+
" <td>7</td>\n",
77+
" <td>9.733756</td>\n",
78+
" <td>46.922368</td>\n",
79+
" <td>744</td>\n",
80+
" <td>Fideris</td>\n",
81+
" </tr>\n",
82+
" <tr>\n",
83+
" <th>2</th>\n",
84+
" <td>11</td>\n",
85+
" <td>7.389462</td>\n",
86+
" <td>47.191804</td>\n",
87+
" <td>467</td>\n",
88+
" <td>Grenchen Nord</td>\n",
89+
" </tr>\n",
90+
" <tr>\n",
91+
" <th>3</th>\n",
92+
" <td>16</td>\n",
93+
" <td>6.513937</td>\n",
94+
" <td>46.659019</td>\n",
95+
" <td>499</td>\n",
96+
" <td>La Sarraz, Couronne</td>\n",
97+
" </tr>\n",
98+
" <tr>\n",
99+
" <th>4</th>\n",
100+
" <td>22</td>\n",
101+
" <td>7.589551</td>\n",
102+
" <td>47.547405</td>\n",
103+
" <td>277</td>\n",
104+
" <td>Basel SBB</td>\n",
105+
" </tr>\n",
106+
" </tbody>\n",
107+
"</table>\n",
108+
"</div>"
109+
],
110+
"text/plain": [
111+
" StationID Longitude Latitude Height Remark\n",
112+
"0 6 7.549783 47.216111 441 St. Katharinen\n",
113+
"1 7 9.733756 46.922368 744 Fideris\n",
114+
"2 11 7.389462 47.191804 467 Grenchen Nord\n",
115+
"3 16 6.513937 46.659019 499 La Sarraz, Couronne\n",
116+
"4 22 7.589551 47.547405 277 Basel SBB"
117+
]
118+
},
119+
"execution_count": 4,
120+
"metadata": {},
121+
"output_type": "execute_result"
122+
}
123+
],
124+
"source": [
125+
"import pandas as pd\n",
126+
"\n",
127+
"df = pd.read_csv('data/bfkoordgeo_utf8.csv')\n",
128+
"df.head()"
129+
]
130+
},
131+
{
132+
"cell_type": "markdown",
133+
"metadata": {},
134+
"source": [
135+
"Now we do some data cleaning and remove all rows where _Longitude_ and _Latitude_ are _'null'_."
136+
]
137+
},
138+
{
139+
"cell_type": "code",
140+
"execution_count": 5,
141+
"metadata": {
142+
"collapsed": false,
143+
"scrolled": true
144+
},
145+
"outputs": [],
146+
"source": [
147+
"df = df[df['Longitude'].notnull()]\n",
148+
"df = df[df['Latitude'].notnull()]\n",
149+
"\n",
150+
"# will display all rows that have null values\n",
151+
"#df[df.isnull().any(axis=1)]"
152+
]
153+
},
154+
{
155+
"cell_type": "markdown",
156+
"metadata": {},
157+
"source": [
158+
"### Convert pandas data frame to GeoJSON\n",
159+
"Next we convert the panda data frame to geosjon objects (_FeatureCollection/Feature/Point_). "
160+
]
161+
},
162+
{
163+
"cell_type": "code",
164+
"execution_count": 6,
165+
"metadata": {
166+
"collapsed": false
167+
},
168+
"outputs": [
169+
{
170+
"ename": "ImportError",
171+
"evalue": "No module named geojson",
172+
"output_type": "error",
173+
"traceback": [
174+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
175+
"\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)",
176+
"\u001b[0;32m<ipython-input-6-24a9a6f30e7a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mgeojson\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mgeojson\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mvalues\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Longitude'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Latitude'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Remark'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mpoints\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mgeojson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFeature\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgeometry\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mgeojson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mPoint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mproperties\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m'name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mv\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
177+
"\u001b[0;31mImportError\u001b[0m: No module named geojson"
178+
]
179+
}
180+
],
181+
"source": [
182+
"import geojson as geojson\n",
183+
"\n",
184+
"values = zip(df['Longitude'], df['Latitude'], df['Remark'])\n",
185+
"points = [geojson.Feature(geometry=geojson.Point((v[0], v[1])), properties={'name': v[2]}) for v in values]\n",
186+
"\n",
187+
"geo_collection = geojson.FeatureCollection(points)\n",
188+
"\n",
189+
"print(points[0])"
190+
]
191+
},
192+
{
193+
"cell_type": "markdown",
194+
"metadata": {},
195+
"source": [
196+
"### Save the GeoJSON (FeatureCollection) to a file\n",
197+
"Finally we dump the GeoJSON objects to a file."
198+
]
199+
},
200+
{
201+
"cell_type": "code",
202+
"execution_count": 1,
203+
"metadata": {
204+
"collapsed": false
205+
},
206+
"outputs": [
207+
{
208+
"ename": "NameError",
209+
"evalue": "name 'geojson' is not defined",
210+
"output_type": "error",
211+
"traceback": [
212+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
213+
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
214+
"\u001b[0;32m<ipython-input-1-49573f81a20e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdump\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgeojson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgeo_collection\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msort_keys\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m '''\n\u001b[1;32m 4\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'stations.geojson'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'w'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdump\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
215+
"\u001b[0;31mNameError\u001b[0m: name 'geojson' is not defined"
216+
]
217+
}
218+
],
219+
"source": [
220+
"dump = geojson.dumps(geo_collection, sort_keys=True)\n",
221+
"\n",
222+
"'''\n",
223+
"with open('stations.geojson', 'w') as file:\n",
224+
" file.write(dump)\n",
225+
"'''"
226+
]
227+
},
228+
{
229+
"cell_type": "markdown",
230+
"metadata": {},
231+
"source": [
232+
"### Result\n",
233+
"You can find the resulat (GeoJSON file) from this snippet here\n",
234+
"- [stations.geojson](stations.geojson)"
235+
]
236+
}
237+
],
238+
"metadata": {
239+
"kernelspec": {
240+
"display_name": "Python 2",
241+
"language": "python",
242+
"name": "python2"
243+
},
244+
"language_info": {
245+
"codemirror_mode": {
246+
"name": "ipython",
247+
"version": 2
248+
},
249+
"file_extension": ".py",
250+
"mimetype": "text/x-python",
251+
"name": "python",
252+
"nbconvert_exporter": "python",
253+
"pygments_lexer": "ipython2",
254+
"version": "2.7.12"
255+
}
256+
},
257+
"nbformat": 4,
258+
"nbformat_minor": 2
259+
}

0 commit comments

Comments
 (0)