Overpass: Sum the values of a tag in every object in a set

Hi,

I’m trying to write a query to count how many residential units (houses + appartments) there are within every suburb of this small municipality, which has 5 ‘suburbs’.

For the sake of simplicity in this thread I’m assuming there are two kinds of residential buildings:

  1. Those without “building:flats” tag are assumed to be 1 residential unit per building.
  2. Those with “building:flats” tag, then extract the tag’s value and add it up to the total.

Below is the code:

// Count residential units within every suburb of a municipality
[out:csv(name, total)];
{{geocodeArea:Maristela, Laranjal Paulista}}->.a;

// select suburbs
rel[admin_level=10](area.a);
map_to_area;

// for each suburb
foreach->.suburb( 

  // select and classify buildings
  wr[building][!"building:flats"](area.suburb)->.houses; 
  wr[building]["building:flats"](area.suburb)->.apartments;
  
// for each apartment building
  make counter n_apartments = 0;
  foreach.apartments (
    n_apartments = n_apartments + t['building:flats']; //**ERROR
  );
  
// print stats
  make stat name = suburb.set(t["name"]), total = houses.count(wr) + n_apartments; //**ERROR
  out;
);

I’m getting error in the lines 18 and 21. The variable ‘n_apartments’ is read as “Unknown type” even though I’ve used ‘make’ to create it as a counter. I’ve tried to get around to it, but no avail.

Any help is appreciated,

Maybe take a look at Counting roundabouts - Step 5 in particular.

1 Like

Great, now no longer crashes and gives a human readable result. Thank you!

But it seems it’s skipping the buildings with the tag building:flats. For example the suburb “Vila Stela Maris” has 241 buildings – 240 doesn’t have building:flats, and only 1 has building:flats = 5; so the expected result is 245, but it returns 240.

I thought the error happened because t['building:flats'] returns a string (“5”, instead of 5), so I used number() to convert it to a number, but still returns 240.

// Count residential units within every suburb of a municipality
[out:csv(name, total)];
{{geocodeArea:Maristela, Laranjal Paulista}}->.a;

// select suburbs
rel[admin_level=10](area.a);
map_to_area;

// for each suburb
foreach->.suburb( 

  // select and classify buildings
  wr[building][!"building:flats"](area.suburb)->.houses; 
  wr[building]["building:flats"](area.suburb)->.apartments;
  
// for each apartment building
  make counter n_apartments = 0 -> .count;
  foreach.apartments (
    .count convert counter n_apartments = t['n_apartments'] + number(t['building:flats']) -> .count;
  );
  
// print stats
  make stat name = suburb.set(t["name"]), total = houses.count(wr) + count.n_apartments;
  out;
);

Any ideas?

Excelent, it worked. Thank you!

FWIW: I would suggest the more compact variant

[out:csv(name, total)];
{{geocodeArea:Maristela, Laranjal Paulista}}->.a;

rel[admin_level=10](area.a);
map_to_area;

foreach->.suburb(
    wr[building](area.suburb);
    make stat name=suburb.set(t["name"]),
        total=sum(is_tag("building:flats") ? number(t["building:flats"]) : 1);
    out;
);
3 Likes