Files
iD/js/id/util.js
John Firebaugh 2c40de62be Add iD.behavior.drag
`iD.behavior.drag` is like `d3.behavior.drag`, with the following differences:

* The `origin` function is expected to return an [x, y] tuple rather than an
  {x, y} object.
* The events are `start`, `move`, and `end`.
  (https://github.com/mbostock/d3/issues/563)
* The `start` event is not dispatched until the first cursor movement occurs.
  (https://github.com/mbostock/d3/pull/368)
* The `move` event has a `loc` and `dxdy` [x, y] tuple properties rather
  than `x`, `y`, `dx`, and `dy` properties.
* The `end` event is not dispatched if no movement occurs.
* An `off` function is available that unbinds the drag's internal event handlers.
* Delegation is supported via the `delegate` function.
2012-12-21 12:10:43 -08:00

144 lines
4.1 KiB
JavaScript

iD.util = {};
iD.util.trueObj = function(arr) {
var o = {};
for (var i = 0, l = arr.length; i < l; i++) o[arr[i]] = true;
return o;
};
iD.util.friendlyName = function(entity) {
// Generate a string such as 'river' or 'Fred's House' for an entity.
if (!entity.tags || !Object.keys(entity.tags).length) { return ''; }
var mainkeys = ['highway','amenity','railway','waterway','natural'],
n = [];
if (entity.tags.name) n.push(entity.tags.name);
if (entity.tags.ref) n.push(entity.tags.ref);
if (!n.length) {
for (var k in entity.tags) {
if (mainkeys.indexOf(k) !== -1) {
n.push(entity.tags[k]);
break;
}
}
}
return n.length === 0 ? 'unknown' : n.join('; ');
};
iD.util.codeWindow = function(content) {
top.win = window.open('','contentWindow',
'width=350,height=350,menubar=0' +
',toolbar=1,status=0,scrollbars=1,resizable=1');
top.win.document.writeln('<pre>' + content + '</pre>');
top.win.document.close();
};
iD.util.tagText = function(entity) {
return d3.entries(entity.tags).map(function(e) {
return e.key + ': ' + e.value;
}).join('\n');
};
iD.util.stringQs = function(str) {
return str.split('&').reduce(function(obj, pair){
var parts = pair.split('=');
obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
return obj;
}, {});
};
iD.util.qsString = function(obj) {
return Object.keys(obj).sort().map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
}).join('&');
};
iD.util.prefixDOMProperty = function(property) {
var prefixes = ['webkit', 'ms', 'moz', 'o'],
i = -1,
n = prefixes.length,
s = document.body;
if (property in s)
return property;
property = property.substr(0, 1).toUpperCase() + property.substr(1);
while (++i < n)
if (prefixes[i] + property in s)
return prefixes[i] + property;
return false;
};
iD.util.prefixCSSProperty = function(property) {
var prefixes = ['webkit', 'ms', 'Moz', 'O'],
i = -1,
n = prefixes.length,
s = document.body.style;
if (property.toLowerCase() in s)
return property.toLowerCase();
while (++i < n)
if (prefixes[i] + property in s)
return '-' + prefixes[i].toLowerCase() + '-' + property.toLowerCase();
return false;
};
iD.util.support3d = function() {
// test for translate3d support. Based on https://gist.github.com/3794226 by lorenzopolidori and webinista
var transformProp = iD.util.prefixCSSProperty('Transform');
var el = document.createElement('div'),
has3d = false;
document.body.insertBefore(el, null);
if (el.style[transformProp] !== undefined) {
el.style[transformProp] = 'translate3d(1px,1px,1px)';
has3d = window.getComputedStyle(el).getPropertyValue(transformProp);
}
document.body.removeChild(el);
return (has3d && has3d.length>0 && has3d!=="none");
};
iD.util.geo = {};
iD.util.geo.roundCoords = function(c) {
return [Math.floor(c[0]), Math.floor(c[1])];
};
iD.util.geo.interp = function(p1, p2, t) {
return [p1[0] + (p2[0] - p1[0]) * t,
p1[1] + (p2[1] - p1[1]) * t];
};
iD.util.geo.dist = function(a, b) {
return Math.sqrt(Math.pow(a[0] - b[0], 2) +
Math.pow(a[1] - b[1], 2));
};
iD.util.geo.chooseIndex = function(way, point, map) {
var dist = iD.util.geo.dist,
projNodes = way.nodes.map(function(n) {
return map.projection(n.loc);
});
for (var i = 0, changes = []; i < projNodes.length - 1; i++) {
changes[i] =
(dist(projNodes[i], point) + dist(point, projNodes[i + 1])) /
dist(projNodes[i], projNodes[i + 1]);
}
var idx = _.indexOf(changes, _.min(changes)),
ratio = dist(projNodes[idx], point) / dist(projNodes[idx], projNodes[idx + 1]),
loc = iD.util.geo.interp(way.nodes[idx].loc, way.nodes[idx + 1].loc, ratio);
return {
index: idx + 1,
loc: loc
};
};