Exportieren Sie OpenStreetMap-Daten mit dem visuellen Editor auf rete.js.

Bei meiner Arbeit habe ich häufig die Aufgabe, Daten aus OpenStreetMap zu exportieren. OSM ist eine erstaunliche Datenquelle, von der aus Sie mindestens Sehenswürdigkeiten , zumindest Bereiche der Stadt , mindestens Straßen für Studien zur Erreichbarkeit von Fußgängern und im Allgemeinen alles erhalten können.


Das ist nur der Prozess der Arbeit mit ihnen, der mich irgendwann zu langweilen begann. Um Daten für eine nicht triviale Anforderung abzurufen, müssen Sie entweder die Überführungsanforderungssprache studieren oder Skripte schreiben und im OSM-XML-Format herumstöbern.


Als ich diese Manipulationen zum hundertsten Mal durchführte, dachte ich darüber nach, ein einfacheres und bequemeres Werkzeug zu entwickeln. Und jetzt ist er bereit - https://yourmaps.io , der visuelle Editor für Exportbeschreibungen von OpenStreetMap. Im Editor können Sie mit der Maus über ein Diagramm fahren, von dem jeder Knoten eine Operation oder einen Filter für einen Stream von OSM-Objekten darstellt, und dann das Ergebnis in GeoJSON herunterladen.


Hier ist ein Beispiel eines Diagramms, in dem alle Schulen in einem bestimmten Stadtbezirk ausgewählt und anschließend 300-Meter-Puffer um sie herum erstellt werden:



Als Ergebnis der Arbeit erhalten wir einen solchen Satz von Polygonen im GeoJSON-Format, die dann in QGIS oder eine andere Software importiert werden können.


— , Rete.js, -.


Rete.js


Rete.js — JS , . , .


, Rete . OpenStreetMap — .


Bild


(node), (component). , ( ). data, (, , )


Rete . : , ( ) .


, , , , - .


— , , ( ). , - , - jquery 220, . , .



InputControl Rete, .


var SelectComponent = {
    //  -  HTML ,       ,        this.root   
    template: '<select></select>',
    data() {
        return {
            value: ""
        };
    },
    methods: {
        update() {
            //        
            this.putData(this.ikey, $(this.root).val())
        }
    },
    //         
    mounted() {
        // this.root -  html ,    template, .. select   
        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;
        //          data
        jqueryRoot.change(function() {
            _self.root.update()
        })
    }
}
//          node.addControl(new SelectControl(...))
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 = {
   //   -  ,        InputControl
    template: '<button type="button" class="btn btn-outline-light">' +
        '<i class="fa fa-plus-circle"></i>&nbsp;Add Value</button>',
    data() {
        return {
            value: ""
        };
    },
    methods: {
        //    ,    ,  InputControl,   id    
        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))
            //     ,   Rete      
            this.node.update()
            this.emitter.view.updateConnections(this)
            //         ,      json  ,     
            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) {
        //         ,       osm. 
        //     Rete  ,         
        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"))
        //       json -  ,     ,    
       //  data.tag_valueCount  AddTextFieldControl,  
        let valuesCount = 1;
        if (node.data.tag_valueCount !== undefined) {
            valuesCount = node.data.tag_valueCount
        }
        //    InputControl
        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 .


In Zukunft möchte ich dort noch mehr hinzufügen - zum Beispiel die Möglichkeit, Daten nicht nur von OSM, sondern auch von meinen GeoJSON-Dateien herunterzuladen, mehr Arten von Operationen und Filtern usw.


Dieser Service hilft mir persönlich. Wenn ein Schüler beispielsweise schnell etwas auf einer OSM-Karte anzeigen muss - ich muss QGIS nicht mehr ausführen und mich an die komplexe Überführungs-Abfragesprache erinnern, klicke ich mit ein paar Mausbewegungen auf das gewünschte Diagramm, es wird in wenigen Sekunden verarbeitet und Sie können das Ergebnis sofort sehen.


Ich hoffe, es wird einigen von Ihnen nützlich sein. Wie immer bin ich bereit, Vorschläge und Wünsche entweder hier in den Kommentaren anzuhören, oder Sie können sie an evsmirnov@itmo.ru senden


All Articles