<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://chiddianozie.github.io/chidubem-iddianozie/feed.xml" rel="self" type="application/atom+xml" /><link href="https://chiddianozie.github.io/chidubem-iddianozie/" rel="alternate" type="text/html" /><updated>2026-11-03T09:50:46-08:00</updated><id>https://chiddianozie.github.io/chidubem-iddianozie/feed.xml</id><title type="html">Chidubem Iddianozie</title><subtitle>data science python google machine learning engineering graphs</subtitle><author><name>Chidubem Iddianozie</name></author><entry><title type="html">Constructing non-overlapping concentric buffers over linestrings</title><link href="https://chiddianozie.github.io/chidubem-iddianozie/posts/2019/06/Constructing-concentric-buffers-linestrings-using-potsgis-postgresql/" rel="alternate" type="text/html" title="Constructing non-overlapping concentric buffers over linestrings" /><published>2019-06-20T00:00:00-07:00</published><updated>2019-06-20T00:00:00-07:00</updated><id>https://chiddianozie.github.io/chidubem-iddianozie/posts/2019/06/constructing-buffers-around-linestrings-using-postgis-postgresql</id><content type="html" xml:base="https://chiddianozie.github.io/chidubem-iddianozie/posts/2019/06/Constructing-concentric-buffers-linestrings-using-potsgis-postgresql/"><![CDATA[<p>TL;DR: We will learn how to construct multiple non-overlapping buffers around <code class="language-plaintext highlighter-rouge">linestring</code> objects using <code class="language-plaintext highlighter-rouge">PostGIS</code> in <code class="language-plaintext highlighter-rouge">PostgreSQL</code>.</p>

<!-- ![single street](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/single_street.png?token=AD5IB4F2Q2IH7DYTBACZGTC6BUNZQ) -->
<p><img src="https://chidubemiddianozie.com/images/single_street.png" width="300" height="300" hspace="20" /><img src="https://chidubemiddianozie.com/images/all_buffers.png" width="300" height="300" hspace="20" /></p>

<!-- <div style="width:300; font-size:80%; text-align:center;"><img src="https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/single_street.png?token=AD5IB4F2Q2IH7DYTBACZGTC6BUNZQ" alt="alternate text" width="300" height="300" style="padding-bottom:0.5em;" 
/>Linestring</div> -->
<!-- <figure>
    <img src='image.jpg' alt='missing' />
    <figcaption>Caption goes here</figcaption>
</figure> -->
<!-- 
![all buffers enclosing street](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/all_buffers.png?token=AD5IB4DEFEDTIBQNH7HZPMC6BUN7Q)  -->

<h2 id="requirements">Requirements</h2>
<p>Ensure that you have Postgresql installed on your computer, we will use the terminal for this post but you can also install the <code class="language-plaintext highlighter-rouge">pgadmin</code> interface  if you prefer a GUI. You can see installation instructions for postgresql <a href="http://www.postgresqltutorial.com/install-postgresql/">here</a> and download <code class="language-plaintext highlighter-rouge">pgadmin</code> <a href="https://www.pgadmin.org/download/">here</a>.</p>

<p>If installed correctly, you can initialize and then start the postgres database as follows:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">sirchidi:~$</span><span class="w"> </span>initdb /usr/local/var/postgres <span class="nt">-E</span> utf8
<span class="gp">sirchidi:~$</span><span class="w"> </span>pg_ctl <span class="nt">-D</span> /usr/local/var/postgres <span class="nt">-l</span> /usr/local/var/postgres/server.log start
</code></pre></div></div>

<p>After the second command, you should see something like this:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">sirchidi:~$</span><span class="w"> </span>waiting <span class="k">for </span>server to start....done
<span class="go">server started
</span></code></pre></div></div>

<p>You can also check the status of the server using</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">sirchidi:~$</span><span class="w"> </span>pg_ctl <span class="nt">-D</span> /usr/local/var/postgres status
</code></pre></div></div>
<p>If it is unable to start server, you can do</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">sirchidi:~$</span><span class="w"> </span>killall postgres
</code></pre></div></div>
<p>to kill any old processes that may be interfering and then retry the above commands.</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">sirchidi:~$</span><span class="w"> </span><span class="nb">whoami</span>
</code></pre></div></div>

<p>For this post, we will be using a very small <code class="language-plaintext highlighter-rouge">.csv</code> file containing the coordinates of six streets, and can be downloaded from  <a href="https://chidubemiddianozie.com/files/sample_data.csv">here</a>.</p>

<p>Okay, all set, lets begin.</p>

<h2 id="methods">Methods</h2>
<p>We can split this section into three sub-sections</p>
<ul>
  <li>Reading from file
    <ul>
      <li>We have to ensure that the files are read correctly into a postgresql table and persisted correctly. Every operation will be done on this table.</li>
    </ul>
  </li>
  <li>Buffer Construction
    <ul>
      <li>This is where we reason about to perform the construction of the multiple buffers.</li>
    </ul>
  </li>
  <li>Writing to file
    <ul>
      <li>Finally, we write the constructed buffers from the postgresql table back to a file.</li>
    </ul>
  </li>
</ul>

<h3 id="reading-from-file">Reading from file</h3>
<p>To read the file and persist to a table in the <code class="language-plaintext highlighter-rouge">postgres</code> database, we can switch to the postgresql terminal as follows:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">sirchidi:~$</span><span class="w"> </span>psql <span class="nt">-d</span> postgres
</code></pre></div></div>
<p>This let’s us use the postgres database.</p>

<p>Then, we create a table <code class="language-plaintext highlighter-rouge">streetSample</code> with three columns to correspond with the number of columns in our <code class="language-plaintext highlighter-rouge">.csv</code> file.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">streetSample</span><span class="p">(</span>
<span class="n">street</span> <span class="nb">text</span><span class="p">,</span>
<span class="n">osmid</span> <span class="nb">text</span><span class="p">,</span>
<span class="n">geom</span> <span class="nb">text</span><span class="p">);</span>
</code></pre></div></div>

<p>Next, we need to create a <code class="language-plaintext highlighter-rouge">postgis</code> extension for the database and a spatial index for the new table</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="n">EXTENSION</span> <span class="n">postgis</span><span class="p">;</span>
<span class="k">CREATE</span> <span class="k">INDEX</span> <span class="n">streetSample_index</span> 
    <span class="k">ON</span> <span class="n">streetSample</span> 
    <span class="k">USING</span> <span class="n">gist</span> <span class="p">(</span><span class="n">geom</span><span class="p">);</span>
</code></pre></div></div>

<p>Now, we copy the file from local to the table thus:</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">COPY</span> <span class="n">streetSample</span> <span class="p">(</span><span class="n">street</span><span class="p">,</span> <span class="n">osmid</span><span class="p">,</span> <span class="n">geom</span><span class="p">)</span> 
<span class="k">FROM</span> <span class="s1">'/path/to/file/on/local/streetSample.csv'</span>  <span class="k">DELIMITER</span> <span class="s1">','</span> <span class="n">CSV</span> <span class="n">HEADER</span><span class="p">;</span>
</code></pre></div></div>

<p>Finally, to finish up this sub-section, we have to set the crs code and column type for the geom object to 4326 which is the crs for lat-long coordinates.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">streetSample</span> 
    <span class="k">ALTER</span> <span class="k">COLUMN</span> <span class="n">geom</span> 
    <span class="k">TYPE</span> <span class="n">geometry</span> 
    <span class="k">USING</span> <span class="n">ST_SetSRID</span> <span class="p">((</span><span class="n">geom</span><span class="p">::</span><span class="n">geometry</span><span class="p">),</span><span class="mi">4326</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="buffer-construction">Buffer Construction</h3>

<p>We will now construct three buffers, the first buffer will have a radius of 20 metres, the second one will be of 100 metres and the last one will be of 200 metres.</p>

<p>But first, we create three columns in the table for the buffers.</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">streetSample</span>  <span class="k">ADD</span> <span class="k">COLUMN</span> <span class="n">buffer_20_metres</span> <span class="n">geometry</span> <span class="p">(</span><span class="n">Geometry</span><span class="p">,</span> <span class="mi">4326</span><span class="p">);</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">streetSample</span>  <span class="k">ADD</span> <span class="k">COLUMN</span> <span class="n">buffer_100_metres</span> <span class="n">geometry</span> <span class="p">(</span><span class="n">Geometry</span><span class="p">,</span> <span class="mi">4326</span><span class="p">);</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">streetSample</span>  <span class="k">ADD</span> <span class="k">COLUMN</span> <span class="n">buffer_200_metres</span> <span class="n">geometry</span> <span class="p">(</span><span class="n">Geometry</span><span class="p">,</span> <span class="mi">4326</span><span class="p">);</span>
</code></pre></div></div>

<p>Then, we update the new columns using the constructed buffers.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">UPDATE</span> <span class="n">streetSample</span>  <span class="k">SET</span> <span class="n">buffer_20_metres</span> <span class="o">=</span> <span class="n">ST_Transform</span><span class="p">(</span><span class="n">ST_Buffer</span><span class="p">(</span><span class="n">ST_Transform</span><span class="p">(</span><span class="n">geom</span><span class="p">,</span><span class="mi">3857</span><span class="p">),</span> <span class="mi">20</span><span class="p">,</span>  <span class="s1">'endcap=round join=round'</span><span class="p">),</span><span class="mi">4326</span><span class="p">);</span>

<span class="k">UPDATE</span> <span class="n">streetSample</span> 
    <span class="k">SET</span> <span class="n">buffer_100_metres</span> <span class="o">=</span>  
        <span class="n">ST_Transform</span><span class="p">(</span>
            <span class="n">ST_Difference</span><span class="p">(</span>
                <span class="n">ST_Buffer</span><span class="p">(</span><span class="n">ST_Transform</span><span class="p">(</span><span class="n">geom</span><span class="p">,</span><span class="mi">3857</span><span class="p">),</span> <span class="mi">100</span><span class="p">,</span>  <span class="s1">'endcap=round join=round'</span><span class="p">),</span>
                <span class="n">ST_Buffer</span><span class="p">(</span><span class="n">ST_Transform</span><span class="p">(</span><span class="n">geom</span><span class="p">,</span><span class="mi">3857</span><span class="p">),</span> <span class="mi">20</span><span class="p">,</span>  <span class="s1">'endcap=round join=round'</span><span class="p">)),</span>
                <span class="mi">4326</span><span class="p">);</span>

<span class="k">UPDATE</span> <span class="n">streetSample</span> 
    <span class="k">SET</span> <span class="n">buffer_200_metres</span> <span class="o">=</span>  
        <span class="n">ST_Transform</span><span class="p">(</span>
            <span class="n">ST_Difference</span><span class="p">(</span>
                <span class="n">ST_Buffer</span><span class="p">(</span><span class="n">ST_Transform</span><span class="p">(</span><span class="n">geom</span><span class="p">,</span><span class="mi">3857</span><span class="p">),</span> <span class="mi">200</span><span class="p">,</span>  <span class="s1">'endcap=round join=round'</span><span class="p">),</span>
                <span class="n">ST_Buffer</span><span class="p">(</span><span class="n">ST_Transform</span><span class="p">(</span><span class="n">geom</span><span class="p">,</span><span class="mi">3857</span><span class="p">),</span> <span class="mi">100</span><span class="p">,</span>  <span class="s1">'endcap=round join=round'</span><span class="p">)),</span>
                <span class="mi">4326</span><span class="p">);</span>
</code></pre></div></div>

<p>Notice how we transform between two crs’s, that is because the 4326 does not support the metres unit we need to define the buffer radius. Thus, we temporarily transform the linestring coordinates to a metre-crs for the buffer creation in each sql statement and transform back to the working crs.
Another thing to bear in mind is the option for the buffer construction <code class="language-plaintext highlighter-rouge">endcap=round join=round</code>. This option can also be changed, please refer to the postgis documentation <a href="https://postgis.net/docs/ST_Buffer.html">here</a>.</p>

<p>Now, we show a visualization of the buffers:</p>

<p><img src="https://chidubemiddianozie.com/images/single_street.png" width="300" height="300" hspace="20" /><img src="https://chidubemiddianozie.com/images/first_buffer.png" width="300" height="300" hspace="20" /></p>

<p><img src="https://chidubemiddianozie.com/images/second_buffer.png" width="300" height="300" hspace="20" /><img src="https://chidubemiddianozie.com/images/third_buffer.png" width="300" height="300" hspace="20" /></p>

<p>And, all buffers superimposed on the linestring. 
<img src="https://chidubemiddianozie.com/images/all_buffers.png" width="400" height="400" hspace="150" /></p>

<!-- ![single street](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/single_street.png?token=AD5IB4F2Q2IH7DYTBACZGTC6BUNZQ)

![first buffer](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/first_buffer.png?token=AD5IB4ESG4P6FKW5OVK4WFC6BUQ6W)

![second buffer](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/second_buffer.png?token=AD5IB4BOFRXF5WMHUOXOIMK6BUQ7Y)

![third buffer](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/third_buffer.png?token=AD5IB4ASAFZGTQS35QQJK3S6BURAY)

![final product](https://raw.githubusercontent.com/sirchidi/chidubem-iddianozie/master/images/all_buffers.png?token=AD5IB4DEFEDTIBQNH7HZPMC6BUN7Q) -->

<p>Our buffers are created and we have to write back to file.</p>

<h3 id="writing-to-file">Writing to file</h3>
<p>We write the updated table to <code class="language-plaintext highlighter-rouge">.csv</code> using:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">COPY</span>
    <span class="p">(</span>
    <span class="k">select</span> 
        <span class="n">street</span><span class="p">,</span> 
        <span class="n">osmid</span><span class="p">,</span> 
        <span class="n">ST_AsText</span><span class="p">(</span><span class="n">geom</span><span class="p">)</span> <span class="k">AS</span> <span class="n">geom</span><span class="p">,</span> 
        <span class="n">ST_AsText</span><span class="p">(</span><span class="n">buffer_20_metres</span><span class="p">)</span> <span class="k">AS</span> <span class="n">buffer_20_metres</span><span class="p">,</span>
        <span class="n">ST_AsText</span><span class="p">(</span><span class="n">buffer_100_metres</span><span class="p">)</span> <span class="k">AS</span> <span class="n">buffer_100_metres</span><span class="p">,</span>
        <span class="n">ST_AsText</span><span class="p">(</span><span class="n">buffer_200_metres</span><span class="p">)</span> <span class="k">AS</span> <span class="n">buffer_200_metres</span>
    <span class="k">from</span> <span class="n">streetSample</span>
    <span class="p">)</span>
<span class="k">TO</span> <span class="s1">'/path/to/file/streetSample_with_buffers.csv'</span> <span class="k">DELIMITER</span> <span class="s1">','</span> <span class="n">CSV</span> <span class="n">HEADER</span><span class="p">;</span>
</code></pre></div></div>

<h2 id="final-words">Final words</h2>

<p>I hope this helps someone, the <code class="language-plaintext highlighter-rouge">SQL</code> queries for this post is available <a href="https://github.com/chiddianozie/concentricBufferConstruction">here</a>. If you have any queries, please leave a comment below or open an issue in the <a href="https://github.com/chiddianozie/concentricBufferConstruction">code repo</a>. Thanks!</p>]]></content><author><name>Chidubem Iddianozie</name></author><category term="Non-overlapping Concentric Buffers" /><category term="Linestrings" /><category term="Geo-spatial" /><category term="PostGIS" /><category term="PostgreSQL" /><summary type="html"><![CDATA[TL;DR: We will learn how to construct multiple non-overlapping buffers around linestring objects using PostGIS in PostgreSQL.]]></summary></entry><entry><title type="html">Fetching Google Street View Images of any location with Python and OSMNx</title><link href="https://chiddianozie.github.io/chidubem-iddianozie/posts/2018/01/Getting-Street-View-Images-with-Python-and-OSMNx/" rel="alternate" type="text/html" title="Fetching Google Street View Images of any location with Python and OSMNx" /><published>2019-01-31T00:00:00-08:00</published><updated>2019-01-31T00:00:00-08:00</updated><id>https://chiddianozie.github.io/chidubem-iddianozie/posts/2018/01/fetching-google-street-view-images-of-any-location-with-osmnx-and-python</id><content type="html" xml:base="https://chiddianozie.github.io/chidubem-iddianozie/posts/2018/01/Getting-Street-View-Images-with-Python-and-OSMNx/"><![CDATA[<p>In this post, i will describe how to collect Google Street view images of any location with OSMNx. For the tutorial, you will need OSMNx and access to Google Street View. If you have a working installation of OSMNx and have accessed the Google Street View api before, skip to <code class="language-plaintext highlighter-rouge">Implementation</code> or to the GitHub <a href="https://github.com/Notable1/FetchingStreetViewImagesWithOSMNx/">repo</a> for the code.</p>

<h2 id="osmnx">OSMNx</h2>

<p>OSMNx is a library for reading and manipulating OpenStreetMap street networks developed for Python by Geoff Boeing. You can read more about it and how to install it <a href="https://geoffboeing.com/2016/11/osmnx-python-street-networks/">here</a>. It is pretty straightforward.</p>

<blockquote>
  <p>As at the time of writing, i tried to install on another computer and ran into some dependency issues. Hence, i recommend <code class="language-plaintext highlighter-rouge">conda install -c conda-forge osmnx</code> for the installation. Also, ensure that your conda channel settings prioritizes conda-forge using <code class="language-plaintext highlighter-rouge">conda config --add channels conda-forge</code>, you can also go ahead to delete the <code class="language-plaintext highlighter-rouge">defaults</code> channel in the <code class="language-plaintext highlighter-rouge">.condarc</code> file.</p>
</blockquote>

<p>Assuming that you have successfully installed the package, you can go ahead to download the street network for the location you are interested in. We will be using that of <code class="language-plaintext highlighter-rouge">Dublin City, Ireland</code> as follows:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kn">import</span> <span class="nn">geopandas</span> <span class="k">as</span> <span class="n">gpd</span>
<span class="kn">import</span> <span class="nn">osmnx</span> <span class="k">as</span> <span class="n">ox</span>

<span class="n">G_dublin</span> <span class="o">=</span> <span class="n">ox</span><span class="p">.</span><span class="n">graph_from_place</span><span class="p">(</span><span class="s">'Dublin, County Dublin, Leinster, Ireland'</span><span class="p">,</span> <span class="n">network_type</span><span class="o">=</span><span class="s">'drive'</span><span class="p">)</span> <span class="c1">#drivable roads
</span><span class="n">ox</span><span class="p">.</span><span class="n">save_graph_shapefile</span><span class="p">(</span><span class="n">G_dublin</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="s">'dublin_network'</span><span class="p">)</span> <span class="c1">#save to disk
</span></code></pre></div></div>
<p>We read only the drivable roads for dublin (see the OSMNx documentation for other options) and save it to disk for use later on.</p>

<h2 id="google-street-view">Google Street View</h2>

<p>Google street view is a feature of GM that holds a panoramic views of streets around the world. The current coverage of GSV varies around the world (see <a href="https://www.google.com/streetview/understand/">here</a>). We will access GSV via the API, but first you need a <code class="language-plaintext highlighter-rouge">key</code>, you can get that <a href="https://developers.google.com/maps/documentation/streetview/get-api-key">here</a>. Also ensure that you enable GSV api access under  <code class="language-plaintext highlighter-rouge">dashboard &gt; Enable APIS AND SERVICES</code>. As long as you are not exceeding 25k requests a day, the api key should be enough for access. Otherwise, you will need the key with a digital signature (<a href="https://developers.google.com/maps/documentation/streetview/usage-and-billing">ref</a>).</p>

<p>Since GSV keeps a panoramic view of the streets, it is important to bear some concepts in mind before making your queries. These concepts are field of view (fov), heading, image size, pitch. You can read about them <a href="https://developers.google.com/maps/documentation/javascript/streetview">here</a>.</p>

<blockquote>
  <p>If you just want to dive in. You can play around with the values for each parameter. They are pretty intuitive.</p>
</blockquote>

<p>To access the API with python, you need to install the library from this <a href="https://pypi.org/project/google-streetview/">link</a>.</p>

<h2 id="implementation">Implementation</h2>

<p>With all the packages and tools collected, we move forward to the actual implementation. First we import the necessary libraries:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">google_streetview.api</span>
<span class="kn">import</span> <span class="nn">urllib</span><span class="p">,</span> <span class="n">os</span>
<span class="kn">import</span> <span class="nn">urllib.parse</span>

</code></pre></div></div>

<p>We will use geopandas to read the street network written to disk above.</p>

<blockquote>
  <p>As OSMNx is dependent on geopandas, you should have it installed already. If for some reason you don’t. install it with <a href="https://anaconda.org/conda-forge/geopandas">conda</a> or <a href="https://pypi.org/project/geopandas/">pip</a>.</p>
</blockquote>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="n">dublin</span> <span class="o">=</span> <span class="n">gpd</span><span class="p">.</span><span class="n">read_file</span><span class="p">(</span><span class="s">'data/dublin_network/edges/edges.shp'</span><span class="p">)</span>

</code></pre></div></div>
<p>Next, we take the centroids of each street edge components and write to a column <code class="language-plaintext highlighter-rouge">streetCentroid</code> in the <code class="language-plaintext highlighter-rouge">geodataframe: dublin</code>. This will be used as a reference point for all the streets.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">getStreetCentroid</span><span class="p">(</span><span class="n">row</span><span class="p">):</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s">'geometry'</span><span class="p">]</span>
    <span class="n">centroid</span> <span class="o">=</span> <span class="n">obj</span><span class="p">.</span><span class="n">centroid</span>
    <span class="k">return</span> <span class="n">centroid</span>

<span class="n">dublin</span><span class="p">[</span><span class="s">'streetCentroid'</span><span class="p">]</span>  <span class="o">=</span> <span class="n">dublin</span><span class="p">.</span><span class="nb">apply</span><span class="p">(</span><span class="n">getStreetCentroid</span><span class="p">,</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>

</code></pre></div></div>
<p>Now, the actual image collection. We consider just three headings <code class="language-plaintext highlighter-rouge">0,125 and 250 degrees</code> here. Notice the values for size, pitch, fov. You can change as you wish in <code class="language-plaintext highlighter-rouge">skeleton</code>. In the actual implementation, 3 images are collected for each street corresponding to the headings specified.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">orientation</span> <span class="o">=</span> <span class="p">[</span><span class="s">'0'</span><span class="p">,</span><span class="s">'125'</span><span class="p">,</span><span class="s">'250'</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">GetStreet</span><span class="p">(</span><span class="n">Add</span><span class="p">,</span><span class="n">SaveLoc</span><span class="p">,</span><span class="n">orientation</span><span class="p">):</span>
    <span class="n">skeleton</span> <span class="o">=</span> <span class="s">'https://maps.googleapis.com/maps/api/streetview?size=640x640&amp;fov=120&amp;pitch=-0.76&amp;heading='</span><span class="o">+</span><span class="n">orientation</span><span class="o">+</span><span class="s">'&amp;location='</span>
    <span class="n">ThisUrl</span> <span class="o">=</span> <span class="n">skeleton</span> <span class="o">+</span> <span class="n">urllib</span><span class="p">.</span><span class="n">parse</span><span class="p">.</span><span class="n">quote</span><span class="p">(</span><span class="n">Add</span><span class="p">)</span> <span class="o">+</span> <span class="s">"&amp;key="</span><span class="o">+</span><span class="s">"YOUR-API_KEY"</span>  
    <span class="n">filePath</span> <span class="o">=</span> <span class="n">Add</span> <span class="o">+</span><span class="s">'_facing='</span><span class="o">+</span><span class="n">orientation</span><span class="o">+</span><span class="s">'.jpg'</span>
    <span class="n">urllib</span><span class="p">.</span><span class="n">request</span><span class="p">.</span><span class="n">urlretrieve</span><span class="p">(</span><span class="n">ThisUrl</span><span class="p">,</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">SaveLoc</span><span class="p">,</span><span class="n">filePath</span><span class="p">))</span>

<span class="k">try</span><span class="p">:</span>
	<span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">dublin</span><span class="p">.</span><span class="n">iterrows</span><span class="p">():</span> 
	    <span class="n">points</span> <span class="o">=</span> <span class="p">(</span><span class="n">dublin</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">index</span><span class="p">,</span><span class="s">'streetCentroid'</span><span class="p">])</span>
	    <span class="n">pointList</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">points</span><span class="p">.</span><span class="n">coords</span><span class="p">)</span>
	    <span class="n">locationCoordinate</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">pointList</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span><span class="o">+</span><span class="s">','</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">pointList</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
	    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">orientation</span><span class="p">:</span>
	    	<span class="c1"># change the value in SaveLoc to the folder you want to save the images
</span>	        <span class="n">GetStreet</span><span class="p">(</span><span class="n">Add</span><span class="o">=</span><span class="n">locationCoordinate</span><span class="p">,</span><span class="n">SaveLoc</span> <span class="o">=</span> <span class="s">'dublinImages'</span><span class="p">,</span><span class="n">orientation</span> <span class="o">=</span> <span class="n">j</span><span class="p">)</span>
	<span class="k">print</span><span class="p">(</span><span class="s">'Finished downloading images for dublin'</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
	<span class="k">print</span><span class="p">(</span><span class="s">'error'</span><span class="p">)</span>
</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>

<p>If this helps you or have some other queries, please send an email or leave a comment below.</p>]]></content><author><name>Chidubem Iddianozie</name></author><category term="Python" /><category term="Google Street View" /><category term="OSMNx" /><category term="Cities" /><category term="Spatial" /><summary type="html"><![CDATA[In this post, i will describe how to collect Google Street view images of any location with OSMNx. For the tutorial, you will need OSMNx and access to Google Street View. If you have a working installation of OSMNx and have accessed the Google Street View api before, skip to Implementation or to the GitHub repo for the code.]]></summary></entry></feed>