Skip to content

Commit 6dc355a

Browse files
Merge pull request #548 from ReliefApplications/feat/AB#58618_Move_all_GIS_random_generation_to_the_back_end
Feat/ab#58618 move all gis random generation to the back end
2 parents 7bbd45b + b1a8ec0 commit 6dc355a

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// import { getRandomIcon } from '../const/fa-icons';
2+
// import { MarkerIconOptions } from '../utils/create-div-icon';
3+
4+
/** Represents the types of geometries that can be generated */
5+
type FeatureTypes = 'Point' | 'Polygon' | 'LineString';
6+
7+
/** Options for generating random features */
8+
type CollectionGeneratorOptions = {
9+
[key in FeatureTypes]?: {
10+
generateProperties: () => any;
11+
probability?: number;
12+
numCoordinates?: number;
13+
maxDistance?: number;
14+
minDistance?: number;
15+
};
16+
} & {
17+
numFeatures: number;
18+
};
19+
20+
/** Default max distance in degrees */
21+
const DEFAULT_MAX_DISTANCE = 15;
22+
23+
/** Default min distance in degrees */
24+
const DEFAULT_MIN_DISTANCE = 5;
25+
26+
/**
27+
* Returns a random item from the given options based on the weights provided.
28+
*
29+
* @param options - Array of options to choose from
30+
* @param weights - Array of weights for each option
31+
* @returns The randomly selected item from the options array
32+
*/
33+
const weightedRandom = (
34+
options: FeatureTypes[],
35+
weights: { [key in FeatureTypes]: number }
36+
) => {
37+
let sum = 0;
38+
const keys = Object.keys(weights) as FeatureTypes[];
39+
for (const key of keys) {
40+
sum += weights[key];
41+
}
42+
43+
const randomNum = Math.random() * sum;
44+
let weightSum = 0;
45+
for (const key of options) {
46+
weightSum += weights[key];
47+
if (randomNum <= weightSum) {
48+
return key;
49+
}
50+
}
51+
return options[options.length - 1];
52+
};
53+
54+
/**
55+
* Generates random features based on the specified options
56+
*
57+
* @param options Options for generating random features
58+
* @returns Array of generated features
59+
*/
60+
export const generateGeoJson = (options: CollectionGeneratorOptions) => {
61+
const featureTypes = Object.keys(options) as FeatureTypes[];
62+
const typeProbabilities = featureTypes.reduce((probabilities, type) => {
63+
const prob = options[type]?.probability;
64+
if (prob !== undefined) {
65+
probabilities[type] = prob;
66+
}
67+
return probabilities;
68+
}, {} as { [key in FeatureTypes]: number });
69+
70+
const features = [];
71+
for (let i = 0; i < options.numFeatures; i++) {
72+
const type = weightedRandom(featureTypes, typeProbabilities);
73+
const option = options[type];
74+
if (!option) continue;
75+
const properties = option.generateProperties();
76+
const maxDistance = option.maxDistance || DEFAULT_MAX_DISTANCE;
77+
const minDistance = option.minDistance || DEFAULT_MIN_DISTANCE;
78+
let coordinates;
79+
switch (type) {
80+
case 'Point':
81+
coordinates = [Math.random() * 360 - 180, Math.random() * 180 - 90];
82+
break;
83+
case 'Polygon':
84+
case 'LineString':
85+
const numCoordinates = options[type]?.numCoordinates || 3;
86+
coordinates = [];
87+
let previousLat = 0;
88+
let previousLng = 0;
89+
for (let j = 0; j < numCoordinates; j++) {
90+
let lat = Math.random() * 180 - 90;
91+
let lng = Math.random() * 360 - 180;
92+
if (j !== 0) {
93+
let latDifference = Math.abs(previousLat - lat);
94+
let lngDifference = Math.abs(previousLng - lng);
95+
while (
96+
latDifference > maxDistance ||
97+
lngDifference > maxDistance ||
98+
latDifference < minDistance ||
99+
lngDifference < minDistance
100+
) {
101+
lat = Math.random() * 180 - 90;
102+
lng = Math.random() * 360 - 180;
103+
latDifference = Math.abs(previousLat - lat);
104+
lngDifference = Math.abs(previousLng - lng);
105+
}
106+
}
107+
previousLat = lat;
108+
previousLng = lng;
109+
coordinates.push([lat, lng]);
110+
}
111+
if (type === 'Polygon') {
112+
coordinates = [coordinates];
113+
}
114+
break;
115+
}
116+
features.push({ type, properties, coordinates });
117+
}
118+
return features;
119+
};

0 commit comments

Comments
 (0)