Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/merge_notes_service' into notes
Browse files Browse the repository at this point in the history
  • Loading branch information
bhousel committed Jun 30, 2018
2 parents 9517635 + b3f7b06 commit d034691
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 20 deletions.
4 changes: 3 additions & 1 deletion modules/services/notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function getTiles(projection) {
s / 2 - projection.translate()[0],
s / 2 - projection.translate()[1]];

return d3_geoTile()
var tiles = d3_geoTile()
.scaleExtent([tileZoom, tileZoom])
.scale(s)
.size(projection.clipExtent()[1])
Expand All @@ -82,6 +82,8 @@ function getTiles(projection) {
)
};
});

return tiles;
}

function getLoc(attrs) {
Expand Down
157 changes: 143 additions & 14 deletions modules/services/osm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import _isEmpty from 'lodash-es/isEmpty';
import _map from 'lodash-es/map';
import _uniq from 'lodash-es/uniq';

import rbush from 'rbush';

var _notesCache = {};

import { dispatch as d3_dispatch } from 'd3-dispatch';
import { xml as d3_xml } from 'd3-request';

Expand All @@ -19,13 +23,14 @@ import {
osmEntity,
osmNode,
osmRelation,
osmWay
osmWay,
osmNote
} from '../osm';

import { utilRebind, utilIdleWorker } from '../util';


var dispatch = d3_dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
var dispatch = d3_dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded', 'loadedNotes');
var urlroot = 'https://www.openstreetmap.org';
var oauth = osmAuth({
url: urlroot,
Expand All @@ -39,12 +44,14 @@ var _blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
var _tiles = { loaded: {}, inflight: {} };
var _changeset = {};
var _entityCache = {};
var _noteTileCache = { loaded: {}, inflight: {}, rtree: rbush() };
var _connectionID = 1;
var _tileZoom = 16;
var _rateLimitError;
var _userChangesets;
var _userDetails;
var _off;
var _loadingNotes = false;


function authLoading() {
Expand Down Expand Up @@ -113,6 +120,28 @@ function getVisible(attrs) {
}


function parseComments(comments) {
var parsedComments = [];

// for each comment
_forEach(comments, function(comment) {
if (comment.nodeName === 'comment') {
var childNodes = comment.childNodes;
var parsedComment = {};

_forEach(childNodes, function(node) {
if (node.nodeName !== '#text') {
var nodeName = node.nodeName;
parsedComment[nodeName] = node.innerHTML;
}
});
if (parsedComment) { parsedComments.push(parsedComment); }
}
});
return parsedComments;
}


var parsers = {
node: function nodeData(obj, uid) {
var attrs = obj.attributes;
Expand Down Expand Up @@ -157,6 +186,37 @@ var parsers = {
tags: getTags(obj),
members: getMembers(obj)
});
},

note: function parseNote(obj, uid) {
var attrs = obj.attributes;
var childNodes = obj.childNodes;
var parsedNote = {};

parsedNote.loc = getLoc(attrs);

_forEach(childNodes, function(node) {
if (node.nodeName !== '#text') {
var nodeName = node.nodeName;
// if the element is comments, parse the comments
if (nodeName === 'comments') {
parsedNote[nodeName] = parseComments(node.childNodes);
} else {
parsedNote[nodeName] = node.innerHTML;
}
}
});

parsedNote.id = uid;
parsedNote.type = 'note';

return {
minX: parsedNote.loc[0],
minY: parsedNote.loc[1],
maxX: parsedNote.loc[0],
maxY: parsedNote.loc[1],
data: new osmNote(parsedNote)
};
}
};

Expand All @@ -171,8 +231,24 @@ function parse(xml, callback, options) {
function parseChild(child) {
var parser = parsers[child.nodeName];
if (parser) {
var uid = osmEntity.id.fromOSM(child.nodeName, child.attributes.id.value);
if (options.cache && _entityCache[uid]) {

var uid;
var cache = _loadingNotes ? _notesCache : _entityCache;

// if loading notes, get the note id
if (_loadingNotes) {
var childNodes = child.childNodes;
_forEach(childNodes, function(node) {
if (node.nodeName === 'id') {
uid = child.nodeName + node.innerHTML;
}
});
}
// otherwise, get the osmEntity id
else {
uid = osmEntity.id.fromOSM(child.nodeName, child.attributes.id.value);
}
if (options.cache && cache[uid]) {
return null;
}
return parser(child, uid);
Expand Down Expand Up @@ -200,6 +276,13 @@ export default {
_tiles = { loaded: {}, inflight: {} };
_changeset = {};
_entityCache = {};

if (_noteTileCache && _noteTileCache.inflight) {
_forEach(_noteTileCache.inflight, abortRequest);
}
_noteTileCache = { loaded: {}, inflight: {}, rtree: rbush() };
_notesCache = {};

return this;
},

Expand Down Expand Up @@ -272,7 +355,11 @@ export default {
parse(xml, function (entities) {
if (options.cache) {
for (var i in entities) {
_entityCache[entities[i].id] = true;
if (_loadingNotes) {
_notesCache[entities[i].id] = true;
} else {
_entityCache[entities[i].id] = true;
}
}
}
callback(null, entities);
Expand Down Expand Up @@ -573,6 +660,9 @@ export default {
if (_off) return;

var that = this;

var cache = _loadingNotes ? _noteTileCache : _tiles;

var s = projection.scale() * 2 * Math.PI;
var z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
var ts = 256 * Math.pow(2, z - _tileZoom);
Expand All @@ -598,36 +688,48 @@ export default {
};
});

_filter(_tiles.inflight, function(v, i) {
_filter(cache.inflight, function(v, i) {
var wanted = _find(tiles, function(tile) {
return i === tile.id;
});
if (!wanted) delete _tiles.inflight[i];
if (!wanted) delete cache.inflight[i];
return !wanted;
}).map(abortRequest);

// check if loading entities, or notes
var path = _loadingNotes ? '/api/0.6/notes?bbox=' : '/api/0.6/map?bbox=';

tiles.forEach(function(tile) {
var id = tile.id;

if (_tiles.loaded[id] || _tiles.inflight[id]) return;
if (cache.loaded[id] || cache.inflight[id]) return;

if (_isEmpty(_tiles.inflight)) {
if (_isEmpty(cache.inflight)) {
dispatch.call('loading');
}

_tiles.inflight[id] = that.loadFromAPI(
'/api/0.6/map?bbox=' + tile.extent.toParam(),
cache.inflight[id] = that.loadFromAPI(
path + tile.extent.toParam(),
function(err, parsed) {
delete _tiles.inflight[id];
delete cache.inflight[id];
if (!err) {
_tiles.loaded[id] = true;
cache.loaded[id] = true;
}
// NOTE: if zoom above min zoom & notes turned on before osm, osm won't render
// TODO: either pick this option, or the next one
if (_loadingNotes) {
cache.rtree.load(parsed);
}

// TODO: figure out how this callback should handle parsed results
if (callback) {
callback(err, _extend({ data: parsed }, tile));
}

if (_isEmpty(_tiles.inflight)) {
if (_isEmpty(cache.inflight)) {
if (_loadingNotes) {
dispatch.call('loadedNotes');
}
dispatch.call('loaded');
}
}
Expand Down Expand Up @@ -696,5 +798,32 @@ export default {
}

return oauth.authenticate(done);
},

loadNotes: function(projection, dimensions, callback) {
var that = this;
_loadingNotes = true;
that.loadTiles(projection, dimensions, callback);
},

// TODO: possibly remove rtree & refactor caches
notes: function(projection) {
var viewport = projection.clipExtent();
var min = [viewport[0][0], viewport[1][1]];
var max = [viewport[1][0], viewport[0][1]];
var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();

return _noteTileCache.rtree.search(bbox)
.map(function(d) { return d.data; });
},

loadedNotes: function(_) {
if (!arguments.length) return _noteTileCache.loaded;
_noteTileCache.loaded = _;
return this;
},

notesCache: function() {
return _noteTileCache;
}
};
17 changes: 12 additions & 5 deletions modules/svg/notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ export function svgNotes(projection, context, dispatch) {
}

function getService() {
if (services.notes && !_notes) {
_notes = services.notes;
_notes.event.on('loadedNotes', throttledRedraw);
} else if (!services.notes && _notes) {
if (services.osm && !_notes) {
_notes = services.osm;
_notes.on('loadedNotes', throttledRedraw);
} else if (!services.osm && _notes) {
_notes = null;
}

Expand Down Expand Up @@ -107,6 +107,13 @@ export function svgNotes(projection, context, dispatch) {
var enabled = svgNotes.enabled,
service = getService();

function dimensions() {
return [window.innerWidth, window.innerHeight];
}
function done() {
console.log('placeholder done within svg/notes.upload.done');
}

layer = selection.selectAll('.layer-notes')
.data(service ? [0] : []);

Expand All @@ -123,7 +130,7 @@ export function svgNotes(projection, context, dispatch) {
if (service && ~~context.map().zoom() >= minZoom) {
editOn();
update();
service.loadNotes(projection);
service.loadNotes(projection, dimensions(), done);
} else {
editOff();
}
Expand Down

0 comments on commit d034691

Please sign in to comment.