UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

202 lines (171 loc) 6.92 kB
/* global itowns, Promise */ /** * A module to parse OGR Virtual Format files. * * See the [GDAL documentation](https://gdal.org/drivers/vector/vrt.html) and * the [xsd * schema](https://github.com/OSGeo/gdal/blob/master/gdal/data/ogrvrt.xsd) of * the OGR VRT file. * * It is highly recommended to use the [Papa Parse](https://www.papaparse.com/) * parser to parse the CSV content before feeding it to this parser. * * @example * Fetcher.multi('data', { * xml: ['vrt'], * text: ['csv'] * }).then(function _(res) { * res.csv = Papa.parse(res.csv.trim()).data; * return CSVnVRTParser.parse(res, { out: { * buildExtent: true, * crs: 'EPSG:4326' * } * }); * }).then(function _(features) { * var source = new itowns.FileSource({ features }); * var layer = new itowns.ColorLayer('CSVnVRT', { source }); * view.addLayer(layer); * }); * * @module CSVnVRTParser */ var CSVnVRTParser = (function _() { var coord = new itowns.Coordinates('EPSG:4326'); var header; function xml2json(xml, json) { var res = {}; var attributes = xml.getAttributeNames(); if (attributes.length > 0) { res['@attributes'] = {}; for (var i = 0; i < attributes.length; i++) { res['@attributes'][attributes[i]] = xml.getAttributeNode(attributes[i]).value; } } if (xml.childElementCount > 0) { for (var j = 0; j < xml.childElementCount; j++) { xml2json(xml.children[j], res); } } else if (xml.textContent) { res.value = xml.textContent; } var name = xml.nodeName; if (!json[name]) { json[name] = res; } else if (json[name].length > 0) { json[name].push(res); } else { json[name] = [res]; } return json; } function getGeometryType(type) { switch (type) { case 'wkbPoint': case 'wkbMultiPoint': return itowns.FEATURE_TYPES.POINT; case 'wkbLineString': case 'wkbMultiLineString': return itowns.FEATURE_TYPES.LINE; case 'wkbPolygon': case 'wkbMultiPolygon': return itowns.FEATURE_TYPES.POLYGON; default: throw new Error('This type of GeometryType is not supported yet: ' + type); } } function OGRVRTLayer2Feature(layer, data, crs, options) { var collection = new itowns.FeatureCollection(options.out); var _crs = (layer.LayerSRS && layer.LayerSRS.value) || crs; var type = itowns.FEATURE_TYPES.POINT; if (layer.GeometryType) { type = getGeometryType(layer.GeometryType.value); } var feature = collection.requestFeatureByType(type); if (layer.Field) { if (!layer.Field.length) { layer.Field = [layer.Field]; } for (var f = 0; f < layer.Field.length; f++) { layer.Field[f]['@attributes'].pos = header.indexOf(layer.Field[f]['@attributes'].src); } } if (layer.GeometryField) { switch (layer.GeometryField['@attributes'].encoding) { case 'PointFromColumns': var x = header.indexOf(layer.GeometryField['@attributes'].x); var y = header.indexOf(layer.GeometryField['@attributes'].y); var z = header.indexOf(layer.GeometryField['@attributes'].z); // var m = header.indexOf(layer.GeometryField['@attributes'].m); var line; for (var i = 0; i < data.length; i++) { line = data[i]; var geometry = feature.bindNewGeometry(); if (layer.Field) { for (var p = 0; p < layer.Field.length; p++) { geometry.properties[layer.Field[p]['@attributes'].name] = line[layer.Field[p]['@attributes'].pos]; } } geometry.startSubGeometry(1, feature); coord.crs = (layer.GeometryField.SRS && layer.GeometryField.SRS.value) || _crs; coord.setFromValues(Number(line[x]), Number(line[y]), Number(line[z]) || 0); geometry.pushCoordinates(coord, feature); geometry.updateExtent(); feature.updateExtent(geometry); } break; case undefined: break; default: throw new Error('This type of encoding is not supported yet: ' + layer.GeometryField['@attributes'].encoding); } } collection.updateExtent(); return collection; } // eslint-disable-next-line no-unused-vars function OGRVRTWarpedLayer2Feature(layer, data, options, crs) { throw new Error('not supported yet'); } // eslint-disable-next-line no-unused-vars function OGRVRTUnionLayer2Feature(layer, data, options, crs) { throw new Error('not supported yet'); } function readLayer(layer, data, options, crs) { if (layer.OGRVRTLayer) { return OGRVRTLayer2Feature(layer.OGRVRTLayer, data, layer.TargetSRS.value, options); } else if (layer.OGRVRTWarpedLayer) { return OGRVRTWarpedLayer2Feature(layer, data, options, crs); } else if (layer.OGRVRTUnionLayer) { return OGRVRTUnionLayer2Feature(layer, data, options, crs); } } return { /** * Parse a CSV associated to a VRT and return a {@link * FeatureCollection}. * * @param {Object} data - The data needed. * @param {string} data.csv - Data from the CSV, with values separated * by comma, semicolon or tabulation. * @param {Document} data.vrt - The OGR VRT file, describing the CSV. * @param {geojsonParserOptions} [options] * * @return {Promise} A promise resolving with a [FeatureCollection]{@link * module:GeoJsonParser~FeatureCollection}. * * @memberof module:CSVnVRTParser */ parse: function _(data, options) { if (!data.csv || !data.vrt) { throw new Error('Missing files when parsing'); } var schema = xml2json(data.vrt.children[0], {}); header = data.csv.shift(); var collection = readLayer(schema.OGRVRTDataSource, data.csv, options); return Promise.resolve(collection); }, }; }()); if (typeof module != 'undefined' && module.exports) { module.exports = CSVnVRTParser; }