diff --git a/data/index.js b/data/index.js index 92cd0a335..0423aa9b4 100644 --- a/data/index.js +++ b/data/index.js @@ -1,3 +1,5 @@ +import _values from 'lodash-es/values'; + export { wikipedia as dataWikipedia } from 'wmf-sitematrix'; export { default as dataSuggestions } from 'name-suggestion-index/name-suggestions.json'; @@ -24,31 +26,31 @@ import { categories } from './presets/categories.json'; import { fields } from './presets/fields.json'; import { geoArea as d3_geoArea } from 'd3-geo'; -import _values from 'lodash-es/values'; import whichPolygon from 'which-polygon'; -var features = _values(ociFeatures).map(function(feature) { - // workaround for which-polygon - // only supports `properties`, not `id` + +// index the osm-community-index +var ociFeatureCollection = _values(ociFeatures).map(function(feature) { + // workaround for which-polygon: only supports `properties`, not `id` // https://github.com/mapbox/which-polygon/pull/6 feature.properties = { id: feature.id, area: d3_geoArea(feature) // also precompute areas }; - return feature; }); + export var data = { community: { features: ociFeatures, resources: ociResources, query: whichPolygon({ type: 'FeatureCollection', - features: features + features: ociFeatureCollection }) }, - imagery: dataImagery, + imagery: dataImagery, //legacy presets: { presets: presets, defaults: defaults, diff --git a/modules/renderer/background.js b/modules/renderer/background.js index 644986cad..71325195f 100644 --- a/modules/renderer/background.js +++ b/modules/renderer/background.js @@ -1,9 +1,12 @@ import _find from 'lodash-es/find'; +import _omit from 'lodash-es/omit'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { interpolateNumber as d3_interpolateNumber } from 'd3-interpolate'; import { select as d3_select } from 'd3-selection'; +import whichPolygon from 'which-polygon'; + import { data } from '../../data'; import { geoExtent, geoMetersToOffset, geoOffsetToMeters} from '../geo'; import { rendererBackgroundSource } from './background_source'; @@ -209,18 +212,24 @@ export function rendererBackground(context) { background.sources = function(extent) { + if (!data.imagery || !data.imagery.query) return []; // called before init()? + + var matchIDs = {}; + var matchImagery = data.imagery.query.bbox(extent.rectangle(), true) || []; + matchImagery.forEach(function(d) { matchIDs[d.id] = true; }); + return _backgroundSources.filter(function(source) { - return source.intersects(extent); + return matchIDs[source.id]; }); }; - background.dimensions = function(_) { - if (!_) return; - baseLayer.dimensions(_); + background.dimensions = function(d) { + if (!d) return; + baseLayer.dimensions(d); _overlayLayers.forEach(function(layer) { - layer.dimensions(_); + layer.dimensions(d); }); }; @@ -366,15 +375,39 @@ export function rendererBackground(context) { return geoExtent([args[2], args[1]]); } - var dataImagery = data.imagery || []; var q = utilStringQs(window.location.hash.substring(1)); var requested = q.background || q.layer; var extent = parseMap(q.map); var first; var best; + + data.imagery = data.imagery || []; + data.imagery.features = {}; + + // build efficient index and querying for data.imagery + var world = [[[-180, -90], [-180, 90], [180, 90], [180, -90], [-180, -90]]]; + var features = data.imagery.map(function(source) { + var feature = { + type: 'Feature', + id: source.id, + properties: _omit(source, ['polygon']), + geometry: { + type: 'MultiPolygon', + coordinates: [ source.polygon || world ] + } + }; + data.imagery.features[source.id] = feature; + return feature; + }); + data.imagery.query = whichPolygon({ + type: 'FeatureCollection', + features: features + }); + + // Add all the available imagery sources - _backgroundSources = dataImagery.map(function(source) { + _backgroundSources = data.imagery.map(function(source) { if (source.type === 'bing') { return rendererBackgroundSource.Bing(source, dispatch); } else if (/^EsriWorldImagery/.test(source.id)) { diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index fc8f07967..f3e2d5014 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -9,13 +9,7 @@ import { import { json as d3_json } from 'd3-request'; import { t } from '../util/locale'; - -import { - geoExtent, - geoPolygonIntersectsPolygon, - geoSphericalDistance -} from '../geo'; - +import { geoExtent, geoSphericalDistance } from '../geo'; import { utilDetect } from '../util/detect'; @@ -116,7 +110,7 @@ export function rendererBackgroundSource(data) { var lat = Math.atan(sinh(Math.PI * (1 - 2 * y / zoomSize))); switch (this.projection) { - case 'EPSG:4326': // todo: alternative codes of WGS 84? + case 'EPSG:4326': return { x: lon * 180 / Math.PI, y: lat * 180 / Math.PI @@ -162,14 +156,6 @@ export function rendererBackgroundSource(data) { }; - source.intersects = function(extent) { - extent = extent.polygon(); - return !data.polygon || data.polygon.some(function(polygon) { - return geoPolygonIntersectsPolygon(polygon, extent, true); - }); - }; - - source.validZoom = function(z) { return source.zoomExtent[0] <= z && (source.overzoom || source.zoomExtent[1] > z); diff --git a/modules/svg/debug.js b/modules/svg/debug.js index 26e6e112e..8476991ff 100644 --- a/modules/svg/debug.js +++ b/modules/svg/debug.js @@ -2,22 +2,12 @@ import _values from 'lodash-es/values'; import { select as d3_select } from 'd3-selection'; -import { geoPolygonIntersectsPolygon } from '../geo'; import { data, dataImperial, dataDriveLeft } from '../../data'; import { svgPath } from './index'; export function svgDebug(projection, context) { - function multipolygons(imagery) { - return imagery.map(function(data) { - return { - type: 'MultiPolygon', - coordinates: [ data.polygon ] - }; - }); - } - function drawDebug(selection) { var showsTile = context.getDebug('tile'); var showsCollision = context.getDebug('collision'); @@ -89,16 +79,11 @@ export function svgDebug(projection, context) { var extent = context.map().extent(); - var dataImagery = data.imagery || []; - var availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) { - if (!source.polygon) return false; - return source.polygon.some(function(polygon) { - return geoPolygonIntersectsPolygon(polygon, extent, true); - }); - })); + var matchImagery = (showsImagery && data.imagery.query.bbox(extent.rectangle(), true)) || []; + var features = matchImagery.map(function(d) { return data.imagery.features[d.id]; }); var imagery = layer.selectAll('path.debug-imagery') - .data(showsImagery ? availableImagery : []); + .data(features); imagery.exit() .remove();