[josm-dev] Problem with referrers
jiri.klement at gmail.com
Mon Oct 5 18:28:56 BST 2009
On Mon, Oct 5, 2009 at 9:43 AM, Frederik Ramm <frederik at remote.org> wrote:
> Can you explain (or point me to a previous post that explains) what
> referrers are good for?
For example when way has list of nodes then every node has that way as
a referrer. Also every primitive included in relation has that
relation saved as referrer. Referrers are needed in lots of places in
JOSM code, for example in DrawAction and DeleteCommand. It's obviously
possible to get list of referrers by iterating over dataset but that's
too slow for big datasets.
>> Currently JOSM quite often makes copies of
>> primitive (using for example cloneFrom or special constructors). It's
>> not obvious whether the copy is added to the dataset or is kept in
>> case we need to get back to old version of primitive (for example
>> Command.cloneMap). That's a bit problem because I don't want to have
>> such copy in referrers list, I want only primitives that are really
>> used in an dataset.
> I'm trying to make sense of this (but might go off in the completely wrong
> direction here) - you're trying to keep a "breadcrumb" trail of what
> happened to an object, is that right? And you want referrer lists to model
> that "family tree"?
> But why can the list not simply reside on the other side, i.e. in the
> descendant object pointing back in history? I have the feeling that you're
> duplicating information by distinguishing objects that are "really used in a
> dataset" from those that aren't - should not the dataset itself be the
> ultimate arbiter on what is "really used" and what not?
I'm not talking about history, I've just mentioned few cases where
JOSM use copies of primitives.
OsmPrimitive is no longer just a storage for osm data. It has (will
have) methods that will automatically update referrers, spatial index
and other things. We need another class that will just hold data -
that's what PrimitivePrototype is for.
Let me explain it on example with DeleteCommand. Currently JOSM makes
a copy of deleted object so it can revert the change. Let's say we
delete way without it's nodes. Now I have now idea whether the copy of
deleted way should be listed as referrer to the nodes or not.
>> To workaround this issues I'm thinking about introducing new classes -
>> PrimitivePrototype, NodePrototype, WayPrototype and RelationPrototype.
>> These classes will hold informations for one primitive, but it will
>> not be possible to add these objects to the dataset. That will allow
>> to clearly distinguish what's real primitive and whats just an backup
>> copy for for example Command.cloneMap or Main.pasteBuffer.
> Could one perhaps forgo the prototype objects you are suggesting and instead
> create a "backup copy dataset" (that is not associated with a visible
> layer); then postulate that every primitive always has to be a member of
> exactly one dataset - either a "proper" dataset or the "backup copy dataset"
> (or maybe others like it)?
Having "backup copy dataset" that will discard all event received from
it's primitives is another possibility. But I think it's cleaner to
have separated classes - one as simple data holder and another one as
part of real dataset with EastNorth coordinates, MapPaint fields etc.
> I am not entirely happy with making primitive constructors protected. Is it
> so unthinkable that people, e.g. those writing plugins, would like to use
> primitives for purposes that are unexpected for us - purposes where they are
> not at all interested in things like "reliable events"? Just because we need
> that somewhere in JOSM doesn't mean we have to force it on everybody, or
> force them to write their own classes instead of re-using ours.
If it turns out that somebody needs to do something unusual with
primitives then it's quite easy to provide special Dataset, that will
miss that features.
> feeling that it would be nice if our Node class was primarily that - an OSM
> node - with perhaps some added JOSM bells and whistles. Maybe, in a way, you
> were aiming at making your "node prototype" represent a basic node, and the
> Node class would play the role of linking that basic node into the greater
> JOSM context? But if that is right, then I guess we should change the naming
> - i.e. instead of saying "datasets consist of primitives which are made from
> prototypes" we should say "datasets consist of adapter classes (or linkage
> classes, or instance classes, or context classes, or wrapper classes or
> something) which refer to a primtive". I.e. instead of further and further
> mangling the primitive and adding a prototype to its side, make the
> primitive into a real primitive (which you called a prototype) and but all
> the fancy stuff in the new PrimitiveContext class.
I think almost everywhere in JOSM are primitives used as
PrimitiveContext class. Most places in JOSM expect to update (future)
spacial index when Node coordinates are changed. So I think it's a bit
late for changing names. But otherwise I agree that it would be nice
if Node was really just osm node without extra features.
Now I should emphasis that PrimitivePrototypes are not meant like some
data holding class below OsmPrimitive. Prototypes are temporary
objects used when you need to make copy of OsmPrimitive. Maybe the
name is not the best, any other suggestions?
> When would your prototype objects be created - only on demand or would they
> always be there? Say I load a data layer from a file - does that then create
> a set of primitives and an associated set of prototypes (memory issue?), or
> would the prototype only be generated when required?
Prototype will be generated only when copy of some primitive is
needed. So for example to allow undo in some actions or for Copy&Paste
> How would you manage
> object identity - could you quickly sketch, for the following sequence of
> actions, at what time what prototypes and primitives would be generated and
> what OSM ID would be associated with them?
> * start JOSM
> * load data layer from API
> * create new, empty layer
> * copy node from data layer
> * insert node into new layer
> * upload new layer to API
Prototypes will be probably used when parsing xml from API (instead of
similar OsmData class that's already there). Then when you copy a node
- properties of the Node will be saved to the NodePrototype and later
new Node will be created based on that values.
More information about the josm-dev