Files
iD/js/id/core/entity.js
John Firebaugh 6060e886cb Reduce calls to iD.svg.TagClasses
For fills and shadows, style changes can happen only when
a new version of the feature is produced. If we include a
version number in the key, we need only call TagClasses on
the enter selection.

We cannot apply the same optimization for strokes, since
stroke style can depend on the tags of parent relations
as well.
2013-05-13 09:37:48 -07:00

125 lines
3.2 KiB
JavaScript

iD.Entity = function(attrs) {
// For prototypal inheritance.
if (this instanceof iD.Entity) return;
// Create the appropriate subtype.
if (attrs && attrs.type) {
return iD.Entity[attrs.type].apply(this, arguments);
}
// Initialize a generic Entity (used only in tests).
return (new iD.Entity()).initialize(arguments);
};
iD.Entity.id = function(type) {
return iD.Entity.id.fromOSM(type, iD.Entity.id.next[type]--);
};
iD.Entity.id.next = {node: -1, way: -1, relation: -1};
iD.Entity.id.fromOSM = function(type, id) {
return type[0] + id;
};
iD.Entity.id.toOSM = function(id) {
return id.slice(1);
};
iD.Entity.id.type = function(id) {
return {'n': 'node', 'w': 'way', 'r': 'relation'}[id[0]];
};
// A function suitable for use as the second argument to d3.selection#data().
iD.Entity.key = function(entity) {
return entity.id + ',' + entity.v;
};
iD.Entity.prototype = {
tags: {},
initialize: function(sources) {
for (var i = 0; i < sources.length; ++i) {
var source = sources[i];
for (var prop in source) {
if (Object.prototype.hasOwnProperty.call(source, prop)) {
this[prop] = source[prop];
}
}
}
if (!this.id && this.type) {
this.id = iD.Entity.id(this.type);
}
if (iD.debug) {
Object.freeze(this);
Object.freeze(this.tags);
if (this.loc) Object.freeze(this.loc);
if (this.nodes) Object.freeze(this.nodes);
if (this.members) Object.freeze(this.members);
}
return this;
},
osmId: function() {
return iD.Entity.id.toOSM(this.id);
},
isNew: function() {
return this.osmId() < 0;
},
update: function(attrs) {
return iD.Entity(this, attrs, {v: 1 + (this.v || 0)});
},
mergeTags: function(tags) {
var merged = _.clone(this.tags), changed = false;
for (var k in tags) {
var t1 = merged[k],
t2 = tags[k];
if (!t1) {
changed = true;
merged[k] = t2;
} else if (t1 !== t2) {
changed = true;
merged[k] = _.union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
}
}
return changed ? this.update({tags: merged}) : this;
},
intersects: function(extent, resolver) {
return this.extent(resolver).intersects(extent);
},
hasInterestingTags: function() {
return _.keys(this.tags).some(function(key) {
return key != 'attribution' &&
key != 'created_by' &&
key != 'source' &&
key != 'odbl' &&
key.indexOf('tiger:') !== 0;
});
},
deprecatedTags: function() {
var tags = _.pairs(this.tags);
var deprecated = {};
iD.data.deprecated.forEach(function(d) {
var match = _.pairs(d.old)[0];
tags.forEach(function(t) {
if (t[0] == match[0] &&
(t[1] == match[1] || match[1] == '*')) {
deprecated[t[0]] = t[1];
}
});
});
return deprecated;
}
};