Question

I'm trying to query OpenStreetMaps through the Overpass API.

What I want to query is roads inside a bounding box that has any kind of bridges crossing above, like railway bridges etc.

I found this example, that does just about what I need: http://maxheight.bplaced.net/overpass/map.html

So, the queries I've got look like this:

Railway bridges View in Overpass Turbo

<osm-script output="json" timeout="25">

  <!-- Railway bridges -->
  <query type="way">
    <has-kv k="bridge" regv="^(yes|viaduct)$"/>
    <has-kv k="railway" />      
    <bbox-query {{bbox}}/>
  </query>

  <!-- Find roads below the above railway bridges -->
  <query type="way">
    <around radius="0" />
    <has-kv k="highway" regv="^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"/>
    <has-kv k="maxheight" modv="not" regv="." />
    <has-kv k="maxheight:physical" modv="not" regv="." />
    <has-kv k="tunnel" modv="not" regv="." />
  </query>

  <union>
    <item />
    <recurse type="way-node"/>
  </union>

  <!-- print results -->
  <print mode="body"/>
  <recurse type="down"/>
  <print mode="skeleton" order="quadtile"/>
</osm-script>

Other briges View in Overpass Turbo

<osm-script output="json" timeout="25">

  <!-- Bridges -->
  <query type="way">
    <has-kv k="bridge" regv="^(yes|viaduct)$"/>
    <has-kv k="railway" modv="not" regv="." />      
    <bbox-query {{bbox}}/>
  </query>

  <!-- Find roads below the above bridges -->
  <query type="way">
    <around radius="0" />
    <has-kv k="highway" regv="^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"/>
    <has-kv k="maxheight" modv="not" regv="." />
    <has-kv k="maxheight:physical" modv="not" regv="." />
    <has-kv k="tunnel" modv="not" regv="." />
  </query>

  <union>
    <item />
    <recurse type="way-node"/>
  </union>

  <!-- print results -->
  <print mode="body"/>
  <recurse type="down"/>
  <print mode="skeleton" order="quadtile"/>
</osm-script>

The problem is the second query. It should find bridges crossing a road, and the accompanying road below.

What it does now is return all bridges, except railway bridges - which means it highlights a road with a bike path underneath, a road crossing a lake - which it shouldn't.

I noticed this today, when I drove past a location it highlighted and saw that it was just a bike path under the road.

Was it helpful?

Solution

A few comments regarding the proposed approach above:

  • Maxheight Map wants to help find streets with missing maximum height information, something which is quite important for truck routing. If I get your use case right, you want to find out about ALL roads where bridges cross. Currently your query would not show any roads, where that maximum height information was already maintained. This is fairly easy to solve if you remove the restriction on both tags "maxheight" and "maxheight:physical" in your query.

  • As already stated, Maxheight Map merges several layers into one Query. But it would also break a large Boundary Box (bbox) into smaller pieces. The XML query posted above has 4 identical parts inside the UNION operation, which makes things look overly complicated. In fact for the purpose of your use case, you could get away with a much simpler approach (see below).

  • You don't have to convert your query into XML format. Overpass QL (query language) is perfectly fine for Overpass API and of course Overpass Turbo.

  • From past experience with Maxheight Map, Overpass API won't give you the solution you're asking for without post-processing the result. If you're familiar with OpenLayers you might want to take a look at the logic I used. Basically you need to find intersections on inner points only, similar to want PostGIS function st_crosses does. Also you would have to take each way's 'layer' information into account as an example.

A very stripped down version (for Overpass Turbo) could look like this. However, you need to make sure that actual highway/bridge types match your requirements, and of course don't forget about post processing your results. Without it your query result will contain quite a number of false positives.

((way({{bbox}})[bridge~"^(yes|viaduct)$"];way(around:0)[highway~"^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"][tunnel!~"."]);>;);out;

OTHER TIPS

The correct query is this. Not only does it get it right in regard to bridges crossing roads, it also combines the two into one query.

I monitored the network on the OSM Truck QA Map, grabbed the POST data of the request to the Overpass API.

I used the Overpass QL converter to turn it into XML.

View query in Overpass Turbo

<osm-script output="json" timeout="20">
  <union into="_">
    <union into="_">
      <union into="_">
        <query into="_" type="way">
          <bbox-query {{bbox}}/>
          <has-kv k="bridge" modv="" regv="^(yes|viaduct)$"/>
          <has-kv k="railway" modv="" v=""/>
        </query>
        <query into="_" type="way">
          <around from="_" into="_" lat="" lon="" radius="0"/>
          <has-kv k="highway" modv="" regv="^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"/>
          <has-kv k="maxheight" modv="not" regv="."/>
          <has-kv k="maxheight:physical" modv="not" regv="."/>
          <has-kv k="tunnel" modv="not" regv="."/>
        </query>
      </union>
      <recurse from="_" into="_" type="down"/>
    </union>
    <union into="_">
      <union into="_">
        <query into="_" type="way">
          <bbox-query {{bbox}}/>
          <has-kv k="bridge" modv="" regv="^(yes|viaduct)$"/>
          <has-kv k="railway" modv="" v=""/>
        </query>
        <query into="_" type="way">
          <around from="_" into="_" lat="" lon="" radius="0"/>
          <has-kv k="highway" modv="" regv="^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"/>
          <has-kv k="maxheight" modv="not" regv="."/>
          <has-kv k="maxheight:physical" modv="not" regv="."/>
          <has-kv k="tunnel" modv="not" regv="."/>
        </query>
      </union>
      <recurse from="_" into="_" type="down"/>
    </union>
    <union into="_">
      <union into="_">
        <query into="_" type="way">
          <bbox-query {{bbox}}/>
          <has-kv k="bridge" modv="" regv="^(yes|viaduct)$"/>
          <has-kv k="railway" modv="" v=""/>
        </query>
        <query into="_" type="way">
          <around from="_" into="_" lat="" lon="" radius="0"/>
          <has-kv k="highway" modv="" regv="^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"/>
          <has-kv k="maxheight" modv="not" regv="."/>
          <has-kv k="maxheight:physical" modv="not" regv="."/>
          <has-kv k="tunnel" modv="not" regv="."/>
        </query>
      </union>
      <recurse from="_" into="_" type="down"/>
    </union>
    <union into="_">
      <union into="_">
        <query into="_" type="way">
          <bbox-query {{bbox}}/>
          <has-kv k="bridge" modv="" regv="^(yes|viaduct)$"/>
          <has-kv k="railway" modv="" v=""/>
        </query>
        <query into="_" type="way">
          <around from="_" into="_" lat="" lon="" radius="0"/>
          <has-kv k="highway" modv="" regv="^((primary|secondary|tertiary|trunk)(_link)?|service|residential|unclassified)$"/>
          <has-kv k="maxheight" modv="not" regv="."/>
          <has-kv k="maxheight:physical" modv="not" regv="."/>
          <has-kv k="tunnel" modv="not" regv="."/>
        </query>
      </union>
      <recurse from="_" into="_" type="down"/>
    </union>
  </union>
  <print from="_" limit="" mode="body" order="id"/>
</osm-script>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top