Finding geometry of an area with overpass API - 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.
Related
Buffers (Circle) in PostGIS
I have to extend the normal GeoJSON format to add some unsopported polygon like Circle. { "type": "Circle", "radius" : 0.001, "coordinates": [ 5.417075157165527, 43.29129488122568 ] } This is an Example. Coordinates marks the center of circle and radius the radius (in meters). Searching on PostGis Docs and Stackoverflow, to draw a Circle you have to user ST_BUFFER. So Im using: ST_Buffer(ST_GeomFromGeoJSON(<center of circle>),0.001, 'quad_segs=16') Has you know, this draw a Circle only in 0,0 (near Africa). Other locations add a distortion that change the shape in an oval. Im using 4326. I have tried to search (even here) but I can't Find a solution to simply draw a circle avoid projection or transforming it. The only post here is: How to create a circle in meters in postgis? but its very old and that solution doesn't works.
Isn't it just doing what is supposed to be done? Which is to compensate the distortion due to projecting the ellipsoid into a 2D flat structure? I believe, the further away you get from the equator, the more oval buffers you will see. Examples: db=# SELECT ST_AsText( ST_Buffer( ST_GeomFromText('SRID=4326;POINT(43.29 5.41)'),0.001, 'quad_segs=16') ); This query returns a circle at the south-east of Ethiopia: POLYGON((43.291 5.41,43.2909951847267 5.40990198285967,43.2909807852804 5.40980490967798,43.2909569403357 5.40970971532275,43.2909238795325 5.40961731656764,43.2908819212644 5.40952860326317,43.2908314696123 5.40944442976698,43.2907730104534 5.40936560671584,43.2907071067812 5.40929289321881,43.2906343932842 5.40922698954664,43.290555570233 5.4091685303877,43.2904713967368 5.40911807873565,43.2903826834324 5.40907612046749,43.2902902846773 5.40904305966427,43.290195090322 5.4090192147196,43.2900980171403 5.40900481527333,43.29 5.409,43.2899019828597 5.40900481527333,43.289804909678 5.4090192147196,43.2897097153227 5.40904305966427,43.2896173165676 5.40907612046749,43.2895286032632 5.40911807873565,43.289444429767 5.4091685303877,43.2893656067158 5.40922698954664,43.2892928932188 5.40929289321881,43.2892269895466 5.40936560671584,43.2891685303877 5.40944442976698,43.2891180787356 5.40952860326317,43.2890761204675 5.40961731656764,43.2890430596643 5.40970971532275,43.2890192147196 5.40980490967798,43.2890048152733 5.40990198285967,43.289 5.41,43.2890048152733 5.41009801714033,43.2890192147196 5.41019509032202,43.2890430596643 5.41029028467725,43.2890761204675 5.41038268343237,43.2891180787356 5.41047139673683,43.2891685303877 5.41055557023302,43.2892269895466 5.41063439328416,43.2892928932188 5.41070710678119,43.2893656067158 5.41077301045336,43.289444429767 5.4108314696123,43.2895286032632 5.41088192126435,43.2896173165676 5.41092387953251,43.2897097153227 5.41095694033573,43.289804909678 5.4109807852804,43.2899019828597 5.41099518472667,43.29 5.411,43.2900980171403 5.41099518472667,43.290195090322 5.4109807852804,43.2902902846773 5.41095694033573,43.2903826834324 5.41092387953251,43.2904713967368 5.41088192126435,43.290555570233 5.4108314696123,43.2906343932842 5.41077301045336,43.2907071067812 5.41070710678119,43.2907730104534 5.41063439328416,43.2908314696123 5.41055557023302,43.2908819212644 5.41047139673683,43.2909238795325 5.41038268343237,43.2909569403357 5.41029028467725,43.2909807852804 5.41019509032202,43.2909951847267 5.41009801714033,43.291 5.41)) The same procedure a bit further away from the equator, in Tunisia POINT(9.76 36.61): POLYGON((9.761 36.61,9.76099518472667 36.6099019828597,9.7609807852804 36.609804909678,9.76095694033573 36.6097097153227,9.76092387953251 36.6096173165676,9.76088192126435 36.6095286032632,9.7608314696123 36.609444429767,9.76077301045336 36.6093656067158,9.76070710678119 36.6092928932188,9.76063439328416 36.6092269895466,9.76055557023302 36.6091685303877,9.76047139673683 36.6091180787356,9.76038268343236 36.6090761204675,9.76029028467725 36.6090430596643,9.76019509032202 36.6090192147196,9.76009801714033 36.6090048152733,9.76 36.609,9.75990198285967 36.6090048152733,9.75980490967798 36.6090192147196,9.75970971532275 36.6090430596643,9.75961731656763 36.6090761204675,9.75952860326317 36.6091180787356,9.75944442976698 36.6091685303877,9.75936560671584 36.6092269895466,9.75929289321881 36.6092928932188,9.75922698954664 36.6093656067158,9.7591685303877 36.609444429767,9.75911807873565 36.6095286032632,9.75907612046749 36.6096173165676,9.75904305966427 36.6097097153227,9.7590192147196 36.609804909678,9.75900481527333 36.6099019828597,9.759 36.61,9.75900481527333 36.6100980171403,9.7590192147196 36.610195090322,9.75904305966427 36.6102902846773,9.75907612046749 36.6103826834324,9.75911807873565 36.6104713967368,9.7591685303877 36.610555570233,9.75922698954664 36.6106343932842,9.75929289321881 36.6107071067812,9.75936560671584 36.6107730104534,9.75944442976698 36.6108314696123,9.75952860326317 36.6108819212644,9.75961731656763 36.6109238795325,9.75970971532275 36.6109569403357,9.75980490967798 36.6109807852804,9.75990198285967 36.6109951847267,9.76 36.611,9.76009801714033 36.6109951847267,9.76019509032202 36.6109807852804,9.76029028467725 36.6109569403357,9.76038268343236 36.6109238795325,9.76047139673683 36.6108819212644,9.76055557023302 36.6108314696123,9.76063439328416 36.6107730104534,9.76070710678119 36.6107071067812,9.76077301045336 36.6106343932842,9.7608314696123 36.610555570233,9.76088192126435 36.6104713967368,9.76092387953251 36.6103826834324,9.76095694033573 36.6102902846773,9.7609807852804 36.610195090322,9.76099518472667 36.6100980171403,9.761 36.61)) And this one much further away, in the north of Norway POINT(23.20 69.94): POLYGON((23.201 69.94,23.2009951847267 69.9399019828597,23.2009807852804 69.939804909678,23.2009569403357 69.9397097153227,23.2009238795325 69.9396173165676,23.2008819212643 69.9395286032632,23.2008314696123 69.939444429767,23.2007730104534 69.9393656067158,23.2007071067812 69.9392928932188,23.2006343932842 69.9392269895466,23.200555570233 69.9391685303877,23.2004713967368 69.9391180787356,23.2003826834324 69.9390761204675,23.2002902846773 69.9390430596643,23.200195090322 69.9390192147196,23.2000980171403 69.9390048152733,23.2 69.939,23.1999019828597 69.9390048152733,23.199804909678 69.9390192147196,23.1997097153227 69.9390430596643,23.1996173165676 69.9390761204675,23.1995286032632 69.9391180787356,23.199444429767 69.9391685303877,23.1993656067158 69.9392269895466,23.1992928932188 69.9392928932188,23.1992269895466 69.9393656067158,23.1991685303877 69.939444429767,23.1991180787357 69.9395286032632,23.1990761204675 69.9396173165676,23.1990430596643 69.9397097153227,23.1990192147196 69.939804909678,23.1990048152733 69.9399019828597,23.199 69.94,23.1990048152733 69.9400980171403,23.1990192147196 69.940195090322,23.1990430596643 69.9402902846772,23.1990761204675 69.9403826834324,23.1991180787357 69.9404713967368,23.1991685303877 69.940555570233,23.1992269895466 69.9406343932842,23.1992928932188 69.9407071067812,23.1993656067158 69.9407730104534,23.199444429767 69.9408314696123,23.1995286032632 69.9408819212643,23.1996173165676 69.9409238795325,23.1997097153227 69.9409569403357,23.199804909678 69.9409807852804,23.1999019828597 69.9409951847267,23.2 69.941,23.2000980171403 69.9409951847267,23.200195090322 69.9409807852804,23.2002902846773 69.9409569403357,23.2003826834324 69.9409238795325,23.2004713967368 69.9408819212643,23.200555570233 69.9408314696123,23.2006343932842 69.9407730104534,23.2007071067812 69.9407071067812,23.2007730104534 69.9406343932842,23.2008314696123 69.940555570233,23.2008819212643 69.9404713967368,23.2009238795325 69.9403826834324,23.2009569403357 69.9402902846772,23.2009807852804 69.940195090322,23.2009951847267 69.9400980171403,23.201 69.94)) To make your buffer ignore the distortion caused by the projection, consider the following query (POINT in Italy): SELECT ST_Buffer( ST_GeomFromGeoJSON('{"type":"Point","coordinates":[11.26,44.42]}')::geography, 1000,'quad_segs=16')::geometry; Explanation: Calculations using GEOMETRY and GEOGRAPHY are made differently, and so are their results. GEOGRAPHY calculates the coordinates over an spherical surface (which can be much slower than GEOMETRY) and uses meters as unit of measurement, while GEOMETRY uses a planar projection and uses the SRS unit. Note: The GEOMETRY casting in the end of the last query is necessary for the OP's use case, see comments bellow.
May be you can try this it is for a zone one kilometer in diameter like. I test it and it works for me: SELECT ST_Buffer( ST_MakePoint(-122.325959,47.625138)::geography, 1000)::geometry; See here for better understanding. I didn't test it but hope it will help you. To recap a bit what Abdullah Alger did in the solution that you can see in the link above: First he has a database called stores with latitude and longitude column no geometry column with Starbuck dataset. Then he adds geometry with the query: SELECT AddGeometryColumn('stores', 'geom', 4326, 'POINT', 2); After that update the geom column
How can I find a tag/way in another way/area with Overpass?
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
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;
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 display polygons that are within a specific range (circle) using Leaflet
I am trying find a solution on how to display polygons that are only within a specific range, a circle with radius using leaflet. Polygons screenshots Before, I have ask for help regarding on the display of points within a specific range but this time, since a polygon have many nodes/coordinates, i don't have any idea of how it can be done for polygons; a foreach statement? Any solution? Thanks for the help! Similar problem solved for displaying points within a specific range
Since you're using MongoDB, the best solution here is (if that's possible), to handle this in the database. Put 2dsphere indexes on your document's loc field and use a $geoWithin query in combination with $centerSphere: The following example queries grid coordinates and returns all documents within a 10 mile radius of longitude 88 W and latitude 30 N. The query converts the distance to radians by dividing by the approximate radius of the earth, 3959 miles: db.places.find( { loc: { $geoWithin: { $centerSphere: [ [ -88, 30 ], 10/3959 ] } } } ) 2dsphere reference: http://docs.mongodb.org/manual/core/2dsphere/ $geoWithin reference: http://docs.mongodb.org/manual/reference/operator/query/geoWithin/ $centerSphere reference: http://docs.mongodb.org/manual/reference/operator/query/centerSphere/ If you really want to do this clientside (which i absolutely wouldn't recommend) and you don't want to build your on solution (which is possible) you could take a look at GeoScript. GeoScript's geom.Geometry() class has a contains method: Tests if this geometry contains the other geometry (without boundaries touching). Geom.geometry reference: http://geoscript.org/js/api/geom/geometry.html EDIT: Here's the pure JS/Leaflet solution as requested in the comments, this is quick-n-dirty, but it should work. Here the containsPolygon method returns true when all of the polygon's points are within the circle: L.Circle.include({ 'containsPoint': function (latLng) { return this.getLatLng().distanceTo(latLng) < this.getRadius(); }, 'containsPolygon': function (polygon) { var results = []; polygon.getLatLngs().forEach(function (latLng) { results.push(this.containsPoint(latLng)); }, this); return (results.indexOf(false) === -1); } }); Here's a working example: http://plnkr.co/edit/JlFToy?p=preview If you want to return true if one or more of the polygon's points are within the circle than you must change the return statement to this: return (results.indexOf(true) !== -1);