diff --git a/modules/services/fb_ml_roads.js b/modules/services/fb_ml_roads.js index df5c62f581..9a4751df0d 100644 --- a/modules/services/fb_ml_roads.js +++ b/modules/services/fb_ml_roads.js @@ -19,7 +19,7 @@ var _tileCache; var _tree; var _deferredFBRoadsParsing = new Set(); -var _off; +var _off; function abortRequest(i) { i.abort(); @@ -163,7 +163,7 @@ export default { // save the current history state checkpoint: function(key) { _checkpoints[key] = { - graph: _graph, + graph: _graph, }; return this; }, @@ -182,10 +182,10 @@ export default { else { _graph = coreGraph(); _tree = coreTree(_graph); - _tileCache = { inflight: {}, loaded: {}, seen: {}, origIdTile: {} }; + _tileCache = { inflight: {}, loaded: {}, seen: {}, origIdTile: {} }; } - return this; + return this; }, @@ -217,12 +217,12 @@ export default { }; } - // access cache directly for testing + // access cache directly for testing if (obj === 'get') { return _tileCache; } - _tileCache = obj; + _tileCache = obj; }, @@ -233,7 +233,7 @@ export default { loadTiles: function(projection, taskExtent) { - if (_off) return; + if (_off) return; var tiles = tiler.getTiles(projection); @@ -262,7 +262,7 @@ export default { dispatch.call('loadedData'); }); }) - .catch(function(err) {}); + .catch(function() {}); _tileCache.inflight[tile.id] = controller; }); } diff --git a/modules/svg/fb_roads.js b/modules/svg/fb_roads.js index 9671187883..9a0b5e4d24 100644 --- a/modules/svg/fb_roads.js +++ b/modules/svg/fb_roads.js @@ -75,7 +75,7 @@ export function svgFbRoads(projection, context, dispatch) { function onHistoryRestore() { - _actioned = new Set(); + _actioned = new Set(); context.history().peekAllAnnotations().forEach(function (annotation) { if (isFbRoadsAnnotation(annotation)) { _actioned.add(annotation.id); @@ -150,7 +150,6 @@ export function svgFbRoads(projection, context, dispatch) { if (!surface || surface.empty() || waitingForTaskExtent) return; // not ready to draw yet, starting up var roadsService = getService(); - var graph = context.graph(); var roadsGraph = roadsService && roadsService.graph(); var getPath = svgPath(projection, roadsGraph); var getTransform = svgPointTransform(projection); diff --git a/modules/svg/lines.js b/modules/svg/lines.js index 76d0605a8f..b17bf1a3b1 100644 --- a/modules/svg/lines.js +++ b/modules/svg/lines.js @@ -9,9 +9,7 @@ import { osmEntity, osmOldMultipolygonOuterMember } from '../osm'; import { utilArrayFlatten, utilArrayGroupBy } from '../util'; import { utilDetect } from '../util/detect'; import _isEqual from 'lodash-es/isEqual'; -import _transform from 'lodash-es/transform'; -import _omit from 'lodash-es/omit'; -import _isObject from 'lodash-es/isObject'; +import _omit from 'lodash-es/omit'; export function svgLines(projection, context) { var detected = utilDetect(); @@ -59,13 +57,13 @@ export function svgLines(projection, context) { .remove(); var graphEditClass = function(d) { - + return d.properties.nodes.some(function(n) { if (!base.entities[n.id]) { - return true; - } - var result = !_isEqual(_omit(graph.entities[n.id], ['tags', 'v']), _omit(base.entities[n.id], ['tags', 'v'])); - return result; + return true; + } + var result = !_isEqual(_omit(graph.entities[n.id], ['tags', 'v']), _omit(base.entities[n.id], ['tags', 'v'])); + return result; }) ? ' graphedited ': ''; }; @@ -93,8 +91,8 @@ export function svgLines(projection, context) { .append('path') .merge(nopes) .attr('d', getPath) - .attr('class', function(d) { - return 'way line target target-nope ' + nopeClass + d.id + graphEditClass(d); + .attr('class', function(d) { + return 'way line target target-nope ' + nopeClass + d.id + graphEditClass(d); }); } @@ -114,21 +112,21 @@ export function svgLines(projection, context) { // Class for styling currently edited lines var tagEditClass = function(d) { - var result = graph.entities[d.id] && base.entities[d.id] && !_isEqual(graph.entities[d.id].tags, base.entities[d.id].tags); + var result = graph.entities[d.id] && base.entities[d.id] && !_isEqual(graph.entities[d.id].tags, base.entities[d.id].tags); - return result ? - ' tagedited ' : ''; + return result ? + ' tagedited ' : ''; }; // Class for styling currently edited lines var graphEditClass = function(d) { if (!base.entities[d.id]) { - return ' graphedited '; + return ' graphedited '; } - var result = graph.entities[d.id] && base.entities[d.id] && !_isEqual(_omit(graph.entities[d.id], ['tags', 'v']), _omit(base.entities[d.id], ['tags', 'v'])); + var result = graph.entities[d.id] && base.entities[d.id] && !_isEqual(_omit(graph.entities[d.id], ['tags', 'v']), _omit(base.entities[d.id], ['tags', 'v'])); - return result ? ' graphedited ' : ''; + return result ? ' graphedited ' : ''; }; function drawLineGroup(selection, klass, isSelected) { diff --git a/modules/ui/fb_road_picker.js b/modules/ui/fb_road_picker.js index 5743de11d6..f970c83a58 100644 --- a/modules/ui/fb_road_picker.js +++ b/modules/ui/fb_road_picker.js @@ -16,7 +16,7 @@ export function uiFbRoadPicker(context, keybinding) { var ML_ROADS_LIMIT_NON_TM_MODE = 50; - function isAddRoadDisabled(_) { + function isAddRoadDisabled() { // when task GPX is set in URL (TM mode), "add roads" is always enabled var gpxInUrl = utilStringQs(window.location.hash).gpx; if (gpxInUrl) return false; @@ -25,7 +25,7 @@ export function uiFbRoadPicker(context, keybinding) { var entities = context.graph().entities; for (var eid in entities) { var e = entities[eid]; - if (eid.startsWith('w-') && e && e.tags['source'] === 'digitalglobe') { + if (eid.startsWith('w-') && e && e.tags.source === 'digitalglobe') { mlRoadsCount += 1; } } @@ -60,11 +60,11 @@ export function uiFbRoadPicker(context, keybinding) { }; context.perform(actionStitchFbRoad(_datum.id, serviceFbMLRoads.graph()), annotation); context.enter(modeSelect(context, [_datum.id])); - + if (context.inIntro()) return; - + if (sessionStorage.getItem('acknowledgedLogin') === 'true') return; - sessionStorage.setItem('acknowledgedLogin', 'true'); + sessionStorage.setItem('acknowledgedLogin', 'true'); var osm = context.connection(); if (!osm.authenticated()) { diff --git a/modules/ui/init.js b/modules/ui/init.js index 474030e44a..8f8f7a0fa5 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -34,7 +34,6 @@ import { uiScale } from './scale'; import { uiShortcuts } from './shortcuts'; import { uiSidebar } from './sidebar'; import { uiSpinner } from './spinner'; -import { uiSplash } from './splash'; import { uiSplashRapid } from './splash_rapid'; import { uiStatus } from './status'; import { uiTopToolbar } from './top_toolbar'; @@ -298,15 +297,15 @@ export function uiInit(context) { context.enter(modeBrowse(context)); + var osm = context.connection(); if (!_initCounter++) { if (!hash.startWalkthrough) { - var osm = context.connection(); if (context.history().lock() && context.history().restorableChanges()) { context.container() .call(uiRestore(context)); } else if (osm.authenticated()) { context.container() - .call(uiSplashRapid(context)) + .call(uiSplashRapid(context)); } } @@ -314,7 +313,6 @@ export function uiInit(context) { .call(uiShortcuts(context)); } - var osm = context.connection(); var auth = uiLoading(context).message(t('loading_auth')).blocking(true); if (osm && auth) { diff --git a/modules/ui/intro/intro.js b/modules/ui/intro/intro.js index 1cdc5bf6aa..59d402abdc 100644 --- a/modules/ui/intro/intro.js +++ b/modules/ui/intro/intro.js @@ -33,7 +33,7 @@ var chapterUi = { area: uiIntroArea, line: uiIntroLine, building: uiIntroBuilding, - rapid: uiIntroRapid, + rapid: uiIntroRapid, startEditing: uiIntroStartEditing }; @@ -52,7 +52,7 @@ var chapterFlow = [ export function uiIntro(context, skipToRapid) { var INTRO_IMAGERY = 'EsriWorldImageryClarity'; var introGraph = {}; - var rapidGraph = {}; + var rapidGraph = {}; var _currChapter; // create entities for intro graph and localize names @@ -61,7 +61,7 @@ export function uiIntro(context, skipToRapid) { } // create entities for RapiD graph and localize names - for (var id in dataIntroRapidGraph) { + for (id in dataIntroRapidGraph) { rapidGraph[id] = osmEntity(localize(dataIntroRapidGraph[id])); } @@ -82,7 +82,7 @@ export function uiIntro(context, skipToRapid) { var caches = osm && osm.caches(); var baseEntities = context.history().graph().base().entities; var countryCode = services.geocoder.countryCode; - var fbMLRoadsEntities = services.fbMLRoads && services.fbMLRoads.graph().entities; + var fbMLRoadsEntities = services.fbMLRoads && services.fbMLRoads.graph().entities; var fbMLRoadsCache = services.fbMLRoads && services.fbMLRoads.cache(); // Show sidebar and disable the sidebar resizing button @@ -97,7 +97,7 @@ export function uiIntro(context, skipToRapid) { if (osm) { osm.toggle(false).reset(); } context.history().reset(); - var loadedGraph = coreGraph().load(introGraph); + var loadedGraph = coreGraph().load(introGraph); var graphEntities = Object.values(loadedGraph.entities); context.history().merge(graphEntities); context.history().checkpoint('initial'); @@ -127,11 +127,11 @@ export function uiIntro(context, skipToRapid) { callback(null, t('intro.graph.countrycode')); }; - if (services.fbMLRoads) services.fbMLRoads.toggle(false).reset(); + if (services.fbMLRoads) services.fbMLRoads.toggle(false).reset(); - var coreGraphEntities = coreGraph().load(rapidGraph).entities; + var coreGraphEntities = coreGraph().load(rapidGraph).entities; services.fbMLRoads.merge(Object.values(coreGraphEntities)); - services.fbMLRoads.checkpoint('initial'); + services.fbMLRoads.checkpoint('initial'); d3_selectAll('#map .layer-background').style('opacity', 1); d3_selectAll('#map .layer-fb-roads').style('opacity', 1); diff --git a/modules/ui/intro/rapid.js b/modules/ui/intro/rapid.js index 4669b7f41e..4634a9de99 100644 --- a/modules/ui/intro/rapid.js +++ b/modules/ui/intro/rapid.js @@ -8,18 +8,17 @@ import { import { t } from '../../util/locale'; import { modeBrowse} from '../../modes'; import { utilRebind } from '../../util/rebind'; -import { icon, pad, selectMenuItem, transitionTime } from './helper'; +import { icon, pad, transitionTime } from './helper'; import { services } from '../../services'; -import { svgLayers } from '../../svg/layers'; export function uiIntroRapid(context, reveal) { var dispatch = d3_dispatch('done'); var timeouts = []; - - var tulipLaneStart = [-85.6297512, 41.9561476]; + + var tulipLaneStart = [-85.6297512, 41.9561476]; var tulipLaneMid = [-85.6281089, 41.9561288]; - var tulipLaneEnd = [-85.6272670, 41.9558780]; + var tulipLaneEnd = [-85.6272670, 41.9558780]; var chapter = { title: 'intro.rapid.title' }; @@ -34,18 +33,18 @@ export function uiIntroRapid(context, reveal) { var padding = 70 * Math.pow(2, context.map().zoom() -18); var box = pad(tulipLaneEnd, padding, context); box.height = box.height + 65; - box.width = box.width + 65; + box.width = box.width + 65; - return box; + return box; } function tulipLaneBoundingBox(){ var padding = 70 * Math.pow(2, context.map().zoom() -18); var box = pad(tulipLaneStart, padding, context); box.height = box.height + 65; - box.width = box.width + 600; + box.width = box.width + 600; - return box; + return box; } @@ -69,11 +68,11 @@ export function uiIntroRapid(context, reveal) { function welcome() { if (fbRoadsEnabled(context)) { - fbRoadsToggle(context); + fbRoadsToggle(context); } context.enter(modeBrowse(context)); context.history().reset('initial'); - services.fbMLRoads.reset('initial'); + services.fbMLRoads.reset('initial'); reveal('.intro-nav-wrap .chapter-rapid', t('intro.rapid.start', { rapid: icon('#iD-logo-rapid', 'pre-text') }), { buttonText: t('intro.ok'), buttonCallback: showHideRoads } @@ -81,17 +80,19 @@ export function uiIntroRapid(context, reveal) { } - function showHideRoads() { + function showHideRoads() { var msec = transitionTime(tulipLaneMid, context.map().center()); if (msec) { reveal(null, null, { duration: 0 }); } context.map().centerZoomEase(tulipLaneMid, 18.5, msec); - + timeout(function() { - var tooltip = reveal('button.fb-roads-toggle', - t('intro.rapid.ai_roads', { rapid: icon('#iD-logo-rapid', 'pre-text') })); + reveal( + 'button.fb-roads-toggle', + t('intro.rapid.ai_roads', { rapid: icon('#iD-logo-rapid', 'pre-text') }) + ); var button = d3_select('.fb-roads-toggle'); - + button.on('click.intro', function() { continueTo(selectRoad); }); @@ -105,17 +106,15 @@ export function uiIntroRapid(context, reveal) { function selectRoad() { - _tulipLaneID = null; - // disallow scrolling d3_select('.inspector-wrap').on('wheel.intro', eventCancel); reveal(tulipLaneBoundingBox(), t('intro.rapid.select_road')); timeout(function() { - var fbRoad = d3_select('.data-layer.fb-roads'); + var fbRoad = d3_select('.data-layer.fb-roads'); fbRoad.on('click.intro', function() { - continueTo(addRoad); - }); + continueTo(addRoad); + }); }, 250); function continueTo(nextStep) { @@ -124,16 +123,15 @@ export function uiIntroRapid(context, reveal) { } - function addRoad() { + function addRoad() { timeout(function() { - var tooltip = reveal('button.fb-roads-accept', - t('intro.rapid.add_road')); + reveal('button.fb-roads-accept', t('intro.rapid.add_road')); - var button = d3_select('button.fb-roads-accept') + var button = d3_select('button.fb-roads-accept'); button.on('click.intro', function() { - continueTo(roadAdded) + continueTo(roadAdded); }); - }, 250); + }, 250); function continueTo(nextStep) { @@ -154,9 +152,9 @@ export function uiIntroRapid(context, reveal) { } function showLint() { - var button = d3_select('li.issue-list-item.actionable > button'); + var button = d3_select('li.issue-list-item.actionable > button'); button.on('click.intro', function() { - continueTo(fixLint); + continueTo(fixLint); }); if (context.mode().id !== 'select') return chapter.restart(); @@ -178,10 +176,10 @@ export function uiIntroRapid(context, reveal) { function fixLint() { if (context.mode().id !== 'select') return chapter.restart(); - var button = d3_select('li.issue-fix-item.actionable') - button.on('click.intro', function() { - continueTo(showFixedRoad) - }); + var button = d3_select('li.issue-fix-item.actionable'); + button.on('click.intro', function() { + continueTo(showFixedRoad); + }); timeout(function() { reveal('li.issue-fix-item.actionable', @@ -195,7 +193,7 @@ export function uiIntroRapid(context, reveal) { } } - + function showFixedRoad() { if (context.mode().id !== 'select') return chapter.restart(); timeout(function() { @@ -218,14 +216,14 @@ export function uiIntroRapid(context, reveal) { reveal('#bar button.undo-button', t('intro.rapid.undo_fix_lint', { button: icon(iconName, 'pre-text') }) ); - + button.on('click.intro', function() { continueTo(undoRoadAdd); }); }, 250); - function continueTo(nextStep) { + function continueTo(nextStep) { nextStep(); } } @@ -241,14 +239,14 @@ export function uiIntroRapid(context, reveal) { reveal('#bar button.undo-button', t('intro.rapid.undo_road_add', { button: icon(iconName, 'pre-text') }) ); - + button.on('click.intro', function() { continueTo(afterUndoRoadAdd); }); }, 250); - function continueTo(nextStep) { + function continueTo(nextStep) { nextStep(); } } @@ -267,35 +265,36 @@ export function uiIntroRapid(context, reveal) { function selectRoadAgain() { timeout(function() { reveal(tulipLaneBoundingBox(), t('intro.rapid.select_road_again')); - var fbRoad = d3_select('.data-layer.fb-roads'); - fbRoad.on('click.intro', function() { deleteRoad() } ); + var fbRoad = d3_select('.data-layer.fb-roads'); + fbRoad.on('click.intro', function() { deleteRoad(); } ); }, 250); } - function deleteRoad() { + function deleteRoad() { timeout(function() { - var tooltip = reveal('button.fb-roads-reject', - t('intro.rapid.delete_road')); - var button = d3_select('button.fb-roads-reject') - button.on('click.intro', function() { showHelp() }); - }, 250); + reveal('button.fb-roads-reject', t('intro.rapid.delete_road')); + var button = d3_select('button.fb-roads-reject'); + button.on('click.intro', function() { showHelp(); }); + }, 250); } function showHelp() { - reveal('.map-control.help-control', - t('intro.rapid.help', - { - rapid: icon('#iD-logo-rapid', 'pre-text'), - button: icon('#iD-icon-help', 'pre-text'), - key: t('help.key') - }), + reveal( + '.map-control.help-control', + t('intro.rapid.help', { - buttonText: t('intro.ok'), - buttonCallback: function() { allDone(); } + rapid: icon('#iD-logo-rapid', 'pre-text'), + button: icon('#iD-icon-help', 'pre-text'), + key: t('help.key') } - ) + ), + { + buttonText: t('intro.ok'), + buttonCallback: function() { allDone(); } + } + ); } @@ -331,5 +330,5 @@ export function uiIntroRapid(context, reveal) { return utilRebind(chapter, dispatch, 'on'); - + } diff --git a/modules/ui/rapid_first_edit_dialog.js b/modules/ui/rapid_first_edit_dialog.js index cbc8601abb..d26fbcd960 100644 --- a/modules/ui/rapid_first_edit_dialog.js +++ b/modules/ui/rapid_first_edit_dialog.js @@ -1,10 +1,8 @@ import { t } from '../util/locale'; -import { modeBrowse } from '../modes'; import { icon } from './intro/helper'; import { uiModal } from './modal'; -import { select as d3_select } from 'd3-selection'; -import { uiSplashRapid } from './splash_rapid'; -import { uiRestore } from './restore'; +import { uiSplashRapid } from './splash_rapid'; + export function uiRapidFirstEdit(context) { @@ -26,12 +24,12 @@ export function uiRapidFirstEdit(context) { { rapidicon: icon('#iD-logo-rapid', 'logo-rapid'), })); - + firstEditModal .append('div') .attr('class','modal-section') .append('p') - .text(t('rapid_first_edit.text')); + .text(t('rapid_first_edit.text')); var buttonWrap = firstEditModal .append('div') @@ -39,7 +37,7 @@ export function uiRapidFirstEdit(context) { var exploring = buttonWrap .append('button') - .attr('class', 'rapid-explore') + .attr('class', 'rapid-explore') .on('click', function() { modalSelection.close(); }); @@ -50,14 +48,13 @@ export function uiRapidFirstEdit(context) { var loginToOsm = buttonWrap .append('button') - .attr('class', 'rapid-login-to-osm') + .attr('class', 'rapid-login-to-osm') .on('click', function() { modalSelection.close(); var osm = context.connection(); - osm.authenticate(function(err) { - context.container() - .call(uiSplashRapid(context)) + osm.authenticate(function() { + context.container().call(uiSplashRapid(context)); }); }); diff --git a/modules/ui/raw_tag_editor.js b/modules/ui/raw_tag_editor.js index 92a8bfedd9..38ce144f6c 100644 --- a/modules/ui/raw_tag_editor.js +++ b/modules/ui/raw_tag_editor.js @@ -282,7 +282,7 @@ export function uiRawTagEditor(context) { function isReadOnly(d) { // Read-only for source=digitalglobe on ML roads. TODO: switch to check on __fbid__ - if (_entityID && _entityID.startsWith('w-') && d.key === 'source' && d.value === 'digitalglobe') { + if (_entityID && _entityID.indexOf('w-') === 0 && d.key === 'source' && d.value === 'digitalglobe') { return true; } for (var i = 0; i < _readOnlyTags.length; i++) { diff --git a/modules/ui/splash_rapid.js b/modules/ui/splash_rapid.js index 8bebeade8e..9699254990 100644 --- a/modules/ui/splash_rapid.js +++ b/modules/ui/splash_rapid.js @@ -2,7 +2,7 @@ import { t } from '../util/locale'; import { uiIntro } from './intro'; import { icon } from './intro/helper'; import { uiModal } from './modal'; -import { select as d3_select } from 'd3-selection'; + export function uiSplashRapid(context) { @@ -26,24 +26,24 @@ export function uiSplashRapid(context) { .attr('class','modal-section') .append('h3').text(t('rapidsplash.welcome')); - var welcomeSection = introModal + introModal .append('div') .attr('class','modal-section') .append('p') - .html(t('rapidsplash.text', + .html(t('rapidsplash.text', { rapidicon: icon('#iD-logo-rapid', 'logo-rapid'), walkthrough: icon('#iD-logo-walkthrough', 'logo-walkthrough'), edit: icon('#iD-logo-features', 'logo-features') })); - + var buttonWrap = introModal .append('div') .attr('class', 'modal-actions'); var walkthrough = buttonWrap .append('button') - .attr('class', 'walkthrough') + .attr('class', 'walkthrough') .on('click', function() { context.container().call(uiIntro(context, false)); modalSelection.close(); @@ -61,18 +61,18 @@ export function uiSplashRapid(context) { var rapidWalkthrough = buttonWrap .append('button') - .attr('class', 'rapid-walkthrough') + .attr('class', 'rapid-walkthrough') .on('click', function() { context.container().call(uiIntro(context, true)); modalSelection.close(); }); - + rapidWalkthrough .append('svg') .attr('class', 'logo logo-rapid') .append('use') .attr('xlink:href', '#iD-logo-rapid') - .attr('fill', 'white'); + .attr('fill', 'white'); rapidWalkthrough .append('div') diff --git a/modules/validations/y_shaped_connection.js b/modules/validations/y_shaped_connection.js index 6252c97fbb..589dea3478 100644 --- a/modules/validations/y_shaped_connection.js +++ b/modules/validations/y_shaped_connection.js @@ -1,5 +1,4 @@ import { geoAngle, geoSphericalDistance } from '../geo'; -import { modeSelect } from '../modes'; import { operationDelete } from '../operations/index'; import { t } from '../util/locale'; import { validationIssue, validationIssueFix } from '../core/validation'; @@ -78,7 +77,7 @@ export function validationYShapedConnection(context) { return new validationIssue({ type: type, severity: 'warning', - message: function(context) { + message: function() { return t('issues.y_shaped_connection.message'); }, reference: function(selection) { @@ -119,19 +118,21 @@ export function validationYShapedConnection(context) { if (edgeLen > SHORT_EDGE_THD_METERS) return false; // check if connNode is a Y-shaped connection + var prevEdgeGeoAngle = 0; + var nextEdgeGeoAngle = 0; var angleBetweenEdges = 0; var otherNodeIdx = connNodeIdx < edgeNodeIdx ? connNodeIdx - 1 : connNodeIdx + 1; var otherNid = way.nodes[otherNodeIdx]; var otherNode = graph.entity(otherNid); if (otherNodeIdx < edgeNodeIdx) { // node order along way: otherNode -> connNode -> edgeNode - var prevEdgeGeoAngle = geoAngle(otherNode, connNode, context.projection); - var nextEdgeGeoAngle = geoAngle(connNode, edgeNode, context.projection); + prevEdgeGeoAngle = geoAngle(otherNode, connNode, context.projection); + nextEdgeGeoAngle = geoAngle(connNode, edgeNode, context.projection); angleBetweenEdges = Math.abs(nextEdgeGeoAngle - prevEdgeGeoAngle) / Math.PI * 180.0; } else { // node order along way: edgeNode -> connNode -> otherNode - var prevEdgeGeoAngle = geoAngle(edgeNode, connNode, context.projection); - var nextEdgeGeoAngle = geoAngle(connNode, otherNode, context.projection); + prevEdgeGeoAngle = geoAngle(edgeNode, connNode, context.projection); + nextEdgeGeoAngle = geoAngle(connNode, otherNode, context.projection); angleBetweenEdges = Math.abs(nextEdgeGeoAngle - prevEdgeGeoAngle) / Math.PI * 180.0; }