How can I find a tag/way in another way/area with Overpass? - openstreetmap

I want all industries in "Chemnitz" with a "hot_water_tank".
This query gives me all objects with tags "landuse"="industrial" and "man_made"="hot_water_tank". I need only the "landuse"="industrial" containing a "hot_water_tank".
area
["name"="Chemnitz"]->.a;
out body qt;
(
way
(area.a)
["landuse"="industrial"];
way(area.a)
["man_made"="hot_water_tank"];
);
out body qt;
>;
out skel qt;
i tried this
area
["name"="Chemnitz"]->.a;
(
way
(area.a)
["landuse"="industrial"]->.c;
way(area.a)
["man_made"="hot_water_tank"]->.s;
(.c; .s;)->.all;
(.c; - .s;)->.I_without_T;
(.s; - .c;)->.T_wihtout_I;
((.all; - .I_without_T;) - .T_without_I;);
);
out body qt;
>;
out skel qt;
Screenshots of the results:

The key here was to use two little known statements from Overpass QL.
First is_in gives us areas in which features are located, second we need to extract relations and/or ways from said areas using pivot.
Here is a sample code:
(area["name"="Chemnitz"]) -> .chemnitz; //Chemnitz
(
way(area.chemnitz)["man_made"="hot_water_tank"];
(._;>;)
)->.hotwatertank; // all tanks in Chemnitz
(.hotwatertank is_in;) -> .areas; // areas in which tanks are located
(
way(pivot.areas)["landuse"="industrial"];
relation(pivot.areas)["landuse"="industrial"];
)->._; // convert areas to ways and relations with "landuse"="industrial" pair
(._;._ >;); // get geometry
out body qt; //print

Related

Using coordinate and radius instead of a bounding box

My current queries look like this:
[out:json]
[timeout:60]
;
(
relation
["type"="multipolygon"]
["landuse"~"brownfield|railway"]
(50.757310,6.054754,50.786730,6.111574);
way
["landuse"~"brownfield|railway"]
(50.757310,6.054754,50.786730,6.111574);
);
out body;
>;
out skel qt;
I would like to replace the bounding box by one coordinate and a radius, similiar to querying nodes around another node.
node["name"="Bonn"];
node
(around:1000)
["name"="Gielgen"];
out body;
Is this possible?
I was able to accomplish that using (around:radius,lat,lon). The radius appears to be given in meters.
A simple example:
node(around:1000.0,50.75,6.05)["historic"="wayside_cross"];
out;
Applied to your query:
[out:json]
[timeout:60]
;
(
relation
(around:1000,50.77675,6.07456)
["type"="multipolygon"]
["landuse"~"brownfield|railway"];
way
(around:1000,50.77675,6.07456)
["landuse"~"brownfield|railway"];
);
out body;
>;
out skel qt;

Finding geometry of an area with overpass API

I am trying to find the geometry of a building from a particular latitude longitude. So my idea was to use a coord-query to get all areas in which the lat,lng. Using http://overpass.osm.rambler.ru/cgi/interpreter, I get all the areas and I can filter to get only the nodes that are buildings.
Now I have an area, for example:
{ id: '2542062474',
'addr:city': 'Nice',
amenity: 'place_of_worship',
building: 'yes',
denomination: 'protestant',
name: 'Église Protestante Unie de Nice Saint-Esprit',
religion: 'christian',
source: 'cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2011' }
I thought it would be easy to get the geometry of this area but I can't find any way of doing that ? I must be missing something.
In http://overpass-turbo.eu, I enter the script:
[out:json][timeout:25];
// gather results
(
// query part for: “area”
area(2542062474);
);
// print results
out body;
>;
out skel qt;
but the result does not include the geometry. How do I get the geometry of an area ?
Thanks !
Here is my script, for the moment: https://gist.github.com/ptbrowne/60d7338502de1d16ac46
Areas are an internal data type of Overpass. You can use pivot to get the geometry:
[out:json][timeout:25];
area(2542062474);
way(pivot);
out body;
>;
out skel qt;
Finally, what I did was to read a bit more the doc and to find out that to get the way associated with an area, I needed to substract 2400000000 from the area id.
Then I could only query for the way. From area id 2542062474, I substract 2400000000, I get 142062474.
[out:json][timeout:25];
way(142062474);
out body;
>;
out skel qt;
It works, but I think the pivot answer by #Alex Morega is better since the 2400000000 might change one day. I do not know about performance.

How to extract only polygons from Overpass Turbo?

The query below extracts Polygons and Points:
[out:json];
area["name:fr"="Bruxelles-Capitale"]["admin_level"=4]->.a;
rel["admin_level"=8](area.a);
out geom;
How do I filter out Points?
Option 1: Simply hide it:
[out:json];
area["name:fr"="Bruxelles-Capitale"]["admin_level"=4]->.a;
rel["admin_level"=8](area.a);
out geom;
{{style:
node {
width: 0;
opacity:0;
fill-opacity:0;
}
}}
http://overpass-turbo.eu/s/98F
Option 2: Only extract ways from relation:
Don't forget to enable the flag "Don't display small features as POIs." in Settings -> Map.
[out:json];
area["name:fr"="Bruxelles-Capitale"]["admin_level"=4]->.a;
rel["admin_level"=8](area.a);
out meta;
way(r);
out geom;
http://overpass-turbo.eu/s/98H

How to create a GtkPixbuf from a stock item llike (new_from_stock)?

I want to get a stock item to use it in a treeview but I can't get it as a pixbuf directly as there is no new_from_stock method for pixbufs!!
say you want to get a pixbuf from stock_item.
There are 2 ways:
First (easy):
pixbuf = gtk_widget_render_icon ( widget, stock_item, size )
Second (hard):
You need to look for it in the list of default icon factories:
icon_set = gtk_style_lookup_icon_set ( style, stock_item )
OR:
icon_set = gtk_icon_factory_lookup_default ( $stock_item )
then check available sizes with get_sizes.
Check if the size you want is available or get the largest size which will be the last in the returned list.
Then you need to render it to get the pixbuf:
pixbuf = gtk_icon_set_render_icon ( icon_set, style, direction, state, size, widget )
Then scale it to whatever size you want using:
gdk_pixbuf_scale_simple ( pixbuf, width, height, GdkInterpType )
Hope you got it
Are you aware of the icon-name property in GtkCellRendererPixbuf? That should solve the problem of showing a stock icon in a treeview.
A slightly easier (and more future-proof) version of ophidion's answer is to do the following:
#define ICON_NAME "go-next"
#define ICON_SIZE 96 /* pixels */
GError *error = NULL;
GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
GdkPixbuf *pixbuf = gtk_icon_theme_load_icon(icon_theme, ICON_NAME, ICON_SIZE,
GTK_ICON_LOOKUP_USE_BUILTIN, &error);
Assuming you don't get an error, you can then put the resulting GdkPixbuf in a treemodel, or use it with a GtkButton, or whatever else you'd like to do with it.
As others have pointed out, GTK stock items are likely to be deprecated, so you should use names according to the Icon Naming Spec instead if you want to be future proof. See this Google Docs spreadsheet for the equivalent icon spec names for GTK stock items.
You can use gtk_image_new_from_stock(), then get the raw pixbuf using gtk_image_get_pixbuf().
But check out #jku's answer first, that sounds like the proper solution. I just wanted to add how you'd do it in any other context.

Intersecting Layers Returns Empty Collection Despite Visible Intersection

When I perform an intersection of a polygon I draw in OpenLayers and a postgis database layer, it seems that I am getting incorrect results.
Intersection works correctly on some layers. For instance, if I intersect a triangle with a layer of polygons that represent crop fields, I get the following:
The query my app generates to produce the above result is:
SELECT ST_AsText(ST_Intersection(%(geometries_0)s::geometry, %(geometry)s::geometry))
where geometries_0 is my triangle:
POLYGON((-104.84928345939991 40.518951354186285,-104.82319093011056 40.51953858115158,-104.83700967095314 40.50707521626648,-104.84928345939991 40.518951354186285))
and geometry is my layer of crop fields, as well-known text:
MULTIPOLYGON(((-104.841309611298 40.5075331998226,-104.84173356681 40.5069932245841,-104.842041204329 40.50640946683,-104.842224948796 40.5057962996657,-104.842280275816 40.5051688207073,-104.842205823049 40.5045424803865,-104.842003423773 40.5039327015263,-104.841678061729 40.5033544995574,-104.841237748411 40.502822112724,-104.840693325791 40.5023486513933,-104.840058199365 40.5019457751149,-104.839348008051 40.5016234053897,-104.838580239118 40.5013894812384,-104.837773797582 40.5012497635973,-104.836948540713 40.501207693373,-104.836124789073 40.5012643066572,-104.83532282616 40.5014182091969,-104.834562398965 40.5016656107496,-104.833862231727 40.5020004184754,-104.833239564888 40.5024143870601,-104.832709730574 40.5028973218633,-104.83228577506 40.5034373300773,-104.831978137541 40.5040211136997,-104.831794393074 40.5046342970926,-104.831739066055 40.5052617810515,-104.831813518821 40.5058881146554,-104.832015918097 40.5064978757385,-104.832341280141 40.5070760506105,-104.83278159346 40.5076084036796,-104.833326016079 40.5080818278834,-104.833961142505 40.5084846673069,-104.834671333819 40.5088070040565,-104.835439102753 40.5090409023397,-104.836245544289 40.5091806037522,-104.837070801158 40.5092226689759,-104.837894552799 40.5091660624086,-104.83869651571 40.509012177646,-104.839456942906 40.5087648031902,-104.840157110143 40.5084300292289,-104.840779776982 40.5080160977709,-104.841309611298 40.5075331998226)))
However, if I perform the same query with a different layer ("soils"), I get an empty result:
The query is the same:
SELECT ST_AsText(ST_Intersection(%(geometries_0)s::geometry, %(geometry)s::geometry))
with a polygon geometries_0 that should overlap:
POLYGON((-104.84627938530097 40.54511058649626,-104.83460641167578 40.545175808723876,-104.84070039055733 40.537283458057615,-104.84627938530097 40.54511058649626))
and a geometry layer representing soils, similar to the crop fields in the above query:
MULTIPOLYGON(((-104.939716 40.258166,-104.939775 40.258174,-104.939963 40.258159,-104.940159 40.258065,-104.940039 40.257671,-104.939917 40.25749,-104.939928 40.257419,-104.94003 40.257404,-104.940265 40.257641,-104.940632 40.257902,-104.940826 40.258061,-104.941051 40.258188,-104.941123 40.258235,-104.941205 40.258283,-104.941246 40.258275,-104.941287 40.258212,-104.941186 40.258094,-104.941186 40.258007,-104.941167 40.257921,-104.941105 40.257858,-104.941044 40.257786,-104.941045 40.257716,-104.941127 40.257676,-104.94122 40.257653,-104.94141 40.257731,-104.941559 40.257671,-104.941255 40.257181,-104.940857 40.256794,-104.940644 40.256478,-104.940319 40.255997,-104.940003 40.255728,-104.939676 40.255561,-104.939419 40.255544,-104.938895 40.255529,-104.938287 40.255512,-104.938046 40.255528,-104.937733 40.255549,-104.937322 40.255533,-104.937012 40.255577,-104.936947 40.255593,-104.936623 40.255774,-104.936581 40.255924,-104.93658 40.256042,-104.936661 40.256223,-104.93671 40.256436,-104.936842 40.256618,-104.937262 40.256753,-104.937662 40.256818,-104.937897 40.257,-104.938181 40.25745,-104.938374 40.257742,-104.938465 40.257931,-104.938782 40.258051,-104.939121 40.258092,-104.939439 40.258133,-104.939716 40.258166)))
I use the postgis ST_AsText function to convert database layers to well-known text, and I checked to make sure that all layers have the EPSG:4326 projection (using the Find_SRID function).
Why would one layer (crop fields) intersect correctly, and another (soils) not? I've tried the same query using geographies instead of geometries, with the same result.
It returns an empty collection because they don't intersect. In fact, they are 32 km away from each other.
SELECT ST_Intersects(A, B), ST_Distance(A, B)/1000 AS dist_km
FROM (
SELECT
'POLYGON((-104.84627938530097 40.54511058649626,-104.83460641167578 40.545175808723876,-104.84070039055733 40.537283458057615,-104.84627938530097 40.54511058649626))'::geography AS A,
'MULTIPOLYGON(((-104.939716 40.258166,-104.939775 40.258174,-104.939963 40.258159,-104.940159 40.258065,-104.940039 40.257671,-104.939917 40.25749,-104.939928 40.257419,-104.94003 40.257404,-104.940265 40.257641,-104.940632 40.257902,-104.940826 40.258061,-104.941051 40.258188,-104.941123 40.258235,-104.941205 40.258283,-104.941246 40.258275,-104.941287 40.258212,-104.941186 40.258094,-104.941186 40.258007,-104.941167 40.257921,-104.941105 40.257858,-104.941044 40.257786,-104.941045 40.257716,-104.941127 40.257676,-104.94122 40.257653,-104.94141 40.257731,-104.941559 40.257671,-104.941255 40.257181,-104.940857 40.256794,-104.940644 40.256478,-104.940319 40.255997,-104.940003 40.255728,-104.939676 40.255561,-104.939419 40.255544,-104.938895 40.255529,-104.938287 40.255512,-104.938046 40.255528,-104.937733 40.255549,-104.937322 40.255533,-104.937012 40.255577,-104.936947 40.255593,-104.936623 40.255774,-104.936581 40.255924,-104.93658 40.256042,-104.936661 40.256223,-104.93671 40.256436,-104.936842 40.256618,-104.937262 40.256753,-104.937662 40.256818,-104.937897 40.257,-104.938181 40.25745,-104.938374 40.257742,-104.938465 40.257931,-104.938782 40.258051,-104.939121 40.258092,-104.939439 40.258133,-104.939716 40.258166)))'::geography AS B
) AS data;
st_intersects | dist_km
---------------+------------------
f | 32.1052124928391
Something with your map is incorrect.
After some debugging (in addition to some helpful troubleshooting steps) I realized that I was building my WKT blobs incorrectly using the ST_AsText function, specifically for my soils layer. As a result, my intersection was not being applied to the entire set of geometries contained within my soils layer.
Currently my soils layer contains a subset of SSURGO soil map units, some of which do not actually contain a geometry. In order to correctly build a text string representing all non-null geometries, I needed to explicitly join the geometries before converting the result to WKT:
SELECT ST_AsText(ST_Union(the_geom)) FROM schema.layer
did the trick.