User:Kovposch/Overpass API/Overpass API by Example

From OpenStreetMap Wiki
Jump to navigation Jump to search

Lack of feature in areas

try it yourself in overpass-turbo
wr({{bbox}})[landuse=farmyard];
foreach
(
  wr(area)[building]->.inside;
  (._; .inside;); 
  wr._(if: count(wr) == 1); // For convenience, to output them together
  out geom meta;
);

3D rendering

try it yourself in overpass-turbo
wr({{bbox}})["building:part"][location!=underground]["building:levels"]["building:levels"!=0] -> .parts;  
.parts out geom;
(
  way.parts;
  way(r.parts); 
); 
node(w)->.partsp;
 
wr({{bbox}})[building][location!=underground];  
foreach->.each
{ 
  (.each; way(r.each);); 
  node(w); 
  node._.partsp ->.shared;
  wr(area.each)["building:part"] -> .inside;
  if (shared.count(nodes) == 0 && inside.count(wr) == 0) // Includes check for `building:part=` lying exactly on `building=` outline, which is not returned by `(area)` 
  {  
    .each out geom;
  }; 
};  

{{style:
area[building]
{ color:blue; fill-color:blue; }

area[building:part]
{ color:green; fill-color:green; }
}}

(To be refined)

Overlapping areas

try it yourself in overpass-turbo
(way({{bbox}})[natural](if: is_closed()); rel({{bbox}})[natural][type=multipolygon];);   
foreach->.this
{ 
  (way(around.this:0)[natural](if: is_closed()); rel(around.this:0)[natural][type=multipolygon];); // Any touching areas
  (._; - .this;) ->.touching; // Removes itself 
  if (touching.count(wr) > 0)
  {
    way(r.this);
    (node(w); node(w.this);) -> .thispts;  
    foreach.touching
    {
      ._ -> .thistouching;
      way(r);
      (node(w); node(w.thistouching);) -> .thistouchingpts;  
      node.thispts.thistouchingpts -> .sharedpts;    
      if (sharedpts.count(nodes) == 0) // Overlapping areas without shared points 
      { 
        (.this; .thistouching;);
        out geom meta; 
      }; 
      if (sharedpts.count(nodes) > 0) 
      { 
        node(area.this);
        (._; - .thispts;) -> .ptsinsidethis; // `node(area)` finds points lying on the area. Need to remove them. 
        node.ptsinsidethis.thistouchingpts -> .crossptsinsidethis; 
        if (crossptsinsidethis.count(nodes) > 0) // Check for points inside to discard areas with exactly shared outlines
        { 
          (.this; .thistouching;);
          out geom meta; 
        }; 
      }; 
    }; 
  };  
};

Intersection streets

Overpass_API_by_Example#Search_for_street_intersections

try it yourself in overpass-turbo
[out:json][timeout:25];

// The public street network
way({{bbox}})["highway"~"^(trunk|primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"]->.streets;

// Get nodes that connect between three or more street segments
node(way_link.streets:3-)->.connections;

// Get intersections between distinct streets
foreach .connections->.connection
{
  // Get adjacent streets
  way(bn.connection);
  // If the names don't all match, add the node to the set of intersections
  if (u(t["name"]) == "< multiple values found >") 
  {
     make node  
      ::id = connection.u(id()), 
      _streets = set(t["name"]);  
    (._; .intersectionstreets;) -> .intersectionstreets;
    (.intersections; .connection;) -> .intersections; 
  };
}; 
for.intersections->.this(id())
{
  foreach.intersectionstreets
  {
    if (this.val == u(id()))
    {
      ._ -> .thisintersectionstreets;
    };
  };
  node.intersections(if: id() == this.val) -> ._;
  convert node 
    ::id = id(),
    ::geom = geom(),
    :: = ::,
    _intersectingstreets = thisintersectionstreets.u(t["_streets"]);
  out geom;
};

Duplicate addresses

Between buildings

try it yourself in overpass-turbo
//[out:json][timeout:55];
[out:csv(st,num,type,id)][timeout:55];
//rel(id:110826);
//map_to_area; 
wr({{bbox}})[building]["addr:housenumber"]["addr:street"]->.all; //wr(area)[building]["addr:housenumber"]["addr:street"]->.all;
for.all->.thisst(t["addr:street"])
{
  wr.all(if: t["addr:street"]==thisst.val)->.onthisst;
  for.onthisst->.thisnum(t["addr:housenumber"])
  {
    wr.onthisst(if: t["addr:housenumber"]==thisnum.val)->.matches;
    if (matches.count(wr) > 1)
    {
      //.matches out geom; 
      make dupe st=thisst.val, num=thisnum.val, type=matches.set(type()), id=matches.set(id());
      out;
    };
  };
};

Glued roads

try it yourself in overpass-turbo
[out:json][timeout:25]; 
(wr({{geocodeBbox:Brisbane}})[landuse];) -> .land;
way(r.land) -> .members; 
(way.land; .members;) -> .all;
node(w.all)->.landpts;  
way({{geocodeBbox:Brisbane}})[highway][area!=yes][highway!=services][highway!=rest_area] -> .roads;
node(w.roads) -> .roadspts;  
node.landpts.roadspts -> .intersecting;  
node.landpts.intersecting -> .landptsintersecting;
node.roadspts.intersecting -> .roadsptsintersecting; 
way.land(bn.landptsintersecting) -> .landmatchw;
way.members(bn,landptsintersecting) -> .membersmatch; 
rel.land(br.membersmatch)->.landmatchr; 
way.roads(bn.roadsptsintersecting) -> .roadsmatch; 
foreach.landmatchw->.thisland
{
  node.landptsintersecting(w.thisland)->.thisintersectingpts;
  node.thisintersectingpts.roadsptsintersecting->.thismatchpts;
  if (thismatchpts.count(nodes)>1)
  { 
    way.roadsmatch(bn.thismatchpts)->.thismatchroads;
    foreach.thismatchroads->.thisthismatchroads
    {
      node.thismatchpts(w.thisthismatchroads);
      if (count(nodes)>1)
      {
        .thisthismatchroads out geom;
        .thisland out geom;
      };
    };
  };
};
foreach.landmatchr->.thisland
{
  way.members(r.thisland) -> .thismembers;
  node.landptsintersecting(w.thismembers) -> .thisintersectingpts;
  node.thisintersectingpts.roadsptsintersecting -> .thismatchpts;
  if (thismatchpts.count(nodes)>1)
  { 
    way.roadsmatch(bn.thismatchpts)->.thismatchroads;
    foreach.thismatchroads->.thisthismatchroads
    {
      node.thismatchpts(w.thisthismatchroads);
      if (count(nodes)>1)
      {
        .thisthismatchroads out geom;
        .thisland out geom;
      };
    };
  }; 
};

Nested features

try it yourself in overpass-turbo
[out:json][timeout:25];
nwr({{bbox}})[amenity=school]->.all;
foreach.all->.this
{
  nwr.all(area.this)->.candidates;
  if (candidates.count(nodes)>0)
  {
    node.candidates;
    out geom;
    .this out geom;
  }
  (wr.candidates; - .this;)->.candidatesareas;
  if (candidatesareas.count(wr)>0)
  {
    (way.candidatesareas; way(r.candidatesareas);)->.candidatessegments;
    node(w.candidatessegments);
    node._(area.this)->.candidatessegmentspts;
    (way.this; way(r.this););
    node(w)->.thispts;
    (.candidatessegmentspts; - node.candidatessegmentspts.thispts;);
    if (count(nodes)>0)
    {
      way.candidatessegments(bn)->.matchessegments;
      (way.matchessegments.candidatesareas; rel.candidatesareas(bw.matchessegments););
      out geom;
      .this out geom;
    };
  };
};

TIGER by road section

try it yourself in overpass-turbo
[out:json][timeout:25];
way({{bbox}})[highway][name]->.all;
node(way_cnt.all:2)->.alljoints; // Find points with 2 lines intersecting 
foreach.alljoints->.this
{
  way.all(bn.this)->.thisroads;
  if (thisroads.u(t["highway"]) != "< multiple values found >" && thisroads.u(t["name"]) != "< multiple values found >") // Find same val
  {
    way.thisroads["tiger:reviewed"=no]->.unreviewed;
    if (unreviewed.count(ways) == 1)
    {
      (.thisroads; - .unreviewed;)->.reviewed;
      way.reviewed[~"^tiger:"~"."]->.tiger; // Find has tiger:*= to eliminate
      if (tiger.count(ways) == 0)
      {
        .thisroads out geom;
      };
    };
  };
};

Isolated photos

try it yourself in overpass-turbo
[out:json][timeout:25];
nwr({{bbox}})[image]->.all;
for.all->.these(t["image"]) // Loops through all unique [image=]
{
  if (these.count(nwr) > 1) // Discards unique ones
  {
    foreach.these->.this
    {
      if (findthese.count(nwr) != these.count(nwr)) // Breaks the loop when all objects of this [image=] are retrieved
      {
        nwr.these(around.this:100)->.aroundthis;
        if (aroundthis.count(nwr) == 1) // Lone object
        {
          .this out geom;
        };
        (.findthese; .aroundthis;)->.findthese; // Records what's found
      };
    };
  };
};