ES:API de Overpass/API de Overpass por ejemplo
Estado de servidores · Versiones · Desarrollo · Diseño técnico · Instalación · Capa de compatibilidad XAPI · Esquemas de transporte público · Aplicaciones · Código fuente e incidenciasOverpass turbo · Asistente · Atajos de Overpass turbo · Hojas de estilo MapCSS · Exportar a GeoJSON · más (español) · Desarrollo · Código fuente e incidencias · Sitio webOverpass Ultra · Examples · Overpass Ultra extensions · Hojas de estilo MapLibre · URL Params · más (español) · Código fuente e incidencias · Sitio web
La API de Overpass ofrece una variedad de posibilidades de búsqueda. Estas búsquedas también se conocen como consultas. Los resultados de esas búsquedas o consultas se pueden mostrar directamente en un mapa, pero también es posible recuperar solo los datos. En esta página nos centraremos en los ejemplos que deben ser mostrados en un mapa. Esto significa que todas las consultas pueden ser insertadas en el editor de código de Overpass turbo. Desde allí se puede ejecutar la consulta y el resultado se mostrará en un mapa.
¡Simplemente haz clic en el icono de junto a la consulta para probarla en Overpass turbo!
Introducción
La forma más simple de empezar con la API de Overpass es usar Taginfo y navegar a la etiqueta que te interese. Toma los buzones de correo como ejemplo. Haz clic en el botón de Overpass turbo en la parte superior derecha. Eso iniciará la interfaz de usuario de Overpass turbo y generará la siguiente consulta.
/*
Esta consulta busca nodos, vías y relaciones
con la combinación de clave/valor especificada.
¡Elige tu región y haz clic en el botón ejecutar de la parte superior!
*/
[out:json][timeout:25];
// recopilando resultados
(
// parte de la consulta para: «amenity=post_box»
node["amenity"="post_box"]({{bbox}});
way["amenity"="post_box"]({{bbox}});
relation["amenity"="post_box"]({{bbox}});
);
// impresión de resultados
out body;
>;
out skel qt;
La interfaz de usuario de Overpass turbo tiene muchas capacidades. Por el momento debería bastar con tener en la esquina superior izquierda de la vista del mapa un campo de texto. Introduce tu ubicación favorita. Luego, haciendo uso de Nominatim, mueve la vista del mapa a esa ubicación. Introduce, p. ej., Manhattan y elige la primera sugerencia de ubicación. El mapa entonces salta al extremo superior del Central Park en Manhattan. Amplía dos niveles de zum para ver parte del área construida. Ejecuta la consulta haciendo clic en Ejecutar.
El ejemplo de Taginfo
Ahora podemos empezar a entender la consulta.
La mayoría de la consulta anterior son comentarios - todo lo que aparece después de // y entre /* y */. Por tanto, una variante más concisa de la consulta sería:
[out:json][timeout:25];
(
node["amenity"="post_box"]({{bbox}});
way["amenity"="post_box"]({{bbox}});
relation["amenity"="post_box"]({{bbox}});
);
out body;
>;
out skel qt;
Como aquí estamos viendo un ejemplo sencillo, reducimos la consulta en dos pasos para que sea realmente simple.
Sabemos que los buzones de correo normalmente suelen ser nodos:
[out:json][timeout:25];
(
node["amenity"="post_box"]({{bbox}});
);
out body;
>;
out skel qt;
Y podemos eliminar la mayor parte de la sintaxis críptica que en su mayoría dice qué hacer con las vías y relaciones. Podemos obtener el mismo resultado que antes con solo dos líneas.
node["amenity"="post_box"]({{bbox}});
out;
Todos estos pasos funcionan con una etiqueta de Taginfo. No hay magia involucrada. Solo reemplaza amenity = post_box con el valor respectivo.
Algunas características estándares
¿Y qué hay de la sintaxis extra? Revisémoslas poco a poco. Para ver el efecto, cambiamos a la consulta de restaurantes en lugar de buzones, porque así podremos ver el efecto de buscar también elementos tipo vía.
node["amenity"="restaurant"]({{bbox}});
out;
No todos los restaurantes están mapeados como nodos. Por tanto, queremos buscar también vías y relaciones:
way["amenity"="restaurant"]({{bbox}});
out;
Ejecutar esta consulta dará como resultado un mensaje indicando que falta la geometría. Esto se debe a que el modelo de datos de OpenStreetMap no asocia directamente las coordenadas con las vías y relaciones. Las vías y relaciones en cambio obtienen su geometría a partir de la posición de sus nodos referenciados.
La declaración out tiene varios modos de resolver este problema de forma conveniente: puedes elegir, por ejemplo, out geom para dejar que la API de Overpass resuelva las coordenadas por ti; o bien puedes usar out center para colapsar la geometría a una sola coordenada por objeto:
way["amenity"="restaurant"]({{bbox}});
out center;
Podemos poner todas estas peticiones simplemente una tras otra. Entonces obtenemos los resultados uno tras otro y Overpass turbo los muestra todos a la vez.
node["amenity"="restaurant"]({{bbox}});
out;
way["amenity"="restaurant"]({{bbox}});
out center;
relation["amenity"="restaurant"]({{bbox}});
out center;
Las consultas generadas por Taginfo usan en su lugar la secuencia out body, out skel qt, out skel qt. Se debe simplemente a razones históricas. Esto hace esencialmente lo mismo que out geom pero entrega elementos estrictamente del modelo de datos de OpenStreetMap. Overpass turbo hoy en día puede procesar directamente los resultados de out geom y out center y los datos en bruto ofrecidos son más concisos.
Como último paso, hacemos la consulta más concisa:
[bbox:{{bbox}}];
( node["amenity"="restaurant"];
way["amenity"="restaurant"];
relation["amenity"="restaurant"]; );
out center;
Esto sigue teniendo el mismo resultado que antes. Pero hemos llevado el recuadro delimitador a un solo lugar al principio de la consulta. Una razón importante para hacerlo es que se debe desarrollar el hábito de tener siempre un recuadro delimitador a menos que realmente quieras resultados de todo el planeta.
También hemos agrupado las declaraciones de consulta mediante una declaración de unión —representada por los paréntesis—. Esto permite tener una sola declaración de salida.
La consulta generada por Taginfo también usa otros dos ajustes globales:
El primero es [out:json]. Esto puede ser una ventaja si quieres leer directamente los datos del resultado de tu consulta. Puedes hacerlo en la pestaña Datos sobre la vista del mapa.
El segundo es [timeout:25]. Esto limita el tiempo de ejecución de la consulta a 25 segundos. Si algo sale mal, el límite asegura que ni el servidor ni tú pierdan tiempo. Al igual que el recuadro delimitador global, es una precaución útil.
En conclusión, llegamos a la siguiente petición:
[timeout:25][bbox:{{bbox}}];
( node["amenity"="restaurant"];
way["amenity"="restaurant"];
relation["amenity"="restaurant"]; );
out center;
Etiquetas raras
Si no sabes de antemano que etiqueta esperas encontrar pero estás bastante seguro de que no hay mucho más que unos pocos cientos de elementos, entonces puedes prescindir del recuadro delimitador.
[timeout:25];
( node[name="Belsenplatz"];
way[name="Belsenplatz"];
rel[name="Belsenplatz"]; );
out center;
Si también prescindes del ajuste timeout, entonces el servidor establece un valor predeterminado de 180 segundos:
( node[name="Belsenplatz"];
way[name="Belsenplatz"];
rel[name="Belsenplatz"]; );
out center;
Otros ejemplos
Además de esta página, hay muchos más ejemplos en el blog de desarrollo de la API de Overpass (en). También incluye enlaces a ejemplos concretos de las secciones que figuran a continuación.
Comprensión de los datos
Esta sección trata de las consultas que responden a la pregunta de si existen situaciones específicas de datos.
No hay un límite definido con la sección de bloques básicos que figuran más adelante. El criterio general es que los ejemplos aquí presentados lo son desde un punto de vista geográfico, pero los bloques básicos lo son desde el punto de vista de la base de datos y pueden seguir criterios puramente técnicos.
La diferencia con el control de calidad es que las consultas aquí recogidas suelen tener resultados válidos, mientras que los resultados de las consultas de control de calidad necesitan ser corregidos de una forma u otra.
Etiquetado
Para tener sentido, un objeto de OpenStreetMap siempre necesita tener un tipo. Normalmente, los humanos necesitan además un referente para referirse a tal objeto —es decir, lo que viene a ser un nombre—. Siguiendo el principio KISS, este referente se encuentra siempre en la etiqueta name. Pero a veces hay una razón válida para tenerlo en otra etiqueta, como ref o name:fr.
Una de las suposiciones estándares cuando se trata de datos de OpenStreetMap es que los objetos con nombres tienen un tipo. Esto se opone a los elementos sin nombre de la base de datos de OpenStreetMap. Estos elementos pueden ser parte de otro objeto y no constituir un objeto por sí mismos.
Por el contrario, al menos ciertos tipos de objetos siempre tienen nombres —no hay un museo sin nombre—. Sin embargo, ¿no existen servicios de bus sin nombre? ¿Todos los restaurantes tienen nombre?
Nodos etiquetados
La siguiente consulta devuelve todos los nodos en el actual recuadro delimitador que tengan al menos una etiqueta:
node({{bbox}})(if:count_tags() > 0);
out geom;
Esta pregunta fue planteada aquí(en).
Nodos con exactamente una etiqueta específica
El objetivo de la siguiente consulta es encontrar todos los nodos con una etiqueta específica y ninguna otra.
A partir de la versión 0.7.54 puedes usar una expresión de filtro:
node({{bbox}})[name](if:count_tags() == 1);
out geom;
Por favor, sustituye el name con cualquier etiqueta que se ajuste a tus necesidades. La desventaja de este enfoque es que no encontrarás objetos que tengan una segunda etiqueta sin sentido. Si quieres hacerlo, entonces deberías filtrar todas las etiquetas aceptables. Un ejemplo sencillo se encuentra en las sección de bloques básicos. Hay más ejemplos en el blog de desarrollo de la API de Overpass.
La pregunta original vino de esta fuente(en).
Espacios principales y secundarios en los nombres
Encuentra los valores de las etiquetas «name» con caracteres de espacio delante y detrás, o varios espacios consecutivos.
[bbox:{{bbox}}];
(
node[~"^name"~"^[[:blank:]]|[[:blank:]]$|[[:blank:]]{2,}"];
way[~"^name"~"^[[:blank:]]|[[:blank:]]$|[[:blank:]]{2,}"];
);
(._;>;);
out meta;
Recuento de farmacias por condado (actualizado a v0.7.54)
En el siguiente ejemplo devuelve el número de farmacias por condado con clave regional que comienza con «057». La salida se ofrece en formato CSV.
/*
Formato CSV: Para cargar los resultados de la consulta en LibreOffice, haz clic en
«Exportar» -> «Datos sin procesar directamente desde API de Overpass»
en Overpass turbo. Los campos están separados por tabulador.
*/
// Define los campos para la salida en formato CSV
[out:csv(::type, "de:regionalschluessel", name,
::count, ::"count:nodes", ::"count:ways", ::"count:relations")];
// Todas las áreas con clave regional (en alemán: «Regionalschlüssel») a partir del 057
area["de:regionalschluessel"~"^057"];
// Cuenta las farmacias en cada área
foreach->.regio(
// muestra los detalles de la zona actual
.regio out;
// Recopila todos los nodos, vías y relaciones con «amenity=pharmacy» en el área actual
( node(area.regio)[amenity=pharmacy];
way(area.regio)[amenity=pharmacy];
rel(area.regio)[amenity=pharmacy];);
// Cuenta los elementos en el área actual
out count;
);
A partir de la versión 0.7.54, podemos fusionar las dos líneas separadas para el área y los recuentos estadísticos en una sola línea:
[out:csv( "de:regionalschluessel", name, total, nodes, ways, relations )];
// Todas las áreas con clave regional (en alemán: «Regionalschlüssel») a partir del 057
area["de:regionalschluessel"~"^057.*"];
// Cuenta las farmacias en cada área
foreach->.regio(
// Recopila todos los nodos, vías y relaciones con «amenity=pharmacy» en el área actual
( node(area.regio)[amenity=pharmacy];
way(area.regio)[amenity=pharmacy];
rel(area.regio)[amenity=pharmacy];);
make count "de:regionalschluessel" = regio.set(t[ "de:regionalschluessel"]),
name = regio.set(t["name"]),
total = count(nodes) + count(ways) + count(relations),
nodes = count(nodes),
ways = count(ways),
relations = count(relations);
out;
);
Recuento del número de wikimedia_commons a nivel global
[out:csv(::count, ::"count:nodes", ::"count:ways", ::"count:relations")][timeout:125];
(
node["wikimedia_commons"];
way["wikimedia_commons"];
relation["wikimedia_commons"];
);
out count;
Recuento del número de addr:housenumber en un área
La siguiente consulta cuenta el número de nodos, vías y relaciones etiquetados con addr:housenumber=* en un área. Las direcciones duplicadas (es decir, varias coincidencias de una misma dirección) no se filtran. El resultado de la consulta se ofrece en formato CSV, empezando por el número total de direcciones, seguido por el número de nodos, vías y, finalmente, relaciones.
[out:csv(::count, ::"count:nodes", ::"count:ways", ::"count:relations")][timeout:25];
{{geocodeArea:Chemnitz}}->.searchArea;
(
node["addr:housenumber"](area.searchArea);
way["addr:housenumber"](area.searchArea);
relation["addr:housenumber"](area.searchArea);
);
out count;
Encontrar relaciones con idénticas etiquetas wikidata (a partir de v0.7.54)
La siguiente consulta determina todas las relaciones con etiquetas admin_level=2 y wikidata=*, donde el mismo valor wikidata
se use en varias relaciones.
Por ejemplo, la relación 1111111 está etiquetada como wikidata=Q183, que es también el caso de las relaciones 51477 y 62781.
[timeout:600];
rel[admin_level=2][wikidata]->.a;
foreach .a -> .b (
rel.a(if:t["wikidata"] == b.u(t["wikidata"]))->.d;
rel.d(if: id() == d.min(id()) && d.count(relations) > 1 );
convert rel ::id = _.u(id()),
wikidata = _.u(t["wikidata"]),
all_relation_ids = d.set( id() );
(._ ; .result; ) -> .result;
);
.result out;
Resultado:
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2017-03-29T19:04:03Z"/>
<rel id="11980">
<tag k="wikidata" v="Q142"/>
<tag k="all_relation_ids" v="11980;2202162"/>
</rel>
<rel id="36990">
<tag k="wikidata" v="Q235"/>
<tag k="all_relation_ids" v="1124039;36990"/>
</rel>
<rel id="51477">
<tag k="wikidata" v="Q183"/>
<tag k="all_relation_ids" v="1111111;51477;62781"/>
</rel>
<rel id="87565">
<tag k="wikidata" v="Q258"/>
<tag k="all_relation_ids" v="1252792;87565"/>
</rel>
</osm>
Para acelerar el procesamiento, una aproximación alternativa consiste en exportar el identificador de la relación de los campos pertinentes y valores wikidata en formato CSV y posprocesar el archivo mediante alguna secuencia de comandos de consola o similar:
[out:csv(wikidata, ::id;false;";")];
rel[admin_level][wikidata];
out;
Encontrar etiquetado divergente
Pregunta original:
Me gustaría encontrar objetos donde ciertas claves tienen el mismo valor. Las calles irlandesas normalmente tienen dos nombres, uno en irlandés y otro en inglés. En OSM tienen tres etiquetas para eso, «name», «name:en» y «name:ga». Me gustaría encontrar todos los objetos que tengan las tres etiquetas donde el nombre no coincida con «name:en» o «name:ga».
[timeout:300]
[bbox:51.08282186160976,-12.8759765625,55.986091533808384,-1.86767578125]
[out:csv(::id, ::type, name, "name:en", "name:ga")];
( node[name]["name:en"]["name:ga"](if:(t["name"] != t["name:en"]) && (t["name"] != t["name:ga"]));
way[name]["name:en"]["name:ga"] (if:(t["name"] != t["name:en"]) && (t["name"] != t["name:ga"]));
rel[name]["name:en"]["name:ga"] (if:(t["name"] != t["name:en"]) && (t["name"] != t["name:ga"]));
);
out;
La pregunta original vino de esta fuente(en)
Encontrar relaciones wikidata que tengan miembros tipo vía con idéntico wikidata
La siguiente consulta encuentra todas las relaciones wikidata en el recuadro delimitador actual, donde tanto la relación como los miembros tipo vía comparten el mismo identificador wikidata.
rel[wikidata]({{bbox}}); // obtiene todas las relaciones con etiqueta wikidata en el actual recuadro delimitador
foreach -> .rel( // procesa cada relación una por una
// determina todos los miembros donde la etiqueta wikidata coincide con la etiqueta de la relación
way[wikidata](r.rel)(if: t["wikidata"] == rel.u(t["wikidata"]))->.ways;
// Si se puede encontrar algún miembro tipo vía, imprime primero la relación actual...
rel.rel(if:ways.count(ways) > 0);
out center;
// ... seguido de todas las vías con una etiqueta wikidata coincidente
.ways out tags;
);
Multipolígonos con roles de miembro inapropiados
La siguiente consulta puede usarse para identificar todas las relaciones multipolígono en el recuadro delimitador actual donde no todos sus miembros tienen un rol «inner» o «outer».
rel({{bbox}})[type=multipolygon]->.relations;
foreach .relations -> .relation (
(
node(r.relation);
way(r.relation);
rel(r.relation);
)->.elem_all;
(
node(r.relation:"inner");
way(r.relation:"inner");
rel(r.relation:"inner");
)->.elem_inner;
(
node(r.relation:"outer");
way(r.relation:"outer");
rel(r.relation:"outer");
)->.elem_outer;
rel.relation( if:elem_all.count(nodes) > elem_inner.count(nodes) +
elem_outer.count(nodes) ||
elem_all.count(ways) > elem_inner.count(ways) +
elem_outer.count(ways) ||
elem_all.count(relations) > elem_inner.count(relations) +
elem_outer.count(relations));
out center;
);
Relaciones con solo relaciones como miembros
Las relaciones con solo relaciones como miembros no pueden consultarse fácilmente usando un cuadro delimitador. Teniendo en cuenta el ejemplo de los límites administrativos, la siguiente consulta devuelve este tipo de relaciones a escala global.
rel[boundary=administrative](if:count_members() > 0 && count_members() == count_members(relations));
out meta bb;
Geometría y topología
Recuento del número de vías y longitud
Esta consulta trata de contar las sendas que no se usan en ciudades, con tráfico designado para peatones o bicicletas, es decir, las sendas campo a través (path).
[out:csv(number,length)][maxsize:1000000000];
{{geocodeArea:Sweden}}->.searchArea;
way["highway"="path"]["foot"!~".*"]["bicycle"!~".*"]["segregated"!~".*"](area.searchArea);
make stat number=count(ways),length=sum(length());
out;
Encontrar multipolígonos con más de un miembro tipo vía exterior (a partir de v0.7.54)
Por favor, ten en cuenta que las relaciones con más de un miembro con rol «outer» son también válidas.
rel[type=multipolygon]({{bbox}});
foreach -> .a (
way(r.a:outer);
( rel.a(if:count(ways) > 1);
.result; )->.result;
);
.result out center;
Buscar intersecciones de las calles
La siguiente consulta devuelve la intersección entre la Sexta Avenida (6th Avenue) y la calle 23 Oeste (West 23rd Street) en Nueva York:
[bbox:{{bbox}}];
way[highway][name="6th Avenue"]->.w1;
way[highway][name="West 23rd Street"]->.w2;
node(w.w1)(w.w2);
out;
Suposición: ambas calles deben estar conectadas a través de un nodo común.
Nota: Si una vía está contenida tanto en .w1 como en .w2 (por ejemplo, porque se hacen coincidir nombres usando dos expresiones regulares), todos los nodos de esta vía estarán en el conjunto de resultados.
Fuente(en)
Encontrar intersecciones entre carreteras principales y secundarias:
[bbox:{{bbox}}];
way[highway~"^(motorway|trunk|primary|secondary|tertiary|(motorway|trunk|primary|secondary)_link)$"]->.major;
way[highway~"^(unclassified|residential|living_street|service)$"]->.minor;
node(w.major)(w.minor);
out;
Encontrar pistas de tenis mal trazadas
[out:xml][timeout:90][bbox:{{bbox}}];
(
node["leisure"="pitch"]["sport"="tennis"];
way["leisure"="pitch"]["sport"="tennis"](if: length() < 60);
way["leisure"="pitch"]["sport"="tennis"](if: length() > 80);
relation["leisure"="pitch"]["sport"="tennis"];
);
(._;>;);
out meta;
Situaciones complejas de etiquetado y geometría
Viales alrededor de escuelas con una velocidad máxima inapropiada (a partir de v0.7.54)
// véase: http://blattspinat.com/index.php/posts/tempo-50-vor-schulen
[out:json][timeout:800];
// Obtener todas las escuelas en el recuadro delimitador actual
( way[amenity=school]({{bbox}});
node[amenity=school]({{bbox}});
rel[amenity=school]({{bbox}});
)->.schools;
// encontrar highway=* en torno a las escuelas en un radio de 50 m, ignorando
// caminos y sendas a pie. Además, los viales son relevantes si
// (1) no tienen etiqueta alguna de límite de velocidad máxima
// (2) la etiqueta de límite de velocidad máximo indica un valor mayor de 30 km/h
way(around.schools:50)[highway][highway!~"^(footway|path)$"]
(if: (is_number(t["maxspeed"]) && t["maxspeed"] > 30) ||
!is_tag(maxspeed) )->.streets;
// obtener escuelas a una distancia de 50 m para todas las calles relevantes
( node.schools(around.streets:50);
way.schools(around.streets:50);
rel.schools(around.streets:50);
)->.matchingSchools;
// Mostrar resultados, escuelas y calles
(.matchingSchools; .streets;);
out geom;
Edificios aislados
Encontrar edificios donde el edificio más próximo se encuentre a 1 km de distancia.
way[building]({{bbox}})->.a;
foreach .a (
way.a(around:1000);
way._(if:count(ways) == 1);
out center;
);
Nota: La consulta es muy lenta, necesita el siguiente arreglo.
Bancos alejados de comisarías de policía
Encuentra bancos donde la comisaría más cercana está a más de 3 km de distancia.
[out:json][bbox:{{bbox}}][timeout:800];
// determina el conjunto de comisarías
(
node[amenity=police];
way[amenity=police];
rel[amenity=police];
)->.polices; // las coloca en el conjunto «polices»
// determina el conjunto de bancos
(
node[amenity=bank];
way[amenity=bank];
rel[amenity=bank];
)->.banks; // los coloca en el conjunto «banks»
// determina el conjunto de bancos cercanos a comisarías
(
node.banks(around.polices:3000);
way.banks(around.polices:3000);
rel.banks(around.polices:3000);
)->.banksNearPolices; // los coloca en el conjunto «banksNearPolices»
// determina los bancos alejados de las comisarías
(.banks; - .banksNearPolices;);
// devuelve los nodos, vías y relaciones como se determinó anteriormente
out geom meta;
Señales de límite de ciudad
La página Tag:traffic sign=city limit recomienda poner un nodo traffic_sign=city_limit en el vial (en lugar de en algún lugar próximo a él). La siguiente consulta identifica esos nodos independientes, excluyendo aquellos nodos que están muy cerca de un nodo «city_limit» ya mapeado correctamente.
[bbox:{{bbox}}];
node[traffic_sign=city_limit] -> .allnodes;
way[highway](bn.allnodes);
node(w)[traffic_sign=city_limit];
node(around:15)[traffic_sign=city_limit] -> .waynodesandfriends;
(.allnodes; - .waynodesandfriends;);
out;
Excursión por pubs en Dublín
Desafío: ¿Qué tan lejos se puede llegar con el próximo pub a solo 500 m de distancia?
node(3470507586); // empezar aquí...
complete(100) { nwr[amenity=pub](around:500); };
out center;
Calles de campo de golf fuera de campos de golf
Desafío: Encontrar todas las calles de un campo de golf que estén fuera de un campo de golf.
[out:json][timeout:60][bbox:{{bbox}}];
// véase https://forum.openstreetmap.org/viewtopic.php?id=70773 (en alemán)
// busca todas las vías y relaciones de campo de golf en el recuadro delimitador
wr[leisure=golf_course];
// convertir en área
map_to_area ->.golfcourse;
// calles de campo de golf dentro de campos de golf
way(area.golfcourse)[golf=fairway] -> .fairGolf;
// .fairGolf out;.fairGolf >;out geom;
// todas las calles de campo de golf
way[golf=fairway] -> .fairAll;
//.fairAll out;.fairAll >;out geom;
// diferencia de forma y salida
(way.fairAll; -way.fairGolf;);
out; > ; out geom;
Datos antiguos y usuarios
Encontrar usuarios principiantes que mapean señales de ferrocarriles
Tarea: Encuentra a todos los principiantes desconocidos en un área que han empezado a mapear señales de ferrocarril railway=signal después de un punto determinado en el tiempo. Si fuese necesario, ayúdales proporcionándoles plantillas JOSM, etc.
node
[railway=signal](newer:"2017-01-01T07:00:00Z") // ajusta la fecha como sea necesario
({{bbox}})->.newnodes;
// Introduce aquí todos los usuarios potenciales conocidos, que deben ser excluidos de la lista de resultados:
(.newnodes; - node.newnodes(user:Nakaner, "Nakaner-repair", bigbug21, mapper999);)->.newnodes;
// Output
.newnodes out meta;
Esta consulta tiene algunos defectos:
- Solo se tiene en cuenta la última modificación de la marca de tiempo de un nodo. Un mapeador no ferroviario que mueve un nodo railway=signal desencadenaría falsos positivos.
- La lista de usuarios potenciales debe ser ajustada manualmente hasta que el número de falsos positivos sea lo suficientemente pequeño.
Datos de OSM en una fecha determinada
El parámetro «date» puede usarse para recuperar los objetos OSM tal y como estaban en una fecha determinada, por ejemplo:
[date:"2014-05-06T00:00:00Z"];
( node({{bbox}}); <; >; );
out meta;
Esta consulta se puede usar para ver el famoso intento de modelado 2.5D que fue revertido bastante rápido dado que era un etiquetado para el representador.
Otro caso de uso es encontrar el identificador de objeto OSM de un objeto eliminado.
Objetos antiguos
Encuentra edificios antiguos, no modificados desde una fecha determinada.
nwr[building]({{bbox}})->.all;
(.all; - nwr.all(newer:"2020-04-01T00:00:00Z");
);
out body;
>;
out skel qt;
Confeccionar una tabla de versiones de objetos
El propósito de las declaraciones retro y timeline es iterar sobre cada versión de un objeto y hacer algo.
Como también se pueden obtener todas las versiones de un objeto de otro lugar, el propósito aquí es más bien determinar una propiedad. Esto a menudo funciona mejor si se hace una tabla de las versiones y la propiedad respectiva.
Empezamos con la versión, la fecha y el identificador del conjunto de cambios.
[out:csv(version,timestamp,changeset)];
timeline(relation,2632934);
for (t["created"])
{
retro(_.val)
{
rel(2632934);
make stat version=u(version()),timestamp=u(timestamp()),changeset=u(changeset());
out;
}
}
Somos libres de usar lo que tenga sentido dentro de las llaves interiores. En este caso, es make con tres atributos: version, timestamp y changeset. Coinciden con los títulos de las columnas tal como se declaran en el out:csv del encabezamiento. El nombre del elemento stat no importa aquí porque el formato CSV no imprime nombres de elementos.
Ahora, cada ejecución de out en el bucle for genera una línea.
En un segundo paso, añadimos un atributo adicional. La relación arriba mencionada fue objeto de escrutinio porque erróneamente tenía decenas de miles de miembros durante un corto tiempo. Podemos añadir una columna para contar los miembros.
En este ejemplo, hacemos recuento de miembros simple sin restricciones sobre roles o tipo de miembro:
[out:csv(version,timestamp,changeset,count)];
timeline(relation,2632934);
for (t["created"])
{
retro(_.val)
{
rel(2632934);
make stat version=u(version()),timestamp=u(timestamp()),changeset=u(changeset()),count=u(count_members());
out;
}
}
Exportación de datos
La exportación de datos tiene sus propios requisitos especiales. A diferencia de la simple visualización de datos, puede tener sentido tener cantidades bastante grandes de datos. Hay algunas precauciones especiales que debes tomar en ese caso para ser eficiente con los recursos del servidor público. El segundo tema específico de la exportación de datos es el formateo de la salida en algo diferente al habitual OSM XML.
Lista de calles
La siguiente consulta permite compilar una lista completa de todos los nombres de las calles de una ciudad. El ejemplo está hecho para la ciudad de Troisdorf:
[out:csv("name";false)];
area[name="Troisdorf"];
way(area)[highway][name];
out;
Esta consulta da como resultado todas las vías dentro de esta ciudad, incluyendo las vías que cruzan los límites de la ciudad. No puede evitarse, pero por suerte no ocurre tan a menudo. Los nodos de los caminos no se ofrecen como resultado.
Solo habría que eliminar los duplicados de esta lista, esto se puede hacer fácilmente con
sort liste.csv | uniq
Y se puede extraer la lista de nombres de calles.
Usando una declaración for
, también es posible ordenar la lista y eliminar los duplicados:
[out:csv("name";false)];
area[name="Troisdorf"];
way(area)[highway][name];
for (t["name"])
(
make x name=_.val;
out;
);
En muchos casos, el límite de una ciudad tiene un nombre diferente al de la propia ciudad. Esto lleva a resultados vacíos. Por ejemplo, Eckernförde requiere el sufijo «Landmasse». El problema se puede resolver de forma general usando una expresión regular
[out:csv("name";false)];
area[name~"Eckernförde"];
way(area)[highway][name];
out;
Añadir detalles de geocodificación a PDI
Pregunta original en help.openstreetmap.org:
Tengo una consulta de la API de Overpass que devuelve muchos nodos. Me gustaría saber si hay alguna forma de añadir información de geocodificación inversa al conjunto de datos resultante. Los detalles de mi caso no son tan importantes, pero solo para completar:
area[name="Česko"];
node[information="guidepost"](area);
out;
De hecho no necesito información completa de geocodificación inversa para los nodos, solo necesito relación de cierto nivel administrativo, así que si esto es posible de agregar al conjunto de resultados, sería genial.
Solución:
area[name="Česko"];
node[information="guidepost"][ele~"^2..$"](area)->.posts;
// Puedes eliminar «ele».
// Se ha añadido para experimentar con un número menor de resultados
foreach.posts(
out;
is_in;
area._[admin_level~"[46]"];
// La elección de «[46]» es arbitraria y podría ser cualquier otra cosa.
// En este caso, «admin_level=4» son condados y «admin_level=6» son ciudades,
// lo que podría ser útil.
out ids;
);
// recopila los detalles del área en el 2.º paso
.posts is_in;
area._[admin_level~"[46]"];
out;
Para evitar repetir los detalles completos del área para cada information=guidepost, la consulta usa el siguiente enfoque alternativo: para cada poste de información, solo imprimiremos el identificador OSM para el área, pero nada más. Solo hacia el final de la consulta, se devuelven los detalles completos de todas las áreas relevantes.
He aquí un breve ejemplo de cómo se ve el formato: un PDI (nodo 691566183) es seguido por dos identificadores de área (3600435511 y 3600442466), que son seguidos por otro PDI y sus respectivos identificadores de área. Para conocer los detalles del área con identificador 3600435511, simplemente consulta los detalles completos del área hacia el final de la respuesta.
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<node id="691566183" lat="49.7982193" lon="13.4686623">
<tag k="ele" v="295"/>
<tag k="information" v="guidepost"/>
<tag k="name" v="Dolanský most (pravý břeh)"/>
<tag k="tourism" v="information"/>
</node>
<area id="3600435511"/>
<area id="3600442466"/>
<node id="691566191" lat="49.8003120" lon="13.4679726">
<tag k="ele" v="295"/>
<tag k="information" v="guidepost"/>
<tag k="name" v="Dolanský most (levý břeh)"/>
<tag k="tourism" v="information"/>
</node>
<area id="3600435511"/>
<area id="3600442466"/>
[...]
<area id="3600435511">
<tag k="admin_level" v="4"/>
<tag k="boundary" v="administrative"/>
<tag k="name" v="Jihozápad"/>
<tag k="name:cs" v="Jihozápad"/>
<tag k="name:de" v="Südwesten"/>
<tag k="population" v="1209298"/>
<tag k="ref" v="CZ03"/>
<tag k="ref:NUTS" v="CZ03"/>
<tag k="source" v="cuzk:ruian"/>
<tag k="source:population" v="csu:uir-zsj"/>
<tag k="type" v="boundary"/>
<tag k="wikipedia" v="cs:NUTS Jihozápad"/>
</area>
<area id="3600442466">
<tag k="ISO3166-2" v="CZ-PL"/>
<tag k="admin_level" v="6"/>
<tag k="boundary" v="administrative"/>
<tag k="name" v="Plzeňský kraj"/>
<tag k="name:cs" v="Plzeňský kraj"/>
<tag k="name:de" v="Region Pilsen"/>
<tag k="name:ru" v="Пльзенский край"/>
<tag k="population" v="572687"/>
<tag k="ref" v="PL"/>
<tag k="ref:NUTS" v="CZ032"/>
<tag k="source" v="cuzk:ruian"/>
<tag k="source:population" v="csu:uir-zsj"/>
<tag k="type" v="boundary"/>
<tag k="wikipedia" v="cs:Plzeňský kraj"/>
</area>
Fuente(en), gracias a Roland
Añadir detalles de georreferencia a nodos de pueblos (a partir de v0.7.54)
A partir de la versión 0.7.54, también es posible generar sobre la marcha detalles de is_in
para nodos de place=village en el recuadro delimitador actual:
node({{bbox}})[place=village];
foreach(
is_in->.a;
area.a[name][boundary=administrative][admin_level~"^[2-8]$"] -> .a;
convert node ::=::,
::id = id(),
is_in=a.set("{" + t["admin_level"] + ":" + t["name"] + "}");
out;
);
Sugerencia de rendimiento: No ejecutes este tipo de consulta en más de 1000 o 10 000 objetos en el caso de overpass-api.de, ya que consume demasiados recursos.
El XML resultante incluye una nueva etiqueta is_in
que relaciona todos los boundary=administrative con «admin_level» de 2-8 y un nombre, ordenado por «admin_level» creciente:
<node id="1724711941">
<tag k="name" v="Steinklingen"/>
<tag k="place" v="village"/>
<tag k="is_in" v="{2:Deutschland};{4:Baden-Württemberg};{5:Regierungsbezirk Karlsruhe};{6:Rhein-Neckar-Kreis};{8:Weinheim}"/>
</node>
Desafortunadamente, cualquier nodo que haya sido mejorado a través de convert
no incluirá ningún detalle de la latitud ni longitud en este momento.
- Vías de edificios de iglesias en un área
Cuando se aplica esta técnica a las vías, hay que tener en cuenta que la declaración is_in
solo funciona en nodos. Por esta razón, primero tenemos que determinar todos los nodos de una vía.
[timeout:60];
area["name"="Mayenne"]->.boundaryarea;
way(area.boundaryarea)["building"="church"];
foreach(
node(w)->.n; // determina todos los nodos de una vía
.n is_in->.a;
area.a[name][boundary=administrative][admin_level~"^[2-8]$"] -> .a;
out center;
convert way ::=::,
::id = id(),
is_in=a.set("{" + t["admin_level"] + ":" + t["name"] + "}");
out;
);
Generador de tabla wiki (a partir de v0.7.54)
La siguiente consulta recurre al CSV y un poco a las características de make para crear una tabla con sintaxis wiki, que puede ser copiada y pegada en una página wiki (véase el resultado más adelante). Esto puede ser útil para evitar el procesamiento de los resultados de Overpass en la línea de comandos.
// Generador (algo pobre) de tabla wiki
[out:csv(_row;false)];
make out _row = "{|class=wikitable "; out;
make out _row = "|- "; out;
make out _row = "! Clave regional "; out;
make out _row = "! Nombre "; out;
make out _row = "! Total "; out;
make out _row = "! Nodos "; out;
make out _row = "! Vías "; out;
make out _row = "! Relaciones "; out;
// Todas las áreas con clave regional (en alemán: «Regionalschlüssel») a partir del 057
area["de:regionalschluessel"~"^05774"];
// Cuenta las farmacias en cada área
foreach->.regio(
// Recopila todos los nodos, vías y relaciones con «amenity=pharmacy» en el área actual
( node(area.regio)[amenity=pharmacy];
way(area.regio)[amenity=pharmacy];
rel(area.regio)[amenity=pharmacy];) -> .r;
make out _row = "|-"; out;
make out _row = "| " + regio.set(t[ "de:regionalschluessel"]) +
" || " + regio.set(t["name"]) +
" || " + (r.count(nodes) + r.count(ways) + r.count(relations)) +
" || " + r.count(nodes) +
" || " + r.count(ways) +
" || " + r.count(relations);
out;
);
make out _row = "|}"; out;
Resultado de la consulta (copiado en una página wiki):
Datos en bruto | Representados como página wiki | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{|class=wikitable
|-
! Clave regional
! Nombre
! Total
! Nodos
! Vías
! Relaciones
|-
| 05774 || Kreis Paderborn || 68 || 61 || 7 || 0
|-
| 057740016016 || Büren || 3 || 3 || 0 || 0
|-
| 057740036036 || Salzkotten || 5 || 5 || 0 || 0
|-
| 057740040040 || Bad Wünnenberg || 3 || 2 || 1 || 0
|-
| 057740028028 || Lichtenau || 2 || 2 || 0 || 0
|-
| 057740024024 || Hövelhof || 3 || 2 || 1 || 0
|-
| 057740020020 || Delbrück || 6 || 6 || 0 || 0
|-
| 057740008008 || Bad Lippspringe || 4 || 4 || 0 || 0
|-
| 057740032032 || Paderborn || 39 || 35 || 4 || 0
|-
| 057740012012 || Borchen || 1 || 1 || 0 || 0
|-
| 057740004004 || Altenbeken || 2 || 1 || 1 || 0
|}
|
|
Todos los datos
(
node({{bbox}});
<;
);
out meta;
ES:API de Overpass/Ejemplos avanzados#Ejemplo: La llamada al mapa más simple posible
Control de calidad
El propósito general de las consultas de control de calidad es comprobar si alguna suposición sobre los datos se mantiene universalmente. Por tanto, los temas tratados aquí son la conversión de las suposiciones en condiciones de consulta y el dominio de la funcionalidad para entender los datos.
Véase Consultas Overpass de herramientas de control de calidad para un inventario de consultas de Overpass basado en herramientas comunes de control de calidad, como Osmose, KeepRight, el validador de JOSM, OSM Lint o Atlas.
Comprobación de relaciones de límites para un etiquetado correcto
Esta consulta busca una relación de límite con boundary=administrative, admin_level=9 y de:amtlicher_gemeindeschluessel=XXXXXXXX, ya que esta combinación es inválida. Las relaciones de límite para pueblos con su propio «Gemeindeschlüssel» (clave de municipio) debería ser al menos admin_level=8 o superior.
La primera consulta también omite «boundary=administrative», ya que es igualmente posible tanto que uno haya establecido el nivel equivocado como que no haya mencionado el nivel en absoluto.
rel[admin_level=9]["de:amtlicher_gemeindeschluessel"];
out;
o
rel[boundary=administrative][admin_level=9]["de:amtlicher_gemeindeschluessel"];
out;
Encontrar miembros de relación con roles de miembro incorrectamente escritos
Esta consulta encuentra relaciones boundary=* con un rol de miembro admin_center
incorrectamente escrito (debería ser admin_centre
)
rel[boundary](if:count_by_role("admin_center") > 0);out meta;
Encontrar todas las paradas de bus que no están incluidas en una relación
Esta consulta devuelve todos los nodos de las paradas de bus que no forman parte de una relación.
// Busca paradas de bus sin relación
// Selecciona la ciudad de Bonn como área
area[name="Bonn"];
// Recopila todas las paradas de bus en Bonn y almacena el resultado en una variable .all
node(area)[highway=bus_stop]->.all;
// Selecciona todas las relaciones donde uno de los nodos en la variable .all sea miembro
rel(bn.all);
// ... y para esas relaciones encuentra todos los miembros tipo nodo relacionados
node(r)->.b;
// Calcula la diferencia de conjuntos (.b contiene todos los nodos que son miembros de una relación).
( .all; - .b; );
// Devuelve el resultado incluyendo los metadatos (necesarios para las exportaciones a JOSM).
out meta;
// Variante para líneas 9/10:
// Devuelve solo las relaciones con un etiquetado específico:
// rel[route=bus](bn.all);
(vía talk-de, gracias a Roland)
Relaciones de bus que no forman parte de una relación maestra
Pregunta original:
Necesito averiguar qué relaciones de bus (route=bus) no forman parte de una relación maestra (route_master=bus) en una zona determinada.
rel({{bbox}})[route=bus]->.all;
rel[route_master=bus](br.all);
rel[route=bus](r)->.b;
(.all; - .b; );
out;
Explicación paso a paso:
- Determina todas las relaciones en el recuadro delimitador actual con el tipo route=bus. Guarda el resultado en la variable .all
- Determina todas las relaciones padre de nuestras relaciones en .all. Esas relaciones deben ser del tipo route_master=bus.
- Basándonos en la lista de relaciones de rutas maestras, determinamos todas las relaciones hijas de tipo route=bus. Esas relaciones son todas parte de una relación maestra.
- Hace la diferencia de conjuntos entre las relaciones en la variable .all y el resultado del paso anterior 3. De esta manera, todas las relaciones que no sean parte de una relación maestra se ofrecen como resultado final de la consulta.
Fuente(en)
Comunidades sin estación de bomberos
La siguiente alternativa da como resultado todas las comunidades [admin_level=8] en Schleswig-Holstein sin amenity=fire_station. El resultado se ofrece en formato CSV y contiene los identificadores OSM de las relaciones, el «amtlichen Gemeindeschlüssel» (código oficial del municipio) y el nombre de la relación.
// Output in CSV format
[out:csv(::id, "de:amtlicher_gemeindeschluessel", name)];
area[admin_level=4]["name"="Schleswig-Holstein"][boundary=administrative]->.boundaryarea;
// Todas las áreas limítrofes con el nivel 8 en Schleswig-Holstein
rel(area.boundaryarea)[admin_level=8];
// mapea las relaciones con sus respectivas áreas
map_to_area -> .all_level_8_areas;
// Busca todas las amenity=fire_station en Schleswig-Holstein
( node(area.boundaryarea)["amenity"="fire_station"];
way(area.boundaryarea)["amenity"="fire_station"];>;);
// ¿en qué zonas limítrofes con el nivel 8 aparecen?
is_in;
area._[admin_level=8] -> .level_8_areas_with_firestation;
// Todas las áreas limítrofes de nivel 8 sin esas
// áreas con estación de bomberos
(.all_level_8_areas; - .level_8_areas_with_firestation;);
// Calcula y devuelve la relación
rel(pivot);
out geom;
Edificios atravesados por viales que no están etiquetados como túneles o cubiertos
Busca edificios atravesados por carreteras (vías) que no tengan una etiqueta «tunnel» o «covered». Dado que la consulta usa el operador «around», que busca en el entorno de un elemento, es posible que se obtengan falsos positivos, por ejemplo, cuando una calle (vía) está directamente conectada al edificio.
Por favor, ten en cuenta que esta es una consulta de ejecución muy lenta y puede resultar mejor ejecutarla para un recuadro delimitador específico.
Puede que quieras añadir también highway=path, highway=footway, highway=cycleway o highway=steps a la consulta (no son carreteras, pero presentan el mismo tipo de problema).
highway=road puede que se trate de otra cosa, pero normalmente también es una carretera y quizás quieras incluirlo.
way[!covered][!tunnel]
["highway"~"motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|service|residential|unclassified|living_street|pedestrian|track"]["access"!~"no|private"][!area]
({{bbox}});
(way(around:0)["building"~"."];
node(w););
out meta;
Encontrar nodos duplicados (a partir de v0.7.54)
Véase fuente(en).
Iteramos todos los nodos en el recuadro delimitador actual uno por uno, y descubrimos la lista de todos los nodos con el mismo valor de latitud y longitud. Suponiendo que haya más de un nodo en la misma latitud y longitud, esos dos nodos tendrán diferentes ID de nodo. Esa también es la condición que usamos para filtrar esos nodos duplicados. Los resultados solo devolverán el nodo duplicado para cada ubicación que tenga el ID de nodo más bajo.
[bbox:{{bbox}}];
node;
foreach->.a(
node(around.a:0)->.b;
node.b(if:id() == b.min(id()) && b.min(id()) != b.max(id()));
out ;
);
Desafortunadamente, esta consulta resulta muy lenta.
Encontrar nodos cercanos duplicados con la misma etiqueta
Esta consulta encuentra picos cercanos entre sí y que compartan el mismo nombre:
node["natural"="peak"]({{bbox}})->.a;
foreach.a->.elem(
node.a(around.elem:50)
(if:is_tag("name")&&t["name"]==elem.u(t["name"]));
(._; - .elem;);
out meta;
);
Enlace a Overpass turbo (con restricción de fecha para fines de demostración) Fuente(de)
Buscar vías sin etiquetar
way({{bbox}})(if:count_tags() == 0);
out geom;
Antes de la versión 0.7.54, la siguiente consulta puede ser ejecutada en Overpass turbo y los resultados exportados a JOSM para su posterior procesamiento.
(way({{bbox}}); - way({{bbox}})[~"."~"."];)->.w1;
rel(bw.w1);way(r)->.w2;
(.w1; - .w2;);
(._; >;);
out meta;
Fuente(en)
Ten en cuenta que encontrarás vías donde el etiquetado sea válido (p. ej., miembros de multipolígonos).
Alternativa: OSM Inspector tiene una capa de Etiquetado que resalta las vías sin etiquetas que aplica filtros adicionales, validador de JOSM u Osmose.
Buscar vías solo con area=yes
[timeout:200];
way({{bbox}})[area=yes](if:count_tags() == 1);
out geom;
Estas vías nunca son correctas y siempre hay que arreglarlas (a veces añadiendo etiquetas adecuadas, a veces borrándolas, a veces eliminando area=yes).
Nodos huérfanos (nodos sin etiquetas, que no forman parte de ninguna vía o relación)
La siguiente consulta busca nodos sin etiquetas en el recuadro delimitador actual, que no forman parte de ninguna vía o relación.
[bbox:{{bbox}}];
rel; > -> .r;
way; > -> .w;
(( node(if:count_tags()==0); - node.r; ); - node.w; );
out meta;
Encontrar relaciones associatedStreet rotas
Esta consulta encuentra relaciones associatedStreet corrompidas de alguna de las formas típicas, por ejemplo, las relaciones generadas por el conector JOSM «terracer», que solía crear de forma predeterminada una relación associatedStreet rota.
Nótese que la opinión en cuanto a lo que debe hacerse con dicha relación difiere entre usuarios: en Alemania, los mapeadores están de acuerdo en que dichas relaciones deben ser eliminadas por ser inútiles; en Francia, los mapeadores prefieren reparar dichas relaciones.
/* Introduce tu ciudad/región/etc. aquí */
{{nominatimArea:Berlin}}
(._; )->.area;
/* Encuentra todas las relaciones «associatedStreet» en tu área */
rel[type=associatedStreet]
[!name]
[!"addr:street"]
(area.area)->.allASRelations;
/* Encuentra relaciones «associatedStreet» con miembros tipo vía que tengan el rol «street» */
way(r.allASRelations:"street");
rel(bw:"street")[type=associatedStreet]->.relationsWithRoleStreet;
/* Encuentra todas las relaciones associatedStreet con miembros tipo vía sin rol asignado */
way(r.allASRelations:"");
rel(bw:"")[type=associatedStreet]->.relationsWithEmptyRole;
/* Encuentra todas las relaciones con miembros tipo nodo */
node(r.allASRelations);
rel(bn)[type=associatedStreet]->.relationsWithNode;
/* Comprueba si hay miembros tipo vía con el rol «house» que no tengan una etiqueta «building» */
way(r.allASRelations:"house")[!building];
rel(bn)[type=associatedStreet]->.relationsWoHouseBuilding;
/* Toma todas las relaciones «associatedStreet» y elimina todas las relaciones que queremos excluir */
( ( ( (.allASRelations; - .relationsWithRoleStreet;);
- .relationsWithEmptyRole; );
- .relationsWithNode; );
- .relationsWoHouseBuilding);
/* añade vías y nodos a la salida*/
(._; );
out meta;
Encontrar números de portal sin calle
La siguiente consulta de la API de Overpass recupera todos los nodos, vías y relaciones que tienen una etiqueta «addr:housenumber» y no «addr:street» ni «addr:place». Para esta búsqueda de datos eliminamos todos los nodos, vías y relaciones que formen parte de una relación associatedStreet con un rol «house».
Notas:
- La consulta asume que la relación associatedStreet es conforme a las directrices del wiki y contiene al menos un miembro con rol «street», de tal forma que se pueda deducir la calle. ¡La consulta no verifica este punto!
- Las relaciones associatedStreet sin rol «street» pueden buscarse con la consulta «Encontrar relaciones associatedStreet rotas». Este problema debe ser resuelto primero, ya que impediría la correcta recuperación de los números de portal.
- La etiqueta «name» en la relación es ignorada. Precaución: en la solución de User:Gehrke para #osmwa3334 se requiere una etiqueta «name» en la relación associatedStreet, pero se ignora los miembros con el rol «street».
El área de búsqueda se puede adaptar en la primera línea. Hay más detalles sobre esto en este hilo del foro(de).
area[type=boundary]["de:amtlicher_gemeindeschluessel"="08115003"]->.boundaryarea;
rel(area.boundaryarea)[type=associatedStreet]->.associatedStreet;
way(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesWay;
way(r.associatedStreet:"house")->.asHouseWay;
((.allHousesWay; - .asHouseWay;); >; );out meta;
node(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesNode;
node(r.associatedStreet:"house")->.asHouseNode;
((.allHousesNode; - .asHouseNode;););out meta;
rel(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesRel;
rel(r.associatedStreet:"house")->.asHouseRel;
((.allHousesRel; - .asHouseRel;); >>; );out meta;
Alternativamente, se puede hacer una búsqueda a través de Nominatim:
{{nominatimArea:"Regionalverband Saarbrücken"}}
(._; )->.boundaryarea;
/* Muestra el área limítrofe como una comprobación adicional - uno es libre de activar este paso */
/* rel(pivot.boundaryarea);(way(r);>;);out; */
rel(area.boundaryarea)[type=associatedStreet]->.associatedStreet;
way(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesWay;
way(r.associatedStreet:"house")->.asHouseWay;
((.allHousesWay; - .asHouseWay); >; );out meta;
node(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesNode;
node(r.associatedStreet:"house")->.asHouseNode;
((.allHousesNode; - .asHouseNode););out meta;
rel(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesRel;
rel(r.associatedStreet:"house")->.asHouseRel;
((.allHousesRel; - .asHouseRel); >>; );out meta;
Toma "addr:street", "addr:place" o "name" de associatedStreet. Si nada coincide, la calle es «nula». Ahora cuenta todos los casos (solo nodos y vías) en los que hay un número de portal, pero la calle es «nula»".
Etiquetas addr:postcode=XXXXX no coincidentes dentro de una relación de límite con código postal ≠ XXXXX
¿Cuál sería la consulta para encontrar todos los nodos y vías con un código postal diferente de la relación de límites circundante?
- Consulta para un código postal específico, p. ej., «42103»:
area[postal_code="42103"]->.a;
(node(area.a)["addr:postcode"]["addr:postcode"!="42103"];
way(area.a)["addr:postcode"]["addr:postcode"!="42103"];);
out;
Etiquetas addr:postcode=XXXXX no coincidentes dentro de múltiples relaciones de límite con código postal ≠ XXXXX (a partir de v0.7.54)
A partir de la versión 0.7.54, también es posible comprobar varios códigos postales en una sola consulta:
area[postal_code](if:number(t[postal_code])>="42103" &&
number(t[postal_code])<="42119")->.pc;
foreach.pc -> .a(
.a out;
(
node(area.a)["addr:postcode"]["addr:postcode"](if: t["addr:postcode"] != a.u(t["postal_code"]));
way(area.a) ["addr:postcode"]["addr:postcode"](if: t["addr:postcode"] != a.u(t["postal_code"]));
);
out geom;
);
La versión amigable de Overpass turbo determina primero todas las relaciones de límites del código postal en el recuadro delimitador y comprueba si hay desviaciones en los nodos y vías, comparando el código postal con la etiqueta addr:postcode.
[bbox:{{bbox}}];
rel[boundary=postal_code][postal_code];
map_to_area;
foreach -> .a(
(
node(area.a)["addr:postcode"](if:t["addr:postcode"] != a.u(t["postal_code"]));
way (area.a)["addr:postcode"](if:t["addr:postcode"] != a.u(t["postal_code"]));
// rel(area.a)["addr:postcode"](if:t["addr:postcode"] != a.u(t["postal_code"]));
);
out geom;
);
Anteriormente, esto requería una secuencia de código para los códigos postales 42103 - 42119
typeset -i i="42103"
while [[ $i -le 42119 ]]; do
{
wget -O false_$i.osm "http://overpass-api.de/api/interpreter?data=area[postal_code=\"$i\"]->.a;(node(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];way(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];>;);out;";
i=$((i++));
};
done
Cuando se reemplaza «out;» con «out meta;», es posible leer los datos del archivo "false_XXXXX.osm" en JOSM para editarlos.
La consulta se vuelve notablemente más rápida con un recuadro delimitador adecuado:
typeset -i i="42103"
while [[ $i -le 42119 ]]; do
{
wget -O false_$i.osm "http://overpass-api.de/api/interpreter?data=area[postal_code=\"$i\"]->.a;(node(51,7,51.5,7.5)(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];way(51,7,51.5,7.5)(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];>;);out meta;";
i=$((i++));
};
done
Vías que son parte de una «Bundesstraßenrelation», pero no tienen etiqueta «ref»
Bundesstraßenrelation o red de carreteras nacionales (en español)
Normalmente, se esperaría que las propiedades de una relación se aplicaran también a sus miembros tipo vía, de modo que no sea necesario poner esas etiquetas explícitamente en las vías. Sin embargo, resulta que la práctica común es colocar la etiqueta «ref» también en cada vía. Esta consulta muestra todas las vías que no tienen la etiqueta de «ref».
rel({{bbox}})[type=route][route=road][ref~"^B."];
way(r)[!ref];
(._;>;);
out meta;
También es posible que la vía tenga una etiqueta «ref» pero no pertenezca a una relación.
area[name="Saarland"][type=boundary]->.a;
(
way(area.a)[highway][ref~"^B.*"]; -
(rel(area.a)[ref~"^B.*"][route=road][type=route];>;);
);
(._;>;);out;
Para una zona seleccionada (en el ejemplo, Sarre o Saarland), la consulta recupera todas las vías cuya etiqueta comienza con una «B». De esta colección, eliminamos todos las vías que forman parte de una relación tipo ruta con «route=road» y que tenga una etiqueta «ref» que comience con «B». Las calles federales restantes (el ejemplo es en Alemania), que no sean parte de una relación, son devueltas junto con sus nodos, para mostrarlas en un mapa.
PDI con sitios web pero con horarios de apertura incorrectos
La siguiente consulta devuelve las instituciones y establecimientos para los cuales se ha etiquetado un sitio web pero cuyos horarios de apertura son incorrectos (es decir, la sintaxis es incorrecta). Se debe intentar primero la primera consulta, porque es más probable que devuelva resultados para los que se pueden encontrar los horarios de apertura en el sitio web. Cuando el resultado de la primera consulta esté vacío, se podría intentar la segunda.
Primera consulta, Segunda consulta
Objetos con horarios de apertura y de recogida obsoletos o ausentes (para buzones de correo)
La consulta siguiente se puede adaptar para destacar los objetos con horarios de apertura y de recogida obsoletos o ausentes (para los buzones). Puedes usarla para preparar un mapa con los lugares que se visitarán con un grupo de mapeadores.
/* carga todos los nodos, vías y relaciones con open_hours establecidos que sean distintos de 24/7 y los almacena */
nwr[opening_hours][opening_hours!="24/7"]({{bbox}})->.oh_all;
/* elimina las entradas más recientes del resultado anterior y lo almacena de nuevo */
(.oh_all; - nwr.oh_all(newer:"2019-04-01T00:00:00Z");)->.oh_old;
/* hace algo similar a lo anterior con collection_times */
nwr[collection_times]({{bbox}})->.ct_all;
(.ct_all; - nwr.ct_all(newer:"2019-04-01T00:00:00Z");)->.ct_old;
/* unifica los resultados anteriores con otras consultas y los almacena */
(
.oh_old;
.ct_old;
/* busca servicios o equipamientos sin horario de apertura y que no sean privados (servicios exentos que normalmente no tienen un horario de apertura público) */
nwr[amenity][!"opening_hours"]["access"!="private"]["amenity"!~"waste_disposal|waste_basket|bench|vending_machine|post_box|fountain|kindergarten|parking_entrance|bus_station|shelter|drinking_water|watering_place|school|college|university|bicycle_parking|bbq|fire_station|hunting_stand|doctors|dentist|clock"]({{bbox}});
/* comercios sin horario de apertura */
nwr[shop][!"opening_hours"]({{bbox}});
/* buzones de correo sin horario de recogida */
nwr["amenity"="post_box"][!"collection_times"]({{bbox}});
);
out center meta qt;
Algunas debilidades conocidas:
- La decisión de si un horario de apertura (u horario de recogida) está desactualizado se hace en base a la fecha cuando cualquier etiqueta del objeto ha sido cambiada: es decir, un objeto puede aparecer como no desactualizado aunque la etiqueta «open_hours=*» fuese creada hace mucho tiempo.
- La fecha para considerar los objetos como obsoletos se codifica en forma fija y se usa en varios lugares de la consulta.
- Algunos servicios y equipamientos no suelen tener horarios de apertura (ya que están abiertos 24/7, por ejemplo, los bancos para sentarse). La consulta contiene una lista (negra) de tales valores y nunca los reportará. Ciertamente, hay otras (raras) etiquetas «amenity=*» tags que no están incluidas (todavía).
Edificios que son más altos que anchos
La siguiente consulta trata de encontrar cualquier edificio en Cincinnati, Ohio y alrededores del condado de Hamilton que sea más alto que ancho. Overpass QL carece de un evaluador que evalúe al área de una vía cerrada; solo tiene un evaluador para la longitud de una vía, o el perímetro en el caso de una vía cerrada. Así que esta consulta encuentra el ancho promedio de una de las fachadas del edificio basándose en el perímetro y lo compara con la altura del mismo. Por simplicidad, solo considera edificios rectangulares. Una consulta más sofisticada podría inspeccionar edificios con más vértices al mismo tiempo que divide el perímetro por los vértices en ángulos aproximadamente rectos.
Esta consulta encuentra mucho más que rascacielos y edificios altos. Una importación de datos del gobierno sobre edificaciones en el condado incluyó el número de plantas de muchos edificios, pero la fuente de datos tenía un recuento de plantas incorrecto para muchos edificios pequeños. Por ejemplo, es raro que un cobertizo de herramientas o un garaje en el patio trasero tenga más de un nivel, pero muchos de estos edificios están etiquetados como si tuviesen más de un nivel.
En otros lugares, los edificios extremadamente altos debido a errores tipográficos han despertado la jocosidad de los usuarios finales y los medios de comunicación. [1][2][3] Esta consulta detectaría fácilmente tales errores, aunque una consulta más simple para números anormalmente grandes probablemente funcionaría mejor.
[out:json][timeout:25];
// La mayoría de edificios en el condado de Hamilton, Ohio, fueron importados de CAGIS, que asignó un número de plantas cuestionable a los edificios pequeños en muchos casos
{{geocodeArea:Hamilton County, Ohio, United States}}->.hamco;
// Encuentra edificios rectangulares que son más altos que anchos
(
// Compara la altura con la longitud media de un lado
way["building"]["height"](area.hamco)(if:
count_members() < 6 && is_closed() &&
number(t["height"]) > length() / 4);
// Se asume que una planta tiene 3 m de alto
way["building"]["building:levels"](area.hamco)(if:
count_members() < 6 && is_closed() &&
number(t["building:levels"]) * 3 > length() / 4);
);
// Imprime los resultados
out body;
>;
out skel qt;
Destacar objetos con un «check_date» anterior a X
El ejemplo anterior usaba una fecha codificada en forma fija y buscaba el momento en que un objeto fue editado por última vez. Si una etiqueta 'check_date' está presente, también se puede buscar por ella.
Esta consulta usa la función 'convertir' de Overpass para añadir etiquetas personalizadas en los objetos que son más antiguos que una fecha determinada. Estas etiquetas pueden ser usadas en un MapCSS para resaltar ciertas antigüedades de ediciones. Por favor, ten en cuenta que la salida de esta consulta solo puede ser usada en Overpass Turbo - las etiquetas añadidas hacen que el formato no sea estándar y que los datos no puedan ser cargados, por ejemplo, en JOSM.
Nota: El código fuente mostrado está abreviado para una verificación de antigüedad y para usar solo nodos. Véase este enlace para la versión completa
[out:json][timeout:25];
nwr({{bbox}})[check_date]->.temp;
.temp out body;
.temp >;
out skel;
node.temp;
convert node
::id=id(),
older365=date(t["check_date"])<date("{{date:365days}}")
;
out;
{{style:
node[older365=1]{
color: yellow;
}
}}
//[...]
Bloques básicos
Estos son ejemplos que no están directamente relacionados con las aplicaciones, sino que más bien complementan con ejemplos a las especificaciones del lenguaje.
Buscar objetos con una determinada etiqueta A pero sin una etiqueta B
Ejemplo: encontrar todos los nodos, vías y áreas que están etiquetados con «addr:city», pero no tienen «addr:postcode». Este ejemplo hace uso del filtro existe y del filtro no existe.
[out:json][timeout:25];
(
node["addr:street"][!"addr:postcode"]({{bbox}});
way["addr:street"][!"addr:postcode"]({{bbox}});
);
out skel;
Encontrar nodos/vías con un rol determinado en una relación
Encontrar todos los nodos con el rol «label» y «admin_centre» en el recuadro delimitador actual:
rel({{bbox}})->.relations;
( node(r.relations:"label");
node(r.relations:"admin_centre");
);
out;
Encontrar todas las vías «inner», es decir, vías miembro de una relación con el rol 'inner':
rel({{bbox}});(way(r:"inner");>;);out;
Encontrar todos los nodos y vías con el rol «via»:
rel({{bbox}})->.relations;
(
node(r.relations:"via");
way(r.relations:"via");>;
);out;
Suma de unas pocas áreas definidas de OSM
Esta consulta se modifica fácilmente para obtener una suma de cualquier área definida por OSM (geocodeArea) y extraer cualquier dato para esta suma de áreas. Véase comentarios para más detalles. El ejemplo solo muestra las áreas elegidas.
[out:json][timeout:900];
// Introduce algunas áreas en .myArea
// Puedes añadir o eliminar un área simplemente
// añadiendo o eliminando una línea aquí.
(
{{geocodeArea:"Warszawa"}};
{{geocodeArea:"Grodzisk Mazowiecki County"}}; // «name:en» se puede usar al igual que «name»
{{geocodeArea:"powiat pruszkowski"}};
{{geocodeArea:"powiat żyrardowski"}};
{{geocodeArea:"powiat warszawski zachodni"}};
{{geocodeArea:"powiat sochaczewski"}};
{{geocodeArea:"powiat nowodworski"}};
{{geocodeArea:"powiat legionowski"}};
{{geocodeArea:"powiat wołomiński"}};
{{geocodeArea:"powiat miński"}};
{{geocodeArea:"powiat otwocki"}};
{{geocodeArea:"powiat piaseczyński"}};
)->.myArea;
// muestra .myArea. Esto puede ser reemplazado por
// cualquier consulta de objetos en .myArea
rel(pivot.myArea);
// imprime los resultados
out geom;
{{style:
node{opacity:0;fill-opacity:0}
}}
«n» vías adyacentes
El siguiente ejemplo ilustra cómo determinar cinco vías adyacentes para la vía OSM 111435507. La declaración around con radio 0 se usa en esta consulta no solo para filtrar las vías directamente conectadas, sino también para encontrar vías que se cruzan (sin un nodo común). Posiblemente esas vías que se cruzan necesiten ser filtradas en un paso adicional de posprocesamiento.
(
way(111435507);
complete(4) {
way(around:0)[highway~"."][highway!~"path|track|cycleway|footway"];
};
);
out geom;
Para limitar el volumen total de datos, solo se consideran las vías con una etiqueta «highway» excluyendo los valores «path», «cycleway» y «footpath».
Buscar nodos que pertenezcan a dos vías diferentes
¿Cómo encontrar nodos que pertenezcan a dos vías diferentes con ciertas etiquetas?
Ejemplos:
Devuelve nodos que son parte de un edificio:
way["building"="yes"]({{bbox}});
node(w);
Devuelve nodos de carreteras terciarias:
way["highway"="tertiary"]({{bbox}});
node(w);
¿Cómo se puede combinar esas dos consultas para que se cumplan ambas condiciones?
way["building"="yes"]({{bbox}});
node(w)->.b;
way["highway"="tertiary"]({{bbox}});
node(w)->.t;
node.b.t; // calcula el conjunto intersección de ambas variables .b y .t
out;
Si las vías no pueden dividirse en dos grupos distintos (por ejemplo, vías de edificios frente a vías de carreteras terciarias), es necesario iterar sobre cada una de las vías y determinar los nodos de intersección con todas las demás vías de un recuadro delimitador:
way({{bbox}})->.allways;
foreach .allways -> .currentway(
(.allways; - .currentway;)->.allotherways;
node(w.currentway)->.e;
node(w.allotherways)->.f;
node.e.f;
(._ ; .result;) -> .result;
);
.result out meta;
Buscar nodos que pertenezcan a un número exacto de vías (a partir de v0.7.54)
Para averiguar todos los nodos que pertenecen a un número exacto de vías (en lugar de solo a más de una vía como en el ejemplo anterior), se puede emplear la siguiente aproximación:
Averigua todos los nodos que pertenecen exactamente a 3 vías distintas:
way({{bbox}})->.a;
foreach .a -> .b(
(.a; - .b;)->.c;
node(w.c)->.e;
node(w.b)->.f;
node.e.f->.f1;
foreach .f1 -> .g(
way(bn.g);
way._(if:count(ways) == 3);
node.g(w);
(._ ; .result;) -> .result;
);
);
.result out meta;
Advertencia: Desafortunadamente, esta consulta es extremadamente lenta.
Recuperar el historial completo del objeto (a partir de v0.7.55)
El siguiente ejemplo de consulta devuelve todas las versiones de una vía determinada.
timeline(way,561040198);
foreach(
retro(u(t["created"]))
(
way(561040198);
out meta geom;
);
);
Nota: El historial de los objetos no incluye las versiones de los objetos que no sean parte del primer planet con licencia ODbL o de cualquier otro diff posterior (fecha límite: septiembre 2012).
Limitar resultados solo a áreas
El siguiente ejemplo de consulta devuelve una etiqueta específica (man_made=pier, en este ejemplo), pero limitado a vías cerradas y relaciones multipoligonales. Los nodos, vías no cerradas y otras relaciones no se ofrecen como resultado.
Ejemplo ejecutado en Cracovia - ya que es uno de los lugares donde los muelles están mapeados como vías y como áreas.
[out:json][timeout:25];
{{geocodeArea:Kraków}}->.searchArea;
(
way["man_made"="pier"](if: is_closed()==1)(area.searchArea);
relation["man_made"="pier"]["type"="multipolygon"](area.searchArea);
);
out body;
>;
out skel qt;
Ejemplos para estilos en Overpass turbo (MapCSS)
Rutas de senderismo
La siguiente consulta de Overpass turbo muestra todas las relaciones de senderismo en el recuadro delimitador actual («route=hiking» y «network=?wn»), como en el estilo de Lonvia. El color de los senderos se toma de la relación.
[bbox:{{bbox}}];
(
relation[route=hiking][network~"^.wn$"];
way(r);
>;
);
out;
{{style:
way
{ color:green; fill-color:green; }
relation[network=lwn] way
{ color:blue; fill-color:cyan; }
relation[network=iwn] way
{ color:red; fill-color:red; }
relation[network=nwn] way
{ color:green; fill-color:green; }
relation[network=rwn] way
{ color:yellow; fill-color:yellow; }
}}
Es posible que esto no sea 100% correcto. Por favor, prueba y adapta la consulta cuando sea necesario (recibido vía osm-dev, MapCSS fue corregido, consulta simplificada).
Cuadros de texto con evaluación
El siguiente estilo de MapCSS muestra todos los pueblos en el recuadro delimitador actual con un cuadro de texto combinado alemán/bajo sorabo.
[bbox:{{bbox}}];
node[place=village];
out;
{{style:
node{
text: eval('tag("name:de") . " - " . tag("name:dsb")');
}
}}
Buzones de correo
Este tema puede ser analizado con las siguientes consultas.
Buzones, coloreados según la disponibilidad de la etiqueta de tiempo de recogida
node[amenity=post_box]
//[!"collection_times"]
({{bbox}});
out;
{{style:
node
{ color:red; fill-color: red;}
node[collection_times]
{ color:green; fill-color:green; }
}}
Alternativa que también comprueba la sintaxis del tiempo de recogida
Enlace a Overpass turbo - válido para 2018
node[amenity=post_box] ({{bbox}});
out;
{{style:
node{
color: #ffffff;
fill-color: #ff0000;
fill-opacity: 0.8;
}
node[operator]{
color: #0000ff;
fill-color: #ff0000;
fill-opacity: 0.8;
}
node[collection_times:lastcheck],
node[last_check],
node[check_date],
node[last_checked],
node[lastcheck]{
color: #ffff00;
fill-color: #ffff00;
fill-opacity: 0.8;
}
node[collection_times:lastcheck][operator],
node[check_date][operator],
node[last_check][operator],
node[last_checked][operator],
node[lastcheck][operator] {
color: #0000ff;
fill-color: #ffff00;
fill-opacity: 0.8;
}
node[collection_times:lastcheck=~/2017-*./],
node[check_date=~/2017-*./],
node[last_check=~/2017-*./],
node[last_checked=~/2017-*./],
node[lastcheck=~/2017-*./]{
color: #ffff00;
fill-color: #00ff00;
fill-opacity: 0.8;
}
node[collection_times:lastcheck=~/2017-*./][operator],
node[check_date=~/2017-*./][operator],
node[last_check=~/2017-*./][operator],
node[last_checked=~/2017-*./][operator],
node[lastcheck=~/2017-*./][operator]{
color: #0000ff;
fill-color: #00ff00;
fill-opacity: 0.8;
}
node[collection_times:lastcheck=~/2016-*./],
node[check_date=~/2016-*./],
node[last_check=~/2016-*./],
node[last_checked=~/2016-*./],
node[lastcheck=~/2016-*./]{
color: #ffff00;
fill-color: #55aa00;
fill-opacity: 0.8;
}
node[collection_times:lastcheck=~/2016-*. /][operator],
node[check_date=~/2016-*./][operator],
node[last_check=~/2016-*./][operator],
node[last_checked=~/2016-*./][operator],
node[lastcheck=~/2016-*./][operator]{
color: #0000ff;
fill-color: #55aa00;
fill-opacity: 0.8;
}
node[collection_times:lastcheck=~/2015-*./],
node[check_date=~/2015-*./],
node[last_check=~/2015-*./],
node[last_checked=~/2015-*./],
node[lastcheck=~/2015-*./]{
color: #ffff00;
fill-color: #aa5500;
fill-opacity: 0.8;
}
node[collection_times:lastcheck=~/2015-*./][operator],
node[check_date=~/2015-*./][operator],
node[last_check=~/2015-*./][operator],
node[last_checked=~/2015-*./][operator],
node[lastcheck=~/2015-*./][operator]{
color: #0000ff;
fill-color: #aa5500;
fill-opacity: 0.8;
}
}}
Recursividad más compleja
Ejemplo: La llamada al mapa más simple posible
Esta llamada incluye todos los nodos del recuadro delimitador, todas las vías que tengan tales nodos como miembros y todas las relaciones que tengan tales nodos y tales vías como miembros. Por favor, observa que no todas las vías o relaciones devueltas se muestran en OpenLayers debido a que OpenLayers requiere que todos los nodos de una vía o miembros de una relación estén presentes.
(
node(50.746,7.154,50.748,7.157);
<;
);
out meta;
|
Mostrar resultado: (OpenLayers no se muestra), JSON, XML.
El operador «<» hace aquí toda la resolución inversa requerida de los vínculos de pertenencia de las vías y relaciones. También se podría dividir esto en una recursividad paso a paso hacia atrás:
- En primer lugar, obtén todas las relaciones que se vinculan a los nodos recién encontrados: rel(bn);
- Luego, obtén los vínculos con los nodos que acabas de encontrar: way(bn);
- Finalmente, obtén todas las relaciones vinculadas a las vías recién encontradas: rel(bw);
Para completar la lista de la resolución de membresía inversa, rel(br); encontraría las relaciones que tienen como miembros las relaciones recién encontradas.
(
node(50.746,7.154,50.748,7.157);
rel(bn)->.x;
way(bn);
rel(bw);
);
out meta;
|
Mostrar resultado: (OpenLayers no se muestra), JSON, XML.
Vías completadas, pero no relaciones
Esta llamada incluye todos los nodos del recuadro delimitador, todos las vías del recuadro delimitador, todos los nodos miembros de estas vías que estén o no dentro del recuadro delimitador, y todas las relaciones que tengan tales nodos o tales vías como miembros. Por el momento, la llamada de vía con un recuadro delimitador hace que la consulta sea a veces lenta. Por favor, sé paciente mientras los desarrolladores trabajan en mejorar el tiempo de consulta. Observa además que no todas las relaciones devueltas se muestran en OpenLayers debido a que OpenLayers requiere que todos los nodos de una vía estén presentes.
(
node(50.746,7.154,50.748,7.157);
rel(bn)->.x;
way(50.746,7.154,50.748,7.157);
node(w)->.x;
rel(bw);
);
out meta;
|
Mostrar resultado: Mapa de OpenLayers, JSON, XML.
Vías y relaciones completadas
Esta llamada incluye todos los nodos del recuadro delimitador, todas las vías que se refieren a cualquiera de esos nodos, todos los nodos miembros de estas vías estén o no dentro del recuadro delimitador, todas las relaciones que tengan tales nodos o tales vías como miembro, y su nodo y vía miembro, e incluso los nodos de estas vías. Ten en cuenta que debido a las relaciones involucradas, se incluyen objetos que se pueden encuentran eventualmente bastante lejos del recuadro delimitador.
(
node(50.746,7.154,50.748,7.157);
<;
>;
);
out meta;
|
Mostrar resultado: Mapa de OpenLayers, JSON, XML.
Aquí «<» hace la resolución de membresía hacia atrás y «>» hace la resolución de membresía hacia adelante. En particular, «>» recoge para todas las relaciones recién encontradas sus nodos miembros, sus vías miembros, y los nodos miembros de estas vías miembros. Esto también puede ser dividido en sus bloques básicos:
- «node(w)» recoge los nodos que son miembros de las vías recién encontradas
- «node(r)» hace lo mismo con las relaciones recién encontradas
- «way(r)» recoge las vías que son miembros de las relaciones recién encontradas
La declaración rel(r) recoge las relaciones que son miembros de las relaciones recién encontradas, pero no se invoca aquí. Ahora, la misma consulta que antes de una manera más gradual:
(
node(50.746,7.154,50.748,7.157);
rel(bn)->.x;
way(bn);
rel(bw);
);
(
._;
way(r);
);
(
._;
node(r)->.x;
node(w);
);
out meta;
|
Mostrar resultado: Mapa de OpenLayers, JSON, XML.
También las relaciones en las relaciones
Esta llamada incluye además todas las relaciones en las relaciones que después de cinco pasos de descenso llegan a los miembros en el recuadro delimitador. Sus miembros no se incluyen deliberadamente porque eso podría dar como resultado una parte significativa de todos los datos del mapa de Alemania; es decir, varios cientos de megabytes de datos. Obsérvese también que cinco niveles de descenso suelen ser más que suficientes para obtener todos los vínculos de retroceso. Si dudas de tener todos los vínculos de retroceso, solo tienes que añadir otra declaración rel(br); y ver si se devuelven más datos.
(
node(50.746,7.154,50.748,7.157);
rel(bn)->.x;
way(bn);
rel(bw);
);
(
._;
way(r);
);
(
._;
node(r)->.x;
node(w);
);
(
._;
rel(br);
rel(br);
rel(br);
rel(br);
);
out meta;
|
Mostrar resultado: Mapa de OpenLayers, JSON, XML.
Consultas sobre el estado del servidor
Si estás alojando un servidor de la API de Overpass, puede ser útil consultarlo para comprobar su estado.
Última actualización de los datos
Cada consulta devuelve una marca de tiempo 'osm_base' que te informa de la última vez que se actualizaron los datos (véase esta pregunta (en) en el Foro de Ayuda de OSM para más detalles). En XML sería `<meta osm_base="2020-07-01T11:54:03Z"/>` y en JSON aparece bajo 'osm3s.timestamp_osm_base'. Puedes hacer cualquier consulta para recuperar esta fecha, usa `out count;` para minimizar la cantidad de datos devueltos al no incluir ningún nodo.
(
node(50.746,7.154,50.748,7.157);
<;
);
out count;
|
Véase también
Enlaces internos
- User:Binnette/OverpassQueries (en): algunas consultas para Francia, Europa y desafíos de MapRoulette.
- User:M!dgard/Overpass queries (en): algunas consultas para Bélgica y para comprobación de errores de etiquetado.
- Cómo conseguir mapas con contenido especial con Overpass Turbo (PDF) (en)
- Ejemplos de Overpass QL frente a SPARQL
- User:EinKonstanzer/overpass (de): algunas consultas para bancos, escuelas, Düsseldorf... Versión traducida
- Ejemplos de Overpass (PDF) (it)
- Peticiones para Overpass Turbo (PDF (fr))
Enlaces externos
- Ejemplos de la API de Overpass, versión 0.7.56 (en)
- Bucle y grupo en el blog de desarrollo de la API de Overpass (en)
- Una colección de consultas útiles para la API de Overpass de OSM (en)