title: How can I find a list of street intersections from OpenStreetMap data?
body: <p>I am looking for a way to retrieve street intersections <em>accurately</em> from OpenStreetMap (OSM) data. I am aware that similar questions were asked and answered, but the data I could retrieve from the suggested method is not very accurate. </p>
  
  <p>First of all, I am aware of following questions:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/12241377/how-to-find-intersections-from-openstreetmap/12249004#12249004">how to find intersections from OpenStreetMap？</a></li>
  <li><a href="https://help.openstreetmap.org/questions/15442/detection-of-intersections-in-the-maps" rel="nofollow noreferrer">Detection of Intersections in the maps</a></li>
  </ul>
  
  <p>The answers to the aforementioned questions suggest to:</p>
  
  <blockquote>
    <p>"Query all ways in a given bounding box and look for nodes shared by two or more ways as explained in the other answer."</p>
  </blockquote>
  
  <p>I followed this suggestion and wrote a python script that extracts node elements from an xml file (osm file) that I downloaded from <a href="http://www.openstreetmap.org/" rel="nofollow noreferrer">OpenStreetMap</a>. Following is the code:</p>
  
  <pre><code>try:
      from xml.etree import cElementTree as ET
  except ImportError, e:
      from xml.etree import ElementTree as ET
  
  def extract_intersections(osm, verbose=True):
      # This function takes an osm file as an input. It then goes through each xml 
      # element and searches for nodes that are shared by two or more ways.
      # Parameter:
      # - osm: An xml file that contains OpenStreetMap's map information
      # - verbose: If true, print some outputs to terminal.
      # 
      # Ex) extract_intersections('WashingtonDC.osm')
      #
      tree = ET.parse(osm)
      root = tree.getroot()
      counter = {}
      for child in root:
          if child.tag == 'way':
              for item in child:
                  if item.tag == 'nd':
                      nd_ref = item.attrib['ref']
                      if not nd_ref in counter:
                          counter[nd_ref] = 0
                      counter[nd_ref] += 1
  
      # Find nodes that are shared with more than one way, which
      # might correspond to intersections
      intersections = filter(lambda x: counter[x] &gt; 1,  counter)
  
      # Extract intersection coordinates
      # You can plot the result using this url.
      # http://www.darrinward.com/lat-long/
      intersection_coordinates = []
      for child in root:
          if child.tag == 'node' and child.attrib['id'] in intersections:
              coordinate = child.attrib['lat'] + ',' + child.attrib['lon']
              if verbose:
                  print coordinate
              intersection_coordinates.append(coordinate)
  
      return intersection_coordinates
  </code></pre>
  
  <p>If I run this code with the data I exported from OSM (<em>e.g.</em>, I used data exported from Area of Export: Min Lat: 38.89239, Max Lat: 38.89981, Min Lon: -77.03212, and Max Lon: -77.02119.), it prints out coordinates that look like:</p>
  
  <pre><code>38.8966440,-77.0259810
  38.8973430,-77.0280900
  38.9010391,-77.0270309
  38.8961050,-77.0319620
  ...
  </code></pre>
  
  <p>If I plot these coordinates on Google Maps, it looks like:
  <img src="https://i.stack.imgur.com/sgXtl.png" alt="enter image description here"></p>
  
  <p>(I used <a href="http://www.darrinward.com/lat-long/" rel="nofollow noreferrer">http://www.darrinward.com/lat-long/</a> to plot data.) Apparently the data contains some nodes that are <em>not</em> intersections (they are probably stores that are facing towards two steets.)</p>
  
  <p>Am I doing something wrong or is this the best "intersection" data I can get from OSM? I appreciate your help and comments.</p>
  
  <p>Best,</p>