| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- /*!
- * DevExtreme (dx.vectormaputils.debug.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- ! function(root, factory) {
- if ("function" === typeof define && define.amd) {
- define(function(require, exports, module) {
- factory(exports)
- })
- } else {
- if ("object" === typeof module && module.exports) {
- factory(exports)
- } else {
- var exports = root.DevExpress = root.DevExpress || {};
- exports = exports.viz = exports.viz || {};
- exports = exports.vectormaputils = {};
- factory(exports)
- }
- }
- }(this, function(exports) {
- function noop() {}
- function eigen(x) {
- return x
- }
- function isFunction(target) {
- return "function" === typeof target
- }
- function wrapSource(source) {
- var stream, buffer = wrapBuffer(source),
- position = 0;
- stream = {
- pos: function() {
- return position
- },
- skip: function(count) {
- position += count;
- return stream
- },
- ui8arr: function(length) {
- var i = 0,
- list = [];
- list.length = length;
- for (; i < length; ++i) {
- list[i] = stream.ui8()
- }
- return list
- },
- ui8: function() {
- var val = ui8(buffer, position);
- position += 1;
- return val
- },
- ui16LE: function() {
- var val = ui16LE(buffer, position);
- position += 2;
- return val
- },
- ui32LE: function() {
- var val = ui32LE(buffer, position);
- position += 4;
- return val
- },
- ui32BE: function() {
- var val = ui32BE(buffer, position);
- position += 4;
- return val
- },
- f64LE: function() {
- var val = f64LE(buffer, position);
- position += 8;
- return val
- }
- };
- return stream
- }
- function parseCore(source, roundCoordinates, errors) {
- var result, shapeData = source[0] ? parseShape(wrapSource(source[0]), errors) : {},
- dataBaseFileData = source[1] ? parseDBF(wrapSource(source[1]), errors) : {},
- features = buildFeatures(shapeData.shapes || [], dataBaseFileData.records || [], roundCoordinates);
- if (features.length) {
- result = {
- type: "FeatureCollection",
- features: features
- };
- result.bbox = shapeData.bBox
- } else {
- result = null
- }
- return result
- }
- function buildFeatures(shapeData, dataBaseFileData, roundCoordinates) {
- var i, shape, features = [],
- ii = features.length = ii = Math.max(shapeData.length, dataBaseFileData.length);
- for (i = 0; i < ii; ++i) {
- shape = shapeData[i] || {};
- features[i] = {
- type: "Feature",
- geometry: {
- type: shape.geoJSON_type || null,
- coordinates: shape.coordinates ? roundCoordinates(shape.coordinates) : []
- },
- properties: dataBaseFileData[i] || null
- }
- }
- return features
- }
- function createCoordinatesRounder(precision) {
- var factor = Number("1E" + precision);
- function round(x) {
- return Math.round(x * factor) / factor
- }
- function process(values) {
- return values.map(values[0].length ? process : round)
- }
- return process
- }
- function buildParseArgs(source) {
- source = source || {};
- return ["shp", "dbf"].map(function(key) {
- return function(done) {
- if (source.substr) {
- key = "." + key;
- sendRequest(source + (source.substr(-key.length).toLowerCase() === key ? "" : key), function(e, response) {
- done(e, response)
- })
- } else {
- done(null, source[key] || null)
- }
- }
- })
- }
- function parse(source, parameters, callback) {
- var result;
- when(buildParseArgs(source), function(errorArray, dataArray) {
- callback = isFunction(parameters) && parameters || isFunction(callback) && callback || noop;
- parameters = !isFunction(parameters) && parameters || {};
- var errors = [];
- errorArray.forEach(function(e) {
- e && errors.push(e)
- });
- result = parseCore(dataArray, parameters.precision >= 0 ? createCoordinatesRounder(parameters.precision) : eigen, errors);
- callback(result, errors.length ? errors : null)
- });
- return result
- }
- exports.parse = parse;
- function when(actions, callback) {
- var errorArray = [],
- dataArray = [],
- counter = 1,
- lock = true;
- actions.forEach(function(action, i) {
- ++counter;
- action(function(e, data) {
- errorArray[i] = e;
- dataArray[i] = data;
- massDone()
- })
- });
- lock = false;
- massDone();
- function massDone() {
- --counter;
- if (0 === counter && !lock) {
- callback(errorArray, dataArray)
- }
- }
- }
- function parseShape(stream, errors) {
- var timeStart, timeEnd, header, record, records = [];
- try {
- timeStart = new Date;
- header = parseShapeHeader(stream)
- } catch (e) {
- errors.push("shp: header parsing error: " + e.message + " / " + e.description);
- return
- }
- if (9994 !== header.fileCode) {
- errors.push("shp: file code: " + header.fileCode + " / expected: 9994")
- }
- if (1e3 !== header.version) {
- errors.push("shp: file version: " + header.version + " / expected: 1000")
- }
- try {
- while (stream.pos() < header.fileLength) {
- record = parseShapeRecord(stream, header.type, errors);
- if (record) {
- records.push(record)
- } else {
- break
- }
- }
- if (stream.pos() !== header.fileLength) {
- errors.push("shp: file length: " + header.fileLength + " / actual: " + stream.pos())
- }
- timeEnd = new Date
- } catch (e) {
- errors.push("shp: records parsing error: " + e.message + " / " + e.description)
- }
- return {
- bBox: header.bBox_XY,
- type: header.shapeType,
- shapes: records,
- errors: errors,
- time: timeEnd - timeStart
- }
- }
- function readPointShape(stream, record) {
- record.coordinates = readPointArray(stream, 1)[0]
- }
- function readPolyLineShape(stream, record) {
- var i, bBox = readBBox(stream),
- numParts = readInteger(stream),
- numPoints = readInteger(stream),
- parts = readIntegerArray(stream, numParts),
- points = readPointArray(stream, numPoints),
- rings = [];
- rings.length = numParts;
- for (i = 0; i < numParts; ++i) {
- rings[i] = points.slice(parts[i], parts[i + 1] || numPoints)
- }
- record.bBox = bBox;
- record.coordinates = rings
- }
- function readMultiPointShape(stream, record) {
- record.bBox = readBBox(stream);
- record.coordinates = readPointArray(stream, readInteger(stream))
- }
- function readPointMShape(stream, record) {
- record.coordinates = readPointArray(stream, 1)[0];
- record.coordinates.push(readDoubleArray(stream, 1)[0])
- }
- function readMultiPointMShape(stream, record) {
- var bBox = readBBox(stream),
- numPoints = readInteger(stream),
- points = readPointArray(stream, numPoints),
- mBox = readPair(stream),
- mValues = readDoubleArray(stream, numPoints);
- record.bBox = bBox;
- record.mBox = mBox;
- record.coordinates = merge_XYM(points, mValues, numPoints)
- }
- function readPolyLineMShape(stream, record) {
- var i, from, to, bBox = readBBox(stream),
- numParts = readInteger(stream),
- numPoints = readInteger(stream),
- parts = readIntegerArray(stream, numParts),
- points = readPointArray(stream, numPoints),
- mBox = readPair(stream),
- mValues = readDoubleArray(stream, numPoints),
- rings = [];
- rings.length = numParts;
- for (i = 0; i < numParts; ++i) {
- from = parts[i];
- to = parts[i + 1] || numPoints;
- rings[i] = merge_XYM(points.slice(from, to), mValues.slice(from, to), to - from)
- }
- record.bBox = bBox;
- record.mBox = mBox;
- record.coordinates = rings
- }
- function readPointZShape(stream, record) {
- record.coordinates = readPointArray(stream, 1)[0];
- record.push(readDoubleArray(stream, 1)[0], readDoubleArray(stream, 1)[0])
- }
- function readMultiPointZShape(stream, record) {
- var bBox = readBBox(stream),
- numPoints = readInteger(stream),
- points = readPointArray(stream, numPoints),
- zBox = readPair(stream),
- zValues = readDoubleArray(stream, numPoints),
- mBox = readPair(stream),
- mValue = readDoubleArray(stream, numPoints);
- record.bBox = bBox;
- record.zBox = zBox;
- record.mBox = mBox;
- record.coordinates = merge_XYZM(points, zValues, mValue, numPoints)
- }
- function readPolyLineZShape(stream, record) {
- var i, from, to, bBox = readBBox(stream),
- numParts = readInteger(stream),
- numPoints = readInteger(stream),
- parts = readIntegerArray(stream, numParts),
- points = readPointArray(stream, numPoints),
- zBox = readPair(stream),
- zValues = readDoubleArray(stream, numPoints),
- mBox = readPair(stream),
- mValues = readDoubleArray(stream, numPoints),
- rings = [];
- rings.length = numParts;
- for (i = 0; i < numParts; ++i) {
- from = parts[i];
- to = parts[i + 1] || numPoints;
- rings[i] = merge_XYZM(points.slice(from, to), zValues.slice(from, to), mValues.slice(from, to), to - from)
- }
- record.bBox = bBox;
- record.zBox = zBox;
- record.mBox = mBox;
- record.coordinates = rings
- }
- function readMultiPatchShape(stream, record) {
- var i, from, to, bBox = readBBox(stream),
- numParts = readInteger(stream),
- numPoints = readInteger(stream),
- parts = readIntegerArray(stream, numParts),
- partTypes = readIntegerArray(stream, numParts),
- points = readPointArray(stream, numPoints),
- zBox = readPair(stream),
- zValues = readDoubleArray(stream, numPoints),
- mBox = readPair(stream),
- rings = [];
- rings.length = numParts;
- for (i = 0; i < numParts; ++i) {
- from = parts[i];
- to = parts[i + 1] || numPoints;
- rings[i] = merge_XYZM(points.slice(from, to), zValues.slice(from, to), mValues.slice(from, to), to - from)
- }
- record.bBox = bBox;
- record.zBox = zBox;
- record.mBox = mBox;
- record.types = partTypes;
- record.coordinates = rings
- }
- var SHP_TYPES = {
- 0: "Null",
- 1: "Point",
- 3: "PolyLine",
- 5: "Polygon",
- 8: "MultiPoint",
- 11: "PointZ",
- 13: "PolyLineZ",
- 15: "PolygonZ",
- 18: "MultiPointZ",
- 21: "PointM",
- 23: "PolyLineM",
- 25: "PolygonM",
- 28: "MultiPointM",
- 31: "MultiPatch"
- };
- var SHP_RECORD_PARSERS = {
- 0: noop,
- 1: readPointShape,
- 3: readPolyLineShape,
- 5: readPolyLineShape,
- 8: readMultiPointShape,
- 11: readPointZShape,
- 13: readPolyLineZShape,
- 15: readPolyLineZShape,
- 18: readMultiPointZShape,
- 21: readPointMShape,
- 23: readPolyLineMShape,
- 25: readPolyLineMShape,
- 28: readMultiPointMShape,
- 31: readMultiPatchShape
- };
- var SHP_TYPE_TO_GEOJSON_TYPE_MAP = {
- Null: "Null",
- Point: "Point",
- PolyLine: "MultiLineString",
- Polygon: "Polygon",
- MultiPoint: "MultiPoint",
- PointZ: "Point",
- PolyLineZ: "MultiLineString",
- PolygonZ: "Polygon",
- MultiPointZ: "MultiPoint",
- PointM: "Point",
- PolyLineM: "MultiLineString",
- PolygonM: "Polygon",
- MultiPointM: "MultiPoint",
- MultiPatch: "MultiPatch"
- };
- function parseShapeHeader(stream) {
- var header = {};
- header.fileCode = stream.ui32BE();
- stream.skip(20);
- header.fileLength = stream.ui32BE() << 1;
- header.version = stream.ui32LE();
- header.type_number = stream.ui32LE();
- header.type = SHP_TYPES[header.type_number];
- header.bBox_XY = readBBox(stream);
- header.bBox_ZM = readPointArray(stream, 2);
- return header
- }
- function readInteger(stream) {
- return stream.ui32LE()
- }
- function readIntegerArray(stream, length) {
- var i, array = [];
- array.length = length;
- for (i = 0; i < length; ++i) {
- array[i] = readInteger(stream)
- }
- return array
- }
- function readDoubleArray(stream, length) {
- var i, array = [];
- array.length = length;
- for (i = 0; i < length; ++i) {
- array[i] = stream.f64LE()
- }
- return array
- }
- function readBBox(stream) {
- return readDoubleArray(stream, 4)
- }
- function readPair(stream) {
- return [stream.f64LE(), stream.f64LE()]
- }
- function readPointArray(stream, count) {
- var i, points = [];
- points.length = count;
- for (i = 0; i < count; ++i) {
- points[i] = readPair(stream)
- }
- return points
- }
- function merge_XYM(xy, m, length) {
- var i, array = [];
- array.length = length;
- for (i = 0; i < length; ++i) {
- array[i] = [xy[i][0], xy[i][1], m[i]]
- }
- return array
- }
- function merge_XYZM(xy, z, m, length) {
- var i, array = [];
- array.length = length;
- for (i = 0; i < length; ++i) {
- array[i] = [xy[i][0], xy[i][1], z[i], m[i]]
- }
- return array
- }
- function parseShapeRecord(stream, generalType, errors) {
- var record = {
- number: stream.ui32BE()
- },
- length = stream.ui32BE() << 1,
- pos = stream.pos(),
- type = stream.ui32LE();
- record.type_number = type;
- record.type = SHP_TYPES[type];
- record.geoJSON_type = SHP_TYPE_TO_GEOJSON_TYPE_MAP[record.type];
- if (record.type) {
- if (record.type !== generalType) {
- errors.push("shp: shape #" + record.number + " type: " + record.type + " / expected: " + generalType)
- }
- SHP_RECORD_PARSERS[type](stream, record);
- pos = stream.pos() - pos;
- if (pos !== length) {
- errors.push("shp: shape #" + record.number + " length: " + length + " / actual: " + pos)
- }
- } else {
- errors.push("shp: shape #" + record.number + " type: " + type + " / unknown");
- record = null
- }
- return record
- }
- function parseDBF(stream, errors) {
- var timeStart, timeEnd, header, parseData, records;
- try {
- timeStart = new Date;
- header = parseDataBaseFileHeader(stream, errors);
- parseData = prepareDataBaseFileRecordParseData(header, errors);
- records = parseDataBaseFileRecords(stream, header.numberOfRecords, header.recordLength, parseData, errors);
- timeEnd = new Date
- } catch (e) {
- errors.push("dbf: parsing error: " + e.message + " / " + e.description)
- }
- return {
- records: records,
- errors: errors,
- time: timeEnd - timeStart
- }
- }
- function parseDataBaseFileHeader(stream, errors) {
- var i, term, header = {
- versionNumber: stream.ui8(),
- lastUpdate: new Date(1900 + stream.ui8(), stream.ui8() - 1, stream.ui8()),
- numberOfRecords: stream.ui32LE(),
- headerLength: stream.ui16LE(),
- recordLength: stream.ui16LE(),
- fields: []
- };
- stream.skip(20);
- for (i = (header.headerLength - stream.pos() - 1) / 32; i > 0; --i) {
- header.fields.push(parseFieldDescriptor(stream))
- }
- term = stream.ui8();
- if (13 !== term) {
- errors.push("dbf: header terminator: " + term + " / expected: 13")
- }
- return header
- }
- var _fromCharCode = String.fromCharCode;
- function getAsciiString(stream, length) {
- return _fromCharCode.apply(null, stream.ui8arr(length))
- }
- function parseFieldDescriptor(stream) {
- var desc = {
- name: getAsciiString(stream, 11).replace(/\0*$/gi, ""),
- type: _fromCharCode(stream.ui8()),
- length: stream.skip(4).ui8(),
- count: stream.ui8()
- };
- stream.skip(14);
- return desc
- }
- var DBF_FIELD_PARSERS = {
- C: function(stream, length) {
- var str = getAsciiString(stream, length);
- try {
- str = decodeURIComponent(escape(str))
- } catch (e) {}
- return str.trim()
- },
- N: function(stream, length) {
- var str = getAsciiString(stream, length);
- return parseFloat(str, 10)
- },
- D: function(stream, length) {
- var str = getAsciiString(stream, length);
- return new Date(str.substring(0, 4), str.substring(4, 6) - 1, str.substring(6, 8))
- }
- };
- function DBF_FIELD_PARSER_DEFAULT(stream, length) {
- stream.skip(length);
- return null
- }
- function prepareDataBaseFileRecordParseData(header, errors) {
- var item, field, list = [],
- i = 0,
- ii = header.fields.length,
- totalLength = 0;
- for (i = 0; i < ii; ++i) {
- field = header.fields[i];
- item = {
- name: field.name,
- parser: DBF_FIELD_PARSERS[field.type],
- length: field.length
- };
- if (!item.parser) {
- item.parser = DBF_FIELD_PARSER_DEFAULT;
- errors.push("dbf: field " + field.name + " type: " + field.type + " / unknown")
- }
- totalLength += field.length;
- list.push(item)
- }
- if (totalLength + 1 !== header.recordLength) {
- errors.push("dbf: record length: " + header.recordLength + " / actual: " + (totalLength + 1))
- }
- return list
- }
- function parseDataBaseFileRecords(stream, recordCount, recordLength, parseData, errors) {
- var i, j, pos, record, pd, jj = parseData.length,
- records = [];
- for (i = 0; i < recordCount; ++i) {
- record = {};
- pos = stream.pos();
- stream.skip(1);
- for (j = 0; j < jj; ++j) {
- pd = parseData[j];
- record[pd.name] = pd.parser(stream, pd.length)
- }
- pos = stream.pos() - pos;
- if (pos !== recordLength) {
- errors.push("dbf: record #" + (i + 1) + " length: " + recordLength + " / actual: " + pos)
- }
- records.push(record)
- }
- return records
- }
- function wrapBuffer(arrayBuffer) {
- return new DataView(arrayBuffer)
- }
- function ui8(stream, position) {
- return stream.getUint8(position)
- }
- function ui16LE(stream, position) {
- return stream.getUint16(position, true)
- }
- function ui32LE(stream, position) {
- return stream.getUint32(position, true)
- }
- function ui32BE(stream, position) {
- return stream.getUint32(position, false)
- }
- function f64LE(stream, position) {
- return stream.getFloat64(position, true)
- }
- function sendRequest(url, callback) {
- var request = new XMLHttpRequest;
- request.addEventListener("load", function() {
- callback(this.response ? null : this.statusText, this.response)
- });
- request.open("GET", url);
- request.responseType = "arraybuffer";
- request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- request.send(null)
- }
- });
|