mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
WIP merge 'gpx' and 'mvt' layers into single 'data' layer
This commit is contained in:
@@ -324,7 +324,7 @@ correspondence with entities:
|
||||
* `iD.svgLayers` - sets up a number of layers that ensure that map elements
|
||||
appear in an appropriate z-order.
|
||||
* `iD.svgOsm` - sets up the OSM-specific data layers
|
||||
* `iD.svgGpx` - draws gpx traces
|
||||
* `iD.svgData` - draws any other overlaid vector data (gpx, kml, geojson, mvt, pbf)
|
||||
* `iD.svgDebug` - draws debugging information
|
||||
|
||||
### Other UI
|
||||
|
||||
@@ -307,60 +307,30 @@ g.turn circle {
|
||||
}
|
||||
|
||||
|
||||
/* GPX Paths */
|
||||
/* Other Data (gpx, kml, geojson, mvt, pbf) */
|
||||
|
||||
.layer-gpx {
|
||||
.layer-geojson {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
path.gpx {
|
||||
.layer-geojson path {
|
||||
stroke: #ff26d4;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
text.gpxlabel-halo,
|
||||
text.gpxlabel {
|
||||
.layer-geojson text.label-halo,
|
||||
.layer-geojson text.label {
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
dominant-baseline: middle;
|
||||
}
|
||||
|
||||
text.gpxlabel {
|
||||
.layer-geojson text.label {
|
||||
fill: #ff26d4;
|
||||
}
|
||||
|
||||
text.gpxlabel-halo {
|
||||
opacity: 0.7;
|
||||
stroke: #000;
|
||||
stroke-width: 5px;
|
||||
stroke-miterlimit: 1;
|
||||
}
|
||||
|
||||
/* MVT Paths */
|
||||
|
||||
.layer-mvt {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
path.mvt {
|
||||
stroke: #ff26d4;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
text.mvtlabel-halo,
|
||||
text.mvtlabel {
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
dominant-baseline: middle;
|
||||
}
|
||||
|
||||
text.mvtlabel {
|
||||
fill: #ff26d4;
|
||||
}
|
||||
|
||||
text.mvtlabel-halo {
|
||||
.layer-geojson text.label-halo {
|
||||
opacity: 0.7;
|
||||
stroke: #000;
|
||||
stroke-width: 5px;
|
||||
|
||||
@@ -2566,8 +2566,7 @@ div.full-screen > button:hover {
|
||||
float: right;
|
||||
}
|
||||
|
||||
[dir='rtl'] .list-item-gpx-browse svg,
|
||||
[dir='rtl'] .list-item-mvt-browse svg {
|
||||
[dir='rtl'] .list-item-data-browse svg {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
|
||||
@@ -171,10 +171,10 @@ export function rendererBackground(context) {
|
||||
.filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
|
||||
.forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
|
||||
|
||||
var gpx = context.layers().layer('gpx');
|
||||
if (gpx && gpx.enabled() && gpx.hasGpx()) {
|
||||
var data = context.layers().layer('data');
|
||||
if (data && data.enabled() && data.hasData()) {
|
||||
// Include a string like '.gpx data file' or '.geojson data file'
|
||||
var match = gpx.getSrc().match(/(kml|gpx|(?:geo)?json)$/i);
|
||||
var match = data.getSrc().match(/(kml|gpx|pbf|mvt|(?:geo)?json)$/i);
|
||||
var extension = match ? ('.' + match[0].toLowerCase() + ' ') : '';
|
||||
imageryUsed.push(extension + 'data file');
|
||||
}
|
||||
@@ -184,14 +184,6 @@ export function rendererBackground(context) {
|
||||
imageryUsed.push('Bing Streetside');
|
||||
}
|
||||
|
||||
var mvt = context.layers().layer('mvt');
|
||||
if (mvt && mvt.enabled() && mvt.hasMvt()) {
|
||||
// Include a string like '.mvt data file' or '.geojson data file'
|
||||
var matchmvt = mvt.getSrc().match(/(pbf|mvt|(?:geo)?json)$/i);
|
||||
var extensionmvt = matchmvt ? ('.' + matchmvt[0].toLowerCase() + ' ') : '';
|
||||
imageryUsed.push(extensionmvt + 'data file');
|
||||
}
|
||||
|
||||
var mapillary_images = context.layers().layer('mapillary-images');
|
||||
if (mapillary_images && mapillary_images.enabled()) {
|
||||
imageryUsed.push('Mapillary Images');
|
||||
@@ -464,19 +456,12 @@ export function rendererBackground(context) {
|
||||
});
|
||||
|
||||
if (q.gpx) {
|
||||
var gpx = context.layers().layer('gpx');
|
||||
var gpx = context.layers().layer('data');
|
||||
if (gpx) {
|
||||
gpx.url(q.gpx);
|
||||
}
|
||||
}
|
||||
|
||||
if (q.mvt) {
|
||||
var mvt = context.layers().layer('mvt');
|
||||
if (mvt) {
|
||||
mvt.url(q.mvt);
|
||||
}
|
||||
}
|
||||
|
||||
if (q.offset) {
|
||||
var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
|
||||
return !isNaN(n) && n;
|
||||
|
||||
@@ -4,16 +4,24 @@ import _reduce from 'lodash-es/reduce';
|
||||
import _union from 'lodash-es/union';
|
||||
|
||||
import { geoBounds as d3_geoBounds } from 'd3-geo';
|
||||
import { text as d3_text } from 'd3-request';
|
||||
|
||||
import {
|
||||
request as d3_request,
|
||||
text as d3_text
|
||||
} from 'd3-request';
|
||||
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
|
||||
import toGeoJSON from '@mapbox/togeojson';
|
||||
import vt from '@mapbox/vector-tile';
|
||||
import Protobuf from 'pbf';
|
||||
|
||||
import { geoExtent, geoPolygonIntersectsPolygon } from '../geo';
|
||||
import { svgPath } from './index';
|
||||
import { utilDetect } from '../util/detect';
|
||||
import toGeoJSON from '@mapbox/togeojson';
|
||||
|
||||
|
||||
var _initialized = false;
|
||||
@@ -21,7 +29,7 @@ var _enabled = false;
|
||||
var _geojson;
|
||||
|
||||
|
||||
export function svgGpx(projection, context, dispatch) {
|
||||
export function svgData(projection, context, dispatch) {
|
||||
var _showLabels = true;
|
||||
var detected = utilDetect();
|
||||
var layer;
|
||||
@@ -42,24 +50,24 @@ export function svgGpx(projection, context, dispatch) {
|
||||
|
||||
d3_select('body')
|
||||
.attr('dropzone', 'copy')
|
||||
.on('drop.localgpx', function() {
|
||||
.on('drop.svgData', function() {
|
||||
d3_event.stopPropagation();
|
||||
d3_event.preventDefault();
|
||||
if (!detected.filedrop) return;
|
||||
drawGpx.files(d3_event.dataTransfer.files);
|
||||
drawData.files(d3_event.dataTransfer.files);
|
||||
})
|
||||
.on('dragenter.localgpx', over)
|
||||
.on('dragexit.localgpx', over)
|
||||
.on('dragover.localgpx', over);
|
||||
.on('dragenter.svgData', over)
|
||||
.on('dragexit.svgData', over)
|
||||
.on('dragover.svgData', over);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
function drawGpx(selection) {
|
||||
function drawData(selection) {
|
||||
var getPath = svgPath(projection).geojson;
|
||||
|
||||
layer = selection.selectAll('.layer-gpx')
|
||||
layer = selection.selectAll('.layer-geojson')
|
||||
.data(_enabled ? [0] : []);
|
||||
|
||||
layer.exit()
|
||||
@@ -67,7 +75,7 @@ export function svgGpx(projection, context, dispatch) {
|
||||
|
||||
layer = layer.enter()
|
||||
.append('g')
|
||||
.attr('class', 'layer-gpx')
|
||||
.attr('class', 'layer-geojson')
|
||||
.merge(layer);
|
||||
|
||||
|
||||
@@ -80,7 +88,7 @@ export function svgGpx(projection, context, dispatch) {
|
||||
|
||||
paths = paths.enter()
|
||||
.append('path')
|
||||
.attr('class', 'gpx')
|
||||
.attr('class', 'pathdata')
|
||||
.merge(paths);
|
||||
|
||||
paths
|
||||
@@ -91,8 +99,8 @@ export function svgGpx(projection, context, dispatch) {
|
||||
labelData = labelData.filter(getPath);
|
||||
|
||||
layer
|
||||
.call(drawLabels, 'gpxlabel-halo', labelData)
|
||||
.call(drawLabels, 'gpxlabel', labelData);
|
||||
.call(drawLabels, 'label-halo', labelData)
|
||||
.call(drawLabels, 'label', labelData);
|
||||
|
||||
|
||||
function drawLabels(selection, textClass, data) {
|
||||
@@ -126,11 +134,6 @@ export function svgGpx(projection, context, dispatch) {
|
||||
}
|
||||
|
||||
|
||||
function toDom(x) {
|
||||
return (new DOMParser()).parseFromString(x, 'text/xml');
|
||||
}
|
||||
|
||||
|
||||
function getExtension(fileName) {
|
||||
if (fileName === undefined) {
|
||||
return '';
|
||||
@@ -145,43 +148,76 @@ export function svgGpx(projection, context, dispatch) {
|
||||
}
|
||||
|
||||
|
||||
function parseSaveAndZoom(extension, data, src) {
|
||||
function toDom(textdata) {
|
||||
return (new DOMParser()).parseFromString(textdata, 'text/xml');
|
||||
}
|
||||
|
||||
|
||||
function vtToGeoJSON(bufferdata) {
|
||||
var tile = new vt.VectorTile(new Protobuf(bufferdata.data.response));
|
||||
var layers = Object.keys(tile.layers);
|
||||
if (!Array.isArray(layers)) { layers = [layers]; }
|
||||
|
||||
var collection = {type: 'FeatureCollection', features: []};
|
||||
|
||||
layers.forEach(function (layerID) {
|
||||
var layer = tile.layers[layerID];
|
||||
if (layer) {
|
||||
for (var i = 0; i < layer.length; i++) {
|
||||
var feature = layer.feature(i).toGeoJSON(bufferdata.zxy[2], bufferdata.zxy[3], bufferdata.zxy[1]);
|
||||
if (layers.length > 1) feature.properties.vt_layer = layerID;
|
||||
collection.features.push(feature);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
||||
function parseSaveAndZoom(extension, data, name) {
|
||||
switch (extension) {
|
||||
default:
|
||||
drawGpx.geojson(toGeoJSON.gpx(toDom(data)), src).fitZoom();
|
||||
case '.gpx':
|
||||
drawData.geojson(toGeoJSON.gpx(toDom(data)), name).fitZoom();
|
||||
break;
|
||||
case '.kml':
|
||||
drawGpx.geojson(toGeoJSON.kml(toDom(data)), src).fitZoom();
|
||||
drawData.geojson(toGeoJSON.kml(toDom(data)), name).fitZoom();
|
||||
break;
|
||||
case '.pbf':
|
||||
drawData.geojson(vtToGeoJSON(data), name).fitZoom();
|
||||
break;
|
||||
case '.mvt':
|
||||
drawData.geojson(vtToGeoJSON(data), name).fitZoom();
|
||||
break;
|
||||
case '.geojson':
|
||||
case '.json':
|
||||
drawGpx.geojson(JSON.parse(data), src).fitZoom();
|
||||
drawData.geojson(JSON.parse(data), name).fitZoom();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drawGpx.showLabels = function(_) {
|
||||
drawData.showLabels = function(val) {
|
||||
if (!arguments.length) return _showLabels;
|
||||
_showLabels = _;
|
||||
_showLabels = val;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
drawGpx.enabled = function(_) {
|
||||
drawData.enabled = function(val) {
|
||||
if (!arguments.length) return _enabled;
|
||||
_enabled = _;
|
||||
_enabled = val;
|
||||
dispatch.call('change');
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
drawGpx.hasGpx = function() {
|
||||
drawData.hasData = function() {
|
||||
return (!(_isEmpty(_geojson) || _isEmpty(_geojson.features)));
|
||||
};
|
||||
|
||||
|
||||
drawGpx.geojson = function(gj, src) {
|
||||
drawData.geojson = function(gj, src) {
|
||||
if (!arguments.length) return _geojson;
|
||||
if (_isEmpty(gj) || _isEmpty(gj.features)) return this;
|
||||
_geojson = gj;
|
||||
@@ -191,41 +227,82 @@ export function svgGpx(projection, context, dispatch) {
|
||||
};
|
||||
|
||||
|
||||
drawGpx.url = function(url) {
|
||||
d3_text(url, function(err, data) {
|
||||
if (!err) {
|
||||
var extension = getExtension(url);
|
||||
parseSaveAndZoom(extension, data, url);
|
||||
}
|
||||
});
|
||||
drawData.url = function(url) {
|
||||
var extension = getExtension(url);
|
||||
if (extension === 'mvt' || extension === 'pbf') {
|
||||
d3_request(url)
|
||||
.responseType('arraybuffer')
|
||||
.get(function(err, data) {
|
||||
if (err || !data) return;
|
||||
_src = url;
|
||||
var match = url.match(/(pbf|mvt)/i);
|
||||
var extension = match ? ('.' + match[0].toLowerCase()) : '';
|
||||
var zxy = url.match(/\/(\d+)\/(\d+)\/(\d+)/);
|
||||
var bufferdata = {
|
||||
data : data,
|
||||
zxy : zxy
|
||||
};
|
||||
parseSaveAndZoom(extension, bufferdata);
|
||||
});
|
||||
} else {
|
||||
d3_text(url, function(err, data) {
|
||||
if (!err) {
|
||||
parseSaveAndZoom(extension, data, url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
drawGpx.files = function(fileList) {
|
||||
drawData.files = function(fileList) {
|
||||
if (!fileList.length) return this;
|
||||
var f = fileList[0];
|
||||
var reader = new FileReader();
|
||||
var extension = getExtension(f.name);
|
||||
|
||||
reader.onload = (function(file) {
|
||||
var extension = getExtension(file.name);
|
||||
return function (e) {
|
||||
parseSaveAndZoom(extension, e.target.result, file.name);
|
||||
};
|
||||
})(f);
|
||||
if (extension === 'mvt' || extension === 'pbf') {
|
||||
reader.onload = (function(file) {
|
||||
return; // todo find x,y,z
|
||||
var data = [];
|
||||
var zxy = [0,0,0];
|
||||
|
||||
_src = file.name;
|
||||
var extension = getExtension(file.name);
|
||||
var bufferdata = {
|
||||
data: data,
|
||||
zxy: zxy
|
||||
};
|
||||
return function (e) {
|
||||
bufferdata.data = e.target.result;
|
||||
parseSaveAndZoom(extension, bufferdata);
|
||||
};
|
||||
})(f);
|
||||
|
||||
reader.readAsArrayBuffer(f);
|
||||
|
||||
} else {
|
||||
reader.onload = (function(file) {
|
||||
return function (e) {
|
||||
parseSaveAndZoom(extension, e.target.result, file.name);
|
||||
};
|
||||
})(f);
|
||||
|
||||
reader.readAsText(f);
|
||||
}
|
||||
|
||||
reader.readAsText(f);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
drawGpx.getSrc = function () {
|
||||
drawData.getSrc = function() {
|
||||
return _src;
|
||||
};
|
||||
|
||||
|
||||
drawGpx.fitZoom = function() {
|
||||
if (!this.hasGpx()) return this;
|
||||
drawData.fitZoom = function() {
|
||||
if (!this.hasData()) return this;
|
||||
|
||||
var map = context.map();
|
||||
var viewport = map.trimmedExtent().polygon();
|
||||
@@ -262,5 +339,5 @@ export function svgGpx(projection, context, dispatch) {
|
||||
|
||||
|
||||
init();
|
||||
return drawGpx;
|
||||
return drawData;
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
export { svgAreas } from './areas.js';
|
||||
export { svgData } from './data.js';
|
||||
export { svgDebug } from './debug.js';
|
||||
export { svgDefs } from './defs.js';
|
||||
export { svgGpx } from './gpx.js';
|
||||
export { svgMvt } from './mvt.js';
|
||||
export { svgIcon } from './icon.js';
|
||||
export { svgLabels } from './labels.js';
|
||||
export { svgLayers } from './layers.js';
|
||||
|
||||
@@ -7,10 +7,9 @@ import _reject from 'lodash-es/reject';
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
|
||||
import { svgData } from './data';
|
||||
import { svgDebug } from './debug';
|
||||
import { svgGpx } from './gpx';
|
||||
import { svgStreetside } from './streetside';
|
||||
import { svgMvt } from './mvt';
|
||||
import { svgMapillaryImages } from './mapillary_images';
|
||||
import { svgMapillarySigns } from './mapillary_signs';
|
||||
import { svgOpenstreetcamImages } from './openstreetcam_images';
|
||||
@@ -26,8 +25,7 @@ export function svgLayers(projection, context) {
|
||||
var layers = [
|
||||
{ id: 'osm', layer: svgOsm(projection, context, dispatch) },
|
||||
{ id: 'notes', layer: svgNotes(projection, context, dispatch) },
|
||||
{ id: 'gpx', layer: svgGpx(projection, context, dispatch) },
|
||||
{ id: 'mvt', layer: svgMvt(projection, context, dispatch) },
|
||||
{ id: 'data', layer: svgData(projection, context, dispatch) },
|
||||
{ id: 'streetside', layer: svgStreetside(projection, context, dispatch)},
|
||||
{ id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch) },
|
||||
{ id: 'mapillary-signs', layer: svgMapillarySigns(projection, context, dispatch) },
|
||||
|
||||
@@ -207,14 +207,14 @@ export function uiMapData(context) {
|
||||
}
|
||||
|
||||
|
||||
function drawGpxItem(selection) {
|
||||
var gpx = layers.layer('gpx');
|
||||
var hasGpx = gpx && gpx.hasGpx();
|
||||
var showsGpx = hasGpx && gpx.enabled();
|
||||
function drawDataItems(selection) {
|
||||
var dataLayer = layers.layer('data');
|
||||
var hasData = dataLayer && dataLayer.hasData();
|
||||
var showsData = hasData && dataLayer.enabled();
|
||||
|
||||
var ul = selection
|
||||
.selectAll('.layer-list-gpx')
|
||||
.data(gpx ? [0] : []);
|
||||
.selectAll('.layer-list-data')
|
||||
.data(dataLayer ? [0] : []);
|
||||
|
||||
// Exit
|
||||
ul.exit()
|
||||
@@ -223,15 +223,15 @@ export function uiMapData(context) {
|
||||
// Enter
|
||||
var ulEnter = ul.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-list-gpx');
|
||||
.attr('class', 'layer-list layer-list-data');
|
||||
|
||||
var liEnter = ulEnter
|
||||
.append('li')
|
||||
.attr('class', 'list-item-gpx');
|
||||
.attr('class', 'list-item-data');
|
||||
|
||||
liEnter
|
||||
.append('button')
|
||||
.attr('class', 'list-item-gpx-extent')
|
||||
.attr('class', 'list-item-data-extent')
|
||||
.call(tooltip()
|
||||
.title(t('gpx.zoom'))
|
||||
.placement((textDirection === 'rtl') ? 'right' : 'left')
|
||||
@@ -239,13 +239,13 @@ export function uiMapData(context) {
|
||||
.on('click', function() {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
gpx.fitZoom();
|
||||
dataLayer.fitZoom();
|
||||
})
|
||||
.call(svgIcon('#iD-icon-search'));
|
||||
|
||||
liEnter
|
||||
.append('button')
|
||||
.attr('class', 'list-item-gpx-browse')
|
||||
.attr('class', 'list-item-data-browse')
|
||||
.call(tooltip()
|
||||
.title(t('gpx.browse'))
|
||||
.placement((textDirection === 'rtl') ? 'right' : 'left')
|
||||
@@ -254,7 +254,7 @@ export function uiMapData(context) {
|
||||
d3_select(document.createElement('input'))
|
||||
.attr('type', 'file')
|
||||
.on('change', function() {
|
||||
gpx.files(d3_event.target.files);
|
||||
dataLayer.files(d3_event.target.files);
|
||||
})
|
||||
.node().click();
|
||||
})
|
||||
@@ -270,7 +270,7 @@ export function uiMapData(context) {
|
||||
labelEnter
|
||||
.append('input')
|
||||
.attr('type', 'checkbox')
|
||||
.on('change', function() { toggleLayer('gpx'); });
|
||||
.on('change', function() { toggleLayer('data'); });
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
@@ -280,96 +280,15 @@ export function uiMapData(context) {
|
||||
ul = ul
|
||||
.merge(ulEnter);
|
||||
|
||||
ul.selectAll('.list-item-gpx')
|
||||
.classed('active', showsGpx)
|
||||
ul.selectAll('.list-item-data')
|
||||
.classed('active', showsData)
|
||||
.selectAll('label')
|
||||
.classed('deemphasize', !hasGpx)
|
||||
.classed('deemphasize', !hasData)
|
||||
.selectAll('input')
|
||||
.property('disabled', !hasGpx)
|
||||
.property('checked', showsGpx);
|
||||
.property('disabled', !hasData)
|
||||
.property('checked', showsData);
|
||||
}
|
||||
|
||||
function drawMvtItem(selection) {
|
||||
var mvt = layers.layer('mvt'),
|
||||
hasMvt = mvt && mvt.hasMvt(),
|
||||
showsMvt = hasMvt && mvt.enabled();
|
||||
|
||||
var ul = selection
|
||||
.selectAll('.layer-list-mvt')
|
||||
.data(mvt ? [0] : []);
|
||||
|
||||
// Exit
|
||||
ul.exit()
|
||||
.remove();
|
||||
|
||||
// Enter
|
||||
var ulEnter = ul.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-list-mvt');
|
||||
|
||||
var liEnter = ulEnter
|
||||
.append('li')
|
||||
.attr('class', 'list-item-mvt');
|
||||
|
||||
liEnter
|
||||
.append('button')
|
||||
.attr('class', 'list-item-mvt-extent')
|
||||
.call(tooltip()
|
||||
.title(t('mvt.zoom'))
|
||||
.placement((textDirection === 'rtl') ? 'right' : 'left')
|
||||
)
|
||||
.on('click', function() {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
mvt.fitZoom();
|
||||
})
|
||||
.call(svgIcon('#iD-icon-search'));
|
||||
|
||||
liEnter
|
||||
.append('button')
|
||||
.attr('class', 'list-item-mvt-browse')
|
||||
.call(tooltip()
|
||||
.title(t('mvt.browse'))
|
||||
.placement((textDirection === 'rtl') ? 'right' : 'left')
|
||||
)
|
||||
.on('click', function() {
|
||||
d3_select(document.createElement('input'))
|
||||
.attr('type', 'file')
|
||||
.on('change', function() {
|
||||
mvt.files(d3_event.target.files);
|
||||
})
|
||||
.node().click();
|
||||
})
|
||||
.call(svgIcon('#iD-icon-geolocate'));
|
||||
|
||||
var labelEnter = liEnter
|
||||
.append('label')
|
||||
.call(tooltip()
|
||||
.title(t('mvt.drag_drop'))
|
||||
.placement('top')
|
||||
);
|
||||
|
||||
labelEnter
|
||||
.append('input')
|
||||
.attr('type', 'checkbox')
|
||||
.on('change', function() { toggleLayer('mvt'); });
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
.text(t('mvt.local_layer'));
|
||||
|
||||
// Update
|
||||
ul = ul
|
||||
.merge(ulEnter);
|
||||
|
||||
ul.selectAll('.list-item-mvt')
|
||||
.classed('active', showsMvt)
|
||||
.selectAll('label')
|
||||
.classed('deemphasize', !hasMvt)
|
||||
.selectAll('input')
|
||||
.property('disabled', !hasMvt)
|
||||
.property('checked', showsMvt);
|
||||
}
|
||||
|
||||
function drawListItems(selection, data, type, name, change, active) {
|
||||
var items = selection.selectAll('li')
|
||||
@@ -462,8 +381,7 @@ export function uiMapData(context) {
|
||||
_dataLayerContainer
|
||||
.call(drawOsmItems)
|
||||
.call(drawPhotoItems)
|
||||
.call(drawGpxItem);
|
||||
// .call(drawMvtItem);
|
||||
.call(drawDataItems);
|
||||
|
||||
_fillList
|
||||
.call(drawListItems, fills, 'radio', 'area_fill', setFill, showsFill);
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
} from '../geo';
|
||||
|
||||
import { rendererTileLayer } from '../renderer';
|
||||
import { svgDebug, svgGpx } from '../svg';
|
||||
import { svgDebug, svgData } from '../svg';
|
||||
import { utilSetTransform } from '../util';
|
||||
import { utilGetDimensions } from '../util/dimensions';
|
||||
|
||||
@@ -33,7 +33,7 @@ export function uiMapInMap(context) {
|
||||
var backgroundLayer = rendererTileLayer(context);
|
||||
var overlayLayers = {};
|
||||
var projection = geoRawMercator();
|
||||
var gpxLayer = svgGpx(projection, context).showLabels(false);
|
||||
var dataLayer = svgData(projection, context).showLabels(false);
|
||||
var debugLayer = svgDebug(projection, context);
|
||||
var zoom = d3_zoom()
|
||||
.scaleExtent([geoZoomToScale(0.5), geoZoomToScale(24)])
|
||||
@@ -242,7 +242,7 @@ export function uiMapInMap(context) {
|
||||
.append('svg')
|
||||
.attr('class', 'map-in-map-data')
|
||||
.merge(dataLayers)
|
||||
.call(gpxLayer)
|
||||
.call(dataLayer)
|
||||
.call(debugLayer);
|
||||
|
||||
|
||||
|
||||
@@ -115,12 +115,11 @@
|
||||
<script src='spec/services/taginfo.js'></script>
|
||||
|
||||
<script src='spec/svg/areas.js'></script>
|
||||
<script src='spec/svg/gpx.js'></script>
|
||||
<script src='spec/svg/data.js'></script>
|
||||
<script src='spec/svg/icon.js'></script>
|
||||
<script src='spec/svg/layers.js'></script>
|
||||
<script src='spec/svg/lines.js'></script>
|
||||
<script src='spec/svg/midpoints.js'></script>
|
||||
<script src='spec/svg/mvt.js'></script>
|
||||
<script src='spec/svg/osm.js'></script>
|
||||
<script src='spec/svg/points.js'></script>
|
||||
<script src='spec/svg/svg.js'></script>
|
||||
@@ -149,4 +148,4 @@
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('iD.svgGpx', function () {
|
||||
describe('iD.svgData', function () {
|
||||
var context;
|
||||
var surface;
|
||||
var dispatch = d3.dispatch('change');
|
||||
@@ -41,19 +41,19 @@ describe('iD.svgGpx', function () {
|
||||
});
|
||||
|
||||
|
||||
it('creates layer-gpx', function () {
|
||||
var render = iD.svgGpx(projection, context, dispatch);
|
||||
it('creates layer-geojson', function () {
|
||||
var render = iD.svgData(projection, context, dispatch);
|
||||
surface.call(render);
|
||||
|
||||
var layers = surface.selectAll('g.layer-gpx').nodes();
|
||||
var layers = surface.selectAll('g.layer-geojson').nodes();
|
||||
expect(layers.length).to.eql(1);
|
||||
});
|
||||
|
||||
it('draws geojson', function () {
|
||||
var render = iD.svgGpx(projection, context, dispatch).geojson(gj);
|
||||
var render = iD.svgData(projection, context, dispatch).geojson(gj);
|
||||
surface.call(render);
|
||||
|
||||
var path = surface.selectAll('path.gpx');
|
||||
var path = surface.selectAll('path');
|
||||
expect(path.nodes().length).to.eql(1);
|
||||
expect(path.attr('d')).to.match(/^M.*z$/);
|
||||
});
|
||||
@@ -61,30 +61,30 @@ describe('iD.svgGpx', function () {
|
||||
describe('#files', function() {
|
||||
it('handles gpx files', function () {
|
||||
var files = '../../data/gpxtest.gpx';
|
||||
var render = iD.svgGpx(projection, context, dispatch).files(files);
|
||||
var render = iD.svgData(projection, context, dispatch).files(files);
|
||||
surface.call(render);
|
||||
|
||||
var path = surface.selectAll('path.gpx');
|
||||
var path = surface.selectAll('path');
|
||||
expect(path.nodes().length).to.eql(1);
|
||||
expect(path.attr('d')).to.match(/^M.*z$/);
|
||||
});
|
||||
|
||||
it('handles geojson files', function () {
|
||||
var files = '../../data/gpxtest.json';
|
||||
var render = iD.svgGpx(projection, context, dispatch).files(files);
|
||||
var render = iD.svgData(projection, context, dispatch).files(files);
|
||||
surface.call(render);
|
||||
|
||||
var path = surface.selectAll('path.gpx');
|
||||
var path = surface.selectAll('path');
|
||||
expect(path.nodes().length).to.eql(1);
|
||||
expect(path.attr('d')).to.match(/^M.*z$/);
|
||||
});
|
||||
|
||||
it('handles kml files', function () {
|
||||
var files = '../../data/gpxtest.kml';
|
||||
var render = iD.svgGpx(projection, context, dispatch).files(files);
|
||||
var render = iD.svgData(projection, context, dispatch).files(files);
|
||||
surface.call(render);
|
||||
|
||||
var path = surface.selectAll('path.gpx');
|
||||
var path = surface.selectAll('path');
|
||||
expect(path.nodes().length).to.eql(1);
|
||||
expect(path.attr('d')).to.match(/^M.*z$/);
|
||||
});
|
||||
@@ -93,25 +93,25 @@ describe('iD.svgGpx', function () {
|
||||
|
||||
describe('#showLabels', function() {
|
||||
it('shows labels by default', function () {
|
||||
var render = iD.svgGpx(projection, context, dispatch).geojson(gj);
|
||||
var render = iD.svgData(projection, context, dispatch).geojson(gj);
|
||||
surface.call(render);
|
||||
|
||||
var label = surface.selectAll('text.gpxlabel');
|
||||
var label = surface.selectAll('text.label');
|
||||
expect(label.nodes().length).to.eql(1);
|
||||
expect(label.text()).to.eql('New Jersey');
|
||||
|
||||
var halo = surface.selectAll('text.gpxlabel-halo');
|
||||
var halo = surface.selectAll('text.label-halo');
|
||||
expect(halo.nodes().length).to.eql(1);
|
||||
expect(halo.text()).to.eql('New Jersey');
|
||||
});
|
||||
|
||||
|
||||
it('hides labels with showLabels(false)', function () {
|
||||
var render = iD.svgGpx(projection, context, dispatch).geojson(gj).showLabels(false);
|
||||
var render = iD.svgData(projection, context, dispatch).geojson(gj).showLabels(false);
|
||||
surface.call(render);
|
||||
|
||||
expect(surface.selectAll('text.gpxlabel').empty()).to.be.ok;
|
||||
expect(surface.selectAll('text.gpxlabel-halo').empty()).to.be.ok;
|
||||
expect(surface.selectAll('text.label').empty()).to.be.ok;
|
||||
expect(surface.selectAll('text.label-halo').empty()).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,16 +26,15 @@ describe('iD.svgLayers', function () {
|
||||
it('creates default data layers', function () {
|
||||
container.call(iD.svgLayers(projection, context));
|
||||
var nodes = container.selectAll('svg .data-layer').nodes();
|
||||
expect(nodes.length).to.eql(9);
|
||||
expect(nodes.length).to.eql(8);
|
||||
expect(d3.select(nodes[0]).classed('data-layer-osm')).to.be.true;
|
||||
expect(d3.select(nodes[1]).classed('data-layer-notes')).to.be.true;
|
||||
expect(d3.select(nodes[2]).classed('data-layer-gpx')).to.be.true;
|
||||
expect(d3.select(nodes[3]).classed('data-layer-mvt')).to.be.true;
|
||||
expect(d3.select(nodes[4]).classed('data-layer-streetside')).to.be.true;
|
||||
expect(d3.select(nodes[5]).classed('data-layer-mapillary-images')).to.be.true;
|
||||
expect(d3.select(nodes[6]).classed('data-layer-mapillary-signs')).to.be.true;
|
||||
expect(d3.select(nodes[7]).classed('data-layer-openstreetcam-images')).to.be.true;
|
||||
expect(d3.select(nodes[8]).classed('data-layer-debug')).to.be.true;
|
||||
expect(d3.select(nodes[2]).classed('data-layer-data')).to.be.true;
|
||||
expect(d3.select(nodes[3]).classed('data-layer-streetside')).to.be.true;
|
||||
expect(d3.select(nodes[4]).classed('data-layer-mapillary-images')).to.be.true;
|
||||
expect(d3.select(nodes[5]).classed('data-layer-mapillary-signs')).to.be.true;
|
||||
expect(d3.select(nodes[6]).classed('data-layer-openstreetcam-images')).to.be.true;
|
||||
expect(d3.select(nodes[7]).classed('data-layer-debug')).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user