Speedup imagery index with which-polygon

(closes #5226)
This commit is contained in:
Bryan Housel
2018-08-16 16:26:01 -04:00
parent ef0636ad01
commit 8b3637e55d
4 changed files with 54 additions and 48 deletions

View File

@@ -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,

View File

@@ -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)) {

View File

@@ -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);

View File

@@ -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();