Coverage for pyguymer3/geo/_buffer_points_crudely.py: 6%

17 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def _buffer_points_crudely( 

5 points1, 

6 dist, 

7 nAng, 

8 /, 

9 *, 

10 eps = 1.0e-12, 

11 nIter = 100, 

12 ramLimit = 1073741824, 

13): 

14 """Buffer some points 

15 

16 This function reads in an array of coordinates (in degrees) that exist on 

17 the surface of the Earth and returns an array of coordinates that are the 

18 rings around the input coordinates buffered by a constant distance (in 

19 metres). 

20 

21 Parameters 

22 ---------- 

23 points1 : numpy.ndarray 

24 the (npoint, 2) array of (lon,lat) coordinates (in degrees) 

25 dist : float 

26 the distance to buffer the (lon,lat) coordinates by (in metres) 

27 nAng : int 

28 the number of angles around the (lon,lat) coordinates that are 

29 calculated when buffering (must be odd; must be ≥ 9) 

30 eps : float, optional 

31 the tolerance of the Vincenty formula iterations 

32 nIter : int, optional 

33 the maximum number of iterations (particularly the Vincenty formula) 

34 ramLimit : int, optional 

35 the maximum RAM usage of each "large" array (in bytes) 

36 

37 Returns 

38 ------- 

39 points2 : numpy.ndarray 

40 the (npoint, nAng, 2) array of (lon,lat) coordinates around the 

41 (lon,lat) coordinates (in degrees) 

42 

43 Notes 

44 ----- 

45 Copyright 2017 Thomas Guymer [1]_ 

46 

47 References 

48 ---------- 

49 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

50 """ 

51 

52 # Import special modules ... 

53 try: 

54 import numpy 

55 except: 

56 raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None 

57 

58 # Import sub-functions ... 

59 from .calc_loc_from_loc_and_bearing_and_dist import calc_loc_from_loc_and_bearing_and_dist 

60 

61 # ************************************************************************** 

62 

63 # Create short-hand ... 

64 npoint = int(points1.shape[0]) # [#] 

65 

66 # Check array size ... 

67 if npoint * nAng * 2 * 8 > ramLimit: 

68 raise Exception(f"\"points2\" is going to be {npoint * nAng * 2 * 8:,d} bytes, which is larger than {ramLimit:,d} bytes") from None 

69 

70 # Initialize array ... 

71 points2 = numpy.zeros((npoint, nAng, 2), dtype = numpy.float64) # [°] 

72 

73 # Loop over angles ... 

74 # NOTE: The first and last angles will *always* be exactly North (therefore, 

75 # use that as a check later on). 

76 # NOTE: The middle angle will *always* be exactly South (therefore, use that 

77 # as a check later on). 

78 # NOTE: The most two subsequent points can be apart is ~45° (with nAng ≥ 9). 

79 for iang in range(nAng - 1): 

80 # Calculate initial angle ... 

81 ang1 = 360.0 * float(nAng - 1 - iang) / float(nAng - 1) # [°] 

82 

83 # Loop over points ... 

84 for ipoint in range(npoint): 

85 # Calculate the ring coordinates and add them to the array ... 

86 points2[ipoint, iang, 0], points2[ipoint, iang, 1], _ = calc_loc_from_loc_and_bearing_and_dist( 

87 points1[ipoint, 0], 

88 points1[ipoint, 1], 

89 ang1 % 360.0, 

90 dist, 

91 eps = eps, 

92 nIter = nIter, 

93 ) # [°], [°] 

94 

95 # Loop over points ... 

96 for ipoint in range(npoint): 

97 # Force the last point to be the same as the first point ... 

98 points2[ipoint, -1, :] = points2[ipoint, 0, :] # [°] 

99 

100 # Return answer ... 

101 return points2