mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-14 17:52:55 +00:00
Merge branch 'jfirebaugh-iD'
Currently broken. Conflicts: index.html js/iD/renderer/Map.js
This commit is contained in:
@@ -84,11 +84,16 @@ input[type=text]:focus {
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#bar button:hover {
|
||||
#bar button[disabled] {
|
||||
color:#eee;
|
||||
cursor:auto;
|
||||
}
|
||||
|
||||
#bar button:hover:not([disabled]) {
|
||||
background:#eee;
|
||||
}
|
||||
|
||||
#bar button.active {
|
||||
#bar button.active:not([disabled]) {
|
||||
background:#eee;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
118
index.html
118
index.html
@@ -7,30 +7,6 @@
|
||||
<link rel='stylesheet' href='css/map.css'>
|
||||
<link rel='stylesheet' href='css/app.css'>
|
||||
<meta name='viewport' content='initial-scale=1.0 maximum-scale=1.0'>
|
||||
</head>
|
||||
<body>
|
||||
<div id='map'></div>
|
||||
<div id='bar'>
|
||||
<button id='place'>
|
||||
+ Place</button><button id='road'>
|
||||
+ Road</button><button id='area'>
|
||||
+ Area</button><button class='mini' id='undo'>
|
||||
←<small> </small></button><button class='mini' id='redo'>
|
||||
→</button><input type='text' id='geocode-location' placeholder='find a place' />
|
||||
<div class='messages'></div>
|
||||
<button id='save'>Save<small id='as-username'></small></button>
|
||||
<div class='zoombuttons'>
|
||||
<button class='zoom-in'>+</button><button class='zoom-out'>–</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='inspector-wrap'></div>
|
||||
<div id='about'>
|
||||
<p>Work in progress: <a href='http://www.geowiki.com/'>introduction</a>,
|
||||
<a href='http://github.com/systemed/iD'>code</a>,
|
||||
<a href='http://www.geowiki.com/docs'>docs</a>.
|
||||
Imagery <a href='http://opengeodata.org/microsoft-imagery-details'>© 2012</a> Bing, GeoEye, Getmapping, Intermap, Microsoft.</p>
|
||||
</div>
|
||||
|
||||
<script type='text/javascript' src='js/lib/lodash.js'></script>
|
||||
<script type='text/javascript' src='js/lib/d3.v3.js'></script>
|
||||
@@ -63,95 +39,9 @@
|
||||
<script type='text/javascript' src='js/iD/graph/Graph.js'></script>
|
||||
<script type='text/javascript' src='js/iD/graph/History.js'></script>
|
||||
<script type='text/javascript' src='js/iD/Connection.js'></script>
|
||||
|
||||
<script>
|
||||
var map = iD.Map(document.getElementById('map'))
|
||||
.setAPI('http://api06.dev.openstreetmap.org/api/0.6/');
|
||||
|
||||
var m = d3.select('#map');
|
||||
var hash = iD.Hash().map(map);
|
||||
if (!hash.hadHash) map.setZoom(19).setCenter({
|
||||
lat: 51.87502,
|
||||
lon: -1.49475
|
||||
});
|
||||
|
||||
var controller = iD.Controller(map);
|
||||
var oauth = iD.OAuth(map)
|
||||
.setAPI('http://api06.dev.openstreetmap.org/api/0.6');
|
||||
|
||||
if (oauth.authenticated()) {
|
||||
oauth.xhr({ method: 'GET', path: '/user/details' }, function(user_details) {
|
||||
var u = user_details.getElementsByTagName('user')[0];
|
||||
map.connection.user({
|
||||
display_name: u.attributes.display_name.nodeValue,
|
||||
id: u.attributes.id.nodeValue
|
||||
});
|
||||
d3.select('.messages').text('logged in as ' +
|
||||
map.connection.user().display_name);
|
||||
});
|
||||
}
|
||||
|
||||
d3.selectAll('button#save').on('click', function() {
|
||||
oauth.authenticate(function() {
|
||||
map.commit();
|
||||
});
|
||||
});
|
||||
|
||||
d3.selectAll('button#place').on('click', function() {
|
||||
controller.enter(iD.modes.AddPlace);
|
||||
});
|
||||
|
||||
d3.selectAll('button#road').on('click', function() {
|
||||
controller.enter(iD.modes.AddRoad);
|
||||
});
|
||||
|
||||
d3.selectAll('button#area').on('click', function() {
|
||||
controller.enter(iD.modes.AddArea);
|
||||
});
|
||||
|
||||
window.onresize = function() {
|
||||
map.setSize({
|
||||
width: m.node().offsetWidth,
|
||||
height: m.node().offsetHeight
|
||||
});
|
||||
};
|
||||
|
||||
function grid(resp) {
|
||||
map.setCentre(resp.results[0][0]);
|
||||
}
|
||||
|
||||
d3.select('#geocode-location').on('keydown', function() {
|
||||
if (d3.event.keyCode !== 13) return;
|
||||
d3.event.preventDefault();
|
||||
var val = d3.select('#geocode-location').node().value;
|
||||
var scr = document.body.appendChild(document.createElement('script'));
|
||||
scr.src = 'http://api.tiles.mapbox.com/v3/mapbox/geocode/' +
|
||||
encodeURIComponent(val) + '.jsonp?callback=grid';
|
||||
});
|
||||
|
||||
d3.select('.zoombuttons .zoom-in').on('click', map.zoomIn);
|
||||
d3.select('.zoombuttons .zoom-out').on('click', map.zoomOut);
|
||||
|
||||
d3.select('#undo').on('click', map.undo);
|
||||
d3.select('#redo').on('click', map.redo);
|
||||
|
||||
d3.select(document).on('keydown', function() {
|
||||
// console.log(d3.event);
|
||||
// cmd-z
|
||||
if (d3.event.which === 90 && d3.event.metaKey) {
|
||||
map.undo();
|
||||
}
|
||||
// cmd-shift-z
|
||||
if (d3.event.which === 90 && d3.event.metaKey && d3.event.shiftKey) {
|
||||
map.redo();
|
||||
}
|
||||
// p
|
||||
if (d3.event.which === 80) controller.enter(iD.modes.AddPlace);
|
||||
// r
|
||||
if (d3.event.which === 82) controller.enter(iD.modes.AddRoad);
|
||||
// a
|
||||
if (d3.event.which === 65) controller.enter(iD.modes.AddArea);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="iD"></div>
|
||||
<script>iD(document.getElementById('iD'));</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,7 +2,8 @@ iD.Connection = function() {
|
||||
var apiURL = 'http://www.openstreetmap.org/api/0.6/',
|
||||
connection = {},
|
||||
refNodes = {},
|
||||
user = {};
|
||||
user = {},
|
||||
oauth = iD.OAuth().setAPI(apiURL);
|
||||
|
||||
// Request data within the bbox from an external OSM server.
|
||||
function bboxFromAPI(box, callback) {
|
||||
@@ -88,9 +89,52 @@ iD.Connection = function() {
|
||||
return iD.Graph(entities);
|
||||
}
|
||||
|
||||
function authenticate(callback) {
|
||||
return oauth.authenticate(callback);
|
||||
}
|
||||
|
||||
function authenticated() {
|
||||
return oauth.authenticated();
|
||||
}
|
||||
|
||||
function createChangeset(modified) {
|
||||
oauth.xhr({
|
||||
method: 'PUT',
|
||||
path: '/changeset/create',
|
||||
options: { header: { 'Content-Type': 'text/xml' } },
|
||||
content: iD.format.XML.changeset()
|
||||
},
|
||||
function (changeset_id) {
|
||||
oauth.xhr({
|
||||
method: 'POST',
|
||||
path: '/changeset/' + changeset_id + '/upload',
|
||||
options: { header: { 'Content-Type': 'text/xml' } },
|
||||
content: iD.format.XML.osmChange(user.id, changeset_id, modified)
|
||||
}, function () {
|
||||
oauth.xhr({
|
||||
method: 'PUT',
|
||||
path: '/changeset/' + changeset_id + '/close'
|
||||
}, function () {
|
||||
alert('saved! ' + apiURL.replace('/api/0.6/', '/browse') + '/changeset/' + changeset_id);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function userDetails(callback) {
|
||||
oauth.xhr({ method: 'GET', path: '/user/details' }, function(user_details) {
|
||||
var u = user_details.getElementsByTagName('user')[0];
|
||||
callback({
|
||||
display_name: u.attributes.display_name.nodeValue,
|
||||
id: u.attributes.id.nodeValue
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
connection.url = function(x) {
|
||||
if (!arguments.length) return apiURL;
|
||||
apiURL = x;
|
||||
oauth.setAPI(x);
|
||||
return connection;
|
||||
};
|
||||
|
||||
@@ -103,6 +147,10 @@ iD.Connection = function() {
|
||||
connection.bboxFromAPI = bboxFromAPI;
|
||||
connection.wayFromAPI = wayFromAPI;
|
||||
connection.loadFromURL = loadFromURL;
|
||||
connection.userDetails = userDetails;
|
||||
connection.authenticate = authenticate;
|
||||
connection.authenticated = authenticated;
|
||||
connection.createChangeset = createChangeset;
|
||||
|
||||
connection.objectData = objectData;
|
||||
connection.apiURL = apiURL;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
iD.OAuth = function(map) {
|
||||
iD.OAuth = function() {
|
||||
var baseurl = 'http://api06.dev.openstreetmap.org',
|
||||
apibase = 'http://api06.dev.openstreetmap.org/api/0.6',
|
||||
oauth_secret = 'aMnOOCwExO2XYtRVWJ1bI9QOdqh1cay2UgpbhA6p',
|
||||
@@ -90,7 +90,5 @@ iD.OAuth = function(map) {
|
||||
return oauth;
|
||||
};
|
||||
|
||||
map.oauth = oauth;
|
||||
|
||||
return oauth;
|
||||
};
|
||||
|
||||
@@ -84,5 +84,11 @@ iD.Graph.prototype = {
|
||||
}
|
||||
entity.nodes = nodes;
|
||||
return entity;
|
||||
},
|
||||
|
||||
modifications: function() {
|
||||
_.filter(this.entities, function(entity) {
|
||||
return entity.modified;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,5 +38,21 @@ iD.History.prototype = {
|
||||
this.index++;
|
||||
if (this.stack[this.index].annotation) break;
|
||||
}
|
||||
},
|
||||
|
||||
undoAnnotation: function() {
|
||||
var index = this.index;
|
||||
while (index >= 0) {
|
||||
if (this.stack[index].annotation) return this.stack[index].annotation;
|
||||
index--;
|
||||
}
|
||||
},
|
||||
|
||||
redoAnnotation: function() {
|
||||
var index = this.index + 1;
|
||||
while (index <= this.stack.length - 1) {
|
||||
if (this.stack[index].annotation) return this.stack[index].annotation;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
160
js/iD/id.js
160
js/iD/id.js
@@ -1,4 +1,162 @@
|
||||
if (typeof iD === 'undefined') var iD = {};
|
||||
var iD = function(container) {
|
||||
container = d3.select(container);
|
||||
|
||||
var m = container.append('div')
|
||||
.attr('id', 'map');
|
||||
|
||||
var connection = iD.Connection()
|
||||
.url('http://api06.dev.openstreetmap.org/api/0.6/');
|
||||
|
||||
var map = iD.Map(m.node(), connection);
|
||||
|
||||
var controller = iD.Controller(map);
|
||||
|
||||
var bar = container.append('div')
|
||||
.attr('id', 'bar');
|
||||
|
||||
bar.append('button')
|
||||
.attr('id', 'place')
|
||||
.html('+ Place')
|
||||
.on('click', function() {
|
||||
controller.go(iD.actions.AddPlace);
|
||||
});
|
||||
|
||||
bar.append('button')
|
||||
.attr('id', 'road')
|
||||
.html('+ Road')
|
||||
.on('click', function() {
|
||||
controller.go(iD.actions.AddRoad);
|
||||
});
|
||||
|
||||
bar.append('button')
|
||||
.attr('id', 'area')
|
||||
.html('+ Area')
|
||||
.on('click', function() {
|
||||
controller.go(iD.actions.AddArea);
|
||||
});
|
||||
|
||||
bar.append('button')
|
||||
.attr('id', 'undo')
|
||||
.attr('class', 'mini')
|
||||
.property('disabled', true)
|
||||
.html('←<small></small>')
|
||||
.on('click', map.undo);
|
||||
|
||||
bar.append('button')
|
||||
.attr('id', 'redo')
|
||||
.attr('class', 'mini')
|
||||
.property('disabled', true)
|
||||
.html('→<small></small>')
|
||||
.on('click', map.redo);
|
||||
|
||||
bar.append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('placeholder', 'find a place')
|
||||
.attr('id', 'geocode-location')
|
||||
.on('keydown', function () {
|
||||
if (d3.event.keyCode !== 13) return;
|
||||
d3.event.preventDefault();
|
||||
var val = d3.select('#geocode-location').node().value;
|
||||
var scr = document.body.appendChild(document.createElement('script'));
|
||||
scr.src = 'http://api.tiles.mapbox.com/v3/mapbox/geocode/' +
|
||||
encodeURIComponent(val) + '.jsonp?callback=grid';
|
||||
});
|
||||
|
||||
function grid(resp) {
|
||||
map.setCentre(resp.results[0][0]);
|
||||
}
|
||||
|
||||
bar.append('div')
|
||||
.attr('class', 'messages');
|
||||
|
||||
|
||||
bar.append('button')
|
||||
.attr('id', 'save')
|
||||
.html("Save<small id='as-username'></small>")
|
||||
.on('click', function() {
|
||||
connection.authenticate(function() {
|
||||
map.commit();
|
||||
});
|
||||
});
|
||||
|
||||
var zoom = bar.append('div')
|
||||
.attr('class', 'zoombuttons');
|
||||
|
||||
zoom.append('button')
|
||||
.attr('class', 'zoom-in')
|
||||
.text('+')
|
||||
.on('click', map.zoomIn);
|
||||
|
||||
zoom.append('button')
|
||||
.attr('class', 'zoom-out')
|
||||
.text('–')
|
||||
.on('click', map.zoomOut);
|
||||
|
||||
container.append('div')
|
||||
.attr('class', 'inspector-wrap');
|
||||
|
||||
container.append('div')
|
||||
.attr('id', 'about')
|
||||
.html("<p>Work in progress: <a href='http://www.geowiki.com/'>introduction</a>," +
|
||||
"<a href='http://github.com/systemed/iD'>code</a>," +
|
||||
"<a href='http://www.geowiki.com/docs'>docs</a>." +
|
||||
"Imagery <a href='http://opengeodata.org/microsoft-imagery-details'>© 2012</a> Bing, GeoEye, Getmapping, Intermap, Microsoft.</p>");
|
||||
|
||||
map.on('update', function() {
|
||||
var undo = map.history.undoAnnotation(),
|
||||
redo = map.history.redoAnnotation();
|
||||
|
||||
bar.select('#undo')
|
||||
.property('disabled', !undo)
|
||||
.select('small')
|
||||
.text(undo);
|
||||
|
||||
bar.select('#redo')
|
||||
.property('disabled', !redo)
|
||||
.select('small')
|
||||
.text(redo);
|
||||
});
|
||||
|
||||
window.onresize = function() {
|
||||
map.setSize({
|
||||
width: m.node().offsetWidth,
|
||||
height: m.node().offsetHeight
|
||||
});
|
||||
};
|
||||
|
||||
d3.select(document).on('keydown', function() {
|
||||
// console.log(d3.event);
|
||||
// cmd-z
|
||||
if (d3.event.which === 90 && d3.event.metaKey) {
|
||||
map.undo();
|
||||
}
|
||||
// cmd-shift-z
|
||||
if (d3.event.which === 90 && d3.event.metaKey && d3.event.shiftKey) {
|
||||
map.redo();
|
||||
}
|
||||
// p
|
||||
if (d3.event.which === 80) controller.go(iD.actions.AddPlace);
|
||||
// r
|
||||
if (d3.event.which === 82) controller.go(iD.actions.AddRoad);
|
||||
// a
|
||||
if (d3.event.which === 65) controller.go(iD.actions.AddArea);
|
||||
});
|
||||
|
||||
var hash = iD.Hash().map(map);
|
||||
if (!hash.hadHash) {
|
||||
map.setZoom(19).setCenter({
|
||||
lat: 51.87502,
|
||||
lon: -1.49475
|
||||
});
|
||||
}
|
||||
|
||||
if (connection.authenticated()) {
|
||||
connection.userDetails(function(user_details) {
|
||||
connection.user(user_details);
|
||||
d3.select('.messages').text('logged in as ' + user_details.display_name);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
iD.supported = function() {
|
||||
if (navigator.appName !== 'Microsoft Internet Explorer') {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
iD.Map = function(elem) {
|
||||
iD.Map = function(elem, connection) {
|
||||
|
||||
if (!iD.supported()) {
|
||||
elem.innerHTML = 'This editor is supported in Firefox, Chrome, Safari, Opera, ' +
|
||||
@@ -12,7 +12,6 @@ iD.Map = function(elem) {
|
||||
dimensions = { width: null, height: null },
|
||||
dispatch = d3.dispatch('move', 'update'),
|
||||
history = iD.History(),
|
||||
connection = iD.Connection(),
|
||||
inspector = iD.Inspector(),
|
||||
parent = d3.select(elem),
|
||||
selection = null,
|
||||
@@ -40,7 +39,7 @@ iD.Map = function(elem) {
|
||||
only[entity.id] = true;
|
||||
redraw(only);
|
||||
})
|
||||
.on('dragend', map.update),
|
||||
.on('dragend', update),
|
||||
nodeline = function(d) {
|
||||
return 'M' + d.nodes.map(ll2a).map(projection).map(roundCoords).join('L');
|
||||
},
|
||||
@@ -412,18 +411,16 @@ iD.Map = function(elem) {
|
||||
.scale(d3.event.scale);
|
||||
if (fast) {
|
||||
if (!translateStart) translateStart = d3.mouse(document.body).slice();
|
||||
fastPan(d3.mouse(document.body), translateStart);
|
||||
var a = d3.mouse(document.body),
|
||||
b = translateStart;
|
||||
surface.style(transformProp,
|
||||
'translate3d(' + (a[0] - b[0]) + 'px,' + (a[1] - b[1]) + 'px, 0px)');
|
||||
} else {
|
||||
redraw();
|
||||
translateStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
function fastPan(a, b) {
|
||||
surface.style(transformProp,
|
||||
'translate3d(' + (a[0] - b[0]) + 'px,' + (a[1] - b[1]) + 'px, 0px)');
|
||||
}
|
||||
|
||||
surface.on('mouseup', function() {
|
||||
if (surface.style(transformProp)) {
|
||||
translateStart = null;
|
||||
@@ -447,26 +444,30 @@ iD.Map = function(elem) {
|
||||
|
||||
// UI elements
|
||||
// -----------
|
||||
var undolabel = d3.select('button#undo small');
|
||||
dispatch.on('update', function() {
|
||||
undolabel.text(history.graph().annotation);
|
||||
function update() {
|
||||
map.update();
|
||||
redraw();
|
||||
});
|
||||
}
|
||||
|
||||
function perform(action) {
|
||||
history.perform(action);
|
||||
map.update();
|
||||
}
|
||||
|
||||
function _do(operation) {
|
||||
history.operate(operation);
|
||||
update();
|
||||
}
|
||||
|
||||
// Undo/redo
|
||||
function undo() {
|
||||
history.undo();
|
||||
map.update();
|
||||
update();
|
||||
}
|
||||
|
||||
function redo() {
|
||||
history.redo();
|
||||
map.update();
|
||||
update();
|
||||
}
|
||||
|
||||
// Getters & setters for map state
|
||||
@@ -535,35 +536,8 @@ iD.Map = function(elem) {
|
||||
return map;
|
||||
}
|
||||
|
||||
function setAPI(x) {
|
||||
connection.url(x);
|
||||
return map;
|
||||
}
|
||||
|
||||
function commit() {
|
||||
var modified = _.filter(history.graph().entities, function(e) {
|
||||
return e.modified;
|
||||
});
|
||||
var userid = connection.user().id;
|
||||
map.oauth.xhr({
|
||||
method: 'PUT',
|
||||
path: '/changeset/create',
|
||||
options: { header: { 'Content-Type': 'text/xml' } },
|
||||
content: iD.format.XML.changeset() }, function(changeset_id) {
|
||||
map.oauth.xhr({
|
||||
method: 'POST',
|
||||
path: '/changeset/' + changeset_id + '/upload',
|
||||
options: { header: { 'Content-Type': 'text/xml' } },
|
||||
content: iD.format.XML.osmChange(userid, changeset_id, modified)
|
||||
}, function() {
|
||||
map.oauth.xhr({
|
||||
method: 'PUT',
|
||||
path: '/changeset/' + changeset_id + '/close'
|
||||
}, function() {
|
||||
alert('saved! ' + connection.url().replace('/api/0.6/', '/browse') + '/changeset/' + changeset_id);
|
||||
});
|
||||
});
|
||||
});
|
||||
connection.createChangeset(history.graph().modifications());
|
||||
}
|
||||
|
||||
map.handleDrag = handleDrag;
|
||||
@@ -583,10 +557,8 @@ iD.Map = function(elem) {
|
||||
map.zoomIn = zoomIn;
|
||||
map.zoomOut = zoomOut;
|
||||
|
||||
map.connection = connection;
|
||||
map.projection = projection;
|
||||
map.setSize = setSize;
|
||||
map.setAPI = setAPI;
|
||||
|
||||
map.history = history;
|
||||
map.surface = surface;
|
||||
|
||||
Reference in New Issue
Block a user