in modules/services/keepRight.js [289:412]
loadIssues(projection) {
const options = {
format: 'geojson',
ch: _krRuleset
};
// determine the needed tiles to cover the view
const proj = new Projection().transform(projection.transform()).dimensions(projection.clipExtent());
const tiles = tiler.getTiles(proj).tiles;
// abort inflight requests that are no longer needed
abortUnwantedRequests(_cache, tiles);
// issue new requests..
tiles.forEach(tile => {
if (_cache.loadedTile[tile.id] || _cache.inflightTile[tile.id]) return;
const [ left, top, right, bottom ] = tile.wgs84Extent.rectangle();
const params = Object.assign({}, options, { left, bottom, right, top });
const url = `${_krUrlRoot}/export.php?` + utilQsString(params);
const controller = new AbortController();
_cache.inflightTile[tile.id] = controller;
d3_json(url, { signal: controller.signal })
.then(data => {
delete _cache.inflightTile[tile.id];
_cache.loadedTile[tile.id] = true;
if (!data || !data.features || !data.features.length) {
throw new Error('No Data');
}
data.features.forEach(feature => {
const {
properties: {
error_type: itemType,
error_id: id,
comment = null,
object_id: objectId,
object_type: objectType,
schema,
title
}
} = feature;
let {
geometry: { coordinates: loc },
properties: { description = '' }
} = feature;
// if there is a parent, save its error type e.g.:
// Error 191 = "highway-highway"
// Error 190 = "intersections without junctions" (parent)
const issueTemplate = _krData.errorTypes[itemType];
const parentIssueType = (Math.floor(itemType / 10) * 10).toString();
// try to handle error type directly, fallback to parent error type.
const whichType = issueTemplate ? itemType : parentIssueType;
const whichTemplate = _krData.errorTypes[whichType];
// Rewrite a few of the errors at this point..
// This is done to make them easier to linkify and translate.
switch (whichType) {
case '170':
description = `This feature has a FIXME tag: ${description}`;
break;
case '292':
case '293':
description = description.replace('A turn-', 'This turn-');
break;
case '294':
case '295':
case '296':
case '297':
case '298':
description = `This turn-restriction~${description}`;
break;
case '300':
description = 'This highway is missing a maxspeed tag';
break;
case '411':
case '412':
case '413':
description = `This feature~${description}`;
break;
}
// move markers slightly so it doesn't obscure the geometry,
// then move markers away from other coincident markers
let coincident = false;
do {
// first time, move marker up. after that, move marker right.
let delta = coincident ? [0.00001, 0] : [0, 0.00001];
loc = vecAdd(loc, delta);
let bbox = new Extent(loc).bbox();
coincident = _cache.rtree.search(bbox).length;
} while (coincident);
let d = new QAItem(loc, this, itemType, id, {
comment,
description,
whichType,
parentIssueType,
severity: whichTemplate.severity || 'error',
objectId,
objectType,
schema,
title
});
d.replacements = tokenReplacements(d);
_cache.data[id] = d;
_cache.rtree.insert(encodeIssueRtree(d));
});
dispatch.call('loaded');
})
.catch(() => {
delete _cache.inflightTile[tile.id];
_cache.loadedTile[tile.id] = true;
});
});
},