En mi trabajo, a menudo encuentro la tarea de exportar datos desde OpenStreetMap. OSM es una fuente de datos sorprendente desde donde puede obtener al menos vistas , al menos áreas de la ciudad , al menos calles para estudios de accesibilidad de peatones y, en general, cualquier cosa.
Ese es solo el proceso de trabajar con ellos en algún momento comenzó a aburrirme. Para recuperar datos de alguna solicitud no trivial, debe estudiar el lenguaje de solicitud Overpass o escribir scripts y hurgar en el formato XML de OSM.
Llevando a cabo estas manipulaciones por centésima vez, pensé en crear una herramienta más simple y conveniente. Y ahora está listo: https://yourmaps.io , el editor visual de descripciones de exportación de OpenStreetMap. En el editor, puede pasar el mouse sobre un gráfico, cada uno de los cuales representará una operación o filtro en una secuencia de objetos OSM, y luego descargará el resultado en GeoJSON.
Aquí hay un ejemplo de un gráfico que selecciona todas las escuelas dentro de un distrito municipal determinado y luego construye zonas de influencia de 300 metros a su alrededor:

Como resultado del trabajo, obtenemos un conjunto de polígonos en formato GeoJSON, que luego se pueden importar a QGIS o algún otro software.
— , Rete.js, -.
Rete.js
Rete.js — JS , . , .
, Rete . OpenStreetMap — .

(node), (component). , ( ). data, (, , )
Rete . : , ( ) .
, , , , - .
— , , ( ). , - , - jquery 220, . , .

InputControl Rete, .
var SelectComponent = {
template: '<select></select>',
data() {
return {
value: ""
};
},
methods: {
update() {
this.putData(this.ikey, $(this.root).val())
}
},
mounted() {
let jqueryRoot = $(this.root)
for (let idx = 0; idx < this.values.length; ++idx) {
let v = this.values[idx]
jqueryRoot.append($("<option></option>")
.attr("value", v[0])
.text(v[1]));
}
let currentVal = this.getData(this.ikey)
if (currentVal === undefined) {
currentVal = this.defaultValue
this.putData(this.ikey, this.defaultValue)
}
jqueryRoot.val(currentVal);
const _self = this;
jqueryRoot.change(function() {
_self.root.update()
})
}
}
class SelectControl extends Rete.Control {
constructor(emitter, key, values, defaultValue) {
super(key);
this.key = key;
this.component = SelectComponent
this.props = { emitter, ikey: key, values: values, defaultValue: defaultValue};
}
}
,var AddTextFieldComponent = {
template: '<button type="button" class="btn btn-outline-light">' +
'<i class="fa fa-plus-circle"></i> Add Value</button>',
data() {
return {
value: ""
};
},
methods: {
getCount(node, prefix) {
let count = 0;
node.controls.forEach((value, key, map) => {
if (key.startsWith(prefix) && value instanceof InputControl) {
++count;
}
});
return count;
},
update(e) {
let count = this.methods.getCount(this.node, this.prefix)
this.node.addControl(new InputControl(this.editor, this.prefix + count))
this.node.update()
this.emitter.view.updateConnections(this)
this.putData(this.iKey, count + 1)
}
},
mounted() {
const _self = this;
this.root.onclick = function(event) {
_self.root.update()
}
}
};
class AddTextFieldControl extends Rete.Control {
constructor(emitter, key, prefix, node, inputPlaceholder) {
super(key);
this.key = key;
this.component = AddTextFieldComponent
this.props = { emitter, iKey: key, prefix: prefix, node: node, inputPlaceholder: inputPlaceholder};
}
}
class FilterByTagValueComponent extends Rete.Component {
constructor(){
super("Filter_by_Tag_Value");
}
builder(node) {
var input = new Rete.Input('osm',"Map Data", osmSocket);
var output = new Rete.Output('osm', "Filtered Map Data", osmSocket);
var tagNameInput = new InputControl(this.editor, 'tag_name')
var modeControl = new SelectControl(this.editor,
"mode",
[["EQUAL", "=="], ["NOT_EQUAL", "!="], ["GREATER", ">"], ["LESS", "<"], ["GE", ">="], ["LE", ">="]],
"EQUAL")
node.addInput(input)
.addControl(tagNameInput)
.addControl(modeControl)
.addControl(new AddTextFieldControl(this.editor, "tag_valueCount", "tag_value", node, "Tag Value"))
let valuesCount = 1;
if (node.data.tag_valueCount !== undefined) {
valuesCount = node.data.tag_valueCount
}
node.addControl(new InputControl(this.editor, 'tag_value'))
for (let i = 1; i < valuesCount; ++i) {
node.addControl(new InputControl(this.editor, 'tag_value' + i))
}
return node
.addOutput(output);
}
}
:

.
, JSON ( Rete ), , .
OSM
, .
: ( leisure=park, OSM):

— , OSM , , . ( ( Java) — ), , , .
, :

: 500- :

, amenity=school, ( — ), .
, . - .
, , ? : ( ), , , Union. :

… . -, — , .. . , amenity=school , , . , .

, , - . :

. . — 4, 3. .
. .. - -, .
:

Rete.js YourMaps .
En el futuro planeo agregar aún más allí, por ejemplo, la capacidad de descargar datos no solo de OSM, sino también de mis archivos GeoJSON, más tipos de operaciones y filtros, etc.
Este servicio me ayuda personalmente personalmente. Por ejemplo, cuando un estudiante necesita mostrar rápidamente algo en el mapa OSM, ya no necesito ejecutar QGIS y recordar el complejo lenguaje de consulta Overpass, hago clic en el gráfico deseado con un par de movimientos del mouse, se procesa en unos segundos y puede ver inmediatamente el resultado.
Espero que sea útil para algunos de ustedes. Como siempre, estoy listo para escuchar sugerencias y deseos, ya sea aquí en los comentarios, o puede enviarlo a evsmirnov@itmo.ru