├── README.md ├── .gitignore └── notebooks └── find_nearest_bgi.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # iResponse 2 | 3 | This repository contains code, data and analyses for [iResponse](http://iresponse-rri.com/), a research project exploring socially responsible crowdsourcing tools for environmental research and decision-making. The project is funded by the Research Council of Norway and the main project partners are listed [here](http://iresponse-rri.com/partners). The code in this repository was created by [NIVA](http://www.niva.no/). 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # Python 21 | .ipynb_checkpoints 22 | *.pyc 23 | 24 | # ========================= 25 | # Operating System Files 26 | # ========================= 27 | 28 | # OSX 29 | # ========================= 30 | 31 | .DS_Store 32 | .AppleDouble 33 | .LSOverride 34 | 35 | # Thumbnails 36 | ._* 37 | 38 | # Files that might appear in the root of a volume 39 | .DocumentRevisions-V100 40 | .fseventsd 41 | .Spotlight-V100 42 | .TemporaryItems 43 | .Trashes 44 | .VolumeIcon.icns 45 | 46 | # Directories potentially created on remote AFP share 47 | .AppleDB 48 | .AppleDesktop 49 | Network Trash Folder 50 | Temporary Items 51 | .apdisk 52 | -------------------------------------------------------------------------------- /notebooks/find_nearest_bgi.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import geopandas as gpd\n", 11 | "import geocoder\n", 12 | "import nivapy\n", 13 | "from shapely.geometry import Point\n", 14 | "from shapely.ops import nearest_points" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "# Find nearest BGI\n", 22 | "\n", 23 | "Quick Python example of identifying the nearest BGI point based on a user-supplied address.\n", 24 | "\n", 25 | "## 1. Read locations for BGI\n", 26 | "\n", 27 | "Line has a Google spreadsheet listing BGI projects in Oslo. This sheet includes lat/lon co-ordinates, but they are not consistently formatted. For the simple example here, I have tidied up the columns with spatial data and copied to Excel." 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/html": [ 38 | "
\n", 39 | "\n", 40 | " \n", 41 | " \n", 42 | " \n", 43 | " \n", 44 | " \n", 45 | " \n", 46 | " \n", 47 | " \n", 48 | " \n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | "
Project namelatlon
0Årvolldammen, Hovinbekken og Glasbergbekken59.94736910.819674
1Olaf Ryes plass59.92346310.758054
2Bjølsen studentby59.94484910.760666
3Hølaløkka ( må sjekkes mht til overvannsløsnin...59.94484910.760666
4Nedre Foss park\\n59.92248810.753258
5OBOS Etterstadsletta ( mer privat?)\\n59.91118410.799387
6Lysaker - stasjonsaksens hovedtorg\\n59.91502610.635812
\n", 93 | "
" 94 | ], 95 | "text/plain": [ 96 | " Project name lat lon\n", 97 | "0 Årvolldammen, Hovinbekken og Glasbergbekken 59.947369 10.819674\n", 98 | "1 Olaf Ryes plass 59.923463 10.758054\n", 99 | "2 Bjølsen studentby 59.944849 10.760666\n", 100 | "3 Hølaløkka ( må sjekkes mht til overvannsløsnin... 59.944849 10.760666\n", 101 | "4 Nedre Foss park\\n 59.922488 10.753258\n", 102 | "5 OBOS Etterstadsletta ( mer privat?)\\n 59.911184 10.799387\n", 103 | "6 Lysaker - stasjonsaksens hovedtorg\\n 59.915026 10.635812" 104 | ] 105 | }, 106 | "execution_count": 2, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "# Read data\n", 113 | "bgi_xls = (r'C:\\Data\\James_Work\\Staff\\Line_B\\iResponse\\Vanniby_BGI-projects.xlsx')\n", 114 | "bgi_df = pd.read_excel(bgi_xls, sheetname='Sheet1')\n", 115 | "bgi_df" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 3, 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "data": { 125 | "text/html": [ 126 | "
\n", 127 | "\n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | "
Project namelatlongeometry
0Årvolldammen, Hovinbekken og Glasbergbekken59.94736910.819674POINT (10.819674 59.947369)
1Olaf Ryes plass59.92346310.758054POINT (10.7580535 59.9234632)
2Bjølsen studentby59.94484910.760666POINT (10.7606661 59.9448494)
3Hølaløkka ( må sjekkes mht til overvannsløsnin...59.94484910.760666POINT (10.7606661 59.9448494)
4Nedre Foss park\\n59.92248810.753258POINT (10.753258 59.922488)
5OBOS Etterstadsletta ( mer privat?)\\n59.91118410.799387POINT (10.799387 59.911184)
6Lysaker - stasjonsaksens hovedtorg\\n59.91502610.635812POINT (10.635812 59.915026)
\n", 189 | "
" 190 | ], 191 | "text/plain": [ 192 | " Project name lat lon \\\n", 193 | "0 Årvolldammen, Hovinbekken og Glasbergbekken 59.947369 10.819674 \n", 194 | "1 Olaf Ryes plass 59.923463 10.758054 \n", 195 | "2 Bjølsen studentby 59.944849 10.760666 \n", 196 | "3 Hølaløkka ( må sjekkes mht til overvannsløsnin... 59.944849 10.760666 \n", 197 | "4 Nedre Foss park\\n 59.922488 10.753258 \n", 198 | "5 OBOS Etterstadsletta ( mer privat?)\\n 59.911184 10.799387 \n", 199 | "6 Lysaker - stasjonsaksens hovedtorg\\n 59.915026 10.635812 \n", 200 | "\n", 201 | " geometry \n", 202 | "0 POINT (10.819674 59.947369) \n", 203 | "1 POINT (10.7580535 59.9234632) \n", 204 | "2 POINT (10.7606661 59.9448494) \n", 205 | "3 POINT (10.7606661 59.9448494) \n", 206 | "4 POINT (10.753258 59.922488) \n", 207 | "5 POINT (10.799387 59.911184) \n", 208 | "6 POINT (10.635812 59.915026) " 209 | ] 210 | }, 211 | "execution_count": 3, 212 | "metadata": {}, 213 | "output_type": "execute_result" 214 | } 215 | ], 216 | "source": [ 217 | "# Convert to gdf\n", 218 | "geometry = [Point(xy) for xy in zip(bgi_df.lon, bgi_df.lat)]\n", 219 | "crs = {'init': 'epsg:4326'}\n", 220 | "bgi_gdf = gpd.GeoDataFrame(bgi_df, crs=crs, geometry=geometry)\n", 221 | "bgi_gdf" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 4, 227 | "metadata": {}, 228 | "outputs": [ 229 | { 230 | "data": { 231 | "text/html": [ 232 | "
" 233 | ], 234 | "text/plain": [ 235 | "" 236 | ] 237 | }, 238 | "execution_count": 4, 239 | "metadata": {}, 240 | "output_type": "execute_result" 241 | } 242 | ], 243 | "source": [ 244 | "# Show BGI locs on map\n", 245 | "map1 = nivapy.spatial.quickmap(bgi_df, \n", 246 | " lat_col='lat', \n", 247 | " lon_col='lon', \n", 248 | " popup='Project name',\n", 249 | " tiles='openstreetmap')\n", 250 | "map1" 251 | ] 252 | }, 253 | { 254 | "cell_type": "markdown", 255 | "metadata": {}, 256 | "source": [ 257 | "## 2. Get user input" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": 5, 263 | "metadata": {}, 264 | "outputs": [ 265 | { 266 | "name": "stdout", 267 | "output_type": "stream", 268 | "text": [ 269 | "The co-ordinates of your address are:\n", 270 | "(10.71573419201851, 59.94240602885344)\n" 271 | ] 272 | } 273 | ], 274 | "source": [ 275 | "# Address supplied by user\n", 276 | "addr = 'NIVA, Gaustadalléen 21, 0349 Oslo'\n", 277 | "\n", 278 | "# Geocode\n", 279 | "g = geocoder.arcgis(addr)\n", 280 | "lat, lon = g.latlng\n", 281 | "\n", 282 | "print 'The co-ordinates of your address are:'\n", 283 | "print (lon, lat)" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": {}, 289 | "source": [ 290 | "## 3. Find nearest BGI\n", 291 | "\n", 292 | "**Note:** The code below treats ellipsoidal (i.e. lat/lon) co-ordinates as Cartesian, which is not correct. However, given that all points are very close together, the errors involved should not affect determination of the nearest BGI." 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 6, 298 | "metadata": {}, 299 | "outputs": [ 300 | { 301 | "name": "stdout", 302 | "output_type": "stream", 303 | "text": [ 304 | "The nearest BGI to your address is:\n" 305 | ] 306 | }, 307 | { 308 | "data": { 309 | "text/html": [ 310 | "
\n", 311 | "\n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | "
Project namelatlongeometry
4Nedre Foss park\\n59.92248810.753258POINT (10.753258 59.922488)
\n", 331 | "
" 332 | ], 333 | "text/plain": [ 334 | " Project name lat lon geometry\n", 335 | "4 Nedre Foss park\\n 59.922488 10.753258 POINT (10.753258 59.922488)" 336 | ] 337 | }, 338 | "execution_count": 6, 339 | "metadata": {}, 340 | "output_type": "execute_result" 341 | } 342 | ], 343 | "source": [ 344 | "# Build point from geocoded address\n", 345 | "addr_loc = Point((lon, lat))\n", 346 | "\n", 347 | "# Find nearest BGI\n", 348 | "bgi_pts = bgi_gdf.unary_union\n", 349 | "nearest = bgi_gdf.geometry == nearest_points(addr_loc, bgi_pts)[1]\n", 350 | "\n", 351 | "print 'The nearest BGI to your address is:'\n", 352 | "bgi_gdf[nearest]" 353 | ] 354 | } 355 | ], 356 | "metadata": { 357 | "kernelspec": { 358 | "display_name": "Python 2", 359 | "language": "python", 360 | "name": "python2" 361 | }, 362 | "language_info": { 363 | "codemirror_mode": { 364 | "name": "ipython", 365 | "version": 2 366 | }, 367 | "file_extension": ".py", 368 | "mimetype": "text/x-python", 369 | "name": "python", 370 | "nbconvert_exporter": "python", 371 | "pygments_lexer": "ipython2", 372 | "version": "2.7.13" 373 | } 374 | }, 375 | "nbformat": 4, 376 | "nbformat_minor": 2 377 | } 378 | --------------------------------------------------------------------------------