From 23b6b15e641f64b1d1a5d69a07fbe7de8797ca2a Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 13 Jun 2018 13:03:11 -0400 Subject: [PATCH] Assemble sequences, adjust styles to better distinguish from osc --- css/60_photos.css | 13 +-- modules/services/streetside.js | 160 +++++++++++++-------------------- modules/svg/streetside.js | 2 +- 3 files changed, 72 insertions(+), 103 deletions(-) diff --git a/css/60_photos.css b/css/60_photos.css index 69ae6cc8c..7d5fa1ebb 100644 --- a/css/60_photos.css +++ b/css/60_photos.css @@ -119,10 +119,11 @@ pointer-events: none; } .layer-streetside-images .viewfield-group * { - fill: #00d8f5; + fill: #0de6b0; } .layer-streetside-images .sequence { - stroke: #00d8f5; + stroke: #0de6b0; + stroke-opacity: 0.7; /* slight bump - only one per road */ } @@ -162,10 +163,10 @@ pointer-events: none; } .layer-openstreetcam-images .viewfield-group * { - fill: #77ddff; + fill: #20c4ff; } .layer-openstreetcam-images .sequence { - stroke: #77ddff; + stroke: #20c4ff; } @@ -175,7 +176,7 @@ } .ms-wrapper .photo-attribution a:active, .ms-wrapper .photo-attribution a:hover { - color: #35af6d; + color: #0de6b0; } .ms-wrapper .pnlm-compass.pnlm-control { @@ -222,7 +223,7 @@ .osc-wrapper .photo-attribution a:active, .osc-wrapper .photo-attribution a:hover { - color: #77ddff; + color: #20c4ff; } .osc-controls-wrap { diff --git a/modules/services/streetside.js b/modules/services/streetside.js index dbfd10c71..b3e8b6ade 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -29,7 +29,6 @@ var pannellumViewerJS = 'pannellum-streetside/pannellum.js'; var tileZoom = 15; var dispatch = d3_dispatch('loadedBubbles', 'viewerChanged'); var _currScene = 0; -var _currSequence = 0; var _ssCache; var _pannellumViewer; var _sceneOptions; @@ -156,42 +155,16 @@ function loadNextTilePage(which, currZoom, url, tile) { pr: bubble.pr, // previous ne: bubble.ne, // next pano: true, - sequenceID: null + sequenceKey: null }; - // determine (or create) a squence to attach this bubble to - var seqID = findSequenceID(d); - var seq; - if (seqID) { - seq = _ssCache.sequences[seqID]; - } else { - seq = { id: ++_currSequence, min: bubble.id, max: bubble.id, bubbles: [] }; - _ssCache.sequences[seq.id] = seq; - } - d.sequenceID = seq.id; - - // expand the range of the sequence to include this bubble - if (d.pr === undefined || bubble.id < seq.min) { - seq.min = bubble.id; - } - if (d.ne === undefined || bubble.id > seq.max) { - seq.max = bubble.id; - } - seq.bubbles.push(bubble.id); - - // if next or previous bubble is already assigned a different sequence, - // merge the sequences - var prev = d.pr && _ssCache.bubbles.points[d.pr]; - if (prev && prev.sequenceID !== seq.id) { - mergeSequences(prev.sequenceID, seq.id); - } - var next = d.ne && _ssCache.bubbles.points[d.ne]; - if (next && next.sequenceID !== seq.id) { - mergeSequences(next.sequenceID, seq.id); - } - cache.points[bubble.id] = d; + // a sequence starts here + if (bubble.pr === undefined) { + cache.leaders.push(bubble.id); + } + return { minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d }; @@ -199,6 +172,9 @@ function loadNextTilePage(which, currZoom, url, tile) { }).filter(Boolean); cache.rtree.load(features); + + connectSequences(); + if (which === 'bubbles') { dispatch.call('loadedBubbles'); } @@ -206,44 +182,55 @@ function loadNextTilePage(which, currZoom, url, tile) { } -function findSequenceID(bubble) { - var prev = bubble.pr && _ssCache.bubbles.points[bubble.pr]; - if (prev && prev.sequenceID) { - return prev.sequenceID; - } - var next = bubble.ne && _ssCache.bubbles.points[bubble.ne]; - if (next && next.sequenceID) { - return next.sequenceID; - } +// call this sometimes to connect the bubbles into sequences +function connectSequences() { + var cache = _ssCache.bubbles; + var keepLeaders = []; - var seqIDs = Object.keys(_ssCache.sequences); - for (var i = 0; i < seqIDs.length; i++) { - var seq = _ssCache.sequences[seqIDs[i]]; - if ((bubble.id >= seq.min && bubble.id <= seq.max) || - (bubble.pr >= seq.min && bubble.pr <= seq.max) || - (bubble.ne >= seq.min && bubble.ne <= seq.max)) { - return seq.id; + for (var i = 0; i < cache.leaders.length; i++) { + var bubble = cache.points[cache.leaders[i]]; + var seen = {}; + + // try to make a sequence.. use the key of the leader bubble. + var sequence = { key: bubble.key, bubbles: [] }; + var complete = false; + + do { + sequence.bubbles.push(bubble); + seen[bubble.key] = true; + + if (bubble.ne === undefined) { + complete = true; + } else { + bubble = cache.points[bubble.ne]; // advance to next + } + } while (bubble && !seen[bubble.key] && !complete); + + + if (complete) { + _ssCache.sequences[sequence.key] = sequence; + + // assign bubbles to the sequence + for (var j = 0; j < sequence.bubbles.length; j++) { + sequence.bubbles[j].sequenceKey = sequence.key; + } + + // create a GeoJSON LineString + sequence.geojson = { + type: 'LineString', + properties: { key: sequence.key }, + coordinates: sequence.bubbles.map(function (d) { return d.loc; }) + }; + + } else { + keepLeaders.push(cache.leaders[i]); } } + + // couldn't complete these, save for later + cache.leaders = keepLeaders; } - -function mergeSequences(oldID, newID) { - var oldSeq = _ssCache.sequences[oldID]; - var newSeq = _ssCache.sequences[newID]; - - newSeq.min = Math.min(oldSeq.min, newSeq.min); - newSeq.max = Math.max(oldSeq.max, newSeq.max); - - oldSeq.bubbles.forEach(function (bubbleID) { - _ssCache.bubbles.points[bubbleID].sequenceID = newID; - }); - - newSeq.bubbles = newSeq.bubbles.concat(oldSeq.bubbles); - delete _ssCache.sequences[oldID]; -} - - /** * getBubbles() handles the request to the server for a tile extent of 'bubbles' (streetside image locations). */ @@ -334,7 +321,7 @@ export default { } _ssCache = { - bubbles: { inflight: {}, loaded: {}, nextPage: {}, rtree: rbush(), points: {} }, + bubbles: { inflight: {}, loaded: {}, nextPage: {}, rtree: rbush(), points: {}, leaders: [] }, sequences: {} }; }, @@ -353,39 +340,20 @@ export default { 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(); - var sequenceIDs = {}; + var seen = {}; + var results = []; // all sequences for bubbles in viewport _ssCache.bubbles.rtree.search(bbox) .forEach(function(d) { - if (d.data.sequenceID) { - sequenceIDs[d.data.sequenceID] = true; + var key = d.data.sequenceKey; + if (key && !seen[key]) { + seen[key] = true; + results.push(_ssCache.sequences[key].geojson); } }); - // make linestrings from those sequences - var lineStrings = []; - Object.keys(sequenceIDs) - .forEach(function(sequenceID) { - var seq = _ssCache.sequences[sequenceID]; - if (seq) { - var coords = []; - for (var i = seq.min; i <= seq.max; i++) { - var point = _ssCache.bubbles.points[i]; - if (point) { - coords.push(point.loc); - } - } - - lineStrings.push({ - type: 'LineString', - properties: { key: sequenceID }, - coordinates: coords - }); - } - }); - - return lineStrings; + return results; }, @@ -612,7 +580,7 @@ export default { getSequenceKeyForBubble: function(d) { - return d && d.sequenceID; + return d && d.sequenceKey; }, @@ -634,14 +602,14 @@ export default { var hoveredBubbleKey = hovered && hovered.key; var hoveredSequenceKey = this.getSequenceKeyForBubble(hovered); var hoveredSequence = hoveredSequenceKey && _ssCache.sequences[hoveredSequenceKey]; - var hoveredBubbleKeys = (hoveredSequence && hoveredSequence.bubbles) || []; + var hoveredBubbleKeys = (hoveredSequence && hoveredSequence.bubbles.map(function (d) { return d.key; })) || []; var viewer = d3_select('#photoviewer'); var selected = viewer.empty() ? undefined : viewer.datum(); var selectedBubbleKey = selected && selected.key; var selectedSequenceKey = this.getSequenceKeyForBubble(selected); var selectedSequence = selectedSequenceKey && _ssCache.sequences[selectedSequenceKey]; - var selectedBubbleKeys = (selectedSequence && selectedSequence.bubbles) || []; + var selectedBubbleKeys = (selectedSequence && selectedSequence.bubbles.map(function (d) { return d.key; })) || []; // highlight sibling viewfields on either the selected or the hovered sequences var highlightedBubbleKeys = _union(hoveredBubbleKeys, selectedBubbleKeys); diff --git a/modules/svg/streetside.js b/modules/svg/streetside.js index c9d26fb05..c3d541797 100644 --- a/modules/svg/streetside.js +++ b/modules/svg/streetside.js @@ -8,7 +8,7 @@ export function svgStreetside(projection, context, dispatch) { var throttledRedraw = _throttle(function () { dispatch.call('change'); }, 1000); var minZoom = 14; var minMarkerZoom = 16; - var minViewfieldZoom = 19; + var minViewfieldZoom = 18; var layer = d3_select(null); var _viewerYaw = 0; var _streetside;