mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
added: notes api service, parse and callback stubs
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import serviceMapillary from './mapillary';
|
||||
import serviceNominatim from './nominatim';
|
||||
import serviceNotes from './notes';
|
||||
import serviceOpenstreetcam from './openstreetcam';
|
||||
import serviceOsm from './osm';
|
||||
import serviceStreetside from './streetside';
|
||||
@@ -10,6 +11,7 @@ import serviceWikipedia from './wikipedia';
|
||||
export var services = {
|
||||
geocoder: serviceNominatim,
|
||||
mapillary: serviceMapillary,
|
||||
notes: serviceNotes,
|
||||
openstreetcam: serviceOpenstreetcam,
|
||||
osm: serviceOsm,
|
||||
streetside: serviceStreetside,
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
import _extend from 'lodash-es/extend';
|
||||
import _filter from 'lodash-es/filter';
|
||||
import _find from 'lodash-es/find';
|
||||
import _forEach from 'lodash-es/forEach';
|
||||
import _isEmpty from 'lodash-es/isEmpty';
|
||||
|
||||
import osmAuth from 'osm-auth';
|
||||
|
||||
import rbush from 'rbush';
|
||||
|
||||
var _entityCache = {};
|
||||
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { xml as d3_xml } from 'd3-request';
|
||||
|
||||
import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile';
|
||||
import { geoExtent } from '../geo';
|
||||
|
||||
import {
|
||||
utilRebind,
|
||||
utilIdleWorker
|
||||
} from '../util';
|
||||
|
||||
var urlroot = 'https://api.openstreetmap.org',
|
||||
_notesCache = { notes: { inflight: {}, loaded: {} } },
|
||||
__notesSelectedNote,
|
||||
dispatch = d3_dispatch('loadedNotes', 'loading'),
|
||||
tileZoom = 14;
|
||||
|
||||
var oauth = osmAuth({
|
||||
url: urlroot,
|
||||
oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
|
||||
oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
|
||||
loading: authLoading,
|
||||
done: authDone
|
||||
});
|
||||
|
||||
function authLoading() {
|
||||
dispatch.call('authLoading');
|
||||
}
|
||||
|
||||
|
||||
function authDone() {
|
||||
dispatch.call('authDone');
|
||||
}
|
||||
|
||||
function abortRequest(i) {
|
||||
i.abort();
|
||||
}
|
||||
|
||||
function getTiles(projection) {
|
||||
var s = projection.scale() * 2 * Math.PI,
|
||||
z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
|
||||
ts = 256 * Math.pow(2, z - tileZoom),
|
||||
origin = [
|
||||
s / 2 - projection.translate()[0],
|
||||
s / 2 - projection.translate()[1]];
|
||||
|
||||
return d3_geoTile()
|
||||
.scaleExtent([tileZoom, tileZoom])
|
||||
.scale(s)
|
||||
.size(projection.clipExtent()[1])
|
||||
.translate(projection.translate())()
|
||||
.map(function(tile) {
|
||||
var x = tile[0] * ts - origin[0],
|
||||
y = tile[1] * ts - origin[1];
|
||||
|
||||
return {
|
||||
id: tile.toString(),
|
||||
xyz: tile,
|
||||
extent: geoExtent(
|
||||
projection.invert([x, y + ts]),
|
||||
projection.invert([x + ts, y])
|
||||
)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function nearNullIsland(x, y, z) {
|
||||
if (z >= 7) {
|
||||
var center = Math.pow(2, z - 1),
|
||||
width = Math.pow(2, z - 6),
|
||||
min = center - (width / 2),
|
||||
max = center + (width / 2) - 1;
|
||||
return x >= min && x <= max && y >= min && y <= max;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
init: function() {
|
||||
if (!_notesCache) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.event = utilRebind(this, dispatch, 'on');
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
var cache = _notesCache;
|
||||
|
||||
if (cache) {
|
||||
if (cache.notes && cache.notes.inflight) {
|
||||
_forEach(cache.notes.inflight, abortRequest);
|
||||
}
|
||||
}
|
||||
|
||||
_notesCache = { notes: { inflight: {}, loaded: {} } };
|
||||
|
||||
__notesSelectedNote = null;
|
||||
},
|
||||
|
||||
authenticated: function() {
|
||||
return oauth.authenticated();
|
||||
},
|
||||
|
||||
loadFromAPI(path, callback, options) {
|
||||
options = _extend({ cache: true }, options);
|
||||
|
||||
function done(err, xml) {}
|
||||
|
||||
if (this.authenticated()) {
|
||||
return oauth.xhr({ method: 'GET', path: path }, done);
|
||||
} else {
|
||||
return d3_xml(path).get(done);
|
||||
}
|
||||
},
|
||||
|
||||
loadTile(which, currZoom, url, tile) {
|
||||
var cache = _notesCache[which];
|
||||
var bbox = tile.extent.toParam();
|
||||
|
||||
var id = tile.id;
|
||||
|
||||
if (cache.loaded[id] || cache.inflight[id]) return;
|
||||
|
||||
if (_isEmpty(cache.inflight)) {
|
||||
dispatch.call('loading');
|
||||
}
|
||||
|
||||
cache.inflight[id] = this.loadFromAPI(
|
||||
url + bbox,
|
||||
function () {
|
||||
|
||||
},
|
||||
[]
|
||||
);
|
||||
},
|
||||
|
||||
loadTiles(which, url, projection) {
|
||||
var that = this;
|
||||
var s = projection.scale() * 2 * Math.PI,
|
||||
currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
|
||||
|
||||
var tiles = getTiles(projection).filter(function(t) {
|
||||
return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
|
||||
});
|
||||
|
||||
_filter(which.inflight, function(v, k) {
|
||||
var wanted = _find(tiles, function(tile) { return k === (tile.id + ',0'); });
|
||||
if (!wanted) delete which.inflight[k];
|
||||
return !wanted;
|
||||
}).map(abortRequest);
|
||||
|
||||
tiles.forEach(function(tile) {
|
||||
that.loadTile(which, currZoom, url, tile);
|
||||
});
|
||||
},
|
||||
|
||||
loadNotes: function(projection) {
|
||||
var url = urlroot + '/api/0.6/notes?bbox=';
|
||||
this.loadTiles('notes', url, projection);
|
||||
}
|
||||
};
|
||||
+98
-8
@@ -1,31 +1,121 @@
|
||||
import _throttle from 'lodash-es/throttle';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
import { services } from '../services';
|
||||
|
||||
export function svgNotes(projection, context, dispatch) {
|
||||
var enabled = false;
|
||||
var throttledRedraw = _throttle(function () { dispatch.call('change'); }, 1000);
|
||||
var minZoom = 12;
|
||||
var minMarkerZoom = 16;
|
||||
var minViewfieldZoom = 18;
|
||||
var layer = d3_select(null);
|
||||
var _notes;
|
||||
|
||||
function drawNotes() {
|
||||
function init() {
|
||||
if (svgNotes.initialized) return; // run once
|
||||
svgNotes.enabled = false;
|
||||
svgNotes.initialized = true;
|
||||
}
|
||||
|
||||
function editOn() {
|
||||
layer.style('display', 'block');
|
||||
}
|
||||
|
||||
|
||||
function editOff() {
|
||||
layer.selectAll('.viewfield-group').remove();
|
||||
layer.style('display', 'none');
|
||||
}
|
||||
|
||||
function getService() {
|
||||
if (services.notes && !_notes) {
|
||||
_notes = services.notes;
|
||||
_notes.event.on('loadedNotes', throttledRedraw);
|
||||
} else if (!services.notes && _notes) {
|
||||
_notes = null;
|
||||
}
|
||||
|
||||
return _notes;
|
||||
}
|
||||
|
||||
function showLayer() {
|
||||
var service = getService();
|
||||
if (!service) return;
|
||||
|
||||
// service.loadViewer(context);
|
||||
editOn();
|
||||
|
||||
layer
|
||||
.style('opacity', 0)
|
||||
.transition()
|
||||
.duration(250)
|
||||
.style('opacity', 1)
|
||||
.on('end', function () { dispatch.call('change'); });
|
||||
}
|
||||
|
||||
function hideLayer() {
|
||||
var service = getService();
|
||||
if (service) {
|
||||
// service.hideViewer();
|
||||
}
|
||||
|
||||
throttledRedraw.cancel();
|
||||
|
||||
layer
|
||||
.transition()
|
||||
.duration(250)
|
||||
.style('opacity', 0)
|
||||
.on('end', editOff);
|
||||
}
|
||||
|
||||
function drawNotes(selection) {
|
||||
var enabled = svgNotes.enabled,
|
||||
service = getService();
|
||||
|
||||
layer = selection.selectAll('.layer-notes')
|
||||
.data(service ? [0] : []);
|
||||
|
||||
layer.exit()
|
||||
.remove();
|
||||
|
||||
var layerEnter = layer.enter()
|
||||
.append('g')
|
||||
.attr('class', 'layer-notes')
|
||||
.style('display', enabled ? 'block' : 'none');
|
||||
|
||||
// layerEnter
|
||||
// .append('g')
|
||||
// .attr('class', 'sequences');
|
||||
|
||||
layerEnter
|
||||
.append('g')
|
||||
.attr('class', 'notes');
|
||||
|
||||
layer = layerEnter
|
||||
.merge(layer);
|
||||
|
||||
if (enabled) {
|
||||
if (service && ~~context.map().zoom() >= minZoom) {
|
||||
editOn();
|
||||
// update();
|
||||
service.loadNotes(projection);
|
||||
} else {
|
||||
editOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawNotes.enabled = function(_) {
|
||||
if (!arguments.length) return enabled;
|
||||
enabled = _;
|
||||
|
||||
if (enabled) {
|
||||
if (!arguments.length) return svgNotes.enabled;
|
||||
svgNotes.enabled = _;
|
||||
if (svgNotes.enabled) {
|
||||
showLayer();
|
||||
} else {
|
||||
hideLayer();
|
||||
}
|
||||
|
||||
dispatch('change');
|
||||
dispatch.call('change');
|
||||
return this;
|
||||
};
|
||||
|
||||
init();
|
||||
return drawNotes;
|
||||
}
|
||||
Reference in New Issue
Block a user