mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 21:48:20 +02:00
Draft: still in progress
This commit is contained in:
+32
-4
@@ -31,12 +31,14 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function init() {
|
||||
console.log('init() called');
|
||||
if (_initialized) return; // run once
|
||||
|
||||
_geojson = {};
|
||||
_enabled = true;
|
||||
|
||||
function over(d3_event) {
|
||||
console.log('over() called');
|
||||
d3_event.stopPropagation();
|
||||
d3_event.preventDefault();
|
||||
d3_event.dataTransfer.dropEffect = 'copy';
|
||||
@@ -59,6 +61,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function getService() {
|
||||
console.log('getService() called');
|
||||
if (services.vectorTile && !_vtService) {
|
||||
_vtService = services.vectorTile;
|
||||
_vtService.event.on('loadedData', throttledRedraw);
|
||||
@@ -71,6 +74,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function showLayer() {
|
||||
console.log('showLayer() called');
|
||||
layerOn();
|
||||
|
||||
layer
|
||||
@@ -83,6 +87,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function hideLayer() {
|
||||
console.log('hideLayer() called');
|
||||
throttledRedraw.cancel();
|
||||
|
||||
layer
|
||||
@@ -94,11 +99,13 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function layerOn() {
|
||||
console.log('layerOn() called');
|
||||
layer.style('display', 'block');
|
||||
}
|
||||
|
||||
|
||||
function layerOff() {
|
||||
console.log('layerOff() called');
|
||||
layer.selectAll('.viewfield-group').remove();
|
||||
layer.style('display', 'none');
|
||||
}
|
||||
@@ -106,6 +113,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
// ensure that all geojson features in a collection have IDs
|
||||
function ensureIDs(gj) {
|
||||
console.log('ensureIDs() called');
|
||||
if (!gj) return null;
|
||||
|
||||
if (gj.type === 'FeatureCollection') {
|
||||
@@ -121,6 +129,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
// ensure that each single Feature object has a unique ID
|
||||
function ensureFeatureID(feature) {
|
||||
console.log('ensureFeatureID() called');
|
||||
if (!feature) return;
|
||||
feature.__featurehash__ = utilHashcode(stringify(feature));
|
||||
return feature;
|
||||
@@ -129,6 +138,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
// Prefer an array of Features instead of a FeatureCollection
|
||||
function getFeatures(gj) {
|
||||
console.log('getFeatures() called');
|
||||
if (!gj) return [];
|
||||
|
||||
if (gj.type === 'FeatureCollection') {
|
||||
@@ -140,21 +150,25 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function featureKey(d) {
|
||||
console.log('featureKey() called');
|
||||
return d.__featurehash__;
|
||||
}
|
||||
|
||||
|
||||
function isPolygon(d) {
|
||||
console.log('isPolygon() called');
|
||||
return d.geometry.type === 'Polygon' || d.geometry.type === 'MultiPolygon';
|
||||
}
|
||||
|
||||
|
||||
function clipPathID(d) {
|
||||
console.log('clipPathID() called');
|
||||
return 'ideditor-data-' + d.__featurehash__ + '-clippath';
|
||||
}
|
||||
|
||||
|
||||
function featureClasses(d) {
|
||||
console.log('featureClasses() called');
|
||||
return [
|
||||
'data' + d.__featurehash__,
|
||||
d.geometry.type,
|
||||
@@ -165,6 +179,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function drawData(selection) {
|
||||
console.log('drawData() called');
|
||||
var vtService = getService();
|
||||
var getPath = svgPath(projection).geojson;
|
||||
var getAreaPath = svgPath(projection, null, true).geojson;
|
||||
@@ -269,6 +284,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function drawLabels(selection, textClass, data) {
|
||||
console.log('drawLabels() called');
|
||||
var labelPath = d3_geoPath(projection);
|
||||
var labelData = data.filter(function(d) {
|
||||
return _showLabels && d.properties && (d.properties.desc || d.properties.name);
|
||||
@@ -302,6 +318,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function getExtension(fileName) {
|
||||
console.log('getExtension() called');
|
||||
if (!fileName) return;
|
||||
|
||||
var re = /\.(gpx|kml|(geo)?json|png)$/i;
|
||||
@@ -311,11 +328,13 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
function xmlToDom(textdata) {
|
||||
console.log('xmlToDom() called');
|
||||
return (new DOMParser()).parseFromString(textdata, 'text/xml');
|
||||
}
|
||||
|
||||
|
||||
function stringifyGeojsonProperties(feature) {
|
||||
console.log('stringifyGeojsonProperties() called');
|
||||
const properties = feature.properties;
|
||||
for (const key in properties) {
|
||||
const property = properties[key];
|
||||
@@ -331,6 +350,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.setFile = function(extension, data) {
|
||||
console.log('drawData.setFile called');
|
||||
_template = null;
|
||||
_fileList = null;
|
||||
_geojson = null;
|
||||
@@ -353,11 +373,11 @@ export function svgData(projection, context, dispatch) {
|
||||
stringifyGeojsonProperties(gj);
|
||||
}
|
||||
break;
|
||||
case '.png':
|
||||
// case '.png':
|
||||
// xx = JSON.parse(data);
|
||||
console.log('Hello world!');
|
||||
console.log(data);
|
||||
break;
|
||||
// console.log('Hello world!');
|
||||
// console.log(data);
|
||||
// break;
|
||||
}
|
||||
|
||||
gj = gj || {};
|
||||
@@ -373,6 +393,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.showLabels = function(val) {
|
||||
console.log('drawData.showLabels called');
|
||||
if (!arguments.length) return _showLabels;
|
||||
|
||||
_showLabels = val;
|
||||
@@ -381,6 +402,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.enabled = function(val) {
|
||||
console.log('drawData.enabled called');
|
||||
if (!arguments.length) return _enabled;
|
||||
|
||||
_enabled = val;
|
||||
@@ -396,12 +418,14 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.hasData = function() {
|
||||
console.log('drawData.hasData called');
|
||||
var gj = _geojson || {};
|
||||
return !!(_template || Object.keys(gj).length);
|
||||
};
|
||||
|
||||
|
||||
drawData.template = function(val, src) {
|
||||
console.log('drawData.template called');
|
||||
if (!arguments.length) return _template;
|
||||
|
||||
// test source against OSM imagery blocklists..
|
||||
@@ -440,6 +464,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.geojson = function(gj, src) {
|
||||
console.log('drawData.geojson called');
|
||||
if (!arguments.length) return _geojson;
|
||||
|
||||
_template = null;
|
||||
@@ -459,6 +484,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.fileList = function(fileList) {
|
||||
console.log('drawData.fileList called');
|
||||
if (!arguments.length) return _fileList;
|
||||
|
||||
_template = null;
|
||||
@@ -483,6 +509,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.url = function(url, defaultExtension) {
|
||||
console.log('drawData.url called');
|
||||
_template = null;
|
||||
_fileList = null;
|
||||
_geojson = null;
|
||||
@@ -515,6 +542,7 @@ export function svgData(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawData.fitZoom = function() {
|
||||
console.log('drawData.fitZoom called');
|
||||
var features = getFeatures(_geojson);
|
||||
if (!features.length) return;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
|
||||
import { svgData } from './data';
|
||||
import { svgLocalPhotos} from './local_photos';
|
||||
import { svgDebug } from './debug';
|
||||
import { svgGeolocate } from './geolocate';
|
||||
import { svgKeepRight } from './keepRight';
|
||||
@@ -27,6 +28,7 @@ export function svgLayers(projection, context) {
|
||||
{ id: 'osm', layer: svgOsm(projection, context, dispatch) },
|
||||
{ id: 'notes', layer: svgNotes(projection, context, dispatch) },
|
||||
{ id: 'data', layer: svgData(projection, context, dispatch) },
|
||||
{ id: 'local-photos', layer: svgLocalPhotos(projection, context, dispatch) },
|
||||
{ id: 'keepRight', layer: svgKeepRight(projection, context, dispatch) },
|
||||
{ id: 'improveOSM', layer: svgImproveOSM(projection, context, dispatch) },
|
||||
{ id: 'osmose', layer: svgOsmose(projection, context, dispatch) },
|
||||
|
||||
@@ -0,0 +1,440 @@
|
||||
import _throttle from 'lodash-es/throttle';
|
||||
|
||||
import { utilDetect } from '../util/detect';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
import { svgPath, svgPointTransform } from './helpers';
|
||||
// import { services } from '../services';
|
||||
// Modern Node.js can import CommonJS
|
||||
import exifr from 'exifr'; // => exifr/dist/full.umd.cjs
|
||||
|
||||
// new
|
||||
var _initialized = false;
|
||||
var _enabled = false;
|
||||
|
||||
export function svgLocalPhotos(projection, context, dispatch) {
|
||||
// required
|
||||
const throttledRedraw = _throttle(function () { dispatch.call('change'); }, 1000);
|
||||
const minZoom = 12;
|
||||
const minMarkerZoom = 16;
|
||||
const minViewfieldZoom = 18;
|
||||
var detected = utilDetect();
|
||||
let layer = d3_select(null);
|
||||
// maybe required
|
||||
// let _mapillary;
|
||||
var _fileList;
|
||||
|
||||
// instead of svgLocalPhotos.something, using global variable at top
|
||||
// function init() {
|
||||
// if (svgMapillaryImages.initialized) return; // run once
|
||||
// svgMapillaryImages.enabled = false;
|
||||
// svgMapillaryImages.initialized = true;
|
||||
// }
|
||||
|
||||
// new
|
||||
function init() {
|
||||
console.log('inti() called');
|
||||
if (_initialized) return; // run once
|
||||
|
||||
_enabled = true;
|
||||
|
||||
function over(d3_event) {
|
||||
d3_event.stopPropagation();
|
||||
d3_event.preventDefault();
|
||||
d3_event.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
|
||||
context.container()
|
||||
.attr('dropzone', 'copy')
|
||||
// .on('drop.svgData', function(d3_event) {
|
||||
.on('drop.svgLocalPhotos', function(d3_event) {
|
||||
d3_event.stopPropagation();
|
||||
d3_event.preventDefault();
|
||||
if (!detected.filedrop) return;
|
||||
drawPhotos.fileList(d3_event.dataTransfer.files);
|
||||
})
|
||||
// .on('dragenter.svgData', over)
|
||||
// .on('dragexit.svgData', over)
|
||||
// .on('dragover.svgData', over);
|
||||
.on('dragenter.svgLocalPhotos', over)
|
||||
.on('dragexit.svgLocalPhotos', over)
|
||||
.on('dragover.svgLocalPhotos', over);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
function showLayer() {
|
||||
console.log('showLayer() called');
|
||||
// if images are not available return
|
||||
// const service = getService();
|
||||
// if (!service) return;
|
||||
|
||||
// same as layerOn() in data.js
|
||||
editOn();
|
||||
|
||||
layer
|
||||
.style('opacity', 0)
|
||||
.transition()
|
||||
.duration(250)
|
||||
.style('opacity', 1)
|
||||
.on('end', function () { dispatch.call('change'); });
|
||||
}
|
||||
|
||||
|
||||
function hideLayer() {
|
||||
console.log('hideLayer() called');
|
||||
throttledRedraw.cancel();
|
||||
|
||||
layer
|
||||
.transition()
|
||||
.duration(250)
|
||||
.style('opacity', 0)
|
||||
.on('end', editOff);
|
||||
}
|
||||
|
||||
// same as layerOn() in data.js
|
||||
function editOn() {
|
||||
console.log('editOn() called');
|
||||
layer.style('display', 'block');
|
||||
}
|
||||
|
||||
|
||||
// same as layerOff() in data.js
|
||||
function editOff() {
|
||||
console.log('editOff() called');
|
||||
layer.selectAll('.viewfield-group').remove();
|
||||
layer.style('display', 'none');
|
||||
}
|
||||
|
||||
// opens the image at bottom left
|
||||
function click(d3_event, image) {
|
||||
console.log('click() called');
|
||||
// const service = getService();
|
||||
// if (!service) return;
|
||||
|
||||
// service
|
||||
// .ensureViewerLoaded(context)
|
||||
// .then(function() {
|
||||
// service
|
||||
// .selectImage(context, image.id)
|
||||
// .showViewer(context);
|
||||
// });
|
||||
|
||||
context.map().centerEase(image.loc);
|
||||
}
|
||||
|
||||
|
||||
function mouseover(d3_event, image) {
|
||||
console.log('mouseover() called');
|
||||
// const service = getService();
|
||||
|
||||
// if (service) service.setStyles(context, image);
|
||||
}
|
||||
|
||||
|
||||
function mouseout() {
|
||||
console.log('mouseout() called');
|
||||
// const service = getService();
|
||||
// if (service) service.setStyles(context, null);
|
||||
}
|
||||
|
||||
// if you want to put any image with geo coordinates
|
||||
// this is coordinates transformation
|
||||
// converting gps coordinates on screen
|
||||
function transform(d) {
|
||||
console.log('transform() called');
|
||||
let t = svgPointTransform(projection)(d);
|
||||
if (d.ca) {
|
||||
t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
// a sequence is a list of images
|
||||
// no need to filter sequence
|
||||
// function filterSequences(sequences) {...}
|
||||
|
||||
// puts the images on the map
|
||||
function update() {
|
||||
console.log('update() called');
|
||||
const z = ~~context.map().zoom();
|
||||
const showMarkers = (z >= minMarkerZoom);
|
||||
const showViewfields = (z >= minViewfieldZoom);
|
||||
|
||||
// const service = getService();
|
||||
// let sequences = (service ? service.sequences(projection) : []);
|
||||
// let images = (service && showMarkers ? service.images(projection) : []);
|
||||
|
||||
// images = filterImages(images);
|
||||
// sequences = filterSequences(sequences, service);
|
||||
|
||||
// service.filterViewer(context);
|
||||
|
||||
let traces = layer.selectAll('.sequences').selectAll('.sequence');
|
||||
// .data(sequences, function(d) { return d.properties.id; });
|
||||
|
||||
// exit
|
||||
traces.exit()
|
||||
.remove();
|
||||
|
||||
// enter/update
|
||||
traces = traces.enter()
|
||||
.append('path')
|
||||
.attr('class', 'sequence')
|
||||
.merge(traces)
|
||||
.attr('d', svgPath(projection).geojson);
|
||||
|
||||
|
||||
const groups = layer.selectAll('.markers').selectAll('.viewfield-group');
|
||||
// .data(images, function(d) { return d.id; });
|
||||
|
||||
// exit
|
||||
groups.exit()
|
||||
.remove();
|
||||
|
||||
// enter
|
||||
const groupsEnter = groups.enter()
|
||||
.append('g')
|
||||
.attr('class', 'viewfield-group')
|
||||
.on('mouseenter', mouseover)
|
||||
.on('mouseleave', mouseout)
|
||||
.on('click', click);
|
||||
|
||||
groupsEnter
|
||||
.append('g')
|
||||
.attr('class', 'viewfield-scale');
|
||||
|
||||
// update
|
||||
const markers = groups
|
||||
.merge(groupsEnter)
|
||||
.sort(function(a, b) {
|
||||
return b.loc[1] - a.loc[1]; // sort Y
|
||||
})
|
||||
.attr('transform', transform)
|
||||
.select('.viewfield-scale');
|
||||
|
||||
|
||||
markers.selectAll('circle')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('circle')
|
||||
.attr('dx', '0')
|
||||
.attr('dy', '0')
|
||||
.attr('r', '6');
|
||||
|
||||
const viewfields = markers.selectAll('.viewfield')
|
||||
.data(showViewfields ? [0] : []);
|
||||
|
||||
viewfields.exit()
|
||||
.remove();
|
||||
|
||||
viewfields.enter() // viewfields may or may not be drawn...
|
||||
.insert('path', 'circle') // but if they are, draw below the circles
|
||||
.attr('class', 'viewfield')
|
||||
.classed('pano', function() { return this.parentNode.__data__.is_pano; })
|
||||
.attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
|
||||
.attr('d', viewfieldPath);
|
||||
|
||||
function viewfieldPath() {
|
||||
console.log('viewfieldPath() called');
|
||||
if (this.parentNode.__data__.is_pano) {
|
||||
return 'M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0';
|
||||
} else {
|
||||
return 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// draws the actual images
|
||||
// create your onw css for this
|
||||
function drawPhotos(selection) {
|
||||
console.log('drawPhotos fn called');
|
||||
// const enabled = svgMapillaryImages.enabled;
|
||||
const enabled = _enabled;
|
||||
// const service = getService();
|
||||
|
||||
// layer = selection.selectAll('.local-photos')
|
||||
// layer = selection.selectAll('.layer-local-photos');
|
||||
// layer = selection.selectAll('.data');
|
||||
// .data(service ? [0] : []);
|
||||
// .data([0]);
|
||||
|
||||
// layer.exit()
|
||||
// .remove();
|
||||
|
||||
// const layerEnter = layer.enter()
|
||||
// .append('g')
|
||||
// // .attr('class', 'layer-local-photos')
|
||||
// .attr('class', 'layer-mapillary')
|
||||
// .style('display', enabled ? 'block' : 'none');
|
||||
|
||||
// layerEnter
|
||||
// .append('g')
|
||||
// .attr('class', 'sequences');
|
||||
|
||||
// layerEnter
|
||||
// .append('g')
|
||||
// .attr('class', 'markers');
|
||||
|
||||
// layer = layerEnter
|
||||
// .merge(layer);
|
||||
|
||||
// if (enabled) {
|
||||
// if (~~context.map().zoom() >= minZoom) {
|
||||
// editOn();
|
||||
// update();
|
||||
// // service.loadImages(projection);
|
||||
// } else {
|
||||
// editOff();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// drawImages.enabled = function(_) {
|
||||
// if (!arguments.length) return svgMapillaryImages.enabled;
|
||||
// svgMapillaryImages.enabled = _;
|
||||
// if (svgMapillaryImages.enabled) {
|
||||
// showLayer();
|
||||
// context.photos().on('change.mapillary_images', update);
|
||||
// } else {
|
||||
// hideLayer();
|
||||
// context.photos().on('change.mapillary_images', null);
|
||||
// }
|
||||
// dispatch.call('change');
|
||||
// return this;
|
||||
// };
|
||||
|
||||
// new
|
||||
// use this since using global value
|
||||
// slightly modified for photos
|
||||
drawPhotos.enabled = function(val) {
|
||||
console.log('drawPhotos.enabled called');
|
||||
if (!arguments.length) return _enabled;
|
||||
|
||||
_enabled = val;
|
||||
if (_enabled) {
|
||||
showLayer();
|
||||
// context.photos().on('change.mapillary_images', update);
|
||||
context.photos().on('change.local_photos', update);
|
||||
} else {
|
||||
hideLayer();
|
||||
// context.photos().on('change.mapillary_images', null);
|
||||
context.photos().on('change.local_photos', null);
|
||||
}
|
||||
|
||||
dispatch.call('change');
|
||||
return this;
|
||||
};
|
||||
|
||||
function extract_exif(image) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = function () {
|
||||
exifr.parse(image)
|
||||
.then(output => console.log('Image parsed', output));
|
||||
};
|
||||
|
||||
reader.readAsText(image);
|
||||
}
|
||||
|
||||
// Step 2
|
||||
// this is where the exif parsing library comes into play
|
||||
// get all info from the image
|
||||
// drawPhotos.setFile = function(extension, data) {
|
||||
// drawPhotos.setFile = function(fileList) {
|
||||
drawPhotos.setFile = function(file) {
|
||||
console.log('drawPhotos.setFile called');
|
||||
_fileList = null;
|
||||
|
||||
// fileList.forEach(image =>
|
||||
// extract_exif(image)
|
||||
// .then(console.log('All images parsed successfully'))
|
||||
// .catch(err => console.log(err))
|
||||
// );
|
||||
|
||||
extract_exif(file);
|
||||
|
||||
dispatch.call('change');
|
||||
return this;
|
||||
};
|
||||
|
||||
// Step 1: entry point
|
||||
drawPhotos.fileList = function(fileList) {
|
||||
console.log('drawPhotos.fileList called');
|
||||
console.log('Step 2: fileList read in local_photos.js', fileList);
|
||||
// if (!arguments.length) return _fileList;
|
||||
|
||||
_fileList = fileList;
|
||||
|
||||
if (!fileList || !fileList.length) return this;
|
||||
// its just fetching one entry
|
||||
// fetch all for local photos
|
||||
// probablay a promise is required
|
||||
var f = fileList[0];
|
||||
drawPhotos.setFile(f);
|
||||
|
||||
// var reader = new FileReader();
|
||||
// reader.onload = (function() {
|
||||
// return function(e) {
|
||||
// // Step 2
|
||||
// drawPhotos.setFile(extension, e.target.result);
|
||||
// };
|
||||
// })(f);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// new
|
||||
// when all photos are uploaded, zoom to see them all
|
||||
drawPhotos.fitZoom = function() {
|
||||
console.log('drawPhotos.fitZoom called');
|
||||
// var features = getFeatures(_geojson);
|
||||
// if (!features.length) return;
|
||||
|
||||
var map = context.map();
|
||||
var viewport = map.trimmedExtent().polygon();
|
||||
// features is not defined
|
||||
// var coords = features.reduce(function(coords) {
|
||||
// var geom = feature.geometry;
|
||||
// if (!geom) return coords;
|
||||
|
||||
// var c = geom.coordinates;
|
||||
|
||||
// /* eslint-disable no-fallthrough */
|
||||
// switch (geom.type) {
|
||||
// case 'Point':
|
||||
// c = [c];
|
||||
// case 'MultiPoint':
|
||||
// case 'LineString':
|
||||
// break;
|
||||
|
||||
// case 'MultiPolygon':
|
||||
// // c = utilArrayFlatten(c);
|
||||
// case 'Polygon':
|
||||
// case 'MultiLineString':
|
||||
// // c = utilArrayFlatten(c);
|
||||
// break;
|
||||
// }
|
||||
// /* eslint-enable no-fallthrough */
|
||||
|
||||
// return utilArrayUnion(coords, c);
|
||||
// }, []);
|
||||
|
||||
// if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
|
||||
// var extent = geoExtent(d3_geoBounds({ type: 'LineString', coordinates: coords }));
|
||||
// map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
|
||||
// }
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
drawPhotos.supported = function() {
|
||||
console.log('drawPhotos.supported called');
|
||||
// return !!getService();
|
||||
};
|
||||
|
||||
|
||||
init();
|
||||
return drawPhotos;
|
||||
}
|
||||
@@ -15,6 +15,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function init() {
|
||||
console.log('init() called');
|
||||
if (svgMapillaryImages.initialized) return; // run once
|
||||
svgMapillaryImages.enabled = false;
|
||||
svgMapillaryImages.initialized = true;
|
||||
@@ -22,6 +23,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function getService() {
|
||||
console.log('getService() called');
|
||||
if (services.mapillary && !_mapillary) {
|
||||
_mapillary = services.mapillary;
|
||||
_mapillary.event.on('loadedImages', throttledRedraw);
|
||||
@@ -34,6 +36,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function showLayer() {
|
||||
console.log('showLayer() called');
|
||||
const service = getService();
|
||||
if (!service) return;
|
||||
|
||||
@@ -49,6 +52,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function hideLayer() {
|
||||
console.log('hideLayer() called');
|
||||
throttledRedraw.cancel();
|
||||
|
||||
layer
|
||||
@@ -60,17 +64,20 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function editOn() {
|
||||
console.log('editOn() called');
|
||||
layer.style('display', 'block');
|
||||
}
|
||||
|
||||
|
||||
function editOff() {
|
||||
console.log('editOff() called');
|
||||
layer.selectAll('.viewfield-group').remove();
|
||||
layer.style('display', 'none');
|
||||
}
|
||||
|
||||
|
||||
function click(d3_event, image) {
|
||||
console.log('click() called');
|
||||
const service = getService();
|
||||
if (!service) return;
|
||||
|
||||
@@ -87,6 +94,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function mouseover(d3_event, image) {
|
||||
console.log('mouseover() called');
|
||||
const service = getService();
|
||||
|
||||
if (service) service.setStyles(context, image);
|
||||
@@ -94,12 +102,14 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function mouseout() {
|
||||
console.log('mouseout() called');
|
||||
const service = getService();
|
||||
if (service) service.setStyles(context, null);
|
||||
}
|
||||
|
||||
|
||||
function transform(d) {
|
||||
console.log('transform() called');
|
||||
let t = svgPointTransform(projection)(d);
|
||||
if (d.ca) {
|
||||
t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
|
||||
@@ -109,6 +119,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function filterImages(images) {
|
||||
console.log('filterImages() called');
|
||||
const showsPano = context.photos().showsPanoramic();
|
||||
const showsFlat = context.photos().showsFlat();
|
||||
const fromDate = context.photos().fromDate();
|
||||
@@ -135,6 +146,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
}
|
||||
|
||||
function filterSequences(sequences) {
|
||||
console.log('filterSequences() called');
|
||||
const showsPano = context.photos().showsPanoramic();
|
||||
const showsFlat = context.photos().showsFlat();
|
||||
const fromDate = context.photos().fromDate();
|
||||
@@ -164,7 +176,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
console.log('update() called');
|
||||
const z = ~~context.map().zoom();
|
||||
const showMarkers = (z >= minMarkerZoom);
|
||||
const showViewfields = (z >= minViewfieldZoom);
|
||||
@@ -254,6 +266,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
function drawImages(selection) {
|
||||
console.log('drawImages() called');
|
||||
const enabled = svgMapillaryImages.enabled;
|
||||
const service = getService();
|
||||
|
||||
@@ -292,6 +305,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawImages.enabled = function(_) {
|
||||
console.log('drawImages.enabled called');
|
||||
if (!arguments.length) return svgMapillaryImages.enabled;
|
||||
svgMapillaryImages.enabled = _;
|
||||
if (svgMapillaryImages.enabled) {
|
||||
@@ -307,6 +321,7 @@ export function svgMapillaryImages(projection, context, dispatch) {
|
||||
|
||||
|
||||
drawImages.supported = function() {
|
||||
console.log('drawImages.supported called');
|
||||
return !!getService();
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ export function uiSectionDataLayers(context) {
|
||||
var settingsLocalPhotosData = uiSettingsLocalPhotosData(context)
|
||||
.on('change', localPhotosChanged);
|
||||
|
||||
// refers to `modules/svg/layers.js` -> function drawLayers(selection) {...}
|
||||
var layers = context.layers();
|
||||
|
||||
var section = uiSection('data-layers', context)
|
||||
@@ -39,6 +40,7 @@ export function uiSectionDataLayers(context) {
|
||||
.call(drawOsmItems)
|
||||
.call(drawQAItems)
|
||||
.call(drawCustomDataItems)
|
||||
// .call(drawLocalPhotos)
|
||||
.call(drawVectorItems) // Beta - Detroit mapping challenge
|
||||
.call(drawPanelItems);
|
||||
}
|
||||
@@ -292,6 +294,178 @@ export function uiSectionDataLayers(context) {
|
||||
}
|
||||
}
|
||||
|
||||
// original function
|
||||
// function drawCustomDataItems(selection) {
|
||||
// var dataLayer = layers.layer('data');
|
||||
// var hasData = dataLayer && dataLayer.hasData();
|
||||
// var showsData = hasData && dataLayer.enabled();
|
||||
|
||||
// var ul = selection
|
||||
// .selectAll('.layer-list-data')
|
||||
// .data(dataLayer ? [0] : []);
|
||||
|
||||
// // Exit
|
||||
// ul.exit()
|
||||
// .remove();
|
||||
|
||||
// // Enter
|
||||
// var ulEnter = ul.enter()
|
||||
// .append('ul')
|
||||
// .attr('class', 'layer-list layer-list-data');
|
||||
|
||||
// var liEnter = ulEnter
|
||||
// .append('li')
|
||||
// .attr('class', 'list-item-data');
|
||||
|
||||
// var labelEnter = liEnter
|
||||
// .append('label')
|
||||
// .call(uiTooltip()
|
||||
// .title(() => t.append('map_data.layers.custom.tooltip'))
|
||||
// .placement('top')
|
||||
// );
|
||||
|
||||
// labelEnter
|
||||
// .append('input')
|
||||
// .attr('type', 'checkbox')
|
||||
// .on('change', function() { toggleLayer('data'); });
|
||||
|
||||
// labelEnter
|
||||
// .append('span')
|
||||
// .call(t.append('map_data.layers.custom.title'));
|
||||
|
||||
// liEnter
|
||||
// .append('button')
|
||||
// .attr('class', 'open-data-options')
|
||||
// .call(uiTooltip()
|
||||
// .title(() => t.append('settings.custom_data.tooltip'))
|
||||
// .placement((localizer.textDirection() === 'rtl') ? 'right' : 'left')
|
||||
// )
|
||||
// .on('click', function(d3_event) {
|
||||
// d3_event.preventDefault();
|
||||
// editCustom();
|
||||
// })
|
||||
// .call(svgIcon('#iD-icon-more'));
|
||||
|
||||
// liEnter
|
||||
// .append('button')
|
||||
// .attr('class', 'zoom-to-data')
|
||||
// .call(uiTooltip()
|
||||
// .title(() => t.append('map_data.layers.custom.zoom'))
|
||||
// .placement((localizer.textDirection() === 'rtl') ? 'right' : 'left')
|
||||
// )
|
||||
// .on('click', function(d3_event) {
|
||||
// if (d3_select(this).classed('disabled')) return;
|
||||
|
||||
// d3_event.preventDefault();
|
||||
// d3_event.stopPropagation();
|
||||
// dataLayer.fitZoom();
|
||||
// })
|
||||
// .call(svgIcon('#iD-icon-framed-dot', 'monochrome'));
|
||||
|
||||
// // Update
|
||||
// ul = ul
|
||||
// .merge(ulEnter);
|
||||
|
||||
// ul.selectAll('.list-item-data')
|
||||
// .classed('active', showsData)
|
||||
// .selectAll('label')
|
||||
// .classed('deemphasize', !hasData)
|
||||
// .selectAll('input')
|
||||
// .property('disabled', !hasData)
|
||||
// .property('checked', showsData);
|
||||
|
||||
// ul.selectAll('button.zoom-to-data')
|
||||
// .classed('disabled', !hasData);
|
||||
// }
|
||||
|
||||
// added/testing: new function for local photos
|
||||
function drawLocalPhotos(selection) {
|
||||
var dataLayer = layers.layer('local-photos');
|
||||
console.log(dataLayer, 'dataLayer');
|
||||
// var hasData = dataLayer && dataLayer.hasData();
|
||||
// var showsData = hasData && dataLayer.enabled();
|
||||
|
||||
// var ul = selection
|
||||
// .selectAll('.layer-list-local-photos')
|
||||
// .data(dataLayer ? [0] : []);
|
||||
|
||||
var ul = selection
|
||||
.selectAll('.layer-list-local-photos')
|
||||
.data(dataLayer ? [0] : []);
|
||||
console.log(ul, 'ul inside drawLocalPhotos');
|
||||
|
||||
// Exit
|
||||
ul.exit()
|
||||
.remove();
|
||||
|
||||
// Enter
|
||||
var ulEnter = ul.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-list-data');
|
||||
console.log(ulEnter, 'ulEnter inside drawLocalPhotos');
|
||||
var localPhotosEnter = ulEnter
|
||||
.append('li')
|
||||
.attr('class', 'list-item-local-photos');
|
||||
|
||||
var localPhotosLabelEnter = localPhotosEnter
|
||||
.append('label');
|
||||
// TODO: Add tooltip
|
||||
|
||||
localPhotosLabelEnter
|
||||
.append('input')
|
||||
.attr('type', 'checkbox')
|
||||
.on('change', function() { toggleLayer('local-photos'); });
|
||||
|
||||
localPhotosLabelEnter
|
||||
.append('span')
|
||||
.text('Local Photos');
|
||||
|
||||
localPhotosEnter
|
||||
.append('button')
|
||||
.attr('class', 'open-data-options')
|
||||
.call(uiTooltip()
|
||||
.title(t.html('settings.custom_data.tooltip'))
|
||||
.placement((localizer.textDirection() === 'rtl') ? 'right' : 'left')
|
||||
)
|
||||
.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
editLocalPhotos();
|
||||
})
|
||||
.call(svgIcon('#iD-icon-more'));
|
||||
|
||||
localPhotosEnter
|
||||
.append('button')
|
||||
.attr('class', 'zoom-to-data')
|
||||
.call(uiTooltip()
|
||||
.title(t.html('map_data.layers.custom.zoom'))
|
||||
.placement((localizer.textDirection() === 'rtl') ? 'right' : 'left')
|
||||
)
|
||||
.on('click', function(d3_event) {
|
||||
if (d3_select(this).classed('disabled')) return;
|
||||
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
dataLayer.fitZoom();
|
||||
})
|
||||
.call(svgIcon('#iD-icon-framed-dot', 'monochrome'));
|
||||
|
||||
// Update
|
||||
ul = ul
|
||||
.merge(ulEnter);
|
||||
|
||||
// ul.selectAll('.list-item-data')
|
||||
// .classed('active', showsData)
|
||||
// .selectAll('label')
|
||||
// .classed('deemphasize', !hasData)
|
||||
// .selectAll('input')
|
||||
// .property('disabled', !hasData)
|
||||
// .property('checked', showsData);
|
||||
|
||||
// ul.selectAll('button.zoom-to-data')
|
||||
// .classed('disabled', !hasData);
|
||||
}
|
||||
|
||||
// current fn
|
||||
function drawCustomDataItems(selection) {
|
||||
var dataLayer = layers.layer('data');
|
||||
var hasData = dataLayer && dataLayer.hasData();
|
||||
@@ -428,12 +602,9 @@ export function uiSectionDataLayers(context) {
|
||||
.call(settingsCustomData);
|
||||
}
|
||||
|
||||
function editLocalPhotos() {
|
||||
context.container()
|
||||
.call(settingsLocalPhotosData);
|
||||
}
|
||||
|
||||
function customChanged(d) {
|
||||
console.log('customChanged called');
|
||||
console.log(layers);
|
||||
var dataLayer = layers.layer('data');
|
||||
|
||||
if (d && d.url) {
|
||||
@@ -443,11 +614,18 @@ export function uiSectionDataLayers(context) {
|
||||
}
|
||||
}
|
||||
|
||||
function editLocalPhotos() {
|
||||
context.container()
|
||||
.call(settingsLocalPhotosData);
|
||||
}
|
||||
|
||||
function localPhotosChanged(d) {
|
||||
var dataLayer = layers.layer('data');
|
||||
console.log('localPhotosChanged called');
|
||||
var localPhotosLayer = layers.layer('local-photos');
|
||||
|
||||
if (d && d.fileList) {
|
||||
dataLayer.fileList(d.fileList);
|
||||
console.log('Step 1: fileList set', d.fileList);
|
||||
localPhotosLayer.fileList(d.fileList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export function uiSettingsLocalPhotosData (context) {
|
||||
var dispatch = d3_dispatch('change');
|
||||
|
||||
function render(selection) {
|
||||
var dataLayer = context.layers().layer('data');
|
||||
var dataLayer = context.layers().layer('local-photos');
|
||||
|
||||
// keep separate copies of original and current settings
|
||||
var _origSettings = {
|
||||
@@ -38,7 +38,7 @@ export function uiSettingsLocalPhotosData (context) {
|
||||
//TODO: Add translation
|
||||
textSection
|
||||
.append('pre')
|
||||
.text('Choose local photos. Supported types are: .jpg, .jpeg, .png');
|
||||
.text('Choose local photos');
|
||||
// .attr('class', 'instructions-file')
|
||||
// .call(t.append('settings.custom_data.file.instructions'));
|
||||
|
||||
@@ -46,11 +46,11 @@ export function uiSettingsLocalPhotosData (context) {
|
||||
.append('input')
|
||||
.attr('class', 'field-file')
|
||||
.attr('type', 'file')
|
||||
.attr('multiple', 'multiple')
|
||||
// .attr('accept', '.gpx,.kml,.geojson,.json,application/gpx+xml,application/vnd.google-earth.kml+xml,application/geo+json,application/json')
|
||||
.property('files', _currSettings.fileList)
|
||||
.on('change', function(d3_event) {
|
||||
var files = d3_event.target.files;
|
||||
console.log(files);
|
||||
if (files && files.length) {
|
||||
// _currSettings.url = '';
|
||||
// textSection.select('.field-url').property('value', '');
|
||||
@@ -60,22 +60,6 @@ export function uiSettingsLocalPhotosData (context) {
|
||||
}
|
||||
});
|
||||
|
||||
// textSection
|
||||
// .append('h4')
|
||||
// .call(t.append('settings.custom_data.or'));
|
||||
|
||||
// textSection
|
||||
// .append('pre')
|
||||
// .attr('class', 'instructions-url')
|
||||
// .call(t.append('settings.custom_data.url.instructions'));
|
||||
|
||||
// textSection
|
||||
// .append('textarea')
|
||||
// .attr('class', 'field-url')
|
||||
// .attr('placeholder', t('settings.custom_data.url.placeholder'))
|
||||
// .call(utilNoAuto)
|
||||
// .property('value', _currSettings.url);
|
||||
|
||||
|
||||
// insert a cancel button
|
||||
var buttonSection = modal.select('.modal-section.buttons');
|
||||
|
||||
+5
-3
@@ -54,8 +54,10 @@
|
||||
"alif-toolkit": "^1.2.9",
|
||||
"core-js-bundle": "^3.19.0",
|
||||
"diacritics": "1.3.0",
|
||||
"exifr": "^7.1.3",
|
||||
"fast-deep-equal": "~3.1.1",
|
||||
"fast-json-stable-stringify": "2.1.0",
|
||||
"fs": "^0.0.1-security",
|
||||
"lodash-es": "~4.17.15",
|
||||
"marked": "~4.0.12",
|
||||
"node-diff3": "~3.1.0",
|
||||
@@ -77,9 +79,9 @@
|
||||
"autoprefixer": "^10.0.1",
|
||||
"btoa": "^1.2.1",
|
||||
"chai": "^4.3.4",
|
||||
"chalk": "^4.1.2",
|
||||
"cldr-core": "37.0.0",
|
||||
"cldr-localenames-full": "37.0.0",
|
||||
"chalk": "^4.1.2",
|
||||
"concat-files": "^0.1.1",
|
||||
"d3": "~7.4.4",
|
||||
"editor-layer-index": "github:osmlab/editor-layer-index#gh-pages",
|
||||
@@ -97,8 +99,8 @@
|
||||
"karma-coverage": "2.1.1",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-remap-istanbul": "^0.6.0",
|
||||
"mapillary-js": "4.1.0",
|
||||
"mapillary_sprite_source": "^1.8.0",
|
||||
"mapillary-js": "4.1.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mocha": "^9.2.0",
|
||||
"name-suggestion-index": "~6.0",
|
||||
@@ -122,4 +124,4 @@
|
||||
"browserslist": [
|
||||
"> 0.2%, last 6 major versions, Firefox ESR, maintained node versions"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user