mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-22 16:19:48 +02:00
Create simple Taginfo wrapper, suggest tags with datalists,
rework tag editor window stashing concept of presets for now.
This commit is contained in:
+17
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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] : '';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user