mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-28 22:56:31 +02:00
Refactoring and fixing layers
* Fixed opacity control * Reorganize layer switcher * Add GPX item to menu * Allow user to cinch to GPX extent Needs: * Moderate refactoring * Possibly a specific 'layerchange event' * Dropping GPX on the map should be a behavior, probably, instead of in the layer * Layers, if we want them, should be named rather than just have list indices * A better icon for zoom to extent and for that icon to be properly placed
This commit is contained in:
+12
-5
@@ -1415,6 +1415,14 @@ div.combobox {
|
||||
height:18px;
|
||||
}
|
||||
|
||||
.background-control .layer-toggle-gpx .layer-extent {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.background-control .layer-toggle-gpx.selected .layer-extent {
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
/* Geocoder */
|
||||
|
||||
.geocode-control, .geocode-control form {
|
||||
@@ -1471,9 +1479,12 @@ div.combobox {
|
||||
background:#000;
|
||||
}
|
||||
|
||||
#surface, #tile-g {
|
||||
#surface, #layer-g, .layer-layer {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transform-origin:0 0;
|
||||
-ms-transform-origin:0 0;
|
||||
-webkit-transform-origin:0 0;
|
||||
@@ -1489,10 +1500,6 @@ div.combobox {
|
||||
position: static;
|
||||
}
|
||||
|
||||
#tile-g {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* About Section
|
||||
------------------------------------------------------- */
|
||||
|
||||
|
||||
@@ -184,3 +184,6 @@ en:
|
||||
out: Zoom Out
|
||||
imagery:
|
||||
provided_by: "Imagery provided by {source}"
|
||||
gpx:
|
||||
local_layer: "Local GPX file"
|
||||
drag_drop: "Drag and drop a .gpx file on the page"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
iD.LocalGpx = function() {
|
||||
iD.LocalGpx = function(context) {
|
||||
var tileSize = 256,
|
||||
projection,
|
||||
gj = {},
|
||||
enable = true,
|
||||
size = [0, 0],
|
||||
transformProp = iD.util.prefixCSSProperty('Transform'),
|
||||
path = d3.geo.path().projection(projection),
|
||||
@@ -12,7 +13,7 @@ iD.LocalGpx = function() {
|
||||
path.projection(projection);
|
||||
|
||||
var surf = selection.selectAll('svg')
|
||||
.data([gj]);
|
||||
.data(enable ? [gj] : []);
|
||||
|
||||
surf.exit().remove();
|
||||
|
||||
@@ -43,17 +44,30 @@ iD.LocalGpx = function() {
|
||||
return render;
|
||||
};
|
||||
|
||||
render.enable = function(_) {
|
||||
if (!arguments.length) return enable;
|
||||
enable = _;
|
||||
return render;
|
||||
};
|
||||
|
||||
render.geojson = function(_) {
|
||||
if (!arguments.length) return gj;
|
||||
gj = _;
|
||||
return render;
|
||||
};
|
||||
|
||||
render.size = function(_) {
|
||||
if (!arguments.length) return size;
|
||||
size = _;
|
||||
return render;
|
||||
};
|
||||
|
||||
render.id = 'layer-gpx';
|
||||
|
||||
function over() {
|
||||
d3.event.stopPropagation();
|
||||
d3.event.preventDefault();
|
||||
d3.event.dataTransfer.dropEffect = 'copy';
|
||||
console.log('here');
|
||||
}
|
||||
|
||||
d3.select('body')
|
||||
@@ -65,7 +79,9 @@ iD.LocalGpx = function() {
|
||||
reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
gj = toGeoJSON.gpx(toDom(e.target.result));
|
||||
render.geojson(toGeoJSON.gpx(toDom(e.target.result)));
|
||||
context.redraw();
|
||||
context.map().pan([0, 0]);
|
||||
};
|
||||
|
||||
reader.readAsText(f);
|
||||
|
||||
@@ -13,7 +13,7 @@ iD.Map = function(context) {
|
||||
minzoom = 0,
|
||||
layers = [
|
||||
iD.Background().projection(projection),
|
||||
iD.LocalGpx().projection(projection)],
|
||||
iD.LocalGpx(context).projection(projection)],
|
||||
transformProp = iD.util.prefixCSSProperty('Transform'),
|
||||
points = iD.svg.Points(roundedProjection, context),
|
||||
vertices = iD.svg.Vertices(roundedProjection, context),
|
||||
@@ -31,7 +31,7 @@ iD.Map = function(context) {
|
||||
selection.call(zoom);
|
||||
|
||||
layergroup = selection.append('div')
|
||||
.attr('id', 'layers-g');
|
||||
.attr('id', 'layer-g');
|
||||
|
||||
var supersurface = selection.append('div')
|
||||
.style('position', 'absolute');
|
||||
@@ -166,13 +166,13 @@ iD.Map = function(context) {
|
||||
|
||||
if (!difference) {
|
||||
var sel = layergroup
|
||||
.selectAll('.tile-layer-group')
|
||||
.selectAll('.layer-layer')
|
||||
.data(layers);
|
||||
|
||||
sel.exit().remove();
|
||||
|
||||
sel.enter().append('div')
|
||||
.attr('class', 'tile-layer-group');
|
||||
.attr('class', 'layer-layer');
|
||||
|
||||
sel.each(function(layer) {
|
||||
d3.select(this).call(layer);
|
||||
|
||||
+135
-90
@@ -1,9 +1,13 @@
|
||||
iD.ui.Background = function(context) {
|
||||
var event = d3.dispatch('cancel', 'save'),
|
||||
key = 'b',
|
||||
opacities = [1, 0.5, 0];
|
||||
|
||||
var layers = context.backgroundSources();
|
||||
opacities = [1, 0.5, 0],
|
||||
directions = [
|
||||
['left', [1, 0]],
|
||||
['top', [0, -1]],
|
||||
['right', [-1, 0]],
|
||||
['bottom', [0, 1]]],
|
||||
layers = context.backgroundSources();
|
||||
|
||||
function getSources() {
|
||||
var ext = context.map().extent();
|
||||
@@ -15,24 +19,6 @@ iD.ui.Background = function(context) {
|
||||
|
||||
function background(selection) {
|
||||
|
||||
var content = selection.append('div')
|
||||
.attr('class', 'content fillD map-overlay hide'),
|
||||
shown = false;
|
||||
|
||||
var tooltip = bootstrap.tooltip()
|
||||
.placement('right')
|
||||
.html(true)
|
||||
.title(iD.ui.tooltipHtml(t('background.description'), key));
|
||||
|
||||
var button = selection.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'fillD')
|
||||
.on('click.background-toggle', toggle)
|
||||
.call(tooltip);
|
||||
|
||||
button.append('span')
|
||||
.attr('class', 'layers icon');
|
||||
|
||||
function toggle() {
|
||||
tooltip.hide(button);
|
||||
setVisible(content.classed('hide'));
|
||||
@@ -55,56 +41,23 @@ iD.ui.Background = function(context) {
|
||||
}
|
||||
}
|
||||
|
||||
context.surface().on('mousedown.background-outside', function() {
|
||||
setVisible(false);
|
||||
});
|
||||
|
||||
context.container().on('mousedown.background-outside', function() {
|
||||
setVisible(false);
|
||||
});
|
||||
|
||||
var opa = content
|
||||
.append('div')
|
||||
.attr('class', 'opacity-options-wrapper');
|
||||
|
||||
opa.append('h4')
|
||||
.text(t('background.title'));
|
||||
|
||||
var opacityList = opa.append('ul')
|
||||
.attr('class', 'opacity-options');
|
||||
|
||||
function setOpacity(d) {
|
||||
context.map().tilesurface
|
||||
context.map().layersurface.selectAll('.layer-layer')
|
||||
.filter(function(d) { return d == context.map().layers[0]; })
|
||||
.transition()
|
||||
.style('opacity', d)
|
||||
.attr('data-opacity', d);
|
||||
|
||||
opacityList.selectAll('li')
|
||||
.classed('selected', false);
|
||||
d3.select(this)
|
||||
.classed('selected', true);
|
||||
|
||||
if (d3.event) {
|
||||
d3.select(this)
|
||||
.classed('selected', true);
|
||||
}
|
||||
}
|
||||
|
||||
opacityList.selectAll('div.opacity')
|
||||
.data(opacities)
|
||||
.enter()
|
||||
.append('li')
|
||||
.attr('data-original-title', function(d) {
|
||||
return t('background.percent_brightness', { opacity: (d * 100) });
|
||||
})
|
||||
.on('click.set-opacity', setOpacity)
|
||||
.html("<div class='select-box'></div>")
|
||||
.call(bootstrap.tooltip()
|
||||
.placement('top'))
|
||||
.append('div')
|
||||
.attr('class', 'opacity')
|
||||
.style('opacity', String);
|
||||
|
||||
// Make sure there is an active selection by default
|
||||
opa.select('.opacity-options li:nth-child(2)')
|
||||
.classed('selected', true);
|
||||
|
||||
function selectLayer(d) {
|
||||
|
||||
content.selectAll('a.layer')
|
||||
.classed('selected', function(d) {
|
||||
return d.data.name === context.background().source().data.name;
|
||||
@@ -135,9 +88,16 @@ iD.ui.Background = function(context) {
|
||||
selectLayer(d);
|
||||
}
|
||||
|
||||
var layerList = content
|
||||
.append('ul')
|
||||
.attr('class', 'toggle-list fillL');
|
||||
function clickGpx(d) {
|
||||
d3.event.preventDefault();
|
||||
if (!_.isEmpty(context.map().layers[1].geojson())) {
|
||||
context.map().layers[1]
|
||||
.enable(!context.map().layers[1].enable());
|
||||
d3.select(this)
|
||||
.classed('selected', context.map().layers[1].enable());
|
||||
context.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
var layerLinks = layerList.selectAll('a.layer')
|
||||
@@ -169,26 +129,121 @@ iD.ui.Background = function(context) {
|
||||
return d.data.name;
|
||||
});
|
||||
|
||||
gpxLayerItem
|
||||
.classed('selected', function() {
|
||||
var gpxLayer = context.map().layers[1];
|
||||
return !_.isEmpty(gpxLayer.geojson()) &&
|
||||
gpxLayer.enable();
|
||||
});
|
||||
|
||||
layerLinks.exit()
|
||||
.remove();
|
||||
|
||||
selectLayer(context.background().source());
|
||||
}
|
||||
|
||||
context.map().on('move.background-update', _.debounce(update, 1000));
|
||||
function clickNudge(d) {
|
||||
var interval = window.setInterval(nudge, 100);
|
||||
|
||||
update();
|
||||
d3.select(this).on('mouseup', function() {
|
||||
window.clearInterval(interval);
|
||||
nudge();
|
||||
});
|
||||
|
||||
function nudge() {
|
||||
context.background().nudge(d[1], context.map().zoom());
|
||||
context.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
var content = selection.append('div')
|
||||
.attr('class', 'content fillD map-overlay hide'),
|
||||
tooltip = bootstrap.tooltip()
|
||||
.placement('right')
|
||||
.html(true)
|
||||
.title(iD.ui.tooltipHtml(t('background.description'), key)),
|
||||
button = selection.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'fillD')
|
||||
.on('click.background-toggle', toggle)
|
||||
.call(tooltip),
|
||||
opa = content
|
||||
.append('div')
|
||||
.attr('class', 'opacity-options-wrapper'),
|
||||
shown = false;
|
||||
|
||||
button.append('span')
|
||||
.attr('class', 'layers icon');
|
||||
|
||||
opa.append('h4')
|
||||
.text(t('background.title'));
|
||||
|
||||
context.surface().on('mousedown.background-outside', function() {
|
||||
setVisible(false);
|
||||
});
|
||||
|
||||
context.container().on('mousedown.background-outside', function() {
|
||||
setVisible(false);
|
||||
});
|
||||
|
||||
var opacityList = opa.append('ul')
|
||||
.attr('class', 'opacity-options');
|
||||
|
||||
opacityList.selectAll('div.opacity')
|
||||
.data(opacities)
|
||||
.enter()
|
||||
.append('li')
|
||||
.attr('data-original-title', function(d) {
|
||||
return t('background.percent_brightness', { opacity: (d * 100) });
|
||||
})
|
||||
.on('click.set-opacity', setOpacity)
|
||||
.html("<div class='select-box'></div>")
|
||||
.call(bootstrap.tooltip()
|
||||
.placement('top'))
|
||||
.append('div')
|
||||
.attr('class', 'opacity')
|
||||
.style('opacity', String);
|
||||
|
||||
// Make sure there is an active selection by default
|
||||
opa.select('.opacity-options li:nth-child(2)')
|
||||
.classed('selected', true);
|
||||
|
||||
var layerList = content
|
||||
.append('ul')
|
||||
.attr('class', 'toggle-list fillL');
|
||||
|
||||
var gpxLayerItem = content
|
||||
.append('ul')
|
||||
.attr('class', 'toggle-list fillL')
|
||||
.append('li')
|
||||
.append('a')
|
||||
.classed('layer-toggle-gpx', true)
|
||||
.call(bootstrap.tooltip()
|
||||
.title(t('gpx.drag_drop'))
|
||||
.placement('right'))
|
||||
.on('click.set-gpx', clickGpx);
|
||||
|
||||
gpxLayerItem
|
||||
.append('span')
|
||||
.attr('class', 'icon toggle');
|
||||
|
||||
gpxLayerItem.append('span')
|
||||
.text(t('gpx.local_layer'));
|
||||
|
||||
gpxLayerItem
|
||||
.append('a')
|
||||
.attr('class', 'icon geocode layer-extent')
|
||||
.on('click', function() {
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
context.map()
|
||||
.extent(d3.geo.bounds(context.map().layers[1].geojson()));
|
||||
});
|
||||
|
||||
var adjustments = content
|
||||
.append('div')
|
||||
.attr('class', 'adjustments pad1');
|
||||
|
||||
var directions = [
|
||||
['left', [1, 0]],
|
||||
['top', [0, -1]],
|
||||
['right', [-1, 0]],
|
||||
['bottom', [0, 1]]];
|
||||
|
||||
adjustments.append('a')
|
||||
.text(t('background.fix_misalignment'))
|
||||
.attr('href', '#')
|
||||
@@ -197,8 +252,7 @@ iD.ui.Background = function(context) {
|
||||
.on('click', function() {
|
||||
var exp = d3.select(this).classed('expanded');
|
||||
nudge_container.style('display', exp ? 'none' : 'block');
|
||||
d3.select(this)
|
||||
.classed('expanded', !exp);
|
||||
d3.select(this).classed('expanded', !exp);
|
||||
d3.event.preventDefault();
|
||||
});
|
||||
|
||||
@@ -212,20 +266,7 @@ iD.ui.Background = function(context) {
|
||||
.append('button')
|
||||
.attr('class', function(d) { return d[0] + ' nudge'; })
|
||||
.text(function(d) { return d[0]; })
|
||||
.on('mousedown', function(d) {
|
||||
|
||||
var interval = window.setInterval(nudge, 100);
|
||||
|
||||
d3.select(this).on('mouseup', function() {
|
||||
window.clearInterval(interval);
|
||||
nudge();
|
||||
});
|
||||
|
||||
function nudge() {
|
||||
context.background().nudge(d[1], context.map().zoom());
|
||||
context.redraw();
|
||||
}
|
||||
});
|
||||
.on('mousedown', clickNudge);
|
||||
|
||||
nudge_container.append('button')
|
||||
.text(t('background.reset'))
|
||||
@@ -235,8 +276,12 @@ iD.ui.Background = function(context) {
|
||||
context.redraw();
|
||||
});
|
||||
|
||||
var keybinding = d3.keybinding('background');
|
||||
context.map()
|
||||
.on('move.background-update', _.debounce(update, 1000));
|
||||
update();
|
||||
setOpacity(0.5);
|
||||
|
||||
var keybinding = d3.keybinding('background');
|
||||
keybinding.on(key, toggle);
|
||||
|
||||
d3.select(document)
|
||||
|
||||
Reference in New Issue
Block a user