1
- import seedrandom from 'seedrandom' ;
2
-
3
-
4
1
/**
5
2
* Generates a random point coordinate within a given polygon.
6
3
*
7
4
* @param {Array } polygon - An array of coordinate arrays representing the polygon.
8
5
* @param {number } index - An index to differentiate points for polygons with similar coordinates.
9
6
* @returns {Array } The random point coordinate [longitude, latitude].
10
7
*/
11
- export const getRandomPointInPolygon = ( polygon , index ) => {
8
+ export const getRandomPointInPolygon = ( polygon ) => {
12
9
// Calculate the bounding box of the polygon
13
10
const bounds = polygon . reduce (
14
11
( prev , curr ) => {
@@ -23,45 +20,39 @@ export const getRandomPointInPolygon = (polygon, index) => {
23
20
{ minLon : Infinity , maxLon : - Infinity , minLat : Infinity , maxLat : - Infinity }
24
21
) ;
25
22
26
- // Create a seed based on the polygon's coordinates and the index
27
- const seed = JSON . stringify ( polygon ) + index ;
28
- const rng = seedrandom ( seed ) ;
29
-
30
- // Generate a random point within the bounding box
31
- let randomPoint ;
32
- let isInPolygon = false ;
33
- while ( ! isInPolygon ) {
34
- const lon = bounds . minLon + rng ( ) * ( bounds . maxLon - bounds . minLon ) ;
35
- const lat = bounds . minLat + rng ( ) * ( bounds . maxLat - bounds . minLat ) ;
36
- randomPoint = [ lon , lat ] ;
37
-
38
- // Check if the random point is within the polygon
39
- isInPolygon = isPointInPolygon ( randomPoint , polygon ) ;
23
+ // Helper function to check if a point is inside the polygon
24
+ const isPointInPolygon = ( point , polygon ) => {
25
+ let inside = false ;
26
+ for ( let i = 0 , j = polygon . length - 1 ; i < polygon . length ; j = i ++ ) {
27
+ const xi = polygon [ i ] [ 0 ] , yi = polygon [ i ] [ 1 ] ;
28
+ const xj = polygon [ j ] [ 0 ] , yj = polygon [ j ] [ 1 ] ;
29
+
30
+ const intersect = ( ( yi > point [ 1 ] ) !== ( yj > point [ 1 ] ) )
31
+ && ( point [ 0 ] < ( xj - xi ) * ( point [ 1 ] - yi ) / ( yj - yi ) + xi ) ;
32
+ if ( intersect ) inside = ! inside ;
33
+ }
34
+ return inside ;
35
+ } ;
36
+
37
+ // Generate random points until we find one inside the polygon
38
+ let attempts = 0 ;
39
+ const maxAttempts = 1000 ; // Prevent infinite loop
40
+
41
+ while ( attempts < maxAttempts ) {
42
+ const randomLon = bounds . minLon + Math . random ( ) * ( bounds . maxLon - bounds . minLon ) ;
43
+ const randomLat = bounds . minLat + Math . random ( ) * ( bounds . maxLat - bounds . minLat ) ;
44
+
45
+ if ( isPointInPolygon ( [ randomLon , randomLat ] , polygon ) ) {
46
+ return [ randomLon , randomLat , 0 ] ; // Adding 0 for elevation to match input format
47
+ }
48
+
49
+ attempts ++ ;
40
50
}
41
-
42
- return randomPoint ;
51
+
52
+ // If we couldn't find a point after max attempts, return center of bounding box
53
+ return [
54
+ ( bounds . minLon + bounds . maxLon ) / 2 ,
55
+ ( bounds . minLat + bounds . maxLat ) / 2 ,
56
+ 0
57
+ ] ;
43
58
} ;
44
-
45
- /**
46
- * Checks if a point is within a given polygon.
47
- *
48
- * @param {Array } point - The point coordinate [longitude, latitude].
49
- * @param {Array } polygon - An array of coordinate arrays representing the polygon.
50
- * @returns {boolean } True if the point is within the polygon, false otherwise.
51
- */
52
- function isPointInPolygon ( point , polygon ) {
53
- const [ x , y ] = point ;
54
- let isInside = false ;
55
-
56
- for ( let i = 0 , j = polygon . length - 1 ; i < polygon . length ; j = i ++ ) {
57
- const [ x1 , y1 ] = polygon [ i ] ;
58
- const [ x2 , y2 ] = polygon [ j ] ;
59
-
60
- const intersect =
61
- y1 > y !== y2 > y && x < ( ( x2 - x1 ) * ( y - y1 ) ) / ( y2 - y1 ) + x1 ;
62
-
63
- if ( intersect ) isInside = ! isInside ;
64
- }
65
-
66
- return isInside ;
67
- }
0 commit comments