Create simple Taginfo wrapper, suggest tags with datalists,

rework tag editor window stashing concept of presets for now.
This commit is contained in:
Tom MacWright
2012-10-17 14:34:34 -04:00
parent 7e62af4344
commit 663f880f57
7 changed files with 144 additions and 61 deletions
+17
View File
@@ -1,7 +1,14 @@
/* Additional CSS rules will go here */
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.currentMode { font-weight: bold; }
/* Zoom controls */
#zoombuttons {
position:absolute;
right:20px;
@@ -31,3 +38,13 @@
border-left:0;
border-radius: 0 4px 4px 0;
}
/* Tag window */
#tagform input.key {
margin-right:10px;
}
#tagform input.key,
#tagform input.value {
font: normal 13px/20px 'Helvetica';
width:135px;
}
+1
View File
@@ -21,6 +21,7 @@
<script type="text/javascript" src="js/lib/underscore-min.js"></script>
<script type="text/javascript" src="js/lib/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/iD/Util.js"></script>
<script type="text/javascript" src="js/iD/Taginfo.js"></script>
<script type="text/javascript" src="js/iD/Node.js"></script>
<script type="text/javascript" src="js/iD/Relation.js"></script>
<script type="text/javascript" src="js/iD/Entity.js"></script>
+25 -25
View File
@@ -16,45 +16,45 @@ iD.Node = function(conn, id, lat, lon, tags, loaded) {
};
iD.Node.prototype = {
project: function() {
// summary: Update the projected latitude value (this.latp) from the latitude (this.lat).
this.latp = 180/Math.PI *
project: function() {
// summary: Update the projected latitude value (this.latp) from the latitude (this.lat).
this.latp = 180/Math.PI *
Math.log(Math.tan(Math.PI/4+this.lat*(Math.PI/180)/2));
},
latp2lat: function(a) {
// summary: Get a latitude from a projected latitude.
// returns: Latitude.
return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2);
},
},
latp2lat: function(a) {
// summary: Get a latitude from a projected latitude.
// returns: Latitude.
return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2);
},
within: function(left, right, top, bottom) {
within: function(left, right, top, bottom) {
return (this.lon >= left) &&
(this.lon <= right) &&
(this.lat >= bottom) &&
(this.lat <= top);
},
refresh: function() {
var ways = this.parentWays();
_.each(ways, _.bind(function(way) { this.connection.refreshEntity(way); }, this));
this.connection.refreshEntity(this);
},
refresh: function() {
var ways = this.parentWays();
_.each(ways, _.bind(function(way) { this.connection.refreshEntity(way); }, this));
this.connection.refreshEntity(this);
},
doSetLonLatp: function(lon,latproj,performAction) {
// summary: Change the position of a node, using an undo stack.
performAction(new iD.actions.MoveNodeAction(this,
doSetLonLatp: function(lon,latproj,performAction) {
// summary: Change the position of a node, using an undo stack.
performAction(new iD.actions.MoveNodeAction(this,
this.latp2lat(latproj),
lon,
lang.hitch(this,this._setLatLonImmediate)));
},
},
_setLatLonImmediate: function(lat,lon) {
this.lat = lat;
this.lon = lon;
this.project();
var ways = this.parentWays();
_setLatLonImmediate: function(lat,lon) {
this.lat = lat;
this.lon = lon;
this.project();
var ways = this.parentWays();
_.each(ways, _.bind(function(way) {
way.expandBbox(this);
}, this));
}
}
};
+28
View File
@@ -0,0 +1,28 @@
if (typeof iD === 'undefined') iD = {};
// Taginfo service singleton
iD.Taginfo = (function() {
var taginfo = {},
endpoint = 'http://taginfo.openstreetmap.org/api/2/';
// Given a key, return common values
// TODO: get type, count correctly based on it
taginfo.values = function(key, callback) {
$.ajax({
url: endpoint + 'db/keys/values',
data: {
key: key,
sortname: 'count_all',
sortorder: 'desc',
page: 1
},
dataType: 'jsonp',
success: function(resp) {
if (resp.data) callback(resp.data);
}
});
};
return taginfo;
})();
+8 -8
View File
@@ -91,16 +91,16 @@ iD.Way.prototype = {
// isSnap: Boolean Should the node position be snapped to be exactly on the segment?
// returns: The index at which the node was inserted.
var closestProportion = 1,
newIndex = 0,
snapped;
newIndex = 0,
snapped;
for (var i = 0; i < this.nodes.length - 1; i++) {
var node1 = this.nodes[i];
var node2 = this.nodes[i + 1];
var directDist = this._pythagoras(node1, node2);
var viaNewDist = this._pythagoras(node1, newNode) +
this._pythagoras(node2, newNode);
var proportion = Math.abs(viaNewDist/directDist - 1);
var node1 = this.nodes[i],
node2 = this.nodes[i + 1],
directDist = this._pythagoras(node1, node2),
viaNewDist = this._pythagoras(node1, newNode) +
this._pythagoras(node2, newNode),
proportion = Math.abs(viaNewDist/directDist - 1);
if (proportion < closestProportion) {
newIndex = i+1;
closestProportion = proportion;
-1
View File
@@ -12,7 +12,6 @@ declare("iD.tags.PresetList", null, {
// summary: List of presets for a given type (e.g. nodes, ways)
this.entityType = type;
console.log(url);
$.ajax({
url: url,
success: _.bind(this.loaded, this),
+65 -27
View File
@@ -1,7 +1,7 @@
// iD/tags/TagEditor.js
define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/xhr','dojo/dom-construct',
'dijit/Dialog','dijit/form/Form','dijit/form/Button','dijit/form/TextBox'],
'dijit/Dialog','dijit/form/Form','dijit/form/Button','dijit/form/TextBox'],
function(declare,lang,xhr,domConstruct){
declare("iD.tags.TagEditor", null, {
@@ -23,21 +23,18 @@ declare("iD.tags.TagEditor", null, {
content: "",
style: "width: 300px" });
var form = new dijit.form.Form({
encType: 'multipart/form-data',
action: '',
method: '',
onSubmit: function(event) { console.log('submit'); }
}, dojo.doc.createElement('div'));
this.$content = $('<div id="tagform"></div>');
this.render();
this.dialog.set('content', form);
this.dialog.set('content', this.$content[0]);
this.dialog.show();
// What editors are relevant?
var presetList = this.controller.presets[entity.entityType];
var applicablePresets = presetList.assembleEditorsForEntity(entity);
/*
// What editors are relevant?
var presetList = this.controller.presets[entity.entityType],
applicablePresets = presetList.assembleEditorsForEntity(entity),
i;
var i;
// Add preset types
for (i in applicablePresets.presets) {
this.appendPreset(i, applicablePresets.presets[i], form.domNode);
@@ -47,14 +44,60 @@ declare("iD.tags.TagEditor", null, {
for (i in applicablePresets.editors) {
this.appendEditor(applicablePresets.editors[i], form.domNode);
}
*/
},
// ------------
// Presets
render: function() {
this.$content.empty();
// TODO: optimize
if (!$('#datalists').size()) {
$(document.body).append('<div id="datalists"></div>');
}
_.each(this.entity.tags, _.bind(function(value, key) {
var row = $('<div></div>'),
keyid = 'key-' + key;
$('<input></input>')
.val(key)
.attr({
'class': 'key'
}).appendTo(row);
$('<input></input>')
.val(value)
.attr({
'list': keyid,
'class': 'value'
}).appendTo(row);
// Share datalists between same-keys
if (!$('datalist#' + keyid).size()) {
iD.Taginfo.values(key, function(values) {
var $dl = $('<datalist></datalist>')
.attr('id', keyid);
_.each(values, function(v) {
$dl.append($('<option></option>')
.attr('value', v.value));
});
$('#datalists').append($dl);
});
}
this.$content.append(row);
}, this));
},
appendPreset:function(name, preset, destination) {
var element=domConstruct.create('h2');
element.appendChild(domConstruct.create('img', { src: 'presets/' + preset.icon }));
var element = domConstruct.create('h2');
element.appendChild(domConstruct.create('img', {
src: 'presets/' + preset.icon
}));
element.appendChild(dojo.doc.createTextNode(name));
destination.appendChild(element);
},
@@ -67,11 +110,10 @@ declare("iD.tags.TagEditor", null, {
if (this.controller.editorCache[editor]) {
this.renderEditor(editor, destination);
} else {
dojo.xhrGet({
url: "presets/editors/"+_editor+".json",
handleAs: "json",
$.ajax({
url: "presets/editors/" + editor + ".json",
// TODO: eliminate lang.hitch here
load: lang.hitch(this, this.loadedEditor, editor, destination),
success: lang.hitch(this, this.loadedEditor, editor, destination),
error: function(err) { console.log("Couldn't load editor"); }
});
}
@@ -83,16 +125,17 @@ declare("iD.tags.TagEditor", null, {
this.renderEditor(editor, destination);
},
renderEditor: function(_editor, destination) {
renderEditor: function(editor_name, destination) {
// summary: Render an editor as a form.
var editor=this.controller.editorCache[_editor];
editor = this.controller.editorCache[editor_name];
// Add the subhead
var element=domConstruct.create('h3');
element.appendChild(dojo.doc.createTextNode(_editor));
var element = domConstruct.create('h3');
element.appendChild(dojo.doc.createTextNode(editor));
destination.appendChild(element);
// Add each form element
// this.$content
for (var label in editor) {
var item = editor[label];
var value = this.getTagValue(item.key);
@@ -117,11 +160,6 @@ declare("iD.tags.TagEditor", null, {
// var resetbtn = new dijit.form.Button({ type: 'reset', label: 'Reset' }, dojo.doc.createElement('button'));
// _destination.appendChild(submitbtn.domNode);
// _destination.appendChild(resetbtn.domNode);
},
getTagValue:function(k) {
// summary: Get the value of a tag for the current entity, or empty string if unset.
return this.entity.tags[k] ? this.entity.tags[k] : '';
}
});