[Talk-de] selektives editieren der OSM-Daten

Gabriel Ebner ge at gabrielebner.at
Do Mai 8 16:33:38 UTC 2008


On Thu, May 08, 2008 at 05:27:37PM +0200, Christoph Wagner wrote:
> Mir ist neulich ein Problem aufgekommen, was sich meiner Meinung nach in
> Zukunft mit wachsendem OSM-Datenvolumen noch verschlimmern wird.
> Je mehr Daten in einem Gebiet sind, desto mehr wird natürlich geladen
> und das Schlimmste: desto langsamer werden die Editoren!

Zumindest bei JOSM steht es schon lange auf der Todo-Liste, große Datensätze
effizient bearbeiten zu können.  Es gab da auch eine proof-of-concept
Implementierung[1] von Petr Nejedy, die problemlos ganz Tschechien verkraftet.

(Wie lange das noch auf der Todo-Liste stehen wird, steht in den Sternen.)

> Mir schwebt da folgende Idee vor: Ist es möglich nur die Daten
> runterzuladen, die man auch wirklich zum editieren benötigt?
> Möchte ich beispielsweise Straßen umbenennen, interessieren mich die
> Häuser kein bisschen. Möchte ich beispielsweise Hausnummer aufnehmen,
> brauche ich keine Gewässer und sonstige POIs usw.
> Und ich meine jetzt nicht, dass die Daten geladen werden und einfach
> ausgeblendet, sondern, dass sie am besten gar nicht erst in den Speicher
> kommen, denn das macht die Editoren ja so verflucht lahm!
> Ich nenne das ganze einfach selektives editieren und frage euch nun, ob
> das technisch überhaupt so einfach machbar ist (ich glaube ja).

Da gibts sogar einen Bug dazu[2].  Die Idee war damals, nicht benötigte Daten
nach dem Laden aus dem Speicher zu entfernen.  Und Frederik hat anscheinend
sogar einen Prototyp geschrieben, nur ist der anscheinend nie in JOSM
gelandet.  (Und da ich den Bug erst jetzt gesehen habe, gibt es zu allem
Überfluss auch noch einen zweiten Prototyp; ein Diff ist angehängt.)

(BTW, am Wochenende haben wir in London die Möglichkeit besprochen, separate
Download- und Upload-Addressen in JOSM zu haben.  Da könnte man dann z.B.
OSMXAPI als Download-Addresse haben -- und OSMXAPI kann die Daten z.B. nach
Tags filtern.  Das wird aber erst mit API 0.6 sinnvoll funktionieren, da
OSMXAPI immer ein bisschen hinterherhinkt, und wir derzeit keine Möglichkeit
haben, festzustellen, ob jemand in der Zwischenzeit etwas geändert hat.)

[1] http://svn.openstreetmap.org/applications/editors/josm-ng
[2] http://josm.openstreetmap.de/ticket/148
-------------- nächster Teil --------------
Index: src/org/openstreetmap/josm/actions/RemoveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/RemoveAction.java	(revision 0)
+++ src/org/openstreetmap/josm/actions/RemoveAction.java	(revision 0)
@@ -0,0 +1,83 @@
+// License: GPL. Copyright 2008 by Gabriel Ebner.
+package org.openstreetmap.josm.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class RemoveAction extends JosmAction implements SelectionChangedListener {
+
+	public RemoveAction() {
+		super(tr("Remove from memory"), "mapmode/delete",
+			tr("Remove selected unmodified objects " +
+				"(+ referenced untagged unmodified nodes and " +
+				"dependent unmodified relations) from memory."),
+			0, 0, true);
+		DataSet.selListeners.add(this);
+	}
+
+	public void actionPerformed(ActionEvent event) {
+		Collection<OsmPrimitive> selection = Main.ds.getSelected();
+
+		Collection<OsmPrimitive> candidates = new HashSet<OsmPrimitive>();
+		for (OsmPrimitive osm : selection) {
+			if (osm.modified || osm.deleted) continue;
+
+			candidates.add(osm);
+
+			if (osm instanceof Way) {
+				for (Node n : ((Way) osm).nodes) {
+					if (!n.tagged && !n.modified && !n.deleted) {
+						candidates.add(n);
+					}
+				}
+			}
+		}
+
+		for (Relation r : Main.ds.relations) {
+			if (!candidates.contains(r) && !r.modified && !r.deleted) {
+				for (RelationMember m : r.members) {
+					if (candidates.contains(m.member)) {
+						candidates.add(r);
+						break;
+					}
+				}
+			}
+		}
+
+		for (Relation r : Main.ds.relations) {
+			if (!candidates.contains(r)) {
+				for (RelationMember m : r.members) {
+					candidates.remove(m.member);
+				}
+			}
+		}
+
+		for (Way w : Main.ds.ways) {
+			if (!candidates.contains(w)) {
+				candidates.removeAll(w.nodes);
+			}
+		}
+
+		Main.ds.nodes.removeAll(candidates);
+		Main.ds.ways.removeAll(candidates);
+		Main.ds.relations.removeAll(candidates);
+
+		Main.ds.fireSelectionChanged(Main.ds.getSelected());
+	}
+
+	public void selectionChanged(Collection<? extends OsmPrimitive> candidates) {
+		setEnabled(!candidates.isEmpty());
+	}
+}
Index: src/org/openstreetmap/josm/gui/MainMenu.java
===================================================================
--- src/org/openstreetmap/josm/gui/MainMenu.java	(revision 622)
+++ src/org/openstreetmap/josm/gui/MainMenu.java	(working copy)
@@ -35,6 +35,7 @@
 import org.openstreetmap.josm.actions.PasteTagsAction;
 import org.openstreetmap.josm.actions.PreferencesAction;
 import org.openstreetmap.josm.actions.RedoAction;
+import org.openstreetmap.josm.actions.RemoveAction;
 import org.openstreetmap.josm.actions.ReverseWayAction;
 import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.actions.SaveAsAction;
@@ -80,6 +81,7 @@
 	public final JosmAction paste = new PasteAction();
 	public final JosmAction pasteTags = new PasteTagsAction(copy); 
 	public final JosmAction duplicate = new DuplicateAction(); 
+	public final JosmAction remove = new RemoveAction(); 
 	public final JosmAction selectAll = new SelectAllAction();
 	public final JosmAction unselectAll = new UnselectAllAction();
     /* crashes when loading data, if using JosmAction for search */
@@ -159,6 +161,7 @@
 		current.setAccelerator(pasteTags.shortCut);
 		current = editMenu.add(duplicate);
 		current.setAccelerator(duplicate.shortCut);
+		current = editMenu.add(remove);
 		editMenu.addSeparator();
 		current = editMenu.add(selectAll);
 		current.setAccelerator(selectAll.shortCut);


Mehr Informationen über die Mailingliste Talk-de