X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/95d406937ee33c04d739bf199df669f0167a9ab4..64604a852f941a2c30aef909073b4f6925c622fa:/vendor/assets/iD/iD.js
diff --git a/vendor/assets/iD/iD.js b/vendor/assets/iD/iD.js
index 6ac452788..346fdbd66 100644
--- a/vendor/assets/iD/iD.js
+++ b/vendor/assets/iD/iD.js
@@ -69,7 +69,7 @@
return toString$1.call(it).slice(8, -1);
};
- var split$2 = ''.split;
+ var split$1 = ''.split;
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var indexedObject = fails(function () {
@@ -77,7 +77,7 @@
// eslint-disable-next-line no-prototype-builtins -- safe
return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
- return classofRaw(it) == 'String' ? split$2.call(it, '') : Object(it);
+ return classofRaw(it) == 'String' ? split$1.call(it, '') : Object(it);
} : Object;
// `RequireObjectCoercible` abstract operation
@@ -226,7 +226,7 @@
(module.exports = function (key, value) {
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
})('versions', []).push({
- version: '3.15.2',
+ version: '3.15.0',
mode: 'global',
copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
});
@@ -2880,8 +2880,7 @@
var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen;
var FORCED$f = isForced_1(PROMISE, function () {
- var PROMISE_CONSTRUCTOR_SOURCE = inspectSource(PromiseConstructor);
- var GLOBAL_CORE_JS_PROMISE = PROMISE_CONSTRUCTOR_SOURCE !== String(PromiseConstructor);
+ var GLOBAL_CORE_JS_PROMISE = inspectSource(PromiseConstructor) !== String(PromiseConstructor);
// V8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
// https://bugs.chromium.org/p/chromium/issues/detail?id=830565
// We can't detect it synchronously, so just check versions
@@ -2889,7 +2888,7 @@
// We can't use @@species feature detection in V8 since it causes
// deoptimization and performance degradation
// https://github.com/zloirock/core-js/issues/679
- if (engineV8Version >= 51 && /native code/.test(PROMISE_CONSTRUCTOR_SOURCE)) return false;
+ if (engineV8Version >= 51 && /native code/.test(PromiseConstructor)) return false;
// Detect correctness of subclassing with @@species support
var promise = new PromiseConstructor(function (resolve) { resolve(1); });
var FakePromise = function (exec) {
@@ -6962,20 +6961,20 @@
});
};
- var DOMException$2 = global$1.DOMException;
+ var DOMException$1 = global$1.DOMException;
try {
- new DOMException$2();
+ new DOMException$1();
} catch (err) {
- DOMException$2 = function DOMException(message, name) {
+ DOMException$1 = function DOMException(message, name) {
this.message = message;
this.name = name;
var error = Error(message);
this.stack = error.stack;
};
- DOMException$2.prototype = Object.create(Error.prototype);
- DOMException$2.prototype.constructor = DOMException$2;
+ DOMException$1.prototype = Object.create(Error.prototype);
+ DOMException$1.prototype.constructor = DOMException$1;
}
function fetch$1(input, init) {
@@ -6983,7 +6982,7 @@
var request = new Request(input, init);
if (request.signal && request.signal.aborted) {
- return reject(new DOMException$2('Aborted', 'AbortError'));
+ return reject(new DOMException$1('Aborted', 'AbortError'));
}
var xhr = new XMLHttpRequest();
@@ -7019,7 +7018,7 @@
xhr.onabort = function () {
setTimeout(function () {
- reject(new DOMException$2('Aborted', 'AbortError'));
+ reject(new DOMException$1('Aborted', 'AbortError'));
}, 0);
};
@@ -8348,7 +8347,7 @@
var setMetadata = function (it) {
defineProperty(it, METADATA, { value: {
- objectID: 'O' + id++, // object ID
+ objectID: 'O' + ++id, // object ID
weakData: {} // weak collections IDs
} });
};
@@ -9475,7 +9474,7 @@
}
});
- var _marked$2 = /*#__PURE__*/regeneratorRuntime.mark(numbers);
+ var _marked$3 = /*#__PURE__*/regeneratorRuntime.mark(numbers);
function number$1 (x) {
return x === null ? NaN : +x;
@@ -9587,7 +9586,7 @@
return _context.stop();
}
}
- }, _marked$2, null, [[2, 13, 16, 19], [23, 34, 37, 40]]);
+ }, _marked$3, null, [[2, 13, 16, 19], [23, 34, 37, 40]]);
}
var ascendingBisect = d3_bisector(d3_ascending);
@@ -10021,7 +10020,7 @@
return quantile(values, 0.5, valueof);
}
- var _marked$1 = /*#__PURE__*/regeneratorRuntime.mark(flatten);
+ var _marked$2 = /*#__PURE__*/regeneratorRuntime.mark(flatten);
function flatten(arrays) {
var _iterator, _step, array;
@@ -10070,7 +10069,7 @@
return _context.stop();
}
}
- }, _marked$1, null, [[1, 10, 13, 16]]);
+ }, _marked$2, null, [[1, 10, 13, 16]]);
}
function merge$4(arrays) {
@@ -14163,7 +14162,7 @@
return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params));
}
- var _marked = /*#__PURE__*/regeneratorRuntime.mark(_callee);
+ var _marked$1 = /*#__PURE__*/regeneratorRuntime.mark(_callee);
function _callee() {
var groups, j, m, group, i, n, node;
@@ -14210,7 +14209,7 @@
return _context.stop();
}
}
- }, _marked, this);
+ }, _marked$1, this);
}
var root$1 = [null];
@@ -14731,16 +14730,17 @@
var patternIsRegExp = isRegexp(pattern);
var flagsAreUndefined = flags === undefined;
var groups = [];
- var rawPattern = pattern;
- var rawFlags, dotAll, sticky, handled, result, state;
+ var rawPattern, rawFlags, dotAll, sticky, handled, result, state;
- if (!thisIsRegExp && patternIsRegExp && flagsAreUndefined && pattern.constructor === RegExpWrapper) {
+ if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) {
return pattern;
}
- if (patternIsRegExp || pattern instanceof RegExpWrapper) {
+ if (CORRECT_NEW) {
+ if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source;
+ } else if (pattern instanceof RegExpWrapper) {
+ if (flagsAreUndefined) flags = regexpFlags.call(pattern);
pattern = pattern.source;
- if (flagsAreUndefined) flags = 'flags' in rawPattern ? rawPattern.flags : regexpFlags.call(rawPattern);
}
pattern = pattern === undefined ? '' : String(pattern);
@@ -14765,7 +14765,11 @@
groups = handled[1];
}
- result = inheritIfRequired(NativeRegExp(pattern, flags), thisIsRegExp ? this : RegExpPrototype, RegExpWrapper);
+ result = inheritIfRequired(
+ CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags),
+ thisIsRegExp ? this : RegExpPrototype,
+ RegExpWrapper
+ );
if (dotAll || sticky || groups.length) {
state = enforceInternalState(result);
@@ -20098,7 +20102,7 @@
});
var name = "iD";
- var version = "2.20.0";
+ var version = "2.20.1";
var description = "A friendly editor for OpenStreetMap";
var main = "dist/iD.min.js";
var repository = "github:openstreetmap/iD";
@@ -20107,8 +20111,8 @@
var keywords = ["editor","openstreetmap"];
var license = "ISC";
var scripts = {all:"npm-run-all -s clean build build:legacy dist",build:"npm-run-all -s build:css build:data build:dev","build:css":"node scripts/build_css.js","build:data":"shx mkdir -p dist/data && node scripts/build_data.js","build:dev":"rollup --config config/rollup.config.dev.js","build:legacy":"rollup --config config/rollup.config.legacy.js","build:stats":"rollup --config config/rollup.config.stats.js",clean:"shx rm -f dist/*.js dist/*.map dist/*.css dist/img/*.svg",dist:"npm-run-all -p dist:**","dist:mapillary":"shx mkdir -p dist/mapillary-js && shx cp -R node_modules/mapillary-js/dist/* dist/mapillary-js/","dist:pannellum":"shx mkdir -p dist/pannellum-streetside && shx cp -R node_modules/pannellum/build/* dist/pannellum-streetside/","dist:min:iD":"uglifyjs dist/iD.legacy.js --compress --mangle --output dist/iD.min.js","dist:svg:iD":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"iD-%s\" --symbol-sprite dist/img/iD-sprite.svg \"svg/iD-sprite/**/*.svg\"","dist:svg:community":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"community-%s\" --symbol-sprite dist/img/community-sprite.svg node_modules/osm-community-index/dist/img/*.svg","dist:svg:fa":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/fa-sprite.svg svg/fontawesome/*.svg","dist:svg:maki":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"maki-%s\" --symbol-sprite dist/img/maki-sprite.svg node_modules/@mapbox/maki/icons/*.svg","dist:svg:mapillary:signs":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-sprite.svg node_modules/mapillary_sprite_source/package_signs/*.svg","dist:svg:mapillary:objects":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-object-sprite.svg node_modules/mapillary_sprite_source/package_objects/*.svg","dist:svg:temaki":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"temaki-%s\" --symbol-sprite dist/img/temaki-sprite.svg node_modules/@ideditor/temaki/icons/*.svg",imagery:"node scripts/update_imagery.js",lint:"eslint scripts test/spec modules","lint:fix":"eslint scripts test/spec modules --fix",start:"npm-run-all -s build start:server",quickstart:"npm-run-all -s build:dev start:server","start:server":"node scripts/server.js",test:"npm-run-all -s lint build:css build:data build:legacy test:spec","test:spec":"phantomjs --web-security=no node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html spec",translations:"node scripts/update_locales.js"};
- var dependencies = {"@ideditor/country-coder":"~5.0.3","@ideditor/location-conflation":"~1.0.2","@mapbox/geojson-area":"^0.2.2","@mapbox/sexagesimal":"1.2.0","@mapbox/togeojson":"0.16.0","@mapbox/vector-tile":"^1.3.1","@turf/bbox-clip":"^6.0.0","abortcontroller-polyfill":"^1.4.0","aes-js":"^3.1.2","alif-toolkit":"^1.2.9","core-js":"^3.6.5",diacritics:"1.3.0","fast-deep-equal":"~3.1.1","fast-json-stable-stringify":"2.1.0","lodash-es":"~4.17.15",marked:"~2.0.0","node-diff3":"2.1.0","osm-auth":"1.1.0",pannellum:"2.5.6","polygon-clipping":"~0.15.1",rbush:"3.0.1","whatwg-fetch":"^3.4.1","which-polygon":"2.2.0"};
- var devDependencies = {"@babel/core":"^7.11.6","@babel/preset-env":"^7.11.5","@fortawesome/fontawesome-svg-core":"^1.2.32","@fortawesome/free-brands-svg-icons":"~5.15.1","@fortawesome/free-regular-svg-icons":"~5.15.1","@fortawesome/free-solid-svg-icons":"~5.15.1","@ideditor/temaki":"~4.4.0","@mapbox/maki":"^6.0.0","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-commonjs":"^17.0.0","@rollup/plugin-json":"^4.0.1","@rollup/plugin-node-resolve":"~11.2.0",autoprefixer:"^10.0.1",btoa:"^1.2.1",chai:"^4.1.0","cldr-core":"37.0.0","cldr-localenames-full":"37.0.0",colors:"^1.1.2","concat-files":"^0.1.1",d3:"~6.6.0","editor-layer-index":"github:osmlab/editor-layer-index#gh-pages",eslint:"^7.1.0",gaze:"^1.1.3",glob:"^7.1.0",happen:"^0.3.1","js-yaml":"^4.0.0","json-stringify-pretty-compact":"^3.0.0",mapillary_sprite_source:"^1.8.0","mapillary-js":"4.0.0",minimist:"^1.2.3",mocha:"^7.0.1","mocha-phantomjs-core":"^2.1.0","name-suggestion-index":"~6.0","node-fetch":"^2.6.1","npm-run-all":"^4.0.0","object-inspect":"1.10.3","osm-community-index":"~5.1.0","phantomjs-prebuilt":"~2.1.16",postcss:"^8.1.1","postcss-selector-prepend":"^0.5.0",rollup:"~2.52.8","rollup-plugin-includepaths":"~0.2.3","rollup-plugin-progress":"^1.1.1","rollup-plugin-visualizer":"~4.2.0",shelljs:"^0.8.0",shx:"^0.3.0",sinon:"7.5.0","sinon-chai":"^3.3.0",smash:"0.0","static-server":"^2.2.1","svg-sprite":"1.5.0","uglify-js":"~3.13.0",vparse:"~1.1.0"};
+ var dependencies = {"@ideditor/country-coder":"~5.0.3","@ideditor/location-conflation":"~1.0.2","@mapbox/geojson-area":"^0.2.2","@mapbox/sexagesimal":"1.2.0","@mapbox/vector-tile":"^1.3.1","@tmcw/togeojson":"^4.5.0","@turf/bbox-clip":"^6.0.0","abortcontroller-polyfill":"^1.4.0","aes-js":"^3.1.2","alif-toolkit":"^1.2.9","core-js":"^3.6.5",diacritics:"1.3.0","fast-deep-equal":"~3.1.1","fast-json-stable-stringify":"2.1.0","lodash-es":"~4.17.15",marked:"~2.0.0","node-diff3":"2.1.0","osm-auth":"1.1.0",pannellum:"2.5.6",pbf:"^3.2.1","polygon-clipping":"~0.15.1",rbush:"3.0.1","whatwg-fetch":"^3.4.1","which-polygon":"2.2.0"};
+ var devDependencies = {"@babel/core":"^7.11.6","@babel/preset-env":"^7.11.5","@fortawesome/fontawesome-svg-core":"^1.2.32","@fortawesome/free-brands-svg-icons":"~5.15.1","@fortawesome/free-regular-svg-icons":"~5.15.1","@fortawesome/free-solid-svg-icons":"~5.15.1","@ideditor/temaki":"~4.4.0","@mapbox/maki":"^6.0.0","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-commonjs":"^17.0.0","@rollup/plugin-json":"^4.0.1","@rollup/plugin-node-resolve":"~11.2.0",autoprefixer:"^10.0.1",btoa:"^1.2.1",chai:"^4.1.0","cldr-core":"37.0.0","cldr-localenames-full":"37.0.0",colors:"^1.1.2","concat-files":"^0.1.1",d3:"~6.6.0","editor-layer-index":"github:osmlab/editor-layer-index#gh-pages",eslint:"^7.1.0",gaze:"^1.1.3",glob:"^7.1.0",happen:"^0.3.1","js-yaml":"^4.0.0","json-stringify-pretty-compact":"^3.0.0",mapillary_sprite_source:"^1.8.0","mapillary-js":"4.0.0",minimist:"^1.2.3",mocha:"^7.0.1","mocha-phantomjs-core":"^2.1.0","name-suggestion-index":"~6.0","node-fetch":"^2.6.1","npm-run-all":"^4.0.0","object-inspect":"1.10.3","osm-community-index":"~5.1.0","phantomjs-prebuilt":"~2.1.16",postcss:"^8.1.1","postcss-selector-prepend":"^0.5.0",rollup:"~2.52.8","rollup-plugin-includepaths":"~0.2.3","rollup-plugin-progress":"^1.1.1","rollup-plugin-visualizer":"~4.2.0",shelljs:"^0.8.0",shx:"^0.3.0",sinon:"7.5.0","sinon-chai":"^3.3.0",smash:"0.0","static-server":"^2.2.1","svg-sprite":"1.5.1","uglify-js":"~3.13.0",vparse:"~1.1.0"};
var engines = {node:">=10"};
var browserslist = ["> 0.2%, last 6 major versions, Firefox ESR, IE 11, maintained node versions"];
var packageJSON = {
@@ -27770,7 +27774,7 @@
* @license MIT
* @preserve
*/
- var Node$1 =
+ var Node =
/** @class */
function () {
function Node(key, data) {
@@ -27797,7 +27801,7 @@
function splay(i, t, comparator) {
- var N = new Node$1(null, null);
+ var N = new Node(null, null);
var l = N;
var r = N;
@@ -27853,7 +27857,7 @@
}
function insert(i, data, t, comparator) {
- var node = new Node$1(i, data);
+ var node = new Node(i, data);
if (t === null) {
node.left = node.right = null;
@@ -27876,7 +27880,7 @@
return node;
}
- function split$1(key, v, comparator) {
+ function split(key, v, comparator) {
var left = null;
var right = null;
@@ -27952,7 +27956,7 @@
Tree.prototype.add = function (key, data) {
- var node = new Node$1(key, data);
+ var node = new Node(key, data);
if (this._root === null) {
node.left = node.right = null;
@@ -28349,7 +28353,7 @@
Tree.prototype.update = function (key, newKey, newData) {
var comparator = this._comparator;
- var _a = split$1(key, this._root, comparator),
+ var _a = split(key, this._root, comparator),
left = _a.left,
right = _a.right;
@@ -28363,7 +28367,7 @@
};
Tree.prototype.split = function (key) {
- return split$1(key, this._root, this._comparator);
+ return split(key, this._root, this._comparator);
};
return Tree;
@@ -28376,7 +28380,7 @@
var middle = start + Math.floor(size / 2);
var key = keys[middle];
var data = values[middle];
- var node = new Node$1(key, data);
+ var node = new Node(key, data);
node.left = loadRecursive(keys, values, start, middle);
node.right = loadRecursive(keys, values, middle + 1, end);
return node;
@@ -28386,11 +28390,11 @@
}
function createList(keys, values) {
- var head = new Node$1(null, null);
+ var head = new Node(null, null);
var p = head;
for (var i = 0; i < keys.length; i++) {
- p = p.next = new Node$1(keys[i], values[i]);
+ p = p.next = new Node(keys[i], values[i]);
}
p.next = null;
@@ -28401,7 +28405,7 @@
var current = root;
var Q = [];
var done = false;
- var head = new Node$1(null, null);
+ var head = new Node(null, null);
var p = head;
while (!done) {
@@ -28438,7 +28442,7 @@
}
function mergeLists(l1, l2, compare) {
- var head = new Node$1(null, null); // dummy
+ var head = new Node(null, null); // dummy
var p = head;
var p1 = l1;
@@ -36943,6 +36947,9 @@
}, this);
return utilArrayUniq(results);
},
+ isCrossing: function isCrossing() {
+ return this.tags.highway === 'crossing' || this.tags.railway && this.tags.railway.indexOf('crossing') !== -1;
+ },
isEndpoint: function isEndpoint(resolver) {
return resolver["transient"](this, 'isEndpoint', function () {
var id = this.id;
@@ -42672,7 +42679,7 @@
};
}
- function copy$1(source, target) {
+ function copy(source, target) {
return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown());
}
function transformer() {
@@ -43176,7 +43183,7 @@
var scale = continuous();
scale.copy = function () {
- return copy$1(scale, linear());
+ return copy(scale, linear());
};
initRange.apply(scale, arguments);
@@ -55604,8 +55611,10 @@
if (connectionTags && (isCrossingIndoors || isCrossingTunnels || isCrossingBridges)) {
crossingTypeID += '_connectable';
- }
+ } // Differentiate based on the loc rounded to 4 digits, since two ways can cross multiple times.
+
+ var uniqueID = '' + crossing.crossPoint[0].toFixed(4) + ',' + crossing.crossPoint[1].toFixed(4);
return new validationIssue({
type: type,
subtype: subtype,
@@ -55628,13 +55637,7 @@
featureTypes: featureTypes,
connectionTags: connectionTags
},
- // differentiate based on the loc since two ways can cross multiple times
- hash: crossing.crossPoint.toString() + // if the edges change then so does the fix
- edges.slice().sort(function (edge1, edge2) {
- // order to assure hash is deterministic
- return edge1[0] < edge2[0] ? -1 : 1;
- }).toString() + // ensure the correct connection tags are added in the fix
- JSON.stringify(connectionTags),
+ hash: uniqueID,
loc: crossing.crossPoint,
dynamicFixes: function dynamicFixes(context) {
var mode = context.mode();
@@ -55896,8 +55899,9 @@
edges.forEach(function (edge) {
var edgeNodes = [graph.entity(edge[0]), graph.entity(edge[1])];
var nearby = geoSphericalClosestNode(edgeNodes, loc); // if there is already a suitable node nearby, use that
+ // use the node if node has no interesting tags or if it is a crossing node #8326
- if (!nearby.node.hasInterestingTags() && nearby.distance < mergeThresholdInMeters) {
+ if ((!nearby.node.hasInterestingTags() || nearby.node.isCrossing()) && nearby.distance < mergeThresholdInMeters) {
nodesToMerge.push(nearby.node.id); // else add the new node to the way
} else {
graph = actionAddMidpoint({
@@ -58121,13 +58125,14 @@
var _resolvedIssueIDs = new Set();
- var _baseCache = validationCache(); // issues before any user edits
+ var _baseCache = validationCache('base'); // issues before any user edits
- var _headCache = validationCache(); // issues after all user edits
+ var _headCache = validationCache('head'); // issues after all user edits
- var _headGraph = null;
+ var _completeDiff = {}; // complete diff base -> head of what the user changed
+
var _headIsCurrent = false;
var _deferredRIC = new Set(); // Set( RequestIdleCallback handles )
@@ -58141,6 +58146,8 @@
var RETRY = 5000; // wait 5sec before revalidating provisional entities
// Allow validation severity to be overridden by url queryparams...
+ // See: https://github.com/openstreetmap/iD/pull/8243
+ //
// Each param should contain a urlencoded comma separated list of
// `type/subtype` rules. `*` may be used as a wildcard..
// Examples:
@@ -58153,7 +58160,14 @@
var _warningOverrides = parseHashParam(context.initialHashParams.validationWarning);
- var _disableOverrides = parseHashParam(context.initialHashParams.validationDisable);
+ var _disableOverrides = parseHashParam(context.initialHashParams.validationDisable); // `parseHashParam()` (private)
+ // Checks hash parameters for severity overrides
+ // Arguments
+ // `param` - a url hash parameter (`validationError`, `validationWarning`, or `validationDisable`)
+ // Returns
+ // Array of Objects like { type: RegExp, subtype: RegExp }
+ //
+
function parseHashParam(param) {
var result = [];
@@ -58171,13 +58185,13 @@
});
});
return result;
- }
- function makeRegExp(str) {
- var escaped = str.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&') // escape all reserved chars except for the '*'
- .replace(/\*/g, '.*'); // treat a '*' like '.*'
+ function makeRegExp(str) {
+ var escaped = str.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&') // escape all reserved chars except for the '*'
+ .replace(/\*/g, '.*'); // treat a '*' like '.*'
- return new RegExp('^' + escaped + '$');
+ return new RegExp('^' + escaped + '$');
+ }
} // `init()`
// Initialize the validator, called once on iD startup
//
@@ -58225,9 +58239,9 @@
_resolvedIssueIDs.clear();
- _baseCache = validationCache();
- _headCache = validationCache();
- _headGraph = null;
+ _baseCache = validationCache('base');
+ _headCache = validationCache('head');
+ _completeDiff = {};
_headIsCurrent = false;
} // `reset()`
// clear caches, called whenever iD resets after a save or switches sources
@@ -58253,23 +58267,23 @@
validator.revalidateUnsquare = function () {
- revalidateUnsquare(_headCache, _headGraph);
- revalidateUnsquare(_baseCache, context.history().base());
+ revalidateUnsquare(_headCache);
+ revalidateUnsquare(_baseCache);
dispatch.call('validated');
};
- function revalidateUnsquare(cache, graph) {
+ function revalidateUnsquare(cache) {
var checkUnsquareWay = _rules.unsquare_way;
- if (!graph || typeof checkUnsquareWay !== 'function') return; // uncache existing
+ if (!cache.graph || typeof checkUnsquareWay !== 'function') return; // uncache existing
cache.uncacheIssuesOfType('unsquare_way');
- var buildings = context.history().tree().intersects(geoExtent([-180, -90], [180, 90]), graph) // everywhere
+ var buildings = context.history().tree().intersects(geoExtent([-180, -90], [180, 90]), cache.graph) // everywhere
.filter(function (entity) {
return entity.type === 'way' && entity.tags.building && entity.tags.building !== 'no';
}); // rerun for all buildings
buildings.forEach(function (entity) {
- var detected = checkUnsquareWay(entity, graph);
+ var detected = checkUnsquareWay(entity, cache.graph);
if (!detected.length) return;
cache.cacheIssues(detected);
});
@@ -58299,54 +58313,46 @@
includeDisabledRules: false
}, options);
var view = context.map().extent();
- var issues = [];
- var seen = new Set(); // collect head issues - caused by user edits
-
- var cache = _headCache;
+ var seen = new Set();
+ var results = []; // collect head issues - caused by user edits
- if (_headGraph) {
- Object.values(cache.issuesByIssueID).forEach(function (issue) {
- if (!filter(issue, _headGraph, cache)) return;
+ if (_headCache.graph && _headCache.graph !== _baseCache.graph) {
+ Object.values(_headCache.issuesByIssueID).forEach(function (issue) {
+ if (!filter(issue)) return;
seen.add(issue.id);
- issues.push(issue);
+ results.push(issue);
});
} // collect base issues - not caused by user edits
if (opts.what === 'all') {
- cache = _baseCache;
- Object.values(cache.issuesByIssueID).forEach(function (issue) {
- if (!filter(issue, context.history().base(), cache)) return;
+ Object.values(_baseCache.issuesByIssueID).forEach(function (issue) {
+ if (!filter(issue)) return;
seen.add(issue.id);
- issues.push(issue);
+ results.push(issue);
});
}
- return issues;
+ return results; // Filter the issue set to include only what the calling code wants to see.
+ // Note that we use `context.graph()`/`context.hasEntity()` here, not `cache.graph`,
+ // because that is the graph that the calling code will be using.
- function filter(issue, resolver, cache) {
+ function filter(issue) {
if (!issue) return false;
if (seen.has(issue.id)) return false;
if (_resolvedIssueIDs.has(issue.id)) return false;
if (opts.includeDisabledRules === 'only' && !_disabledRules[issue.type]) return false;
if (!opts.includeDisabledRules && _disabledRules[issue.type]) return false;
if (opts.includeIgnored === 'only' && !_ignoredIssueIDs.has(issue.id)) return false;
- if (!opts.includeIgnored && _ignoredIssueIDs.has(issue.id)) return false; // Sanity check: This issue may be for an entity that not longer exists.
- // If we detect this, uncache and return false so it is not included..
+ if (!opts.includeIgnored && _ignoredIssueIDs.has(issue.id)) return false; // This issue may involve an entity that doesn't exist in context.graph()
+ // This can happen because validation is async and rendering the issue lists is async.
- var entityIDs = issue.entityIds || [];
-
- for (var i = 0; i < entityIDs.length; i++) {
- var entityID = entityIDs[i];
-
- if (!resolver.hasEntity(entityID)) {
- cache.uncacheEntityID(entityID);
- return false;
- }
- }
+ if ((issue.entityIds || []).some(function (id) {
+ return !context.hasEntity(id);
+ })) return false;
if (opts.where === 'visible') {
- var extent = issue.extent(resolver);
+ var extent = issue.extent(context.graph());
if (!view.intersects(extent)) return false;
}
@@ -58354,7 +58360,9 @@
}
}; // `getResolvedIssues()`
// Gets the issues that have been fixed by the user.
- // Resolved issues are tracked in the `_resolvedIssueIDs` Set
+ //
+ // Resolved issues are tracked in the `_resolvedIssueIDs` Set,
+ // and they should all be issues that exist in the _baseCache.
//
// Returns
// An Array containing the issues
@@ -58362,14 +58370,9 @@
validator.getResolvedIssues = function () {
- var collected = new Set();
- Object.values(_baseCache.issuesByIssueID).forEach(function (issue) {
- if (_resolvedIssueIDs.has(issue.id)) collected.add(issue);
- });
- Object.values(_headCache.issuesByIssueID).forEach(function (issue) {
- if (_resolvedIssueIDs.has(issue.id)) collected.add(issue);
- });
- return Array.from(collected);
+ return Array.from(_resolvedIssueIDs).map(function (issueID) {
+ return _baseCache.issuesByIssueID[issueID];
+ }).filter(Boolean);
}; // `focusIssue()`
// Adjusts the map to focus on the given issue.
// (requires the issue to have a reasonable extent defined)
@@ -58380,15 +58383,57 @@
validator.focusIssue = function (issue) {
- var extent = issue.extent(context.graph());
- if (!extent) return;
- var setZoom = Math.max(context.map().zoom(), 19);
- context.map().unobscuredCenterZoomEase(extent.center(), setZoom); // select the first entity
+ // Note that we use `context.graph()`/`context.hasEntity()` here, not `cache.graph`,
+ // because that is the graph that the calling code will be using.
+ var graph = context.graph();
+ var selectID;
+ var focusCenter; // Try to focus the map at the center of the issue..
+
+ var issueExtent = issue.extent(graph);
+
+ if (issueExtent) {
+ focusCenter = issueExtent.center();
+ } // Try to select the first entity in the issue..
+
if (issue.entityIds && issue.entityIds.length) {
+ selectID = issue.entityIds[0]; // If a relation, focus on one of its members instead.
+ // Otherwise we might be focusing on a part of map where the relation is not visible.
+
+ if (selectID && selectID.charAt(0) === 'r') {
+ // relation
+ var ids = utilEntityAndDeepMemberIDs([selectID], graph);
+ var nodeID = ids.find(function (id) {
+ return id.charAt(0) === 'n' && graph.hasEntity(id);
+ });
+
+ if (!nodeID) {
+ // relation has no downloaded nodes to focus on
+ var wayID = ids.find(function (id) {
+ return id.charAt(0) === 'w' && graph.hasEntity(id);
+ });
+
+ if (wayID) {
+ nodeID = graph.entity(wayID).first(); // focus on the first node of this way
+ }
+ }
+
+ if (nodeID) {
+ focusCenter = graph.entity(nodeID).loc;
+ }
+ }
+ }
+
+ if (focusCenter) {
+ // Adjust the view
+ var setZoom = Math.max(context.map().zoom(), 19);
+ context.map().unobscuredCenterZoomEase(focusCenter, setZoom);
+ }
+
+ if (selectID) {
+ // Enter select mode
window.setTimeout(function () {
- var ids = issue.entityIds;
- context.enter(modeSelect(context, [ids[0]]));
+ context.enter(modeSelect(context, [selectID]));
dispatch.call('focusedIssue', _this, issue);
}, 250); // after ease
}
@@ -58426,12 +58471,12 @@
validator.getSharedEntityIssues = function (entityIDs, options) {
- // show some issue types in a particular order
- var orderedIssueTypes = [// flag missing data first
- 'missing_tag', 'missing_role', // then flag identity issues
- 'outdated_tags', 'mismatched_geometry', // flag geometry issues where fixing them might solve connectivity issues
- 'crossing_ways', 'almost_junction', // then flag connectivity issues
- 'disconnected_way', 'impossible_oneway'];
+ var orderedIssueTypes = [// Show some issue types in a particular order:
+ 'missing_tag', 'missing_role', // - missing data first
+ 'outdated_tags', 'mismatched_geometry', // - identity issues
+ 'crossing_ways', 'almost_junction', // - geometry issues where fixing them might solve connectivity issues
+ 'disconnected_way', 'impossible_oneway' // - finally connectivity issues
+ ];
var allIssues = validator.getIssues(options);
var forEntityIDs = new Set(entityIDs);
return allIssues.filter(function (issue) {
@@ -58547,12 +58592,16 @@
validator.validate = function () {
+ // Make sure the caches have graphs assigned to them.
+ // (we don't do this in `reset` because context is still resetting things and `history.base()` is unstable then)
+ var baseGraph = context.history().base();
+ if (!_headCache.graph) _headCache.graph = baseGraph;
+ if (!_baseCache.graph) _baseCache.graph = baseGraph;
+ var prevGraph = _headCache.graph;
var currGraph = context.graph();
- var prevGraph = _headGraph || context.history().base();
-
if (currGraph === prevGraph) {
- // _headGraph is current - we are caught up
+ // _headCache.graph is current - we are caught up
_headIsCurrent = true;
dispatch.call('validated');
return Promise.resolve();
@@ -58563,30 +58612,21 @@
_headIsCurrent = false; // We will need to catch up after the validation promise fulfills
return _headPromise;
- }
-
- _headGraph = currGraph; // take snapshot
+ } // If we get here, its time to start validating stuff.
- var difference = coreDifference(prevGraph, _headGraph); // Gather all entities related to this difference..
- // For created/modified, use the head graph
- var entityIDs = difference.extantIDs(true); // created/modified (true = w/relation members)
+ _headCache.graph = currGraph; // take snapshot
- entityIDs = entityIDsToValidate(entityIDs, _headGraph); // For modified/deleted, use the previous graph
- // (e.g. deleting the only highway connected to a road should create a disconnected highway issue)
+ _completeDiff = context.history().difference().complete();
+ var incrementalDiff = coreDifference(prevGraph, currGraph);
+ var entityIDs = Object.keys(incrementalDiff.complete()); // if (!entityIDs.size) {
- var previousEntityIDs = difference.deleted().concat(difference.modified()).map(function (entity) {
- return entity.id;
- });
- previousEntityIDs = entityIDsToValidate(previousEntityIDs, prevGraph);
- previousEntityIDs.forEach(entityIDs.add, entityIDs); // concat the sets
-
- if (!entityIDs.size) {
+ if (!entityIDs.length) {
dispatch.call('validated');
return Promise.resolve();
}
- _headPromise = validateEntitiesAsync(entityIDs, _headGraph, _headCache).then(function () {
+ _headPromise = validateEntitiesAsync(entityIDs, _headCache).then(function () {
return updateResolvedIssues(entityIDs);
}).then(function () {
return dispatch.call('validated');
@@ -58619,13 +58659,17 @@
context.on('exit.validator', validator.validate); // When merging fetched data, validate base graph:
context.history().on('merge.validator', function (entities) {
- if (!entities) return;
+ if (!entities) return; // Make sure the caches have graphs assigned to them.
+ // (we don't do this in `reset` because context is still resetting things and `history.base()` is unstable then)
+
var baseGraph = context.history().base();
+ if (!_headCache.graph) _headCache.graph = baseGraph;
+ if (!_baseCache.graph) _baseCache.graph = baseGraph;
var entityIDs = entities.map(function (entity) {
return entity.id;
- });
- entityIDs = entityIDsToValidate(entityIDs, baseGraph);
- validateEntitiesAsync(entityIDs, baseGraph, _baseCache);
+ }); // entityIDs = entityIDsToValidate(entityIDs, baseGraph); // expand set
+
+ validateEntitiesAsync(entityIDs, _baseCache);
}); // `validateEntity()` (private)
// Runs all validation rules on a single entity.
// Some things to note:
@@ -58651,7 +58695,10 @@
var result = {
issues: [],
provisional: false
- }; // runs validation and appends resulting issues
+ };
+ Object.keys(_rules).forEach(runValidation); // run all rules
+
+ return result; // runs validation and appends resulting issues
function runValidation(key) {
var fn = _rules[key];
@@ -58662,128 +58709,78 @@
return;
}
- var detected = fn(entity, graph).filter(applySeverityOverrides);
+ var detected = fn(entity, graph);
if (detected.provisional) {
// this validation should be run again later
result.provisional = true;
}
- result.issues = result.issues.concat(detected);
- } // run all rules
+ detected = detected.filter(applySeverityOverrides);
+ result.issues = result.issues.concat(detected); // If there are any override rules that match the issue type/subtype,
+ // adjust severity (or disable it) and keep/discard as quickly as possible.
+ function applySeverityOverrides(issue) {
+ var type = issue.type;
+ var subtype = issue.subtype || '';
+ var i;
- Object.keys(_rules).forEach(runValidation);
- return result;
- } // If there are any override rules that match the issue type/subtype,
- // adjust severity (or disable it) and keep/discard as quickly as possible.
-
+ for (i = 0; i < _errorOverrides.length; i++) {
+ if (_errorOverrides[i].type.test(type) && _errorOverrides[i].subtype.test(subtype)) {
+ issue.severity = 'error';
+ return true;
+ }
+ }
- function applySeverityOverrides(issue) {
- var type = issue.type;
- var subtype = issue.subtype || '';
- var i;
+ for (i = 0; i < _warningOverrides.length; i++) {
+ if (_warningOverrides[i].type.test(type) && _warningOverrides[i].subtype.test(subtype)) {
+ issue.severity = 'warning';
+ return true;
+ }
+ }
- for (i = 0; i < _errorOverrides.length; i++) {
- if (_errorOverrides[i].type.test(type) && _errorOverrides[i].subtype.test(subtype)) {
- issue.severity = 'error';
- return true;
- }
- }
+ for (i = 0; i < _disableOverrides.length; i++) {
+ if (_disableOverrides[i].type.test(type) && _disableOverrides[i].subtype.test(subtype)) {
+ return false;
+ }
+ }
- for (i = 0; i < _warningOverrides.length; i++) {
- if (_warningOverrides[i].type.test(type) && _warningOverrides[i].subtype.test(subtype)) {
- issue.severity = 'warning';
return true;
}
}
-
- for (i = 0; i < _disableOverrides.length; i++) {
- if (_disableOverrides[i].type.test(type) && _disableOverrides[i].subtype.test(subtype)) {
- return false;
- }
- }
-
- return true;
- } // `entityIDsToValidate()` (private)
- // Collects the complete list of entityIDs related to the input entityIDs.
- //
- // Arguments
- // `entityIDs` - Set or Array containing entityIDs.
- // `graph` - graph containing the entities
- //
- // Returns
- // Set containing entityIDs
- //
-
-
- function entityIDsToValidate(entityIDs, graph) {
- var seen = new Set();
- var collected = new Set();
- entityIDs.forEach(function (entityID) {
- // keep `seen` separate from `collected` because an `entityID`
- // could have been added to `collected` as a related entity through an earlier pass
- if (seen.has(entityID)) return;
- seen.add(entityID);
- var entity = graph.hasEntity(entityID);
- if (!entity) return;
- collected.add(entityID); // collect self
-
- var checkParentRels = [entity];
-
- if (entity.type === 'node') {
- graph.parentWays(entity).forEach(function (parentWay) {
- collected.add(parentWay.id); // collect parent ways
-
- checkParentRels.push(parentWay);
- });
- } else if (entity.type === 'relation') {
- entity.members.forEach(function (member) {
- return collected.add(member.id);
- }); // collect members
- } else if (entity.type === 'way') {
- entity.nodes.forEach(function (nodeID) {
- collected.add(nodeID); // collect child nodes
-
- graph._parentWays[nodeID].forEach(function (wayID) {
- return collected.add(wayID);
- }); // collect connected ways
-
- });
- }
-
- checkParentRels.forEach(function (entity) {
- // collect parent relations
- if (entity.type !== 'relation') {
- // but not super-relations
- graph.parentRelations(entity).forEach(function (parentRelation) {
- return collected.add(parentRelation.id);
- });
- }
- });
- });
- return collected;
} // `updateResolvedIssues()` (private)
// Determine if any issues were resolved for the given entities.
// This is called by `validate()` after validation of the head graph
//
+ // Give the user credit for fixing an issue if:
+ // - the issue is in the base cache
+ // - the issue is not in the head cache
+ // - the user did something to one of the entities involved in the issue
+ //
// Arguments
- // `entityIDs` - Set containing entity IDs.
+ // `entityIDs` - Array containing entity IDs.
//
function updateResolvedIssues(entityIDs) {
entityIDs.forEach(function (entityID) {
- var headIssues = _headCache.issuesByEntityID[entityID];
var baseIssues = _baseCache.issuesByEntityID[entityID];
if (!baseIssues) return;
baseIssues.forEach(function (issueID) {
- if (headIssues && headIssues.has(issueID)) {
+ // Check if the user did something to one of the entities involved in this issue.
+ // (This issue could involve multiple entities, e.g. disconnected routable features)
+ var issue = _baseCache.issuesByIssueID[issueID];
+ var userModified = (issue.entityIds || []).some(function (id) {
+ return _completeDiff.hasOwnProperty(id);
+ });
+
+ if (userModified && !_headCache.issuesByIssueID[issueID]) {
+ // issue seems fixed
+ _resolvedIssueIDs.add(issueID);
+ } else {
// issue still not resolved
_resolvedIssueIDs["delete"](issueID); // (did undo, or possibly fixed and then re-caused the issue)
- } else {
- _resolvedIssueIDs.add(issueID);
}
});
});
@@ -58791,7 +58788,7 @@
// Schedule validation for many entities.
//
// Arguments
- // `entityIDs` - Set containing entity IDs.
+ // `entityIDs` - Array containing entity IDs.
// `graph` - the graph to validate that contains those entities
// `cache` - the cache to store results in (_headCache or _baseCache)
//
@@ -58801,29 +58798,35 @@
//
- function validateEntitiesAsync(entityIDs, graph, cache) {
+ function validateEntitiesAsync(entityIDs, cache) {
// Enqueue the work
- var jobs = Array.from(entityIDs).map(function (entityID) {
+ var jobs = entityIDs.map(function (entityID) {
if (cache.queuedEntityIDs.has(entityID)) return null; // queued already
cache.queuedEntityIDs.add(entityID);
return function () {
- // clear caches for existing issues related to this entity
+ // Clear caches for existing issues related to this entity
cache.uncacheEntityID(entityID);
- cache.queuedEntityIDs["delete"](entityID); // detect new issues and update caches
+ cache.queuedEntityIDs["delete"](entityID);
+ var graph = cache.graph;
+ if (!graph) return; // was reset?
var entity = graph.hasEntity(entityID); // Sanity check: don't validate deleted entities
- if (entity) {
- var result = validateEntity(entity, graph);
+ if (!entity) return; // In the head cache, only validate features that the user is responsible for - #8632
+ // For example, a user can undo some work and an issue will still present in the
+ // head graph, but we don't want to credit the user for causing that issue.
- if (result.provisional) {
- // provisional result
- cache.provisionalEntityIDs.add(entityID); // we'll need to revalidate this entity again later
- }
+ if (cache.which === 'head' && !_completeDiff.hasOwnProperty(entityID)) return; // detect new issues and update caches
- cache.cacheIssues(result.issues); // update cache
+ var result = validateEntity(entity, graph);
+
+ if (result.provisional) {
+ // provisional result
+ cache.provisionalEntityIDs.add(entityID); // we'll need to revalidate this entity again later
}
+
+ cache.cacheIssues(result.issues); // update cache
};
}).filter(Boolean); // Perform the work in chunks.
// Because this will happen during idle callbacks, we want to choose a chunk size
@@ -58858,8 +58861,7 @@
if (!cache.provisionalEntityIDs.size) return; // nothing to do
- var graph = cache === _headCache ? _headGraph : context.history().base();
- validateEntitiesAsync(cache.provisionalEntityIDs, graph, cache);
+ validateEntitiesAsync(Array.from(cache.provisionalEntityIDs), cache);
}, RETRY);
_deferredST.add(handle);
@@ -58876,8 +58878,7 @@
function processQueue(cache) {
- // const which = (cache === _headCache) ? 'head' : 'base';
- // console.log(`${which} queue length ${cache.queue.length}`);
+ // console.log(`${cache.which} queue length ${cache.queue.length}`);
if (!cache.queue.length) return Promise.resolve(); // we're done
var chunk = cache.queue.pop();
@@ -58910,16 +58911,21 @@
// `_baseCache` for validation on the base graph (unedited)
// `_headCache` for validation on the head graph (user edits applied)
//
+ // Arguments
+ // `which` - just a String 'base' or 'head' to keep track of it
+ //
- function validationCache() {
+ function validationCache(which) {
var cache = {
+ which: which,
+ graph: null,
queue: [],
queuePromise: null,
queuedEntityIDs: new Set(),
provisionalEntityIDs: new Set(),
issuesByIssueID: {},
// issue.id -> issue
- issuesByEntityID: {} // entity.id -> set(issue.id)
+ issuesByEntityID: {} // entity.id -> Set(issue.id)
};
@@ -59622,7 +59628,7 @@
// https://docs.microsoft.com/en-us/bingmaps/rest-services/imagery/get-imagery-metadata
// https://docs.microsoft.com/en-us/bingmaps/rest-services/directly-accessing-the-bing-maps-tiles
//fallback url template
- data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=10555&n=z';
+ data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&n=z';
var bing = rendererBackgroundSource(data); //var key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU'; // P2, JOSM, etc
var key = 'Ak5oTE46TUbjRp08OFVcGpkARErDobfpuyNKa-W2mQ8wbt1K1KL8p1bIRwWwcF-Q'; // iD
@@ -62145,3126 +62151,798 @@
}(data);
};
- //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
- //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
- //[5] Name ::= NameStartChar (NameChar)*
- var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; //\u10000-\uEFFFF
-
- var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
- var tagNamePattern = new RegExp('^' + nameStartChar.source + nameChar.source + '*(?:\:' + nameStartChar.source + nameChar.source + '*)?$'); //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
- //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
- //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
- //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
-
- var S_TAG = 0; //tag name offerring
+ var $entries = objectToArray.entries;
- var S_ATTR = 1; //attr name offerring
-
- var S_ATTR_SPACE = 2; //attr name end and space offer
-
- var S_EQ = 3; //=space?
-
- var S_ATTR_NOQUOT_VALUE = 4; //attr value(no quot value only)
+ // `Object.entries` method
+ // https://tc39.es/ecma262/#sec-object.entries
+ _export({ target: 'Object', stat: true }, {
+ entries: function entries(O) {
+ return $entries(O);
+ }
+ });
- var S_ATTR_END = 5; //attr value end and no space(quot end)
+ var _marked = /*#__PURE__*/regeneratorRuntime.mark(gpxGen),
+ _marked3 = /*#__PURE__*/regeneratorRuntime.mark(kmlGen);
- var S_TAG_SPACE = 6; //(attr value end || tag end ) && (space offer)
+ // cast array x into numbers
+ // get the content of a text node, if any
+ function nodeVal(x) {
+ if (x && x.normalize) {
+ x.normalize();
+ }
- var S_TAG_CLOSE = 7; //closed el
+ return x && x.textContent || "";
+ } // one Y child of X, if any, otherwise null
- function XMLReader() {}
- XMLReader.prototype = {
- parse: function parse(source, defaultNSMap, entityMap) {
- var domBuilder = this.domBuilder;
- domBuilder.startDocument();
+ function get1(x, y) {
+ var n = x.getElementsByTagName(y);
+ return n.length ? n[0] : null;
+ }
- _copy(defaultNSMap, defaultNSMap = {});
+ function getLineStyle(extensions) {
+ var style = {};
- _parse(source, defaultNSMap, entityMap, domBuilder, this.errorHandler);
+ if (extensions) {
+ var lineStyle = get1(extensions, "line");
- domBuilder.endDocument();
- }
- };
+ if (lineStyle) {
+ var color = nodeVal(get1(lineStyle, "color")),
+ opacity = parseFloat(nodeVal(get1(lineStyle, "opacity"))),
+ width = parseFloat(nodeVal(get1(lineStyle, "width")));
+ if (color) style.stroke = color;
+ if (!isNaN(opacity)) style["stroke-opacity"] = opacity; // GPX width is in mm, convert to px with 96 px per inch
- function _parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) {
- function fixedFromCharCode(code) {
- // String.prototype.fromCharCode does not supports
- // > 2 bytes unicode chars directly
- if (code > 0xffff) {
- code -= 0x10000;
- var surrogate1 = 0xd800 + (code >> 10),
- surrogate2 = 0xdc00 + (code & 0x3ff);
- return String.fromCharCode(surrogate1, surrogate2);
- } else {
- return String.fromCharCode(code);
+ if (!isNaN(width)) style["stroke-width"] = width * 96 / 25.4;
}
}
- function entityReplacer(a) {
- var k = a.slice(1, -1);
-
- if (k in entityMap) {
- return entityMap[k];
- } else if (k.charAt(0) === '#') {
- return fixedFromCharCode(parseInt(k.substr(1).replace('x', '0x')));
- } else {
- errorHandler.error('entity not found:' + a);
- return a;
- }
- }
+ return style;
+ } // get the contents of multiple text nodes, if present
- function appendText(end) {
- //has some bugs
- if (end > start) {
- var xt = source.substring(start, end).replace(/?\w+;/g, entityReplacer);
- locator && position(start);
- domBuilder.characters(xt, 0, end - start);
- start = end;
- }
- }
- function position(p, m) {
- while (p >= lineEnd && (m = linePattern.exec(source))) {
- lineStart = m.index;
- lineEnd = lineStart + m[0].length;
- locator.lineNumber++; //console.log('line++:',locator,startPos,endPos)
- }
+ function getMulti(x, ys) {
+ var o = {};
+ var n;
+ var k;
- locator.columnNumber = p - lineStart + 1;
+ for (k = 0; k < ys.length; k++) {
+ n = get1(x, ys[k]);
+ if (n) o[ys[k]] = nodeVal(n);
}
- var lineStart = 0;
- var lineEnd = 0;
- var linePattern = /.*(?:\r\n?|\n)|.*$/g;
- var locator = domBuilder.locator;
- var parseStack = [{
- currentNSMap: defaultNSMapCopy
- }];
- var closeMap = {};
- var start = 0;
-
- while (true) {
- try {
- var tagStart = source.indexOf('<', start);
-
- if (tagStart < 0) {
- if (!source.substr(start).match(/^\s*$/)) {
- var doc = domBuilder.doc;
- var text = doc.createTextNode(source.substr(start));
- doc.appendChild(text);
- domBuilder.currentElement = text;
- }
-
- return;
- }
+ return o;
+ }
- if (tagStart > start) {
- appendText(tagStart);
- }
+ function getProperties$1(node) {
+ var prop = getMulti(node, ["name", "cmt", "desc", "type", "time", "keywords"]); // Parse additional data from our Garmin extension(s)
- switch (source.charAt(tagStart + 1)) {
- case '/':
- var end = source.indexOf('>', tagStart + 3);
- var tagName = source.substring(tagStart + 2, end);
- var config = parseStack.pop();
+ var extensions = node.getElementsByTagNameNS("http://www.garmin.com/xmlschemas/GpxExtensions/v3", "*");
- if (end < 0) {
- tagName = source.substring(tagStart + 2).replace(/[\s<].*/, ''); //console.error('#@@@@@@'+tagName)
+ for (var i = 0; i < extensions.length; i++) {
+ var extension = extensions[i]; // Ignore nested extensions, like those on routepoints or trackpoints
- errorHandler.error("end tag name: " + tagName + ' is not complete:' + config.tagName);
- end = tagStart + 1 + tagName.length;
- } else if (tagName.match(/\s)) {
- tagName = tagName.replace(/[\s<].*/, '');
- errorHandler.error("end tag name: " + tagName + ' maybe not complete');
- end = tagStart + 1 + tagName.length;
- } //console.error(parseStack.length,parseStack)
- //console.error(config);
+ if (extension.parentNode.parentNode === node) {
+ prop[extension.tagName.replace(":", "_")] = nodeVal(extension);
+ }
+ }
+ var links = node.getElementsByTagName("link");
+ if (links.length) prop.links = [];
- var localNSMap = config.localNSMap;
- var endMatch = config.tagName == tagName;
- var endIgnoreCaseMach = endMatch || config.tagName && config.tagName.toLowerCase() == tagName.toLowerCase();
+ for (var _i = 0; _i < links.length; _i++) {
+ prop.links.push(Object.assign({
+ href: links[_i].getAttribute("href")
+ }, getMulti(links[_i], ["text", "type"])));
+ }
- if (endIgnoreCaseMach) {
- domBuilder.endElement(config.uri, config.localName, tagName);
+ return prop;
+ }
- if (localNSMap) {
- for (var prefix in localNSMap) {
- domBuilder.endPrefixMapping(prefix);
- }
- }
+ function coordPair$1(x) {
+ var ll = [parseFloat(x.getAttribute("lon")), parseFloat(x.getAttribute("lat"))];
+ var ele = get1(x, "ele"); // handle namespaced attribute in browser
- if (!endMatch) {
- errorHandler.fatalError("end tag name: " + tagName + ' is not match the current start tagName:' + config.tagName);
- }
- } else {
- parseStack.push(config);
- }
+ var heart = get1(x, "gpxtpx:hr") || get1(x, "hr");
+ var time = get1(x, "time");
+ var e;
- end++;
- break;
- // end elment
+ if (ele) {
+ e = parseFloat(nodeVal(ele));
- case '?':
- // ...?>
- locator && position(tagStart);
- end = parseInstruction(source, tagStart, domBuilder);
- break;
+ if (!isNaN(e)) {
+ ll.push(e);
+ }
+ }
- case '!':
- // start) {
- start = end;
- } else {
- //TODO: è¿éæå¯è½saxåéï¼æä½ç½®é误é£é©
- appendText(Math.max(tagStart, start) + 1);
+ extendedValues[plural][i] = val;
}
}
- }
- function copyLocator(f, t) {
- t.lineNumber = f.lineNumber;
- t.columnNumber = f.columnNumber;
- return t;
+ return {
+ line: line,
+ times: times,
+ extendedValues: extendedValues
+ };
}
- /**
- * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
- * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
- */
-
- function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler) {
- var attrName;
- var value;
- var p = ++start;
- var s = S_TAG; //status
+ function getTrack(node) {
+ var segments = node.getElementsByTagName("trkseg");
+ var track = [];
+ var times = [];
+ var extractedLines = [];
- while (true) {
- var c = source.charAt(p);
-
- switch (c) {
- case '=':
- if (s === S_ATTR) {
- //attrName
- attrName = source.slice(start, p);
- s = S_EQ;
- } else if (s === S_ATTR_SPACE) {
- s = S_EQ;
- } else {
- //fatalError: equal must after attrName or space after attrName
- throw new Error('attribute equal must after attrName');
- }
+ for (var i = 0; i < segments.length; i++) {
+ var line = getPoints$1(segments[i], "trkpt");
- break;
+ if (line) {
+ extractedLines.push(line);
+ if (line.times && line.times.length) times.push(line.times);
+ }
+ }
- case '\'':
- case '"':
- if (s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
- ) {
- //equal
- if (s === S_ATTR) {
- errorHandler.warning('attribute value must after "="');
- attrName = source.slice(start, p);
- }
+ if (extractedLines.length === 0) return;
+ var multi = extractedLines.length > 1;
+ var properties = Object.assign(getProperties$1(node), getLineStyle(get1(node, "extensions")), {
+ _gpxType: "trk"
+ }, times.length ? {
+ coordinateProperties: {
+ times: multi ? times : times[0]
+ }
+ } : {});
- start = p + 1;
- p = source.indexOf(c, start);
+ for (var _i3 = 0; _i3 < extractedLines.length; _i3++) {
+ var _line = extractedLines[_i3];
+ track.push(_line.line);
- if (p > 0) {
- value = source.slice(start, p).replace(/?\w+;/g, entityReplacer);
- el.add(attrName, value, start - 1);
- s = S_ATTR_END;
- } else {
- //fatalError: no end quot match
- throw new Error('attribute value no end \'' + c + '\' match');
- }
- } else if (s == S_ATTR_NOQUOT_VALUE) {
- value = source.slice(start, p).replace(/?\w+;/g, entityReplacer); //console.log(attrName,value,start,p)
+ for (var _i4 = 0, _Object$entries = Object.entries(_line.extendedValues); _i4 < _Object$entries.length; _i4++) {
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i4], 2),
+ name = _Object$entries$_i[0],
+ val = _Object$entries$_i[1];
- el.add(attrName, value, start); //console.dir(el)
+ var props = properties;
- errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ')!!');
- start = p + 1;
- s = S_ATTR_END;
- } else {
- //fatalError: no equal before
- throw new Error('attribute value must after "="');
+ if (name === "heart") {
+ if (!properties.coordinateProperties) {
+ properties.coordinateProperties = {};
}
- break;
-
- case '/':
- switch (s) {
- case S_TAG:
- el.setTagName(source.slice(start, p));
-
- case S_ATTR_END:
- case S_TAG_SPACE:
- case S_TAG_CLOSE:
- s = S_TAG_CLOSE;
- el.closed = true;
-
- case S_ATTR_NOQUOT_VALUE:
- case S_ATTR:
- case S_ATTR_SPACE:
- break;
- //case S_EQ:
-
- default:
- throw new Error("attribute invalid close char('/')");
- }
+ props = properties.coordinateProperties;
+ }
- break;
+ if (multi) {
+ if (!props[name]) props[name] = extractedLines.map(function (line) {
+ return new Array(line.line.length).fill(null);
+ });
+ props[name][_i3] = val;
+ } else {
+ props[name] = val;
+ }
+ }
+ }
- case '':
- //end document
- //throw new Error('unexpected end of input')
- errorHandler.error('unexpected end of input');
+ return {
+ type: "Feature",
+ properties: properties,
+ geometry: multi ? {
+ type: "MultiLineString",
+ coordinates: track
+ } : {
+ type: "LineString",
+ coordinates: track[0]
+ }
+ };
+ }
- if (s == S_TAG) {
- el.setTagName(source.slice(start, p));
- }
+ function getPoint(node) {
+ return {
+ type: "Feature",
+ properties: Object.assign(getProperties$1(node), getMulti(node, ["sym"])),
+ geometry: {
+ type: "Point",
+ coordinates: coordPair$1(node).coordinates
+ }
+ };
+ }
- return p;
+ function gpxGen(doc) {
+ var tracks, routes, waypoints, i, feature, _i5, _feature, _i6;
- case '>':
- switch (s) {
- case S_TAG:
- el.setTagName(source.slice(start, p));
+ return regeneratorRuntime.wrap(function gpxGen$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ tracks = doc.getElementsByTagName("trk");
+ routes = doc.getElementsByTagName("rte");
+ waypoints = doc.getElementsByTagName("wpt");
+ i = 0;
- case S_ATTR_END:
- case S_TAG_SPACE:
- case S_TAG_CLOSE:
+ case 4:
+ if (!(i < tracks.length)) {
+ _context.next = 12;
break;
- //normal
-
- case S_ATTR_NOQUOT_VALUE: //Compatible state
-
- case S_ATTR:
- value = source.slice(start, p);
-
- if (value.slice(-1) === '/') {
- el.closed = true;
- value = value.slice(0, -1);
- }
-
- case S_ATTR_SPACE:
- if (s === S_ATTR_SPACE) {
- value = attrName;
- }
-
- if (s == S_ATTR_NOQUOT_VALUE) {
- errorHandler.warning('attribute "' + value + '" missed quot(")!!');
- el.add(attrName, value.replace(/?\w+;/g, entityReplacer), start);
- } else {
- if (currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)) {
- errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!');
- }
+ }
- el.add(value, value, start);
- }
+ feature = getTrack(tracks[i]);
+ if (!feature) {
+ _context.next = 9;
break;
+ }
- case S_EQ:
- throw new Error('attribute value missed!!');
- } // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
-
-
- return p;
-
- /*xml space '\x20' | #x9 | #xD | #xA; */
-
- case "\x80":
- c = ' ';
+ _context.next = 9;
+ return feature;
- default:
- if (c <= ' ') {
- //space
- switch (s) {
- case S_TAG:
- el.setTagName(source.slice(start, p)); //tagName
+ case 9:
+ i++;
+ _context.next = 4;
+ break;
- s = S_TAG_SPACE;
- break;
+ case 12:
+ _i5 = 0;
- case S_ATTR:
- attrName = source.slice(start, p);
- s = S_ATTR_SPACE;
- break;
+ case 13:
+ if (!(_i5 < routes.length)) {
+ _context.next = 21;
+ break;
+ }
- case S_ATTR_NOQUOT_VALUE:
- var value = source.slice(start, p).replace(/?\w+;/g, entityReplacer);
- errorHandler.warning('attribute "' + value + '" missed quot(")!!');
- el.add(attrName, value, start);
+ _feature = getRoute(routes[_i5]);
- case S_ATTR_END:
- s = S_TAG_SPACE;
- break;
- //case S_TAG_SPACE:
- //case S_EQ:
- //case S_ATTR_SPACE:
- // void();break;
- //case S_TAG_CLOSE:
- //ignore warning
+ if (!_feature) {
+ _context.next = 18;
+ break;
}
- } else {
- //not space
- //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
- //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
- switch (s) {
- //case S_TAG:void();break;
- //case S_ATTR:void();break;
- //case S_ATTR_NOQUOT_VALUE:void();break;
- case S_ATTR_SPACE:
- el.tagName;
-
- if (currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)) {
- errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!');
- }
- el.add(attrName, attrName, start);
- start = p;
- s = S_ATTR;
- break;
-
- case S_ATTR_END:
- errorHandler.warning('attribute space is required"' + attrName + '"!!');
+ _context.next = 18;
+ return _feature;
- case S_TAG_SPACE:
- s = S_ATTR;
- start = p;
- break;
+ case 18:
+ _i5++;
+ _context.next = 13;
+ break;
- case S_EQ:
- s = S_ATTR_NOQUOT_VALUE;
- start = p;
- break;
+ case 21:
+ _i6 = 0;
- case S_TAG_CLOSE:
- throw new Error("elements closed character '/' and '>' must be connected to");
+ case 22:
+ if (!(_i6 < waypoints.length)) {
+ _context.next = 28;
+ break;
}
- }
- } //end outer switch
- //console.log('p++',p)
+ _context.next = 25;
+ return getPoint(waypoints[_i6]);
+ case 25:
+ _i6++;
+ _context.next = 22;
+ break;
- p++;
- }
+ case 28:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _marked);
}
- /**
- * @return true if has new namespace define
- */
-
- function appendElement(el, domBuilder, currentNSMap) {
- var tagName = el.tagName;
- var localNSMap = null; //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
+ function gpx(doc) {
+ return {
+ type: "FeatureCollection",
+ features: Array.from(gpxGen(doc))
+ };
+ }
- var i = el.length;
+ var removeSpace = /\s*/g;
+ var trimSpace = /^\s*|\s*$/g;
+ var splitSpace = /\s+/; // generate a short, numeric hash of a string
- while (i--) {
- var a = el[i];
- var qName = a.qName;
- var value = a.value;
- var nsp = qName.indexOf(':');
-
- if (nsp > 0) {
- var prefix = a.prefix = qName.slice(0, nsp);
- var localName = qName.slice(nsp + 1);
- var nsPrefix = prefix === 'xmlns' && localName;
- } else {
- localName = qName;
- prefix = null;
- nsPrefix = qName === 'xmlns' && '';
- } //can not set prefix,because prefix !== ''
+ function okhash(x) {
+ if (!x || !x.length) return 0;
+ var h = 0;
+ for (var i = 0; i < x.length; i++) {
+ h = (h << 5) - h + x.charCodeAt(i) | 0;
+ }
- a.localName = localName; //prefix == null for no ns prefix attribute
+ return h;
+ } // get one coordinate from a coordinate array, if any
- if (nsPrefix !== false) {
- //hack!!
- if (localNSMap == null) {
- localNSMap = {}; //console.log(currentNSMap,0)
- _copy(currentNSMap, currentNSMap = {}); //console.log(currentNSMap,1)
+ function coord1(v) {
+ return v.replace(removeSpace, "").split(",").map(parseFloat);
+ } // get all coordinates from a coordinate array as [[],[]]
- }
- currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
- a.uri = 'http://www.w3.org/2000/xmlns/';
- domBuilder.startPrefixMapping(nsPrefix, value);
- }
- }
+ function coord(v) {
+ return v.replace(trimSpace, "").split(splitSpace).map(coord1);
+ }
- var i = el.length;
+ function xml2str(node) {
+ if (node.xml !== undefined) return node.xml;
- while (i--) {
- a = el[i];
- var prefix = a.prefix;
+ if (node.tagName) {
+ var output = node.tagName;
- if (prefix) {
- //no prefix attribute has no namespace
- if (prefix === 'xml') {
- a.uri = 'http://www.w3.org/XML/1998/namespace';
- }
+ for (var i = 0; i < node.attributes.length; i++) {
+ output += node.attributes[i].name + node.attributes[i].value;
+ }
- if (prefix !== 'xmlns') {
- a.uri = currentNSMap[prefix || '']; //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
- }
+ for (var _i9 = 0; _i9 < node.childNodes.length; _i9++) {
+ output += xml2str(node.childNodes[_i9]);
}
- }
- var nsp = tagName.indexOf(':');
+ return output;
+ }
- if (nsp > 0) {
- prefix = el.prefix = tagName.slice(0, nsp);
- localName = el.localName = tagName.slice(nsp + 1);
- } else {
- prefix = null; //important!!
+ if (node.nodeName === "#text") {
+ return (node.nodeValue || node.value || "").trim();
+ }
- localName = el.localName = tagName;
- } //no prefix element has default namespace
+ if (node.nodeName === "#cdata-section") {
+ return node.nodeValue;
+ }
+ return "";
+ }
- var ns = el.uri = currentNSMap[prefix || ''];
- domBuilder.startElement(ns, localName, tagName, el); //endPrefixMapping and startPrefixMapping have not any help for dom builder
- //localNSMap = null
+ var geotypes = ["Polygon", "LineString", "Point", "Track", "gx:Track"];
- if (el.closed) {
- domBuilder.endElement(ns, localName, tagName);
+ function kmlColor(properties, elem, prefix) {
+ var v = nodeVal(get1(elem, "color")) || "";
+ var colorProp = prefix == "stroke" || prefix === "fill" ? prefix : prefix + "-color";
- if (localNSMap) {
- for (prefix in localNSMap) {
- domBuilder.endPrefixMapping(prefix);
- }
- }
- } else {
- el.currentNSMap = currentNSMap;
- el.localNSMap = localNSMap; //parseStack.push(el);
+ if (v.substr(0, 1) === "#") {
+ v = v.substr(1);
+ }
- return true;
+ if (v.length === 6 || v.length === 3) {
+ properties[colorProp] = v;
+ } else if (v.length === 8) {
+ properties[prefix + "-opacity"] = parseInt(v.substr(0, 2), 16) / 255;
+ properties[colorProp] = "#" + v.substr(6, 2) + v.substr(4, 2) + v.substr(2, 2);
}
}
- function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) {
- if (/^(?:script|textarea)$/i.test(tagName)) {
- var elEndStart = source.indexOf('' + tagName + '>', elStartEnd);
- var text = source.substring(elStartEnd + 1, elEndStart);
+ function numericProperty(properties, elem, source, target) {
+ var val = parseFloat(nodeVal(get1(elem, source)));
+ if (!isNaN(val)) properties[target] = val;
+ }
- if (/[&<]/.test(text)) {
- if (/^script$/i.test(tagName)) {
- //if(!/\]\]>/.test(text)){
- //lexHandler.startCDATA();
- domBuilder.characters(text, 0, text.length); //lexHandler.endCDATA();
+ function gxCoords(root) {
+ var elems = root.getElementsByTagName("coord");
+ var coords = [];
+ var times = [];
+ if (elems.length === 0) elems = root.getElementsByTagName("gx:coord");
- return elEndStart; //}
- } //}else{//text area
+ for (var i = 0; i < elems.length; i++) {
+ coords.push(nodeVal(elems[i]).split(" ").map(parseFloat));
+ }
+ var timeElems = root.getElementsByTagName("when");
- text = text.replace(/?\w+;/g, entityReplacer);
- domBuilder.characters(text, 0, text.length);
- return elEndStart; //}
- }
+ for (var j = 0; j < timeElems.length; j++) {
+ times.push(nodeVal(timeElems[j]));
}
- return elStartEnd + 1;
+ return {
+ coords: coords,
+ times: times
+ };
}
- function fixSelfClosed(source, elStartEnd, tagName, closeMap) {
- //if(tagName in closeMap){
- var pos = closeMap[tagName];
-
- if (pos == null) {
- //console.log(tagName)
- pos = source.lastIndexOf('' + tagName + '>');
-
- if (pos < elStartEnd) {
- //å¿è®°éå
- pos = source.lastIndexOf('' + tagName);
- }
+ function getGeometry(root) {
+ var geomNode;
+ var geomNodes;
+ var i;
+ var j;
+ var k;
+ var geoms = [];
+ var coordTimes = [];
- closeMap[tagName] = pos;
+ if (get1(root, "MultiGeometry")) {
+ return getGeometry(get1(root, "MultiGeometry"));
}
- return pos < elStartEnd; //}
- }
-
- function _copy(source, target) {
- for (var n in source) {
- target[n] = source[n];
+ if (get1(root, "MultiTrack")) {
+ return getGeometry(get1(root, "MultiTrack"));
}
- }
- function parseDCC(source, start, domBuilder, errorHandler) {
- //sure start with '', start + 4); //append comment source.substring(4,end)//");
-
- case DOCUMENT_TYPE_NODE:
- var pubid = node.publicId;
- var sysid = node.systemId;
- buf.push('');
- } else if (sysid && sysid != '.') {
- buf.push(' SYSTEM "', sysid, '">');
- } else {
- var sub = node.internalSubset;
-
- if (sub) {
- buf.push(" [", sub, "]");
- }
-
- buf.push(">");
- }
-
- return;
-
- case PROCESSING_INSTRUCTION_NODE:
- return buf.push("", node.target, " ", node.data, "?>");
-
- case ENTITY_REFERENCE_NODE:
- return buf.push('&', node.nodeName, ';');
- //case ENTITY_NODE:
- //case NOTATION_NODE:
-
- default:
- buf.push('??', node.nodeName);
- }
- }
-
- function _importNode(doc, node, deep) {
- var node2;
-
- switch (node.nodeType) {
- case ELEMENT_NODE:
- node2 = node.cloneNode(false);
- node2.ownerDocument = doc;
- //var attrs = node2.attributes;
- //var len = attrs.length;
- //for(var i=0;i',
- 'amp': '&',
- 'quot': '"',
- 'apos': "'"
- };
-
- if (locator) {
- domBuilder.setDocumentLocator(locator);
- }
-
- sax.errorHandler = buildErrorHandler(errorHandler, domBuilder, locator);
- sax.domBuilder = options.domBuilder || domBuilder;
-
- if (/\/x?html?$/.test(mimeType)) {
- entityMap.nbsp = '\xa0';
- entityMap.copy = '\xa9';
- defaultNSMap[''] = 'http://www.w3.org/1999/xhtml';
- }
-
- defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
-
- if (source) {
- sax.parse(source, defaultNSMap, entityMap);
- } else {
- sax.errorHandler.error("invalid doc source");
- }
-
- return domBuilder.doc;
- };
-
- function buildErrorHandler(errorImpl, domBuilder, locator) {
- if (!errorImpl) {
- if (domBuilder instanceof DOMHandler) {
- return domBuilder;
- }
-
- errorImpl = domBuilder;
- }
-
- var errorHandler = {};
- var isCallback = errorImpl instanceof Function;
- locator = locator || {};
-
- function build(key) {
- var fn = errorImpl[key];
-
- if (!fn && isCallback) {
- fn = errorImpl.length == 2 ? function (msg) {
- errorImpl(key, msg);
- } : errorImpl;
- }
-
- errorHandler[key] = fn && function (msg) {
- fn('[xmldom ' + key + ']\t' + msg + _locator(locator));
- } || function () {};
- }
-
- build('warning');
- build('error');
- build('fatalError');
- return errorHandler;
- } //console.log('#\n\n\n\n\n\n\n####')
-
- /**
- * +ContentHandler+ErrorHandler
- * +LexicalHandler+EntityResolver2
- * -DeclHandler-DTDHandler
- *
- * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
- * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
- * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
- */
-
-
- function DOMHandler() {
- this.cdata = false;
- }
-
- function position(locator, node) {
- node.lineNumber = locator.lineNumber;
- node.columnNumber = locator.columnNumber;
- }
- /**
- * @see org.xml.sax.ContentHandler#startDocument
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
- */
-
-
- DOMHandler.prototype = {
- startDocument: function startDocument() {
- this.doc = new DOMImplementation().createDocument(null, null, null);
-
- if (this.locator) {
- this.doc.documentURI = this.locator.systemId;
- }
- },
- startElement: function startElement(namespaceURI, localName, qName, attrs) {
- var doc = this.doc;
- var el = doc.createElementNS(namespaceURI, qName || localName);
- var len = attrs.length;
- appendElement(this, el);
- this.currentElement = el;
- this.locator && position(this.locator, el);
-
- for (var i = 0; i < len; i++) {
- var namespaceURI = attrs.getURI(i);
- var value = attrs.getValue(i);
- var qName = attrs.getQName(i);
- var attr = doc.createAttributeNS(namespaceURI, qName);
- this.locator && position(attrs.getLocator(i), attr);
- attr.value = attr.nodeValue = value;
- el.setAttributeNode(attr);
- }
- },
- endElement: function endElement(namespaceURI, localName, qName) {
- var current = this.currentElement;
- current.tagName;
- this.currentElement = current.parentNode;
- },
- startPrefixMapping: function startPrefixMapping(prefix, uri) {},
- endPrefixMapping: function endPrefixMapping(prefix) {},
- processingInstruction: function processingInstruction(target, data) {
- var ins = this.doc.createProcessingInstruction(target, data);
- this.locator && position(this.locator, ins);
- appendElement(this, ins);
- },
- ignorableWhitespace: function ignorableWhitespace(ch, start, length) {},
- characters: function characters(chars, start, length) {
- chars = _toString.apply(this, arguments); //console.log(chars)
-
- if (chars) {
- if (this.cdata) {
- var charNode = this.doc.createCDATASection(chars);
- } else {
- var charNode = this.doc.createTextNode(chars);
- }
-
- if (this.currentElement) {
- this.currentElement.appendChild(charNode);
- } else if (/^\s*$/.test(chars)) {
- this.doc.appendChild(charNode); //process xml
- }
-
- this.locator && position(this.locator, charNode);
- }
- },
- skippedEntity: function skippedEntity(name) {},
- endDocument: function endDocument() {
- this.doc.normalize();
- },
- setDocumentLocator: function setDocumentLocator(locator) {
- if (this.locator = locator) {
- // && !('lineNumber' in locator)){
- locator.lineNumber = 0;
- }
- },
- //LexicalHandler
- comment: function comment(chars, start, length) {
- chars = _toString.apply(this, arguments);
- var comm = this.doc.createComment(chars);
- this.locator && position(this.locator, comm);
- appendElement(this, comm);
- },
- startCDATA: function startCDATA() {
- //used in characters() methods
- this.cdata = true;
- },
- endCDATA: function endCDATA() {
- this.cdata = false;
- },
- startDTD: function startDTD(name, publicId, systemId) {
- var impl = this.doc.implementation;
-
- if (impl && impl.createDocumentType) {
- var dt = impl.createDocumentType(name, publicId, systemId);
- this.locator && position(this.locator, dt);
- appendElement(this, dt);
- }
- },
-
- /**
- * @see org.xml.sax.ErrorHandler
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
- */
- warning: function warning(error) {
- console.warn('[xmldom warning]\t' + error, _locator(this.locator));
- },
- error: function error(_error) {
- console.error('[xmldom error]\t' + _error, _locator(this.locator));
- },
- fatalError: function fatalError(error) {
- console.error('[xmldom fatalError]\t' + error, _locator(this.locator));
- throw error;
- }
- };
-
- function _locator(l) {
- if (l) {
- return '\n@' + (l.systemId || '') + '#[line:' + l.lineNumber + ',col:' + l.columnNumber + ']';
- }
- }
-
- function _toString(chars, start, length) {
- if (typeof chars == 'string') {
- return chars.substr(start, length);
- } else {
- //java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
- if (chars.length >= start + length || start) {
- return new java.lang.String(chars, start, length) + '';
- }
-
- return chars;
- }
- }
- /*
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
- * used method of org.xml.sax.ext.LexicalHandler:
- * #comment(chars, start, length)
- * #startCDATA()
- * #endCDATA()
- * #startDTD(name, publicId, systemId)
- *
- *
- * IGNORED method of org.xml.sax.ext.LexicalHandler:
- * #endDTD()
- * #startEntity(name)
- * #endEntity(name)
- *
- *
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
- * IGNORED method of org.xml.sax.ext.DeclHandler
- * #attributeDecl(eName, aName, type, mode, value)
- * #elementDecl(name, model)
- * #externalEntityDecl(name, publicId, systemId)
- * #internalEntityDecl(name, value)
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
- * IGNORED method of org.xml.sax.EntityResolver2
- * #resolveEntity(String name,String publicId,String baseURI,String systemId)
- * #resolveEntity(publicId, systemId)
- * #getExternalSubset(name, baseURI)
- * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
- * IGNORED method of org.xml.sax.DTDHandler
- * #notationDecl(name, publicId, systemId) {};
- * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
- */
-
-
- "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g, function (key) {
- DOMHandler.prototype[key] = function () {
- return null;
- };
- });
- /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
-
- function appendElement(hander, node) {
- if (!hander.currentElement) {
- hander.doc.appendChild(node);
- } else {
- hander.currentElement.appendChild(node);
- }
- } //appendChild and setAttributeNS are preformance key
- //if(typeof require == 'function'){
-
-
- var XMLReader = sax.XMLReader;
- var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
- exports.XMLSerializer = dom.XMLSerializer;
- exports.DOMParser = DOMParser; //}
- });
-
- var togeojson = createCommonjsModule(function (module, exports) {
- var toGeoJSON = function () {
-
- var removeSpace = /\s*/g,
- trimSpace = /^\s*|\s*$/g,
- splitSpace = /\s+/; // generate a short, numeric hash of a string
-
- function okhash(x) {
- if (!x || !x.length) return 0;
-
- for (var i = 0, h = 0; i < x.length; i++) {
- h = (h << 5) - h + x.charCodeAt(i) | 0;
- }
-
- return h;
- } // all Y children of X
-
-
- function get(x, y) {
- return x.getElementsByTagName(y);
- }
-
- function attr(x, y) {
- return x.getAttribute(y);
- }
-
- function attrf(x, y) {
- return parseFloat(attr(x, y));
- } // one Y child of X, if any, otherwise null
-
-
- function get1(x, y) {
- var n = get(x, y);
- return n.length ? n[0] : null;
- } // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
-
-
- function norm(el) {
- if (el.normalize) {
- el.normalize();
- }
-
- return el;
- } // cast array x into numbers
-
-
- function numarray(x) {
- for (var j = 0, o = []; j < x.length; j++) {
- o[j] = parseFloat(x[j]);
- }
-
- return o;
- } // get the content of a text node, if any
-
-
- function nodeVal(x) {
- if (x) {
- norm(x);
- }
-
- return x && x.textContent || '';
- } // get the contents of multiple text nodes, if present
-
-
- function getMulti(x, ys) {
- var o = {},
- n,
- k;
-
- for (k = 0; k < ys.length; k++) {
- n = get1(x, ys[k]);
- if (n) o[ys[k]] = nodeVal(n);
- }
-
- return o;
- } // add properties of Y to X, overwriting if present in both
-
-
- function extend(x, y) {
- for (var k in y) {
- x[k] = y[k];
- }
- } // get one coordinate from a coordinate array, if any
-
-
- function coord1(v) {
- return numarray(v.replace(removeSpace, '').split(','));
- } // get all coordinates from a coordinate array as [[],[]]
-
-
- function coord(v) {
- var coords = v.replace(trimSpace, '').split(splitSpace),
- o = [];
-
- for (var i = 0; i < coords.length; i++) {
- o.push(coord1(coords[i]));
- }
-
- return o;
- }
-
- function coordPair(x) {
- var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
- ele = get1(x, 'ele'),
- // handle namespaced attribute in browser
- heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
- time = get1(x, 'time'),
- e;
-
- if (ele) {
- e = parseFloat(nodeVal(ele));
-
- if (!isNaN(e)) {
- ll.push(e);
- }
- }
-
- return {
- coordinates: ll,
- time: time ? nodeVal(time) : null,
- heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
- };
- } // create a new feature collection parent object
-
-
- function fc() {
- return {
- type: 'FeatureCollection',
- features: []
- };
- }
-
- var serializer;
-
- if (typeof XMLSerializer !== 'undefined') {
- /* istanbul ignore next */
- serializer = new XMLSerializer(); // only require xmldom in a node environment
- } else if ((typeof process === "undefined" ? "undefined" : _typeof(process)) === 'object' && !process.browser) {
- serializer = new domParser.XMLSerializer();
- }
-
- function xml2str(str) {
- // IE9 will create a new XMLSerializer but it'll crash immediately.
- // This line is ignored because we don't run coverage tests in IE9
-
- /* istanbul ignore next */
- if (str.xml !== undefined) return str.xml;
- return serializer.serializeToString(str);
- }
-
- var t = {
- kml: function kml(doc) {
- var gj = fc(),
- // styleindex keeps track of hashed styles in order to match features
- styleIndex = {},
- styleByHash = {},
- // stylemapindex keeps track of style maps to expose in properties
- styleMapIndex = {},
- // atomic geospatial types supported by KML - MultiGeometry is
- // handled separately
- geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
- // all root placemarks in the file
- placemarks = get(doc, 'Placemark'),
- styles = get(doc, 'Style'),
- styleMaps = get(doc, 'StyleMap');
-
- for (var k = 0; k < styles.length; k++) {
- var hash = okhash(xml2str(styles[k])).toString(16);
- styleIndex['#' + attr(styles[k], 'id')] = hash;
- styleByHash[hash] = styles[k];
- }
-
- for (var l = 0; l < styleMaps.length; l++) {
- styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
- var pairs = get(styleMaps[l], 'Pair');
- var pairsMap = {};
-
- for (var m = 0; m < pairs.length; m++) {
- pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
- }
-
- styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
- }
-
- for (var j = 0; j < placemarks.length; j++) {
- gj.features = gj.features.concat(getPlacemark(placemarks[j]));
- }
-
- function kmlColor(v) {
- var color, opacity;
- v = v || '';
-
- if (v.substr(0, 1) === '#') {
- v = v.substr(1);
- }
-
- if (v.length === 6 || v.length === 3) {
- color = v;
- }
-
- if (v.length === 8) {
- opacity = parseInt(v.substr(0, 2), 16) / 255;
- color = '#' + v.substr(6, 2) + v.substr(4, 2) + v.substr(2, 2);
- }
-
- return [color, isNaN(opacity) ? undefined : opacity];
- }
-
- function gxCoord(v) {
- return numarray(v.split(' '));
- }
-
- function gxCoords(root) {
- var elems = get(root, 'coord'),
- coords = [],
- times = [];
- if (elems.length === 0) elems = get(root, 'gx:coord');
-
- for (var i = 0; i < elems.length; i++) {
- coords.push(gxCoord(nodeVal(elems[i])));
- }
-
- var timeElems = get(root, 'when');
-
- for (var j = 0; j < timeElems.length; j++) {
- times.push(nodeVal(timeElems[j]));
- }
-
- return {
- coords: coords,
- times: times
- };
- }
-
- function getGeometry(root) {
- var geomNode,
- geomNodes,
- i,
- j,
- k,
- geoms = [],
- coordTimes = [];
-
- if (get1(root, 'MultiGeometry')) {
- return getGeometry(get1(root, 'MultiGeometry'));
- }
-
- if (get1(root, 'MultiTrack')) {
- return getGeometry(get1(root, 'MultiTrack'));
- }
-
- if (get1(root, 'gx:MultiTrack')) {
- return getGeometry(get1(root, 'gx:MultiTrack'));
- }
-
- for (i = 0; i < geotypes.length; i++) {
- geomNodes = get(root, geotypes[i]);
-
- if (geomNodes) {
- for (j = 0; j < geomNodes.length; j++) {
- geomNode = geomNodes[j];
-
- if (geotypes[i] === 'Point') {
- geoms.push({
- type: 'Point',
- coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
- });
- } else if (geotypes[i] === 'LineString') {
- geoms.push({
- type: 'LineString',
- coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
- });
- } else if (geotypes[i] === 'Polygon') {
- var rings = get(geomNode, 'LinearRing'),
- coords = [];
-
- for (k = 0; k < rings.length; k++) {
- coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
- }
-
- geoms.push({
- type: 'Polygon',
- coordinates: coords
- });
- } else if (geotypes[i] === 'Track' || geotypes[i] === 'gx:Track') {
- var track = gxCoords(geomNode);
- geoms.push({
- type: 'LineString',
- coordinates: track.coords
- });
- if (track.times.length) coordTimes.push(track.times);
- }
- }
- }
- }
-
- return {
- geoms: geoms,
- coordTimes: coordTimes
- };
- }
-
- function getPlacemark(root) {
- var geomsAndTimes = getGeometry(root),
- i,
- properties = {},
- name = nodeVal(get1(root, 'name')),
- address = nodeVal(get1(root, 'address')),
- styleUrl = nodeVal(get1(root, 'styleUrl')),
- description = nodeVal(get1(root, 'description')),
- timeSpan = get1(root, 'TimeSpan'),
- timeStamp = get1(root, 'TimeStamp'),
- extendedData = get1(root, 'ExtendedData'),
- lineStyle = get1(root, 'LineStyle'),
- polyStyle = get1(root, 'PolyStyle'),
- visibility = get1(root, 'visibility');
- if (!geomsAndTimes.geoms.length) return [];
- if (name) properties.name = name;
- if (address) properties.address = address;
-
- if (styleUrl) {
- if (styleUrl[0] !== '#') {
- styleUrl = '#' + styleUrl;
- }
-
- properties.styleUrl = styleUrl;
-
- if (styleIndex[styleUrl]) {
- properties.styleHash = styleIndex[styleUrl];
- }
-
- if (styleMapIndex[styleUrl]) {
- properties.styleMapHash = styleMapIndex[styleUrl];
- properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
- } // Try to populate the lineStyle or polyStyle since we got the style hash
-
-
- var style = styleByHash[properties.styleHash];
-
- if (style) {
- if (!lineStyle) lineStyle = get1(style, 'LineStyle');
- if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
- }
- }
-
- if (description) properties.description = description;
-
- if (timeSpan) {
- var begin = nodeVal(get1(timeSpan, 'begin'));
- var end = nodeVal(get1(timeSpan, 'end'));
- properties.timespan = {
- begin: begin,
- end: end
- };
- }
-
- if (timeStamp) {
- properties.timestamp = nodeVal(get1(timeStamp, 'when'));
- }
-
- if (lineStyle) {
- var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
- color = linestyles[0],
- opacity = linestyles[1],
- width = parseFloat(nodeVal(get1(lineStyle, 'width')));
- if (color) properties.stroke = color;
- if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
- if (!isNaN(width)) properties['stroke-width'] = width;
- }
-
- if (polyStyle) {
- var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
- pcolor = polystyles[0],
- popacity = polystyles[1],
- fill = nodeVal(get1(polyStyle, 'fill')),
- outline = nodeVal(get1(polyStyle, 'outline'));
- if (pcolor) properties.fill = pcolor;
- if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
- if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
- if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
- }
-
- if (extendedData) {
- var datas = get(extendedData, 'Data'),
- simpleDatas = get(extendedData, 'SimpleData');
-
- for (i = 0; i < datas.length; i++) {
- properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
- }
-
- for (i = 0; i < simpleDatas.length; i++) {
- properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
- }
- }
-
- if (visibility) {
- properties.visibility = nodeVal(visibility);
- }
-
- if (geomsAndTimes.coordTimes.length) {
- properties.coordTimes = geomsAndTimes.coordTimes.length === 1 ? geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
- }
-
- var feature = {
- type: 'Feature',
- geometry: geomsAndTimes.geoms.length === 1 ? geomsAndTimes.geoms[0] : {
- type: 'GeometryCollection',
- geometries: geomsAndTimes.geoms
- },
- properties: properties
- };
- if (attr(root, 'id')) feature.id = attr(root, 'id');
- return [feature];
- }
-
- return gj;
- },
- gpx: function gpx(doc) {
- var i,
- tracks = get(doc, 'trk'),
- routes = get(doc, 'rte'),
- waypoints = get(doc, 'wpt'),
- // a feature collection
- gj = fc(),
- feature;
-
- for (i = 0; i < tracks.length; i++) {
- feature = getTrack(tracks[i]);
- if (feature) gj.features.push(feature);
- }
-
- for (i = 0; i < routes.length; i++) {
- feature = getRoute(routes[i]);
- if (feature) gj.features.push(feature);
- }
-
- for (i = 0; i < waypoints.length; i++) {
- gj.features.push(getPoint(waypoints[i]));
- }
-
- function getPoints(node, pointname) {
- var pts = get(node, pointname),
- line = [],
- times = [],
- heartRates = [],
- l = pts.length;
- if (l < 2) return {}; // Invalid line in GeoJSON
-
- for (var i = 0; i < l; i++) {
- var c = coordPair(pts[i]);
- line.push(c.coordinates);
- if (c.time) times.push(c.time);
- if (c.heartRate) heartRates.push(c.heartRate);
- }
-
- return {
- line: line,
- times: times,
- heartRates: heartRates
- };
- }
-
- function getTrack(node) {
- var segments = get(node, 'trkseg'),
- track = [],
- times = [],
- heartRates = [],
- line;
-
- for (var i = 0; i < segments.length; i++) {
- line = getPoints(segments[i], 'trkpt');
-
- if (line) {
- if (line.line) track.push(line.line);
- if (line.times && line.times.length) times.push(line.times);
- if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
- }
- }
-
- if (track.length === 0) return;
- var properties = getProperties(node);
- extend(properties, getLineStyle(get1(node, 'extensions')));
- if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
- if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
- return {
- type: 'Feature',
- properties: properties,
- geometry: {
- type: track.length === 1 ? 'LineString' : 'MultiLineString',
- coordinates: track.length === 1 ? track[0] : track
- }
- };
- }
-
- function getRoute(node) {
- var line = getPoints(node, 'rtept');
- if (!line.line) return;
- var prop = getProperties(node);
- extend(prop, getLineStyle(get1(node, 'extensions')));
- var routeObj = {
- type: 'Feature',
- properties: prop,
- geometry: {
- type: 'LineString',
- coordinates: line.line
- }
- };
- return routeObj;
- }
-
- function getPoint(node) {
- var prop = getProperties(node);
- extend(prop, getMulti(node, ['sym']));
- return {
- type: 'Feature',
- properties: prop,
- geometry: {
- type: 'Point',
- coordinates: coordPair(node).coordinates
- }
- };
- }
-
- function getLineStyle(extensions) {
- var style = {};
-
- if (extensions) {
- var lineStyle = get1(extensions, 'line');
-
- if (lineStyle) {
- var color = nodeVal(get1(lineStyle, 'color')),
- opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
- width = parseFloat(nodeVal(get1(lineStyle, 'width')));
- if (color) style.stroke = color;
- if (!isNaN(opacity)) style['stroke-opacity'] = opacity; // GPX width is in mm, convert to px with 96 px per inch
-
- if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
- }
- }
-
- return style;
- }
-
- function getProperties(node) {
- var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
- links = get(node, 'link');
- if (links.length) prop.links = [];
-
- for (var i = 0, link; i < links.length; i++) {
- link = {
- href: attr(links[i], 'href')
- };
- extend(link, getMulti(links[i], ['text', 'type']));
- prop.links.push(link);
- }
-
- return prop;
- }
-
- return gj;
- }
- };
- return t;
- }();
-
- module.exports = toGeoJSON;
- });
-
- var _initialized = false;
- var _enabled = false;
-
- var _geojson;
-
- function svgData(projection, context, dispatch) {
- var throttledRedraw = throttle(function () {
- dispatch.call('change');
- }, 1000);
-
- var _showLabels = true;
- var detected = utilDetect();
- var layer = select(null);
-
- var _vtService;
-
- var _fileList;
-
- var _template;
-
- var _src;
-
- function init() {
- if (_initialized) return; // run once
-
- _geojson = {};
- _enabled = true;
-
- function over(d3_event) {
- d3_event.stopPropagation();
- d3_event.preventDefault();
- d3_event.dataTransfer.dropEffect = 'copy';
- }
-
- context.container().attr('dropzone', 'copy').on('drop.svgData', function (d3_event) {
- d3_event.stopPropagation();
- d3_event.preventDefault();
- if (!detected.filedrop) return;
- drawData.fileList(d3_event.dataTransfer.files);
- }).on('dragenter.svgData', over).on('dragexit.svgData', over).on('dragover.svgData', over);
- _initialized = true;
- }
-
- function getService() {
- if (services.vectorTile && !_vtService) {
- _vtService = services.vectorTile;
-
- _vtService.event.on('loadedData', throttledRedraw);
- } else if (!services.vectorTile && _vtService) {
- _vtService = null;
- }
-
- return _vtService;
- }
-
- function showLayer() {
- layerOn();
- layer.style('opacity', 0).transition().duration(250).style('opacity', 1).on('end', function () {
- dispatch.call('change');
- });
- }
-
- function hideLayer() {
- throttledRedraw.cancel();
- layer.transition().duration(250).style('opacity', 0).on('end', layerOff);
- }
-
- function layerOn() {
- layer.style('display', 'block');
- }
+ function layerOn() {
+ layer.style('display', 'block');
+ }
function layerOff() {
layer.selectAll('.viewfield-group').remove();
@@ -65424,11 +63102,11 @@
switch (extension) {
case '.gpx':
- gj = togeojson.gpx(xmlToDom(data));
+ gj = gpx(xmlToDom(data));
break;
case '.kml':
- gj = togeojson.kml(xmlToDom(data));
+ gj = kml(xmlToDom(data));
break;
case '.geojson':
@@ -70224,7 +67902,8 @@
context.on('enter.map', function () {
if (!map.editableDataEnabled(true
/* skip zoom check */
- )) return; // redraw immediately any objects affected by a change in selectedIDs.
+ )) return;
+ if (_isTransformed) return; // redraw immediately any objects affected by a change in selectedIDs.
var graph = context.graph();
var selectedAndParents = {};
@@ -70513,11 +68192,11 @@
k2 = t0.k * Math.pow(2, -dY / 500);
k2 = clamp$1(k2, kMin, kMax);
x2 = p0[0] - p1[0] * k2;
- y2 = p0[1] - p1[1] * k2; // 2 finger map panning (Mac only, all browsers) - #5492, #5512
+ y2 = p0[1] - p1[1] * k2; // 2 finger map panning (Mac only, all browsers except Firefox #8595) - #5492, #5512
// Panning via the `wheel` event will always have:
// - `ctrlKey = false`
// - `deltaX`,`deltaY` are round integer pixels
- } else if (detected.os === 'mac' && !source.ctrlKey && isInteger(dX) && isInteger(dY)) {
+ } else if (detected.os === 'mac' && detected.browser !== 'Firefox' && !source.ctrlKey && isInteger(dX) && isInteger(dY)) {
p1 = projection.translate();
x2 = p1[0] - dX;
y2 = p1[1] - dY;
@@ -87518,8 +85197,8 @@
var modalSection = introModal.append('div').attr('class', 'modal-section');
modalSection.append('p').html(_t.html('splash.text', {
version: context.version,
- website: 'ideditor.blog',
- github: 'github.com'
+ website: 'changelog',
+ github: 'github.com'
}));
modalSection.append('p').html(_t.html('splash.privacy', {
updateMessage: updateMessage,
@@ -88576,6 +86255,14 @@
for (var severity in issuesBySeverity) {
var issues = issuesBySeverity[severity];
+
+ if (severity !== 'error') {
+ // exclude 'fixme' and similar - #8603
+ issues = issues.filter(function (issue) {
+ return issue.type !== 'help_request';
+ });
+ }
+
var section = severity + '-section';
var issueItem = severity + '-item';
var container = selection.selectAll('.' + section).data(issues.length ? [0] : []);
@@ -88786,7 +86473,10 @@
where: 'all',
includeIgnored: true,
includeDisabledRules: true
- }).warning;
+ }).warning.filter(function (issue) {
+ return issue.type !== 'help_request';
+ }); // exclude 'fixme' and similar - #8603
+
addIssueCounts(warnings, 'warnings'); // add counts of issues resolved by the user's edits
var resolvedIssues = context.validator().getResolvedIssues();
@@ -92679,7 +90369,7 @@
var _deferred = new Set();
- context.version = '2.20.0';
+ context.version = '2.20.1';
context.privacyVersion = '20201202'; // iD will alter the hash so cache the parameters intended to setup the session
context.initialHashParams = window.location.hash ? utilStringQs(window.location.hash) : {};
@@ -93519,7 +91209,7 @@
// and fallbacks like
// "amenity/yes"
// excluding things like
- // "highway", "surface", "ref", etc.
+ // "tiger:reviewed", "surface", "ref", etc.
//
// Arguments
// `tags`: `Object` containing the feature's OSM tags
@@ -93537,16 +91227,19 @@
var alternate = new Set();
Object.keys(tags).forEach(function (osmkey) {
var osmvalue = tags[osmkey];
- if (!osmvalue) return;
+ if (!osmvalue) return; // Match a 'route_master' as if it were a 'route' - name-suggestion-index#5184
+
+ if (osmkey === 'route_master') osmkey = 'route';
var vmap = _nsi.kvt.get(osmkey);
- if (!vmap) return;
+ if (!vmap) return; // not an interesting key
- if (osmvalue !== 'yes') {
- primary.add("".concat(osmkey, "/").concat(osmvalue));
- } else {
- alternate.add("".concat(osmkey, "/").concat(osmvalue));
+ if (vmap.get(osmvalue)) {
+ // Matched a category in NSI
+ primary.add("".concat(osmkey, "/").concat(osmvalue)); // interesting key/value
+ } else if (osmvalue === 'yes') {
+ alternate.add("".concat(osmkey, "/").concat(osmvalue)); // fallback key/yes
}
}); // Can we try a generic building fallback match? - See #6122, #7197
// Only try this if we do a preset match and find nothing else remarkable about that building.
@@ -93585,7 +91278,9 @@
if (t) return; // found already
var osmvalue = tags[osmkey];
- if (!osmvalue) return;
+ if (!osmvalue) return; // Match a 'route_master' as if it were a 'route' - name-suggestion-index#5184
+
+ if (osmkey === 'route_master') osmkey = 'route';
var vmap = _nsi.kvt.get(osmkey);
@@ -93716,6 +91411,7 @@
}
function isNamelike(osmkey, which) {
+ if (osmkey === 'old_name') return false;
return patterns[which].test(osmkey) && !notNames.test(osmkey);
}
} // `gatherTuples()`
@@ -93802,7 +91498,9 @@
}
}
}
- }); // Gather key/value tag pairs to try to match
+ }); // Match a 'route_master' as if it were a 'route' - name-suggestion-index#5184
+
+ var isRouteMaster = tags.type === 'route_master'; // Gather key/value tag pairs to try to match
var tryKVs = gatherKVs(tags);
if (!tryKVs.primary.size && !tryKVs.alternate.size) return changed ? newTags : null; // Gather namelike tag values to try to match
@@ -93868,11 +91566,15 @@
var category = _nsi.data[tkv];
var properties = category.properties || {}; // Preserve some tags that we specifically don't want NSI to overwrite. ('^name', sometimes)
- var preserveTags = item.preserveTags || properties.preserveTags || [];
+ var preserveTags = item.preserveTags || properties.preserveTags || []; // These tags can be toplevel tags -or- attributes - so we generally want to preserve existing values - #8615
+ // We'll only _replace_ the tag value if this tag is the toplevel/defining tag for the matched item (`k`)
+
+ ['building', 'emergency', 'internet_access', 'takeaway'].forEach(function (osmkey) {
+ if (k !== osmkey) preserveTags.push("^".concat(osmkey, "$"));
+ });
var regexes = preserveTags.map(function (s) {
return new RegExp(s, 'i');
});
- regexes.push(/^building$/i, /^takeaway$/i);
var keepTags = {};
Object.keys(newTags).forEach(function (osmkey) {
if (regexes.some(function (regex) {
@@ -93880,8 +91582,8 @@
})) {
keepTags[osmkey] = newTags[osmkey];
}
- }); // Remove any primary tags ("amenity", "craft", "shop", "man_made", "route", etc)
- // with a value like `amenity=yes` or `shop=yes`
+ }); // Remove any primary tags ("amenity", "craft", "shop", "man_made", "route", etc) that have a
+ // value like `amenity=yes` or `shop=yes` (exceptions have already been added to `keepTags` above)
_nsi.kvt.forEach(function (vmap, k) {
if (newTags[k] === 'yes') delete newTags[k];
@@ -93894,13 +91596,19 @@
} // Do the tag upgrade
- Object.assign(newTags, item.tags, keepTags); // Special `branch` splitting rules - IF..
+ Object.assign(newTags, item.tags, keepTags); // Swap `route` back to `route_master` - name-suggestion-index#5184
+
+ if (isRouteMaster) {
+ newTags.route_master = newTags.route;
+ delete newTags.route;
+ } // Special `branch` splitting rules - IF..
// - NSI is suggesting to replace `name`, AND
// - `branch` doesn't already contain something, AND
// - original name has not moved to an alternate name (e.g. "Dunkin' Donuts" -> "Dunkin'"), AND
// - original name is "some name" + "some stuff", THEN
// consider splitting `name` into `name`/`branch`..
+
var origName = tags.name;
var newName = newTags.name;
@@ -104762,9 +102470,10 @@
utilDisplayLabel: utilDisplayLabel,
utilEntityRoot: utilEntityRoot,
utilEditDistance: utilEditDistance,
- utilEntitySelector: utilEntitySelector,
+ utilEntityAndDeepMemberIDs: utilEntityAndDeepMemberIDs,
utilEntityOrMemberSelector: utilEntityOrMemberSelector,
utilEntityOrDeepMemberSelector: utilEntityOrDeepMemberSelector,
+ utilEntitySelector: utilEntitySelector,
utilFastMouse: utilFastMouse,
utilFetchJson: utilFetchJson,
utilFunctor: utilFunctor,