-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_user_mapping.py
More file actions
115 lines (88 loc) · 5.65 KB
/
make_user_mapping.py
File metadata and controls
115 lines (88 loc) · 5.65 KB
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
"""
%┏━┓┏━┓┏━━━┓┏┓┏━┓┏━━━┓━━━━┏┓━┏┓┏━━━┓┏━━━┓┏━━━┓━━━━┏━┓┏━┓┏━━━┓┏━━━┓
?┃┃┗┛┃┃┃┏━┓┃┃┃┃┏┛┃┏━━┛━━━━┃┃━┃┃┃┏━┓┃┃┏━━┛┃┏━┓┃━━━━┃┃┗┛┃┃┃┏━┓┃┃┏━┓┃
%┃┏┓┏┓┃┃┃━┃┃┃┗┛┛━┃┗━━┓━━━━┃┃━┃┃┃┗━━┓┃┗━━┓┃┗━┛┃━━━━┃┏┓┏┓┃┃┃━┃┃┃┗━┛┃
?┃┃┃┃┃┃┃┗━┛┃┃┏┓┃━┃┏━━┛━━━━┃┃━┃┃┗━━┓┃┃┏━━┛┃┏┓┏┛━━━━┃┃┃┃┃┃┃┗━┛┃┃┏━━┛
%┃┃┃┃┃┃┃┏━┓┃┃┃┃┗┓┃┗━━┓━━━━┃┗━┛┃┃┗━┛┃┃┗━━┓┃┃┃┗┓━━━━┃┃┃┃┃┃┃┏━┓┃┃┃━━━
?┗┛┗┛┗┛┗┛━┗┛┗┛┗━┛┗━━━┛━━━━┗━━━┛┗━━━┛┗━━━┛┗┛┗━┛━━━━┗┛┗┛┗┛┗┛━┗┛┗┛━━━
%━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
?━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
This script generates the user mapping based on demand points and radio units from the dataset.
It uses the Haversine formula to determine if users are within range of radio units and assigns them accordingly. The output is saved as a JSON file in the dataset directory.
If an RU's coverage radius is changed, this script must be run again to update the user mapping. The file made tells the script whether a user is within range of a radio unit and which radio units they could be assigned to.
Example usage:
python make_user_mapping.py
This will generate the user mapping and save it to a JSON file in the dataset directory.
"""
import json, os, math, random
# Set the dataset you want to use, being either "small-dataset" or "full-dataset"
dataset = "small-dataset"
# Set base directory for data files
current_dir = os.path.dirname(os.path.abspath(__file__)) # scripts/
base_dir = os.path.dirname(current_dir) # project root
scenario = os.path.join(base_dir, "dataset", dataset) # dataset directory
def load_json_data(file_name):
"""Load JSON data from a specified file."""
with open(file_name, 'r') as file:
return json.load(file)
def load_all_data():
"""Load all necessary JSON data from the dataset directory."""
file_paths = {
"radio_units": os.path.join(scenario, "radio_units.json"),
"demand_points": os.path.join(scenario, "demand_points.json")
}
data = {}
for key, path in file_paths.items():
data[key] = load_json_data(path)
return data
def is_within_range(lat1, lon1, lat2, lon2, radius, margin=0):
"""Calculate the distance between two points on the Earth specified in decimal degrees and check if it is within the specified radius plus a margin."""
R = 6371e3 # Earth radius in metres
phi1 = math.radians(lat1)
phi2 = math.radians(lat2)
delta_phi = math.radians(lat2 - lat1)
delta_lambda = math.radians(lon2 - lon1)
a = math.sin(delta_phi / 2) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(delta_lambda / 2) ** 2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance = R * c # in metres
return distance <= (radius + margin)
def generate_random_coordinate_in_square(center_lat, center_lon, size):
"""Generate a random coordinate within a square of given size (in metres) centered at (center_lat, center_lon)."""
# Convert size from metres to degrees (approximation)
half_size = size / 2 # half of the square size in metres
# Random offsets within the square
offset_lat = random.uniform(-half_size, half_size) / 111320 # approx metres per degree latitude
offset_lon = random.uniform(-half_size, half_size) / (111320 * math.cos(math.radians(center_lat)))
return center_lat + offset_lat, center_lon + offset_lon
# Load all JSON data
data = load_all_data()
# Extracting the data
radio_units_data = data["radio_units"]
demand_points = data["demand_points"]
# Prepare the result structure
results = []
# Generate users for each demand point and assign them to RUs
for dp in demand_points["demand_points"]:
users = []
# Generate unique users within the demand point's square
for user_id in range(dp["users"]):
user_lat, user_lon = generate_random_coordinate_in_square(dp["latitude"], dp["longitude"], dp["size"])
user_info = {
"user_id": f"{dp['demand_id']}_user_{user_id+1}",
"latitude": user_lat,
"longitude": user_lon,
"assigned_ru": []
}
users.append(user_info)
# Determine which RUs each user is within range of
for user in users:
for ru in radio_units_data["radio_units"]:
if is_within_range(user["latitude"], user["longitude"], ru["latitude"], ru["longitude"], ru["range_m"], margin=10):
user["assigned_ru"].append(ru["ru_name"])
# Append user data to results
results.extend(users)
# Output results to JSON
output_file_path = os.path.join(scenario, "user_map.json")
with open(output_file_path, 'w') as json_file:
json.dump(results, json_file, indent=4)
print(f"JSON file created successfully at {output_file_path}.")