From 0c0642e3217d98b9536c7e5007c84a999e1b369c Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 15 Jun 2016 16:29:20 -0400 Subject: [PATCH 1/2] Attempt to put services into module --- Makefile | 47 +- index.html | 9 +- js/id/modes.js | 1 - js/id/services.js | 1 - js/lib/id/services.js | 720 +++++++++++++++++++++++ modules/services/index.js | 5 + {js/id => modules}/services/mapillary.js | 21 +- {js/id => modules}/services/nominatim.js | 20 +- {js/id => modules}/services/taginfo.js | 4 +- {js/id => modules}/services/wikidata.js | 13 +- {js/id => modules}/services/wikipedia.js | 17 +- test/index.html | 9 +- test/rendering.html | 4 +- 13 files changed, 796 insertions(+), 75 deletions(-) delete mode 100644 js/id/modes.js delete mode 100644 js/id/services.js create mode 100644 js/lib/id/services.js create mode 100644 modules/services/index.js rename {js/id => modules}/services/mapillary.js (96%) rename {js/id => modules}/services/nominatim.js (72%) rename {js/id => modules}/services/taginfo.js (99%) rename {js/id => modules}/services/wikidata.js (73%) rename {js/id => modules}/services/wikipedia.js (83%) diff --git a/Makefile b/Makefile index 70f5d558e..66df62a45 100644 --- a/Makefile +++ b/Makefile @@ -44,30 +44,43 @@ $(BUILDJS_TARGETS): $(BUILDJS_SOURCES) build.js MODULE_TARGETS = \ js/lib/id/actions.js \ + js/lib/id/geo.js \ js/lib/id/modes.js \ js/lib/id/presets.js \ + js/lib/id/services.js \ js/lib/id/util.js \ - js/lib/id/validations.js \ js/lib/id/geo.js \ - js/lib/id/operations.js + js/lib/id/operations.js \ + js/lib/id/validations.js -js/lib/id/actions.js: modules/ - node_modules/.bin/rollup -f umd -n iD.actions modules/actions/index.js --no-strict > $@ +js/lib/id/actions.js: $(shell find modules/actions -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.actions modules/actions/index.js --no-strict -o $@ -js/lib/id/modes.js: modules/ - node_modules/.bin/rollup -f umd -n iD.modes modules/modes/index.js --no-strict > $@ +js/lib/id/geo.js: $(shell find modules/geo -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.geo modules/geo/index.js --no-strict -o $@ -js/lib/id/presets.js: modules/ - node_modules/.bin/rollup -f umd -n iD.presets modules/presets/index.js --no-strict > $@ +js/lib/id/modes.js: $(shell find modules/modes -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.modes modules/modes/index.js --no-strict -o $@ -js/lib/id/util.js: modules/ - node_modules/.bin/rollup -f umd -n iD.util modules/util/index.js --no-strict > $@ +js/lib/id/presets.js: $(shell find modules/presets -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.presets modules/presets/index.js --no-strict -o $@ -js/lib/id/validations.js: modules/ - node_modules/.bin/rollup -f umd -n iD.validations modules/validations/index.js --no-strict > $@ +js/lib/id/services.js: $(shell find modules/services -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.services modules/services/index.js --no-strict -o $@ + +js/lib/id/util.js: $(shell find modules/util -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.util modules/util/index.js --no-strict -o $@ + +js/lib/id/validations.js: $(shell find modules/validations -type f) + @rm -f $@ + node_modules/.bin/rollup -f umd -n iD.validations modules/validations/index.js --no-strict -o $@ -js/lib/id/geo.js: modules/ - node_modules/.bin/rollup -f umd -n iD.geo modules/geo/index.js --no-strict > $@ js/lib/id/operations.js: modules/ node_modules/.bin/rollup -f umd -n iD.operations modules/operations/index.js --no-strict > $@ @@ -95,12 +108,6 @@ dist/iD.js: \ js/id/start.js \ js/id/id.js \ $(MODULE_TARGETS) \ - js/id/services.js \ - js/id/services/mapillary.js \ - js/id/services/nominatim.js \ - js/id/services/taginfo.js \ - js/id/services/wikidata.js \ - js/id/services/wikipedia.js \ js/id/behavior.js \ js/id/behavior/add_way.js \ js/id/behavior/breathe.js \ diff --git a/index.html b/index.html index 16256a922..2e83560f9 100644 --- a/index.html +++ b/index.html @@ -37,17 +37,12 @@ + - - - - - - - + diff --git a/js/id/modes.js b/js/id/modes.js deleted file mode 100644 index bae5c1837..000000000 --- a/js/id/modes.js +++ /dev/null @@ -1 +0,0 @@ -iD.modes = {}; diff --git a/js/id/services.js b/js/id/services.js deleted file mode 100644 index c11dc788f..000000000 --- a/js/id/services.js +++ /dev/null @@ -1 +0,0 @@ -iD.services = {}; diff --git a/js/lib/id/services.js b/js/lib/id/services.js new file mode 100644 index 000000000..88ba00a2c --- /dev/null +++ b/js/lib/id/services.js @@ -0,0 +1,720 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.iD = global.iD || {}, global.iD.services = global.iD.services || {}))); +}(this, function (exports) { 'use strict'; + + const apibase = 'https://a.mapillary.com/v2/'; + const viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css'; + const viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js'; + const clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi'; + const maxResults = 1000; + const maxPages = 10; + const tileZoom = 14; + function mapillary() { + var mapillary = {}, + dispatch = d3.dispatch('loadedImages', 'loadedSigns'); + + + function loadSignStyles(context) { + d3.select('head').selectAll('#traffico') + .data([0]) + .enter() + .append('link') + .attr('id', 'traffico') + .attr('rel', 'stylesheet') + .attr('href', context.asset('traffico/stylesheets/traffico.css')); + } + + function loadSignDefs(context) { + if (iD.services.mapillary.sign_defs) return; + iD.services.mapillary.sign_defs = {}; + + _.each(['au', 'br', 'ca', 'de', 'us'], function(region) { + d3.json(context.asset('traffico/string-maps/' + region + '-map.json'), function(err, data) { + if (err) return; + if (region === 'de') region = 'eu'; + iD.services.mapillary.sign_defs[region] = data; + }); + }); + } + + function loadViewer() { + // mapillary-wrap + var wrap = d3.select('#content').selectAll('.mapillary-wrap') + .data([0]); + + var enter = wrap.enter().append('div') + .attr('class', 'mapillary-wrap') + .classed('al', true) // 'al'=left, 'ar'=right + .classed('hidden', true); + + enter.append('button') + .attr('class', 'thumb-hide') + .on('click', function () { mapillary.hideViewer(); }) + .append('div') + .call(iD.svg.Icon('#icon-close')); + + enter.append('div') + .attr('id', 'mly') + .attr('class', 'mly-wrapper') + .classed('active', false); + + // mapillary-viewercss + d3.select('head').selectAll('#mapillary-viewercss') + .data([0]) + .enter() + .append('link') + .attr('id', 'mapillary-viewercss') + .attr('rel', 'stylesheet') + .attr('href', viewercss); + + // mapillary-viewerjs + d3.select('head').selectAll('#mapillary-viewerjs') + .data([0]) + .enter() + .append('script') + .attr('id', 'mapillary-viewerjs') + .attr('src', viewerjs); + } + + function initViewer(imageKey, context) { + + function nodeChanged(d) { + var clicks = iD.services.mapillary.clicks; + var index = clicks.indexOf(d.key); + if (index > -1) { // nodechange initiated from clicking on a marker.. + clicks.splice(index, 1); + } else { // nodechange initiated from the Mapillary viewer controls.. + var loc = d.apiNavImIm ? [d.apiNavImIm.lon, d.apiNavImIm.lat] : [d.latLon.lon, d.latLon.lat]; + context.map().centerEase(loc); + mapillary.setSelectedImage(d.key, false); + } + } + + if (Mapillary && imageKey) { + var opts = { + baseImageSize: 320, + cover: false, + cache: true, + debug: false, + imagePlane: true, + loading: true, + sequence: true + }; + + var viewer = new Mapillary.Viewer('mly', clientId, imageKey, opts); + viewer.on('nodechanged', nodeChanged); + viewer.on('loadingchanged', mapillary.setViewerLoading); + iD.services.mapillary.viewer = viewer; + } + } + + function abortRequest(i) { + i.abort(); + } + + 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; + } + + function getTiles(projection, dimensions) { + 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.geo.tile() + .scaleExtent([tileZoom, tileZoom]) + .scale(s) + .size(dimensions) + .translate(projection.translate())() + .map(function(tile) { + var x = tile[0] * ts - origin[0], + y = tile[1] * ts - origin[1]; + + return { + id: tile.toString(), + extent: iD.geo.Extent( + projection.invert([x, y + ts]), + projection.invert([x + ts, y])) + }; + }); + } + + + function loadTiles(which, url, projection, dimensions) { + var tiles = getTiles(projection, dimensions).filter(function(t) { + var xyz = t.id.split(','); + return !nearNullIsland(xyz[0], xyz[1], 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) { + loadTilePage(which, url, tile, 0); + }); + } + + function loadTilePage(which, url, tile, page) { + var cache = iD.services.mapillary.cache[which], + id = tile.id + ',' + String(page), + rect = tile.extent.rectangle(); + + if (cache.loaded[id] || cache.inflight[id]) return; + + cache.inflight[id] = d3.json(url + + iD.util.qsString({ + geojson: 'true', + limit: maxResults, + page: page, + client_id: clientId, + min_lon: rect[0], + min_lat: rect[1], + max_lon: rect[2], + max_lat: rect[3] + }), function(err, data) { + cache.loaded[id] = true; + delete cache.inflight[id]; + if (err || !data.features || !data.features.length) return; + + var features = [], + nextPage = page + 1, + feature, loc, d; + + for (var i = 0; i < data.features.length; i++) { + feature = data.features[i]; + loc = feature.geometry.coordinates; + d = { key: feature.properties.key, loc: loc }; + if (which === 'images') d.ca = feature.properties.ca; + if (which === 'signs') d.signs = feature.properties.rects; + + features.push([loc[0], loc[1], loc[0], loc[1], d]); + } + + cache.rtree.load(features); + + if (which === 'images') dispatch.loadedImages(); + if (which === 'signs') dispatch.loadedSigns(); + + if (data.features.length === maxResults && nextPage < maxPages) { + loadTilePage(which, url, tile, nextPage); + } + } + ); + } + + mapillary.loadImages = function(projection, dimensions) { + var url = apibase + 'search/im/geojson?'; + loadTiles('images', url, projection, dimensions); + }; + + mapillary.loadSigns = function(context, projection, dimensions) { + var url = apibase + 'search/im/geojson/or?'; + loadSignStyles(context); + loadSignDefs(context); + loadTiles('signs', url, projection, dimensions); + }; + + mapillary.loadViewer = function() { + loadViewer(); + }; + + + // partition viewport into `psize` x `psize` regions + function partitionViewport(psize, projection, dimensions) { + psize = psize || 16; + var cols = d3.range(0, dimensions[0], psize), + rows = d3.range(0, dimensions[1], psize), + partitions = []; + + rows.forEach(function(y) { + cols.forEach(function(x) { + var min = [x, y + psize], + max = [x + psize, y]; + partitions.push( + iD.geo.Extent(projection.invert(min), projection.invert(max))); + }); + }); + + return partitions; + } + + // no more than `limit` results per partition. + function searchLimited(psize, limit, projection, dimensions, rtree) { + limit = limit || 3; + + var partitions = partitionViewport(psize, projection, dimensions); + return _.flatten(_.compact(_.map(partitions, function(extent) { + return rtree.search(extent.rectangle()) + .slice(0, limit) + .map(function(d) { return d[4]; }); + }))); + } + + mapillary.images = function(projection, dimensions) { + var psize = 16, limit = 3; + return searchLimited(psize, limit, projection, dimensions, iD.services.mapillary.cache.images.rtree); + }; + + mapillary.signs = function(projection, dimensions) { + var psize = 32, limit = 3; + return searchLimited(psize, limit, projection, dimensions, iD.services.mapillary.cache.signs.rtree); + }; + + mapillary.signsSupported = function() { + var detected = iD.detect(); + return (!(detected.ie || detected.browser.toLowerCase() === 'safari')); + }; + + mapillary.signHTML = function(d) { + if (!iD.services.mapillary.sign_defs) return; + + var detectionPackage = d.signs[0].package, + type = d.signs[0].type, + country = detectionPackage.split('_')[1]; + + return iD.services.mapillary.sign_defs[country][type]; + }; + + mapillary.showViewer = function() { + d3.select('#content') + .selectAll('.mapillary-wrap') + .classed('hidden', false) + .selectAll('.mly-wrapper') + .classed('active', true); + + return mapillary; + }; + + mapillary.hideViewer = function() { + d3.select('#content') + .selectAll('.mapillary-wrap') + .classed('hidden', true) + .selectAll('.mly-wrapper') + .classed('active', false); + + d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') + .classed('selected', false); + + iD.services.mapillary.image = null; + + return mapillary; + }; + + mapillary.setViewerLoading = function(loading) { + var canvas = d3.select('#content') + .selectAll('.mly-wrapper canvas'); + + if (canvas.empty()) return; // viewer not loaded yet + + var cover = d3.select('#content') + .selectAll('.mly-wrapper .Cover'); + + cover.classed('CoverDone', !loading); + + var button = cover.selectAll('.CoverButton') + .data(loading ? [0] : []); + + button.enter() + .append('div') + .attr('class', 'CoverButton') + .append('div') + .attr('class', 'uil-ripple-css') + .append('div'); + + button.exit() + .remove(); + + return mapillary; + }; + + mapillary.updateViewer = function(imageKey, context) { + if (!iD.services.mapillary) return; + if (!imageKey) return; + + if (!iD.services.mapillary.viewer) { + initViewer(imageKey, context); + } else { + iD.services.mapillary.viewer.moveToKey(imageKey); + } + + return mapillary; + }; + + mapillary.getSelectedImage = function() { + if (!iD.services.mapillary) return null; + return iD.services.mapillary.image; + }; + + mapillary.setSelectedImage = function(imageKey, fromClick) { + if (!iD.services.mapillary) return null; + + iD.services.mapillary.image = imageKey; + if (fromClick) { + iD.services.mapillary.clicks.push(imageKey); + } + + d3.selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign') + .classed('selected', function(d) { return d.key === imageKey; }); + + return mapillary; + }; + + mapillary.reset = function() { + var cache = iD.services.mapillary.cache; + + if (cache) { + _.forEach(cache.images.inflight, abortRequest); + _.forEach(cache.signs.inflight, abortRequest); + } + + iD.services.mapillary.cache = { + images: { inflight: {}, loaded: {}, rtree: rbush() }, + signs: { inflight: {}, loaded: {}, rtree: rbush() } + }; + + iD.services.mapillary.image = null; + iD.services.mapillary.clicks = []; + + return mapillary; + }; + + + if (!iD.services.mapillary.cache) { + mapillary.reset(); + } + + return d3.rebind(mapillary, dispatch, 'on'); + } + + const endpoint = 'https://nominatim.openstreetmap.org/reverse?'; + var cache; + + function nominatim() { + var nominatim = {}; + + nominatim.countryCode = function(location, callback) { + var countryCodes = cache.search([location[0], location[1], location[0], location[1]]); + + if (countryCodes.length > 0) + return callback(null, countryCodes[0][4]); + + d3.json(endpoint + + iD.util.qsString({ + format: 'json', + addressdetails: 1, + lat: location[1], + lon: location[0] + }), function(err, result) { + if (err) + return callback(err); + else if (result && result.error) + return callback(result.error); + + var extent = iD.geo.Extent(location).padByMeters(1000); + + cache.insert(extent.rectangle().concat(result.address.country_code)); + + callback(null, result.address.country_code); + }); + }; + + nominatim.reset = function() { + cache = rbush(); + return this; + }; + + if (!cache) { + nominatim.reset(); + } + + return nominatim; + } + + function taginfo() { + var taginfo = {}, + endpoint = 'https://taginfo.openstreetmap.org/api/4/', + tag_sorts = { + point: 'count_nodes', + vertex: 'count_nodes', + area: 'count_ways', + line: 'count_ways' + }, + tag_filters = { + point: 'nodes', + vertex: 'nodes', + area: 'ways', + line: 'ways' + }; + + + function sets(parameters, n, o) { + if (parameters.geometry && o[parameters.geometry]) { + parameters[n] = o[parameters.geometry]; + } + return parameters; + } + + function setFilter(parameters) { + return sets(parameters, 'filter', tag_filters); + } + + function setSort(parameters) { + return sets(parameters, 'sortname', tag_sorts); + } + + function clean(parameters) { + return _.omit(parameters, 'geometry', 'debounce'); + } + + function filterKeys(type) { + var count_type = type ? 'count_' + type : 'count_all'; + return function(d) { + return parseFloat(d[count_type]) > 2500 || d.in_wiki; + }; + } + + function filterMultikeys() { + return function(d) { + return (d.key.match(/:/g) || []).length === 1; // exactly one ':' + }; + } + + function filterValues() { + return function(d) { + if (d.value.match(/[A-Z*;,]/) !== null) return false; // exclude some punctuation, uppercase letters + return parseFloat(d.fraction) > 0.0 || d.in_wiki; + }; + } + + function valKey(d) { + return { + value: d.key, + title: d.key + }; + } + + function valKeyDescription(d) { + return { + value: d.value, + title: d.description || d.value + }; + } + + // sort keys with ':' lower than keys without ':' + function sortKeys(a, b) { + return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1 + : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1 + : 0; + } + + var debounced = _.debounce(d3.json, 100, true); + + function request(url, debounce, callback) { + var cache = iD.services.taginfo.cache; + + if (cache[url]) { + callback(null, cache[url]); + } else if (debounce) { + debounced(url, done); + } else { + d3.json(url, done); + } + + function done(err, data) { + if (!err) cache[url] = data; + callback(err, data); + } + } + + taginfo.keys = function(parameters, callback) { + var debounce = parameters.debounce; + parameters = clean(setSort(parameters)); + request(endpoint + 'keys/all?' + + iD.util.qsString(_.extend({ + rp: 10, + sortname: 'count_all', + sortorder: 'desc', + page: 1 + }, parameters)), debounce, function(err, d) { + if (err) return callback(err); + var f = filterKeys(parameters.filter); + callback(null, d.data.filter(f).sort(sortKeys).map(valKey)); + }); + }; + + taginfo.multikeys = function(parameters, callback) { + var debounce = parameters.debounce; + parameters = clean(setSort(parameters)); + request(endpoint + 'keys/all?' + + iD.util.qsString(_.extend({ + rp: 25, + sortname: 'count_all', + sortorder: 'desc', + page: 1 + }, parameters)), debounce, function(err, d) { + if (err) return callback(err); + var f = filterMultikeys(); + callback(null, d.data.filter(f).map(valKey)); + }); + }; + + taginfo.values = function(parameters, callback) { + var debounce = parameters.debounce; + parameters = clean(setSort(setFilter(parameters))); + request(endpoint + 'key/values?' + + iD.util.qsString(_.extend({ + rp: 25, + sortname: 'count_all', + sortorder: 'desc', + page: 1 + }, parameters)), debounce, function(err, d) { + if (err) return callback(err); + var f = filterValues(); + callback(null, d.data.filter(f).map(valKeyDescription)); + }); + }; + + taginfo.docs = function(parameters, callback) { + var debounce = parameters.debounce; + parameters = clean(setSort(parameters)); + + var path = 'key/wiki_pages?'; + if (parameters.value) path = 'tag/wiki_pages?'; + else if (parameters.rtype) path = 'relation/wiki_pages?'; + + request(endpoint + path + iD.util.qsString(parameters), debounce, function(err, d) { + if (err) return callback(err); + callback(null, d.data); + }); + }; + + taginfo.endpoint = function(_) { + if (!arguments.length) return endpoint; + endpoint = _; + return taginfo; + }; + + taginfo.reset = function() { + iD.services.taginfo.cache = {}; + return taginfo; + }; + + + if (!iD.services.taginfo.cache) { + taginfo.reset(); + } + + return taginfo; + } + + const endpoint$1 = 'https://www.wikidata.org/w/api.php?'; + + function wikidata() { + var wikidata = {}; + + // Given a Wikipedia language and article title, return an array of + // corresponding Wikidata entities. + wikidata.itemsByTitle = function(lang, title, callback) { + lang = lang || 'en'; + d3.jsonp(endpoint$1 + iD.util.qsString({ + action: 'wbgetentities', + format: 'json', + sites: lang.replace(/-/g, '_') + 'wiki', + titles: title, + languages: 'en', // shrink response by filtering to one language + callback: '{callback}' + }), function(data) { + callback(title, data.entities || {}); + }); + }; + + return wikidata; + } + + const endpoint$2 = 'https://en.wikipedia.org/w/api.php?'; + + function wikipedia() { + var wikipedia = {}; + + wikipedia.search = function(lang, query, callback) { + lang = lang || 'en'; + d3.jsonp(endpoint$2.replace('en', lang) + + iD.util.qsString({ + action: 'query', + list: 'search', + srlimit: '10', + srinfo: 'suggestion', + format: 'json', + callback: '{callback}', + srsearch: query + }), function(data) { + if (!data.query) return; + callback(query, data.query.search.map(function(d) { + return d.title; + })); + }); + }; + + wikipedia.suggestions = function(lang, query, callback) { + lang = lang || 'en'; + d3.jsonp(endpoint$2.replace('en', lang) + + iD.util.qsString({ + action: 'opensearch', + namespace: 0, + suggest: '', + format: 'json', + callback: '{callback}', + search: query + }), function(d) { + callback(d[0], d[1]); + }); + }; + + wikipedia.translations = function(lang, title, callback) { + d3.jsonp(endpoint$2.replace('en', lang) + + iD.util.qsString({ + action: 'query', + prop: 'langlinks', + format: 'json', + callback: '{callback}', + lllimit: 500, + titles: title + }), function(d) { + var list = d.query.pages[Object.keys(d.query.pages)[0]], + translations = {}; + if (list && list.langlinks) { + list.langlinks.forEach(function(d) { + translations[d.lang] = d['*']; + }); + callback(translations); + } + }); + }; + + return wikipedia; + } + + exports.mapillary = mapillary; + exports.nominatim = nominatim; + exports.taginfo = taginfo; + exports.wikidata = wikidata; + exports.wikipedia = wikipedia; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); \ No newline at end of file diff --git a/modules/services/index.js b/modules/services/index.js new file mode 100644 index 000000000..44f5a6f08 --- /dev/null +++ b/modules/services/index.js @@ -0,0 +1,5 @@ +export { mapillary } from './mapillary'; +export { nominatim } from './nominatim'; +export { taginfo } from './taginfo'; +export { wikidata } from './wikidata'; +export { wikipedia } from './wikipedia'; diff --git a/js/id/services/mapillary.js b/modules/services/mapillary.js similarity index 96% rename from js/id/services/mapillary.js rename to modules/services/mapillary.js index 960714b59..a1d15b20a 100644 --- a/js/id/services/mapillary.js +++ b/modules/services/mapillary.js @@ -1,13 +1,14 @@ -iD.services.mapillary = function() { +const apibase = 'https://a.mapillary.com/v2/', + viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css', + viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js', + clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi', + maxResults = 1000, + maxPages = 10, + tileZoom = 14; + +export function mapillary() { var mapillary = {}, - dispatch = d3.dispatch('loadedImages', 'loadedSigns'), - apibase = 'https://a.mapillary.com/v2/', - viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css', - viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js', - clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi', - maxResults = 1000, - maxPages = 10, - tileZoom = 14; + dispatch = d3.dispatch('loadedImages', 'loadedSigns'); function loadSignStyles(context) { @@ -393,4 +394,4 @@ iD.services.mapillary = function() { } return d3.rebind(mapillary, dispatch, 'on'); -}; +} diff --git a/js/id/services/nominatim.js b/modules/services/nominatim.js similarity index 72% rename from js/id/services/nominatim.js rename to modules/services/nominatim.js index e57921331..799e16469 100644 --- a/js/id/services/nominatim.js +++ b/modules/services/nominatim.js @@ -1,11 +1,11 @@ -iD.services.nominatim = function() { - var nominatim = {}, - endpoint = 'https://nominatim.openstreetmap.org/reverse?'; +const endpoint = 'https://nominatim.openstreetmap.org/reverse?'; +var cache; +export function nominatim() { + var nominatim = {}; nominatim.countryCode = function(location, callback) { - var cache = iD.services.nominatim.cache, - countryCodes = cache.search([location[0], location[1], location[0], location[1]]); + var countryCodes = cache.search([location[0], location[1], location[0], location[1]]); if (countryCodes.length > 0) return callback(null, countryCodes[0][4]); @@ -31,14 +31,14 @@ iD.services.nominatim = function() { }; nominatim.reset = function() { - iD.services.nominatim.cache = rbush(); - return nominatim; + cache = rbush(); + return this; }; - - if (!iD.services.nominatim.cache) { + if (!cache) { nominatim.reset(); } return nominatim; -}; +} + diff --git a/js/id/services/taginfo.js b/modules/services/taginfo.js similarity index 99% rename from js/id/services/taginfo.js rename to modules/services/taginfo.js index 76148c014..2e423ba52 100644 --- a/js/id/services/taginfo.js +++ b/modules/services/taginfo.js @@ -1,4 +1,4 @@ -iD.services.taginfo = function() { +export function taginfo() { var taginfo = {}, endpoint = 'https://taginfo.openstreetmap.org/api/4/', tag_sorts = { @@ -173,4 +173,4 @@ iD.services.taginfo = function() { } return taginfo; -}; +} diff --git a/js/id/services/wikidata.js b/modules/services/wikidata.js similarity index 73% rename from js/id/services/wikidata.js rename to modules/services/wikidata.js index 0718e2fdd..49d407cd0 100644 --- a/js/id/services/wikidata.js +++ b/modules/services/wikidata.js @@ -1,10 +1,11 @@ -iD.services.wikidata = function() { - var wiki = {}, - endpoint = 'https://www.wikidata.org/w/api.php?'; +const endpoint = 'https://www.wikidata.org/w/api.php?'; + +export function wikidata() { + var wikidata = {}; // Given a Wikipedia language and article title, return an array of // corresponding Wikidata entities. - wiki.itemsByTitle = function(lang, title, callback) { + wikidata.itemsByTitle = function(lang, title, callback) { lang = lang || 'en'; d3.jsonp(endpoint + iD.util.qsString({ action: 'wbgetentities', @@ -18,5 +19,5 @@ iD.services.wikidata = function() { }); }; - return wiki; -}; + return wikidata; +} diff --git a/js/id/services/wikipedia.js b/modules/services/wikipedia.js similarity index 83% rename from js/id/services/wikipedia.js rename to modules/services/wikipedia.js index a33143a07..1ba599c98 100644 --- a/js/id/services/wikipedia.js +++ b/modules/services/wikipedia.js @@ -1,8 +1,9 @@ -iD.services.wikipedia = function() { - var wiki = {}, - endpoint = 'https://en.wikipedia.org/w/api.php?'; +const endpoint = 'https://en.wikipedia.org/w/api.php?'; - wiki.search = function(lang, query, callback) { +export function wikipedia() { + var wikipedia = {}; + + wikipedia.search = function(lang, query, callback) { lang = lang || 'en'; d3.jsonp(endpoint.replace('en', lang) + iD.util.qsString({ @@ -21,7 +22,7 @@ iD.services.wikipedia = function() { }); }; - wiki.suggestions = function(lang, query, callback) { + wikipedia.suggestions = function(lang, query, callback) { lang = lang || 'en'; d3.jsonp(endpoint.replace('en', lang) + iD.util.qsString({ @@ -36,7 +37,7 @@ iD.services.wikipedia = function() { }); }; - wiki.translations = function(lang, title, callback) { + wikipedia.translations = function(lang, title, callback) { d3.jsonp(endpoint.replace('en', lang) + iD.util.qsString({ action: 'query', @@ -57,5 +58,5 @@ iD.services.wikipedia = function() { }); }; - return wiki; -}; + return wikipedia; +} diff --git a/test/index.html b/test/index.html index 01c41b4f3..4d0a833ad 100644 --- a/test/index.html +++ b/test/index.html @@ -42,20 +42,15 @@ + + - - - - - - - diff --git a/test/rendering.html b/test/rendering.html index f24097f7c..798427917 100644 --- a/test/rendering.html +++ b/test/rendering.html @@ -11,12 +11,10 @@ + - - - From 82f0a813089d42d6f1b67b33816a426126462a2d Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 15 Jun 2016 17:03:41 -0400 Subject: [PATCH 2/2] Resolve module variable collisions --- js/lib/id/services.js | 48 +++++++++++++++++------------------ modules/services/mapillary.js | 15 +++++------ modules/services/nominatim.js | 14 +++++----- modules/services/wikidata.js | 6 ++--- modules/services/wikipedia.js | 6 ++--- 5 files changed, 44 insertions(+), 45 deletions(-) diff --git a/js/lib/id/services.js b/js/lib/id/services.js index 88ba00a2c..58810eb77 100644 --- a/js/lib/id/services.js +++ b/js/lib/id/services.js @@ -4,15 +4,15 @@ (factory((global.iD = global.iD || {}, global.iD.services = global.iD.services || {}))); }(this, function (exports) { 'use strict'; - const apibase = 'https://a.mapillary.com/v2/'; - const viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css'; - const viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js'; - const clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi'; - const maxResults = 1000; - const maxPages = 10; - const tileZoom = 14; function mapillary() { var mapillary = {}, + apibase = 'https://a.mapillary.com/v2/', + viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css', + viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js', + clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi', + maxResults = 1000, + maxPages = 10, + tileZoom = 14, dispatch = d3.dispatch('loadedImages', 'loadedSigns'); @@ -401,14 +401,14 @@ return d3.rebind(mapillary, dispatch, 'on'); } - const endpoint = 'https://nominatim.openstreetmap.org/reverse?'; - var cache; - function nominatim() { - var nominatim = {}; + var nominatim = {}, + endpoint = 'https://nominatim.openstreetmap.org/reverse?'; + nominatim.countryCode = function(location, callback) { - var countryCodes = cache.search([location[0], location[1], location[0], location[1]]); + var cache = iD.services.nominatim.cache, + countryCodes = cache.search([location[0], location[1], location[0], location[1]]); if (countryCodes.length > 0) return callback(null, countryCodes[0][4]); @@ -434,11 +434,11 @@ }; nominatim.reset = function() { - cache = rbush(); + iD.services.nominatim.cache = rbush(); return this; }; - if (!cache) { + if (!iD.services.nominatim.cache) { nominatim.reset(); } @@ -622,16 +622,16 @@ return taginfo; } - const endpoint$1 = 'https://www.wikidata.org/w/api.php?'; - function wikidata() { - var wikidata = {}; + var wikidata = {}, + endpoint = 'https://www.wikidata.org/w/api.php?'; + // Given a Wikipedia language and article title, return an array of // corresponding Wikidata entities. wikidata.itemsByTitle = function(lang, title, callback) { lang = lang || 'en'; - d3.jsonp(endpoint$1 + iD.util.qsString({ + d3.jsonp(endpoint + iD.util.qsString({ action: 'wbgetentities', format: 'json', sites: lang.replace(/-/g, '_') + 'wiki', @@ -646,14 +646,14 @@ return wikidata; } - const endpoint$2 = 'https://en.wikipedia.org/w/api.php?'; - function wikipedia() { - var wikipedia = {}; + var wikipedia = {}, + endpoint = 'https://en.wikipedia.org/w/api.php?'; + wikipedia.search = function(lang, query, callback) { lang = lang || 'en'; - d3.jsonp(endpoint$2.replace('en', lang) + + d3.jsonp(endpoint.replace('en', lang) + iD.util.qsString({ action: 'query', list: 'search', @@ -672,7 +672,7 @@ wikipedia.suggestions = function(lang, query, callback) { lang = lang || 'en'; - d3.jsonp(endpoint$2.replace('en', lang) + + d3.jsonp(endpoint.replace('en', lang) + iD.util.qsString({ action: 'opensearch', namespace: 0, @@ -686,7 +686,7 @@ }; wikipedia.translations = function(lang, title, callback) { - d3.jsonp(endpoint$2.replace('en', lang) + + d3.jsonp(endpoint.replace('en', lang) + iD.util.qsString({ action: 'query', prop: 'langlinks', diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index a1d15b20a..ed313746d 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -1,13 +1,12 @@ -const apibase = 'https://a.mapillary.com/v2/', - viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css', - viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js', - clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi', - maxResults = 1000, - maxPages = 10, - tileZoom = 14; - export function mapillary() { var mapillary = {}, + apibase = 'https://a.mapillary.com/v2/', + viewercss = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.css', + viewerjs = 'https://npmcdn.com/mapillary-js@1.3.0/dist/mapillary-js.min.js', + clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi', + maxResults = 1000, + maxPages = 10, + tileZoom = 14, dispatch = d3.dispatch('loadedImages', 'loadedSigns'); diff --git a/modules/services/nominatim.js b/modules/services/nominatim.js index 799e16469..987ceea8c 100644 --- a/modules/services/nominatim.js +++ b/modules/services/nominatim.js @@ -1,11 +1,11 @@ -const endpoint = 'https://nominatim.openstreetmap.org/reverse?'; -var cache; - export function nominatim() { - var nominatim = {}; + var nominatim = {}, + endpoint = 'https://nominatim.openstreetmap.org/reverse?'; + nominatim.countryCode = function(location, callback) { - var countryCodes = cache.search([location[0], location[1], location[0], location[1]]); + var cache = iD.services.nominatim.cache, + countryCodes = cache.search([location[0], location[1], location[0], location[1]]); if (countryCodes.length > 0) return callback(null, countryCodes[0][4]); @@ -31,11 +31,11 @@ export function nominatim() { }; nominatim.reset = function() { - cache = rbush(); + iD.services.nominatim.cache = rbush(); return this; }; - if (!cache) { + if (!iD.services.nominatim.cache) { nominatim.reset(); } diff --git a/modules/services/wikidata.js b/modules/services/wikidata.js index 49d407cd0..e8e682523 100644 --- a/modules/services/wikidata.js +++ b/modules/services/wikidata.js @@ -1,7 +1,7 @@ -const endpoint = 'https://www.wikidata.org/w/api.php?'; - export function wikidata() { - var wikidata = {}; + var wikidata = {}, + endpoint = 'https://www.wikidata.org/w/api.php?'; + // Given a Wikipedia language and article title, return an array of // corresponding Wikidata entities. diff --git a/modules/services/wikipedia.js b/modules/services/wikipedia.js index 1ba599c98..35334e6c8 100644 --- a/modules/services/wikipedia.js +++ b/modules/services/wikipedia.js @@ -1,7 +1,7 @@ -const endpoint = 'https://en.wikipedia.org/w/api.php?'; - export function wikipedia() { - var wikipedia = {}; + var wikipedia = {}, + endpoint = 'https://en.wikipedia.org/w/api.php?'; + wikipedia.search = function(lang, query, callback) { lang = lang || 'en';