-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
index.ts
140 lines (118 loc) · 3.48 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
function formatName(name: string) {
if(!name) throw new Error("missing parameter for formatName");
return name
.replace(/ /g, "_")
.replace(/\./g, "")
.replace(/&/g, "and")
.toLowerCase();
}
const AREA_PATH = "./areas";
const STATE_PATH = "./states";
const COUNTRY_PATH = "./countries";
//retrieve json country Code
type GeoJsonFeature = {
type: string;
properties: { [key: string]: any };
geometry: {
type: string;
coordinates: any[];
};
};
const GEOJSON_BASE: { type: string, features: GeoJsonFeature[] } = {
type: 'FeatureCollection',
features: [],
};
function requireFile(filePath: string) {
try {
return require(`${filePath}.json`);
} catch (e) {
// @ts-ignore
if (e.code !== "MODULE_NOT_FOUND") throw e;
return null;
}
}
/**
* Type definition for the parameters to generate a GeoJSON.
* @param {string} countryName
* @param {string} stateName
* @param {string} areaName
* @param {Object} properties
* @return {Object}
*
*/
export type geoParamsType = {
countryName: string,
countryCode?: string,
stateName?: string,
areaName?: string,
properties?: {
[key: string]: any
},
}
/**
* Generates a GeoJSON based on the given parameters.
* @param params - Parameters to generate the GeoJSON.
* @returns The generated GeoJSON.
*/
function getGeoJsonFromParams(params: geoParamsType) {
//countryName is required
if (!params.countryName && !params.countryCode) {
throw new Error("countryName or countryCode is required");
} else if (!params.countryName && params.countryCode) {
//check if countryCode is valid, must be 2 letters
if (params.countryCode.length !== 2) {
throw new Error("countryCode must be 2 letters");
}
}
let filePath: string;
if (params.countryName && params.areaName){
filePath = `${AREA_PATH}/${formatName(params.countryName)}/${formatName(params.areaName)}`;
} else if (params.countryName && params.stateName){
filePath = `${STATE_PATH}/${formatName(params.countryName)}/${formatName(params.stateName)}`;
} else{
filePath = `${COUNTRY_PATH}/${formatName(params.countryName)}`;
}
const geoJson = requireFile(filePath);
// Add properties to the GeoJSON
if (geoJson && geoJson.features) {
geoJson.features.forEach((feature: { properties: any }) => {
if (params.properties) {
feature.properties = {
...feature.properties,
...params.properties,
};
}
});
}
return geoJson;
}
/**
* Combines multiple GeoJSONs into a single one.
* @param paramsArray - An array of parameters to generate multiple GeoJSONs.
* @returns The combined GeoJSON.
*/
function combineGeoJson(paramsArray: geoParamsType[]) {
const combinedGeoJson = { ...GEOJSON_BASE };
paramsArray.forEach(params => {
const geoJson = getGeoJsonFromParams(params);
if (geoJson && geoJson.features) {
combinedGeoJson.features.push(...geoJson.features);
}
});
return combinedGeoJson;
}
function forCountry(countryName: string) {
return requireFile(`./countries/${formatName(countryName)}`)
}
function forArea(countryName:string, areaName:string) {
return requireFile(`./areas/${formatName(countryName)}/${formatName(areaName)}`)
}
function forState(countryName:string, stateName:string) {
return requireFile(`./states/${formatName(countryName)}/${formatName(stateName)}`)
}
export {
combineGeoJson,
forCountry,
forState,
forArea,
};