terriajs
Version:
Geospatial data visualization platform.
109 lines (96 loc) • 3.18 kB
text/typescript
import JsonValue, {
assertNumber,
assertObject,
assertString
} from "../../Core/Json";
import EnumIndex, { EnumValue } from "./EnumIndex";
import NumericIndex from "./NumericIndex";
import TextIndex from "./TextIndex";
import { IndexType, indexTypes } from "./Types";
export { IndexType, indexTypes } from "./Types";
export { default as EnumIndex } from "./EnumIndex";
export { default as NumericIndex } from "./NumericIndex";
// IndexRoot holds the indexes for each property and top level options
export type IndexRoot = {
resultsDataUrl: string; // Url of the CSV data file.
idProperty: string; // Name of the property to be used as ID
indexes: Record<string, Index>; // A map from property name to its `Index` definition.
};
export type Index = NumericIndex | EnumIndex | TextIndex;
export type ID = number;
const indexParsers: Record<IndexType, (json: any) => Index> = {
numeric: parseNumericIndex,
enum: parseEnumIndex,
text: parseTextIndex
};
export function parseIndexRoot(json: JsonValue): IndexRoot {
assertObject(json, "IndexRoot");
assertString(json.resultsDataUrl, "resultsDataUrl");
assertString(json.idProperty, "idProperty");
assertObject(json.indexes, "indexes");
const indexes: Record<string, Index> = Object.entries(json.indexes).reduce(
(indexes: Record<string, Index>, [property, index]) => {
indexes[property] = parseIndex(index);
return indexes;
},
{}
);
return {
resultsDataUrl: json.resultsDataUrl,
idProperty: json.idProperty,
indexes
};
}
export function parseIndexType(json: JsonValue): IndexType {
assertString(json, "IndexType");
if (indexTypes.includes(json)) return json as IndexType;
throw new Error(
`Expected index type to be ${indexTypes.join("|")}, got ${json}`
);
}
function parseIndex(json: JsonValue): Index {
assertObject(json, "Index");
assertString(json.type, "type");
const parser = indexParsers[json.type as IndexType];
if (parser) return parser(json);
throw new Error(
`Expected index type to be ${indexTypes.join("|")}, got ${json.type}`
);
}
function parseNumericIndex(json: JsonValue): NumericIndex {
assertObject(json, "NumericIndex");
assertObject(json.range, "range");
assertNumber(json.range.max, "range.max");
assertNumber(json.range.min, "range.min");
assertString(json.url, "url");
return new NumericIndex(json.url, {
min: json.range.min,
max: json.range.max
});
}
function parseEnumIndex(json: JsonValue): EnumIndex {
assertObject(json, "EnumIndex");
assertObject(json.values);
const values: Record<string, EnumValue> = Object.entries(json.values).reduce(
(values: Record<string, EnumValue>, [id, value]) => {
values[id] = parseEnumValue(value);
return values;
},
{}
);
return new EnumIndex(values);
}
function parseEnumValue(json: JsonValue): EnumValue {
assertObject(json, "EnumValue");
assertNumber(json.count);
assertString(json.url);
return {
count: json.count,
url: json.url
};
}
function parseTextIndex(json: JsonValue): TextIndex {
assertObject(json, "EnumIndex");
assertString(json.url);
return new TextIndex(json.url);
}