Skip to content

Commit 5e5ae2c

Browse files
committed
support parsing CSV with position column
1 parent 2bba71f commit 5e5ae2c

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

src/parseData.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
} from 'geojson';
1313
import Papa from 'papaparse';
1414
import { kml } from './togeojson';
15+
import { decodeCoord } from './util';
1516

1617
const readFile = (f: Blob): Promise<string> =>
1718
new Promise((resolve, reject) => {
@@ -40,15 +41,30 @@ const NUMERIC_RE = /^-?[0-9]+(:?\.[0-9]+)?$/;
4041

4142
const isNumeric = (s: string) => NUMERIC_RE.test(s.trim());
4243

44+
type RowParser = (row: Record<string, string>) => Feature<Point>;
45+
46+
const parseWithLatLng =
47+
(latCol: string, lngCol: string): RowParser =>
48+
(row: Record<string, string>) => {
49+
const { [latCol]: lat, [lngCol]: lng, ...rest } = row;
50+
return point([Number(lng), Number(lat)], rest);
51+
};
52+
53+
const parseWithPos =
54+
(posCol: string): RowParser =>
55+
(row: Record<string, string>) => {
56+
const { [posCol]: pos, ...rest } = row;
57+
return feature(decodeCoord(pos), rest);
58+
};
59+
4360
const parseCsv = (csv: string) => {
4461
const firstRowResult = Papa.parse<string[]>(csv, {
4562
preview: 1,
4663
skipEmptyLines: true,
4764
worker: false,
4865
download: false,
4966
});
50-
let latCol: string;
51-
let lngCol: string;
67+
let parser: RowParser;
5268
let finalCsv: string;
5369
if (firstRowResult.data.length === 0) {
5470
throw new Error('Empty CSV File');
@@ -58,17 +74,19 @@ const parseCsv = (csv: string) => {
5874
isNumeric(firstRowResult.data[0][1])
5975
) {
6076
// special case for https://tpg.scottytremaine.uk/ exports
61-
latCol = 'lat';
62-
lngCol = 'lng';
77+
parser = parseWithLatLng('lat', 'lng');
6378
finalCsv = 'lat,lng,Label,Image\n' + csv;
6479
} else {
6580
const maybeLatCol = firstRowResult.data[0].find((col) => /lat/i.test(col));
6681
const maybeLngCol = firstRowResult.data[0].find((col) =>
6782
/lon|lng/i.test(col)
6883
);
84+
const maybePosCol = firstRowResult.data[0].find((col) => /^pos/i.test(col));
6985
if (maybeLatCol && maybeLngCol) {
70-
latCol = maybeLatCol;
71-
lngCol = maybeLngCol;
86+
parser = parseWithLatLng(maybeLatCol, maybeLngCol);
87+
finalCsv = csv;
88+
} else if (maybePosCol) {
89+
parser = parseWithPos(maybePosCol);
7290
finalCsv = csv;
7391
} else {
7492
throw new Error('CSV must contain latitude & longitude columns');
@@ -81,12 +99,7 @@ const parseCsv = (csv: string) => {
8199
skipEmptyLines: true,
82100
});
83101

84-
return featureCollection(
85-
result.data.map((row) => {
86-
const { [latCol]: lat, [lngCol]: lng, ...rest } = row;
87-
return point([Number(lng), Number(lat)], rest);
88-
})
89-
);
102+
return featureCollection(result.data.map(parser));
90103
};
91104

92105
const isJson = (data: string, type: string) =>

0 commit comments

Comments
 (0)