Gordon Li commited on
Commit
ae72b3f
·
1 Parent(s): ecf5538

comment reformat

Browse files
app.py CHANGED
@@ -1,26 +1,24 @@
1
- """
2
- app.py
3
-
4
- This application provides a user interface for HKUST students to browse, search,
5
- and find accommodations in different neighborhoods of Hong Kong. It features an interactive map
6
- visualization, listing cards with pricing information, traffic-based discounts, and smart search
7
- functionality to match user preferences with available properties.
8
-
9
- Key features:
10
- - Interactive map displaying BNB listings with location markers
11
- - Neighborhood-based filtering of available accommodations
12
- - Smart search system that highlights matching terms in descriptions and reviews
13
- - Traffic-based discount system promoting eco-friendly housing options
14
- - Detailed view of property reviews with highlighted search terms
15
- - Responsive pagination for browsing through large sets of listings
16
- - Loading animations and informative UI elements for better user experience
17
-
18
- The application uses Folium for map visualization, Streamlit for the web interface
19
-
20
- Author: Gordon Li (20317033)
21
- Company : HKUST Sustainability
22
- Date: March 2025
23
- """
24
 
25
  import os
26
  import re
@@ -46,24 +44,24 @@ from constant.hkust_bnb_constant import (
46
  )
47
 
48
 
49
- """
50
- Loads CSS styles from a file and applies them to the Streamlit application.
51
- Parameters:
52
- css_file: Path to the CSS file to be loaded
53
- """
 
54
  def load_css(css_file):
55
  with open(css_file) as f:
56
  st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
57
 
58
 
59
- """
60
- Highlights search terms within text by wrapping them in a span with highlight class.
61
- Parameters:
62
- text: The original text to process
63
- search_query: The search terms to highlight within the text
64
- Returns:
65
- Text with highlighted search terms
66
- """
67
  def highlight_search_terms(text, search_query):
68
  if not search_query:
69
  return text
@@ -80,17 +78,15 @@ def highlight_search_terms(text, search_query):
80
  return highlighted_text
81
 
82
 
83
- """
84
- Renders a loading animation using Lottie animation in HTML format.
85
- """
86
  def render_lottie_loading_animation():
87
  components.html(LOTTIE_HTML, height=750)
88
 
89
 
90
- """
91
- Renders a dialog containing reviews for the currently selected listing.
92
- Displays reviewer name, review date, and comments with search terms highlighted.
93
- """
94
  def render_review_dialog():
95
  with st.container():
96
  col_title = st.columns([5, 1])
@@ -122,10 +118,9 @@ def render_review_dialog():
122
  st.info("No reviews available for this listing.")
123
 
124
 
125
- """
126
- Initializes the session state with default values for various application parameters.
127
- Sets up the visualizer and loads required resources for the application.
128
- """
129
  def initialize_session_state():
130
  default_states = {
131
  'center_lat': None,
@@ -156,11 +151,9 @@ def initialize_session_state():
156
  st.session_state.loading_complete = True
157
 
158
 
159
- """
160
- Main function that sets up the Streamlit application interface.
161
- Handles page configuration, sidebar setup, map rendering, listing display,
162
- pagination, and user interactions with the application elements.
163
- """
164
  def main():
165
  st.set_page_config(
166
  layout="wide",
@@ -405,10 +398,8 @@ def main():
405
  render_review_dialog()
406
 
407
 
408
- """
409
- Main entry point for the application. Authenticates with Hugging Face if a token is available,
410
- then calls the main function to start the application.
411
- """
412
  if __name__ == "__main__":
413
  token = os.environ.get("HF_TOKEN")
414
  if token:
 
1
+ # app.py
2
+
3
+ # This application provides a user interface for HKUST students to browse, search,
4
+ # and find accommodations in different neighborhoods of Hong Kong. It features an interactive map
5
+ # visualization, listing cards with pricing information, traffic-based discounts, and smart search
6
+ # functionality to match user preferences with available properties.
7
+
8
+ # Key features:
9
+ # - Interactive map displaying BNB listings with location markers
10
+ # - Neighborhood-based filtering of available accommodations
11
+ # - Smart search system that highlights matching terms in descriptions and reviews
12
+ # - Traffic-based discount system promoting eco-friendly housing options
13
+ # - Detailed view of property reviews with highlighted search terms
14
+ # - Responsive pagination for browsing through large sets of listings
15
+ # - Loading animations and informative UI elements for better user experience
16
+
17
+ # The application uses Folium for map visualization, Streamlit for the web interface
18
+
19
+ # Author: Gordon Li (20317033)
20
+ # Company : HKUST Sustainability
21
+ # Date: March 2025
 
 
22
 
23
  import os
24
  import re
 
44
  )
45
 
46
 
47
+
48
+ # Loads CSS styles from a file and applies them to the Streamlit application.
49
+ # Parameters:
50
+ # css_file: Path to the CSS file to be loaded
51
+
52
+
53
  def load_css(css_file):
54
  with open(css_file) as f:
55
  st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
56
 
57
 
58
+ # Highlights search terms within text by wrapping them in a span with highlight class.
59
+ # Parameters:
60
+ # text: The original text to process
61
+ # search_query: The search terms to highlight within the text
62
+ # Returns:
63
+ # Text with highlighted search terms
64
+
 
65
  def highlight_search_terms(text, search_query):
66
  if not search_query:
67
  return text
 
78
  return highlighted_text
79
 
80
 
81
+ # Renders a loading animation using Lottie animation in HTML format.
82
+
 
83
  def render_lottie_loading_animation():
84
  components.html(LOTTIE_HTML, height=750)
85
 
86
 
87
+ # Renders a dialog containing reviews for the currently selected listing.
88
+ # Displays reviewer name, review date, and comments with search terms highlighted.
89
+
 
90
  def render_review_dialog():
91
  with st.container():
92
  col_title = st.columns([5, 1])
 
118
  st.info("No reviews available for this listing.")
119
 
120
 
121
+ # Initializes the session state with default values for various application parameters.
122
+ # Sets up the visualizer and loads required resources for the application.
123
+
 
124
  def initialize_session_state():
125
  default_states = {
126
  'center_lat': None,
 
151
  st.session_state.loading_complete = True
152
 
153
 
154
+ # Main function that sets up the Streamlit application interface.
155
+ # Handles page configuration, sidebar setup, map rendering, listing display,
156
+ # pagination, and user interactions with the application elements.
 
 
157
  def main():
158
  st.set_page_config(
159
  layout="wide",
 
398
  render_review_dialog()
399
 
400
 
401
+ # Main entry point for the application. Authenticates with Hugging Face if a token is available,
402
+ # then calls the main function to start the application.
 
 
403
  if __name__ == "__main__":
404
  token = os.environ.get("HF_TOKEN")
405
  if token:
cronjob/abstract_traffic_image_analyzer.py CHANGED
@@ -1,16 +1,14 @@
1
- """
2
- Traffic Image Analysis Module for HKUST BNB+ Platform
3
 
4
- This module provides functionality for analyzing traffic camera images to detect and count vehicles.
5
- It downloads images from traffic cameras, processes them using computer vision models, and records
6
- traffic data that is used for traffic-based discount calculations in the BNB+ platform.
7
 
8
- The analyzer connects to a database to retrieve camera locations, downloads and processes images,
9
- detects vehicles, and stores the results for visualization and analysis.
10
 
11
- Author: Gordon Li (20317033)
12
- Date: March 2025
13
- """
14
 
15
 
16
  import requests
@@ -27,16 +25,14 @@ import random
27
 
28
 
29
  class AbstractTrafficImageAnalyzer:
30
- """
31
- Initializes the traffic image analyzer with database connection, signal handlers, and directories.
32
 
33
- Sets up:
34
- - Database connection parameters
35
- - Signal handlers for graceful shutdown
36
- - Vehicle class identifiers for detection
37
- - Directory structure for storing downloaded images
38
- - Logging configuration
39
- """
40
 
41
  def __init__(self):
42
  self.connection_params = {
@@ -60,22 +56,18 @@ class AbstractTrafficImageAnalyzer:
60
 
61
  self.setup_logging()
62
 
63
- """
64
- Handles termination signals to ensure graceful shutdown.
65
 
66
- Parameters:
67
- signum: Signal number
68
- frame: Current stack frame
69
- """
70
 
71
  def signal_handler(self, signum, frame):
72
  print("\nShutdown signal received. Completing current task...")
73
  self.running = False
74
 
75
- """
76
- Sets up logging configuration for the analyzer.
77
- Creates log files with timestamps and configures console output.
78
- """
79
 
80
  def setup_logging(self):
81
  logging.basicConfig(
@@ -87,12 +79,10 @@ class AbstractTrafficImageAnalyzer:
87
  ]
88
  )
89
 
90
- """
91
- Retrieves traffic camera locations and URLs from the database.
92
 
93
- Returns:
94
- List of tuples containing camera location key and URL
95
- """
96
 
97
  def get_camera_locations(self):
98
  try:
@@ -104,15 +94,13 @@ class AbstractTrafficImageAnalyzer:
104
  logging.error(f"Error fetching camera locations: {str(e)}")
105
  raise
106
 
107
- """
108
- Downloads an image from a given URL.
109
 
110
- Parameters:
111
- url: URL of the traffic camera image
112
 
113
- Returns:
114
- PIL Image object
115
- """
116
 
117
  def download_image(self, url):
118
  try:
@@ -123,16 +111,14 @@ class AbstractTrafficImageAnalyzer:
123
  logging.error(f"Error downloading image from {url}: {str(e)}")
124
  raise
125
 
126
- """
127
- Detects vehicles in an image using a computer vision model.
128
 
129
- Parameters:
130
- image: PIL Image object to analyze
131
- confidence_threshold: Minimum confidence score for detections (default: 0.7)
132
 
133
- Returns:
134
- List of vehicle detection dictionaries with bounding boxes and scores
135
- """
136
 
137
  def detect_vehicles(self, image, confidence_threshold=0.7):
138
  try:
@@ -178,16 +164,14 @@ class AbstractTrafficImageAnalyzer:
178
  logging.error(f"Error detecting vehicles: {str(e)}")
179
  raise
180
 
181
- """
182
- Draws vehicle detection bounding boxes and labels on the image.
183
 
184
- Parameters:
185
- image: Original PIL Image
186
- detections: List of vehicle detection dictionaries
187
 
188
- Returns:
189
- New PIL Image with bounding boxes and labels drawn
190
- """
191
 
192
  def draw_detections(self, image, detections):
193
  try:
@@ -241,16 +225,14 @@ class AbstractTrafficImageAnalyzer:
241
  logging.error(f"Error drawing detections: {str(e)}")
242
  raise
243
 
244
- """
245
- Processes all traffic cameras, detects vehicles, and prepares data for storage.
246
 
247
- This method:
248
- 1. Gets all camera locations
249
- 2. Downloads images from each camera
250
- 3. Detects vehicles in each image
251
- 4. Processes images to visualize detections
252
- 5. Prepares data for storage
253
- """
254
 
255
  def process_traffic_cameras(self):
256
  try:
@@ -338,45 +320,37 @@ class AbstractTrafficImageAnalyzer:
338
  logging.error(f"Error in process_traffic_cameras: {str(e)}")
339
  raise
340
 
341
- """
342
- Updates the HuggingFace dataset with new traffic data.
343
- This method must be implemented by subclasses.
344
 
345
- Parameters:
346
- batch_data: Dictionary containing the batch data to add
347
- timestamp_str: Timestamp string for the current batch
348
- """
349
 
350
  def update_huggingface_dataset(self, batch_data, timestamp_str):
351
  raise NotImplementedError("Subclasses must implement update_huggingface_dataset method")
352
 
353
- """
354
- Creates COCO annotation files for the dataset.
355
- This method must be implemented by subclasses.
356
 
357
- Parameters:
358
- dataset_dict: Dictionary containing the dataset
359
- timestamp_str: Timestamp string for the current batch
360
- """
361
 
362
  def create_coco_annotation_files(self, dataset_dict, timestamp_str):
363
  raise NotImplementedError("Subclasses must implement create_coco_annotation_files method")
364
 
365
- """
366
- Updates the README file for the dataset.
367
- This method must be implemented by subclasses.
368
 
369
- Parameters:
370
- dataset_dict: Dictionary containing the dataset
371
- timestamp_str: Timestamp string for the current batch
372
- """
373
 
374
  def update_readme(self, dataset_dict, timestamp_str):
375
  raise NotImplementedError("Subclasses must implement update_readme method")
376
 
377
- """
378
- Runs the traffic image analyzer, processing all cameras and updating the dataset.
379
- """
380
 
381
  def run(self):
382
  try:
 
1
+ # Traffic Image Analysis Module for HKUST BNB+ Platform
 
2
 
3
+ # This module provides functionality for analyzing traffic camera images to detect and count vehicles.
4
+ # It downloads images from traffic cameras, processes them using computer vision models, and records
5
+ # traffic data that is used for traffic-based discount calculations in the BNB+ platform.
6
 
7
+ # The analyzer connects to a database to retrieve camera locations, downloads and processes images,
8
+ # detects vehicles, and stores the results for visualization and analysis.
9
 
10
+ # Author: Gordon Li (20317033)
11
+ # Date: March 2025
 
12
 
13
 
14
  import requests
 
25
 
26
 
27
  class AbstractTrafficImageAnalyzer:
28
+ # Initializes the traffic image analyzer with database connection, signal handlers, and directories.
 
29
 
30
+ # Sets up:
31
+ # - Database connection parameters
32
+ # - Signal handlers for graceful shutdown
33
+ # - Vehicle class identifiers for detection
34
+ # - Directory structure for storing downloaded images
35
+ # - Logging configuration
 
36
 
37
  def __init__(self):
38
  self.connection_params = {
 
56
 
57
  self.setup_logging()
58
 
59
+ # Handles termination signals to ensure graceful shutdown.
 
60
 
61
+ # Parameters:
62
+ # signum: Signal number
63
+ # frame: Current stack frame
 
64
 
65
  def signal_handler(self, signum, frame):
66
  print("\nShutdown signal received. Completing current task...")
67
  self.running = False
68
 
69
+ # Sets up logging configuration for the analyzer.
70
+ # Creates log files with timestamps and configures console output.
 
 
71
 
72
  def setup_logging(self):
73
  logging.basicConfig(
 
79
  ]
80
  )
81
 
82
+ # Retrieves traffic camera locations and URLs from the database.
 
83
 
84
+ # Returns:
85
+ # List of tuples containing camera location key and URL
 
86
 
87
  def get_camera_locations(self):
88
  try:
 
94
  logging.error(f"Error fetching camera locations: {str(e)}")
95
  raise
96
 
97
+ # Downloads an image from a given URL.
 
98
 
99
+ # Parameters:
100
+ # url: URL of the traffic camera image
101
 
102
+ # Returns:
103
+ # PIL Image object
 
104
 
105
  def download_image(self, url):
106
  try:
 
111
  logging.error(f"Error downloading image from {url}: {str(e)}")
112
  raise
113
 
114
+ # Detects vehicles in an image using a computer vision model.
 
115
 
116
+ # Parameters:
117
+ # image: PIL Image object to analyze
118
+ # confidence_threshold: Minimum confidence score for detections (default: 0.7)
119
 
120
+ # Returns:
121
+ # List of vehicle detection dictionaries with bounding boxes and scores
 
122
 
123
  def detect_vehicles(self, image, confidence_threshold=0.7):
124
  try:
 
164
  logging.error(f"Error detecting vehicles: {str(e)}")
165
  raise
166
 
167
+ # Draws vehicle detection bounding boxes and labels on the image.
 
168
 
169
+ # Parameters:
170
+ # image: Original PIL Image
171
+ # detections: List of vehicle detection dictionaries
172
 
173
+ # Returns:
174
+ # New PIL Image with bounding boxes and labels drawn
 
175
 
176
  def draw_detections(self, image, detections):
177
  try:
 
225
  logging.error(f"Error drawing detections: {str(e)}")
226
  raise
227
 
228
+ # Processes all traffic cameras, detects vehicles, and prepares data for storage.
 
229
 
230
+ # This method:
231
+ # 1. Gets all camera locations
232
+ # 2. Downloads images from each camera
233
+ # 3. Detects vehicles in each image
234
+ # 4. Processes images to visualize detections
235
+ # 5. Prepares data for storage
 
236
 
237
  def process_traffic_cameras(self):
238
  try:
 
320
  logging.error(f"Error in process_traffic_cameras: {str(e)}")
321
  raise
322
 
323
+ # Updates the HuggingFace dataset with new traffic data.
324
+ # This method must be implemented by subclasses.
 
325
 
326
+ # Parameters:
327
+ # batch_data: Dictionary containing the batch data to add
328
+ # timestamp_str: Timestamp string for the current batch
 
329
 
330
  def update_huggingface_dataset(self, batch_data, timestamp_str):
331
  raise NotImplementedError("Subclasses must implement update_huggingface_dataset method")
332
 
333
+ # Creates COCO annotation files for the dataset.
334
+ # This method must be implemented by subclasses.
 
335
 
336
+ # Parameters:
337
+ # dataset_dict: Dictionary containing the dataset
338
+ # timestamp_str: Timestamp string for the current batch
 
339
 
340
  def create_coco_annotation_files(self, dataset_dict, timestamp_str):
341
  raise NotImplementedError("Subclasses must implement create_coco_annotation_files method")
342
 
343
+ # Updates the README file for the dataset.
344
+ # This method must be implemented by subclasses.
 
345
 
346
+ # Parameters:
347
+ # dataset_dict: Dictionary containing the dataset
348
+ # timestamp_str: Timestamp string for the current batch
 
349
 
350
  def update_readme(self, dataset_dict, timestamp_str):
351
  raise NotImplementedError("Subclasses must implement update_readme method")
352
 
353
+ # Runs the traffic image analyzer, processing all cameras and updating the dataset.
 
 
354
 
355
  def run(self):
356
  try:
cronjob/application_traffic_image_analyzer.py CHANGED
@@ -1,16 +1,14 @@
1
- """
2
- Application Traffic Image Analyzer Module
3
 
4
- This module extends the AbstractTrafficImageAnalyzer to provide specific implementation for
5
- application-specific traffic analysis. It handles the processing of traffic camera images,
6
- vehicle detection using the DETR model, and updating a HuggingFace dataset with the results.
7
 
8
- The analyzer is used in the HKUST BNB+ platform to collect and analyze traffic data for
9
- determining eco-friendly discounts based on traffic conditions.
10
 
11
- Author: Gordon Li (20317033)
12
- Date: March 2025
13
- """
14
 
15
  from transformers import DetrImageProcessor, DetrForObjectDetection
16
  from datasets import Dataset, Features, Value, load_dataset, DatasetDict, concatenate_datasets
@@ -24,13 +22,12 @@ import logging
24
 
25
 
26
  class ApplicationTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
27
- """
28
- Initializes the application traffic analyzer with the DETR model and processor.
 
 
 
29
 
30
- Sets up:
31
- - DETR image processor and model for vehicle detection
32
- - Application-specific directory for storing results
33
- """
34
  def __init__(self):
35
  super().__init__()
36
  self.processor = DetrImageProcessor.from_pretrained("slliac/detr-group37-liaujianjie-resnet-50",
@@ -40,13 +37,11 @@ class ApplicationTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
40
  self.application_dir = os.path.join(self.dataset_dir, "application")
41
  os.makedirs(self.application_dir, exist_ok=True)
42
 
43
- """
44
- Updates the HuggingFace dataset with new traffic data.
45
 
46
- Parameters:
47
- batch_data: Dictionary containing batch data including capture time, location, images, and vehicle counts
48
- timestamp_str: Timestamp string for the current batch
49
- """
50
 
51
  def update_huggingface_dataset(self, batch_data, timestamp_str):
52
  try:
@@ -119,13 +114,11 @@ class ApplicationTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
119
  logging.error(f"Error in update_huggingface_dataset: {str(e)}")
120
  raise
121
 
122
- """
123
- Creates COCO annotation files for the dataset, which are standard format for object detection.
124
 
125
- Parameters:
126
- dataset_dict: Dictionary containing the dataset with traffic observations
127
- timestamp_str: Timestamp string for the current batch
128
- """
129
 
130
  def create_coco_annotation_files(self, dataset_dict, timestamp_str):
131
  try:
@@ -244,11 +237,9 @@ class ApplicationTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
244
  logging.error(f"Error creating COCO annotation files: {str(e)}")
245
 
246
 
247
- """
248
- Main function to execute the traffic image analysis process.
249
- Initializes the analyzer, loads existing data if available, runs the analysis,
250
- and displays dataset information before and after the process.
251
- """
252
 
253
 
254
  def main():
@@ -279,8 +270,6 @@ def main():
279
  print("\nProgram terminated")
280
 
281
 
282
- """
283
- Entry point for the script.
284
- """
285
  if __name__ == "__main__":
286
  main()
 
1
+ # Application Traffic Image Analyzer Module
 
2
 
3
+ # This module extends the AbstractTrafficImageAnalyzer to provide specific implementation for
4
+ # application-specific traffic analysis. It handles the processing of traffic camera images,
5
+ # vehicle detection using the DETR model, and updating a HuggingFace dataset with the results.
6
 
7
+ # The analyzer is used in the HKUST BNB+ platform to collect and analyze traffic data for
8
+ # determining eco-friendly discounts based on traffic conditions.
9
 
10
+ # Author: Gordon Li (20317033)
11
+ # Date: March 2025
 
12
 
13
  from transformers import DetrImageProcessor, DetrForObjectDetection
14
  from datasets import Dataset, Features, Value, load_dataset, DatasetDict, concatenate_datasets
 
22
 
23
 
24
  class ApplicationTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
25
+ # Initializes the application traffic analyzer with the DETR model and processor.
26
+
27
+ # Sets up:
28
+ # - DETR image processor and model for vehicle detection
29
+ # - Application-specific directory for storing results
30
 
 
 
 
 
31
  def __init__(self):
32
  super().__init__()
33
  self.processor = DetrImageProcessor.from_pretrained("slliac/detr-group37-liaujianjie-resnet-50",
 
37
  self.application_dir = os.path.join(self.dataset_dir, "application")
38
  os.makedirs(self.application_dir, exist_ok=True)
39
 
40
+ # Updates the HuggingFace dataset with new traffic data.
 
41
 
42
+ # Parameters:
43
+ # batch_data: Dictionary containing batch data including capture time, location, images, and vehicle counts
44
+ # timestamp_str: Timestamp string for the current batch
 
45
 
46
  def update_huggingface_dataset(self, batch_data, timestamp_str):
47
  try:
 
114
  logging.error(f"Error in update_huggingface_dataset: {str(e)}")
115
  raise
116
 
117
+ # Creates COCO annotation files for the dataset, which are standard format for object detection.
 
118
 
119
+ # Parameters:
120
+ # dataset_dict: Dictionary containing the dataset with traffic observations
121
+ # timestamp_str: Timestamp string for the current batch
 
122
 
123
  def create_coco_annotation_files(self, dataset_dict, timestamp_str):
124
  try:
 
237
  logging.error(f"Error creating COCO annotation files: {str(e)}")
238
 
239
 
240
+ # Main function to execute the traffic image analysis process.
241
+ # Initializes the analyzer, loads existing data if available, runs the analysis,
242
+ # and displays dataset information before and after the process.
 
 
243
 
244
 
245
  def main():
 
270
  print("\nProgram terminated")
271
 
272
 
273
+ # Entry point for the script.
 
 
274
  if __name__ == "__main__":
275
  main()
cronjob/train_detr_traffic_image_analyzer.py CHANGED
@@ -1,18 +1,16 @@
1
- """
2
- Traffic Image Analyzer for DETR Model Training
3
 
4
- This module extends the AbstractTrafficImageAnalyzer to provide implementation for training
5
- data collection for the DETR object detection model. It processes traffic camera images,
6
- detects vehicles using the pretrained Facebook DETR ResNet-50 model, and organizes the data
7
- for model training purposes.
8
 
9
- The data collected by this analyzer is used to train custom DETR models that improve vehicle
10
- detection accuracy, which ultimately enhances the traffic analysis component of the HKUST BNB+
11
- platform's eco-friendly discount system.
12
 
13
- Author: Gordon Li (20317033)
14
- Date: March 2025
15
- """
16
 
17
  from transformers import DetrImageProcessor, DetrForObjectDetection
18
  from datasets import Dataset, Features, Value, load_dataset, concatenate_datasets, DatasetDict
@@ -28,13 +26,12 @@ import logging
28
  class TrainDETRTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
29
 
30
 
31
- """
32
- Initializes the DETR training data collector with the Facebook pretrained model.
 
 
 
33
 
34
- Sets up:
35
- - Facebook DETR ResNet-50 image processor and model
36
- - Directory structure for storing DETR training data
37
- """
38
  def __init__(self):
39
  super().__init__()
40
 
@@ -44,13 +41,11 @@ class TrainDETRTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
44
  self.fb_detr_dir = os.path.join(self.dataset_dir, "fb_detr_res_50")
45
  os.makedirs(self.fb_detr_dir, exist_ok=True)
46
 
47
- """
48
- Updates the HuggingFace dataset with new traffic data for DETR model training.
49
 
50
- Parameters:
51
- batch_data: Dictionary containing traffic image data and annotations
52
- timestamp_str: Timestamp string for the current batch
53
- """
54
 
55
  def update_huggingface_dataset(self, batch_data, timestamp_str):
56
  try:
@@ -110,13 +105,11 @@ class TrainDETRTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
110
  logging.error(f"Error updating Hugging Face dataset: {str(e)}")
111
  raise
112
 
113
- """
114
- Creates COCO annotation files for the DETR training dataset.
115
 
116
- Parameters:
117
- dataset_dict: Dictionary containing the dataset splits
118
- timestamp_str: Timestamp string for the current batch
119
- """
120
 
121
  def create_coco_annotation_files(self, dataset_dict, timestamp_str):
122
  try:
@@ -230,11 +223,9 @@ class TrainDETRTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
230
  logging.error(f"Error creating COCO annotation files: {str(e)}")
231
 
232
 
233
- """
234
- Main function to execute the DETR training data collection process.
235
- Initializes the analyzer, loads existing data if available, runs the analysis,
236
- and displays dataset information before and after the process.
237
- """
238
 
239
 
240
  def main():
@@ -264,8 +255,6 @@ def main():
264
  print("\nProgram terminated")
265
 
266
 
267
- """
268
- Entry point for the script.
269
- """
270
  if __name__ == "__main__":
271
  main()
 
1
+ # Traffic Image Analyzer for DETR Model Training
 
2
 
3
+ # This module extends the AbstractTrafficImageAnalyzer to provide implementation for training
4
+ # data collection for the DETR object detection model. It processes traffic camera images,
5
+ # detects vehicles using the pretrained Facebook DETR ResNet-50 model, and organizes the data
6
+ # for model training purposes.
7
 
8
+ # The data collected by this analyzer is used to train custom DETR models that improve vehicle
9
+ # detection accuracy, which ultimately enhances the traffic analysis component of the HKUST BNB+
10
+ # platform's eco-friendly discount system.
11
 
12
+ # Author: Gordon Li (20317033)
13
+ # Date: March 2025
 
14
 
15
  from transformers import DetrImageProcessor, DetrForObjectDetection
16
  from datasets import Dataset, Features, Value, load_dataset, concatenate_datasets, DatasetDict
 
26
  class TrainDETRTrafficImageAnalyzer(AbstractTrafficImageAnalyzer):
27
 
28
 
29
+ # Initializes the DETR training data collector with the Facebook pretrained model.
30
+
31
+ # Sets up:
32
+ # - Facebook DETR ResNet-50 image processor and model
33
+ # - Directory structure for storing DETR training data
34
 
 
 
 
 
35
  def __init__(self):
36
  super().__init__()
37
 
 
41
  self.fb_detr_dir = os.path.join(self.dataset_dir, "fb_detr_res_50")
42
  os.makedirs(self.fb_detr_dir, exist_ok=True)
43
 
44
+ # Updates the HuggingFace dataset with new traffic data for DETR model training.
 
45
 
46
+ # Parameters:
47
+ # batch_data: Dictionary containing traffic image data and annotations
48
+ # timestamp_str: Timestamp string for the current batch
 
49
 
50
  def update_huggingface_dataset(self, batch_data, timestamp_str):
51
  try:
 
105
  logging.error(f"Error updating Hugging Face dataset: {str(e)}")
106
  raise
107
 
108
+ # Creates COCO annotation files for the DETR training dataset.
 
109
 
110
+ # Parameters:
111
+ # dataset_dict: Dictionary containing the dataset splits
112
+ # timestamp_str: Timestamp string for the current batch
 
113
 
114
  def create_coco_annotation_files(self, dataset_dict, timestamp_str):
115
  try:
 
223
  logging.error(f"Error creating COCO annotation files: {str(e)}")
224
 
225
 
226
+ # Main function to execute the DETR training data collection process.
227
+ # Initializes the analyzer, loads existing data if available, runs the analysis,
228
+ # and displays dataset information before and after the process.
 
 
229
 
230
 
231
  def main():
 
255
  print("\nProgram terminated")
256
 
257
 
258
+ # Entry point for the script.
 
 
259
  if __name__ == "__main__":
260
  main()
visualiser/hkust_bnb_visualiser.py CHANGED
@@ -1,18 +1,16 @@
1
- """
2
- hkust_bnb_visualiser.py
3
 
4
- This module provides the main visualization for the HKUST BNB+ platform.
5
- It handles database connections, data retrieval, search relevance calculation, and map visualization
6
- for BNB listings across different neighborhoods in Hong Kong. The class integrates with traffic data
7
- to provide eco-friendly discount calculations based on traffic conditions.
8
 
9
- Key capabilities:
10
- - Semantic search functionality using sentence transformers
11
- - Traffic spot integration for eco-friendly discount calculations
12
 
13
- Author: Gordon Li (20317033)
14
- Date: March 2025
15
- """
16
 
17
  import oracledb
18
  import pandas as pd
@@ -36,16 +34,12 @@ from constant.hkust_bnb_constant import (
36
  )
37
 
38
  class HKUSTBNBVisualiser:
39
- """
40
- Main class for BNB data visualization and management.
41
- Handles database connections, data retrieval, and rendering of interactive maps.
42
- """
43
 
44
- """
45
- Initializes the BNB visualizer with database connection, traffic spot manager, and NLP model.
46
- Sets up connection pool, loads traffic data, initializes sentence transformer model,
47
- and prepares neighborhood data with caching structures.
48
- """
49
 
50
  def __init__(self):
51
  self.connection_params = {
@@ -81,17 +75,15 @@ class HKUSTBNBVisualiser:
81
  self.cached_listings = {}
82
  self.cached_embeddings = {}
83
 
84
- """
85
- Finds the nearest traffic spot to a given BNB listing location.
86
 
87
- Parameters:
88
- airbnb_lat: The latitude of the BNB listing
89
- airbnb_lng: The longitude of the BNB listing
90
- max_distance_km: Maximum distance in kilometers to consider a traffic spot (default: 0.7)
91
 
92
- Returns:
93
- Tuple containing (nearest_traffic_spot, distance_in_km) or (None, None) if no spot is found
94
- """
95
 
96
  def find_nearest_traffic_spot(self, airbnb_lat, airbnb_lng, max_distance_km=0.7):
97
  nearest_spot = None
@@ -111,12 +103,10 @@ class HKUSTBNBVisualiser:
111
  else:
112
  return None, None
113
 
114
- """
115
- Retrieves all available neighborhoods from the database.
116
 
117
- Returns:
118
- List of neighborhood names as strings
119
- """
120
 
121
  def get_all_neighborhoods(self):
122
  connection = self.pool.acquire()
@@ -133,16 +123,14 @@ class HKUSTBNBVisualiser:
133
  finally:
134
  self.pool.release(connection)
135
 
136
- """
137
- Retrieves BNB listings for a specific neighborhood with caching.
138
 
139
- Parameters:
140
- neighborhood: The neighborhood name to retrieve listings for
141
- limit: Maximum number of listings to retrieve (default: 10)
142
 
143
- Returns:
144
- List of listing data rows from the database
145
- """
146
 
147
  def get_neighborhood_listings(self, neighborhood, limit=10):
148
  if limit not in [10, 20, 30, 40, 50]:
@@ -174,15 +162,13 @@ class HKUSTBNBVisualiser:
174
  finally:
175
  self.pool.release(connection)
176
 
177
- """
178
- Retrieves reviews for a specific listing ID.
179
 
180
- Parameters:
181
- listing_id: The ID of the listing to get reviews for
182
 
183
- Returns:
184
- List of tuples containing (review_date, reviewer_name, comments)
185
- """
186
 
187
  def get_listing_reviews(self, listing_id):
188
  connection = self.pool.acquire()
@@ -211,15 +197,13 @@ class HKUSTBNBVisualiser:
211
  finally:
212
  self.pool.release(connection)
213
 
214
- """
215
- Retrieves review content for search functionality.
216
 
217
- Parameters:
218
- listing_id: The ID of the listing to get reviews for
219
 
220
- Returns:
221
- List of review comment strings for semantic search
222
- """
223
 
224
  def get_listing_reviews_for_search(self, listing_id):
225
  connection = self.pool.acquire()
@@ -246,16 +230,14 @@ class HKUSTBNBVisualiser:
246
  finally:
247
  self.pool.release(connection)
248
 
249
- """
250
- Computes cosine similarity between two embeddings.
251
 
252
- Parameters:
253
- query_embedding: Embedding tensor for the search query
254
- target_embedding: Embedding tensor for the target text
255
 
256
- Returns:
257
- Float value representing similarity (0.0-1.0)
258
- """
259
 
260
  def compute_similarity(self, query_embedding, target_embedding):
261
  if query_embedding is None or target_embedding is None:
@@ -267,16 +249,14 @@ class HKUSTBNBVisualiser:
267
  print(f"Error computing similarity: {str(e)}")
268
  return 0.0
269
 
270
- """
271
- Computes relevance scores for listings based on search query.
272
 
273
- Parameters:
274
- df: DataFrame containing listing data
275
- search_query: User's search query string
276
 
277
- Returns:
278
- List of relevance scores for each listing in the DataFrame
279
- """
280
 
281
  def compute_search_scores(self, df, search_query):
282
  if not search_query or self.model is None:
@@ -317,16 +297,14 @@ class HKUSTBNBVisualiser:
317
  print(f"Error in search scoring: {str(e)}")
318
  return [0.0] * len(df)
319
 
320
- """
321
- Sorts a DataFrame of listings by their relevance to a search query.
322
 
323
- Parameters:
324
- df: DataFrame containing listing data
325
- search_query: User's search query string
326
 
327
- Returns:
328
- DataFrame sorted by relevance to the search query
329
- """
330
 
331
  def sort_by_relevance(self, df, search_query):
332
  if not search_query:
@@ -336,23 +314,21 @@ class HKUSTBNBVisualiser:
336
  df['relevance_percentage'] = df['relevance_score'] * 100
337
  return df.sort_values('relevance_score', ascending=False)
338
 
339
- """
340
- Creates an interactive map and DataFrame for display in the UI.
341
-
342
- Parameters:
343
- neighborhood: The neighborhood to display listings for (default: "Sha Tin")
344
- show_traffic: Whether to show traffic spots on the map (default: True)
345
- center_lat: Latitude to center the map on (default: None, will use mean of listings)
346
- center_lng: Longitude to center the map on (default: None, will use mean of listings)
347
- selected_id: ID of the currently selected listing (default: None)
348
- search_query: User's search query string (default: None)
349
- current_page: Current page number for pagination (default: 1)
350
- items_per_page: Number of items to show per page (default: 3)
351
- listings_limit: Maximum number of listings to retrieve (default: 10)
352
-
353
- Returns:
354
- Tuple containing (folium_map, listings_dataframe)
355
- """
356
 
357
  def create_map_and_data(self, neighborhood="Sha Tin", show_traffic=True, center_lat=None, center_lng=None,
358
  selected_id=None, search_query=None, current_page=1, items_per_page=3, listings_limit=10):
 
1
+ # hkust_bnb_visualiser.py
 
2
 
3
+ # This module provides the main visualization for the HKUST BNB+ platform.
4
+ # It handles database connections, data retrieval, search relevance calculation, and map visualization
5
+ # for BNB listings across different neighborhoods in Hong Kong. The class integrates with traffic data
6
+ # to provide eco-friendly discount calculations based on traffic conditions.
7
 
8
+ # Key capabilities:
9
+ # - Semantic search functionality using sentence transformers
10
+ # - Traffic spot integration for eco-friendly discount calculations
11
 
12
+ # Author: Gordon Li (20317033)
13
+ # Date: March 2025
 
14
 
15
  import oracledb
16
  import pandas as pd
 
34
  )
35
 
36
  class HKUSTBNBVisualiser:
37
+ # Main class for BNB data visualization and management.
38
+ # Handles database connections, data retrieval, and rendering of interactive maps.
 
 
39
 
40
+ # Initializes the BNB visualizer with database connection, traffic spot manager, and NLP model.
41
+ # Sets up connection pool, loads traffic data, initializes sentence transformer model,
42
+ # and prepares neighborhood data with caching structures.
 
 
43
 
44
  def __init__(self):
45
  self.connection_params = {
 
75
  self.cached_listings = {}
76
  self.cached_embeddings = {}
77
 
78
+ # Finds the nearest traffic spot to a given BNB listing location.
 
79
 
80
+ # Parameters:
81
+ # airbnb_lat: The latitude of the BNB listing
82
+ # airbnb_lng: The longitude of the BNB listing
83
+ # max_distance_km: Maximum distance in kilometers to consider a traffic spot (default: 0.7)
84
 
85
+ # Returns:
86
+ # Tuple containing (nearest_traffic_spot, distance_in_km) or (None, None) if no spot is found
 
87
 
88
  def find_nearest_traffic_spot(self, airbnb_lat, airbnb_lng, max_distance_km=0.7):
89
  nearest_spot = None
 
103
  else:
104
  return None, None
105
 
106
+ # Retrieves all available neighborhoods from the database.
 
107
 
108
+ # Returns:
109
+ # List of neighborhood names as strings
 
110
 
111
  def get_all_neighborhoods(self):
112
  connection = self.pool.acquire()
 
123
  finally:
124
  self.pool.release(connection)
125
 
126
+ # Retrieves BNB listings for a specific neighborhood with caching.
 
127
 
128
+ # Parameters:
129
+ # neighborhood: The neighborhood name to retrieve listings for
130
+ # limit: Maximum number of listings to retrieve (default: 10)
131
 
132
+ # Returns:
133
+ # List of listing data rows from the database
 
134
 
135
  def get_neighborhood_listings(self, neighborhood, limit=10):
136
  if limit not in [10, 20, 30, 40, 50]:
 
162
  finally:
163
  self.pool.release(connection)
164
 
165
+ # Retrieves reviews for a specific listing ID.
 
166
 
167
+ # Parameters:
168
+ # listing_id: The ID of the listing to get reviews for
169
 
170
+ # Returns:
171
+ # List of tuples containing (review_date, reviewer_name, comments)
 
172
 
173
  def get_listing_reviews(self, listing_id):
174
  connection = self.pool.acquire()
 
197
  finally:
198
  self.pool.release(connection)
199
 
200
+ # Retrieves review content for search functionality.
 
201
 
202
+ # Parameters:
203
+ # listing_id: The ID of the listing to get reviews for
204
 
205
+ # Returns:
206
+ # List of review comment strings for semantic search
 
207
 
208
  def get_listing_reviews_for_search(self, listing_id):
209
  connection = self.pool.acquire()
 
230
  finally:
231
  self.pool.release(connection)
232
 
233
+ # Computes cosine similarity between two embeddings.
 
234
 
235
+ # Parameters:
236
+ # query_embedding: Embedding tensor for the search query
237
+ # target_embedding: Embedding tensor for the target text
238
 
239
+ # Returns:
240
+ # Float value representing similarity (0.0-1.0)
 
241
 
242
  def compute_similarity(self, query_embedding, target_embedding):
243
  if query_embedding is None or target_embedding is None:
 
249
  print(f"Error computing similarity: {str(e)}")
250
  return 0.0
251
 
252
+ # Computes relevance scores for listings based on search query.
 
253
 
254
+ # Parameters:
255
+ # df: DataFrame containing listing data
256
+ # search_query: User's search query string
257
 
258
+ # Returns:
259
+ # List of relevance scores for each listing in the DataFrame
 
260
 
261
  def compute_search_scores(self, df, search_query):
262
  if not search_query or self.model is None:
 
297
  print(f"Error in search scoring: {str(e)}")
298
  return [0.0] * len(df)
299
 
300
+ # Sorts a DataFrame of listings by their relevance to a search query.
 
301
 
302
+ # Parameters:
303
+ # df: DataFrame containing listing data
304
+ # search_query: User's search query string
305
 
306
+ # Returns:
307
+ # DataFrame sorted by relevance to the search query
 
308
 
309
  def sort_by_relevance(self, df, search_query):
310
  if not search_query:
 
314
  df['relevance_percentage'] = df['relevance_score'] * 100
315
  return df.sort_values('relevance_score', ascending=False)
316
 
317
+ # Creates an interactive map and DataFrame for display in the UI.
318
+
319
+ # Parameters:
320
+ # neighborhood: The neighborhood to display listings for (default: "Sha Tin")
321
+ # show_traffic: Whether to show traffic spots on the map (default: True)
322
+ # center_lat: Latitude to center the map on (default: None, will use mean of listings)
323
+ # center_lng: Longitude to center the map on (default: None, will use mean of listings)
324
+ # selected_id: ID of the currently selected listing (default: None)
325
+ # search_query: User's search query string (default: None)
326
+ # current_page: Current page number for pagination (default: 1)
327
+ # items_per_page: Number of items to show per page (default: 3)
328
+ # listings_limit: Maximum number of listings to retrieve (default: 10)
329
+
330
+ # Returns:
331
+ # Tuple containing (folium_map, listings_dataframe)
 
 
332
 
333
  def create_map_and_data(self, neighborhood="Sha Tin", show_traffic=True, center_lat=None, center_lng=None,
334
  selected_id=None, search_query=None, current_page=1, items_per_page=3, listings_limit=10):
visualiser/td_traffic_spot_visualiser.py CHANGED
@@ -1,17 +1,15 @@
1
- """
2
- td_traffic_spot_visualiser.py
3
 
4
- This module handles traffic data integration for the BNB+ platform, providing traffic-based
5
- discount calculations and map visualization of traffic spots. It includes classes for
6
- individual traffic spots and a manager to handle collections of spots.
7
 
8
- The module integrates with a dataset of traffic observations to determine traffic conditions
9
- and calculate eco-friendly discounts for BNB listings based on local traffic volume.
10
 
11
- Author: Gordon Li (20317033)
12
- Date: March 2025
13
 
14
- """
15
  import folium
16
  import oracledb
17
  import logging
@@ -31,15 +29,13 @@ from constant.hkust_bnb_constant import (
31
 
32
 
33
  class TDTrafficSpot:
34
- """
35
- Initializes a traffic spot with location and historical traffic data.
36
 
37
- Parameters:
38
- key: Unique identifier for the traffic spot
39
- latitude: Geographic latitude of the traffic spot
40
- longitude: Geographic longitude of the traffic spot
41
- dataset_rows: List of dictionaries containing historical traffic observations (default: None)
42
- """
43
 
44
  def __init__(self, key, latitude, longitude, dataset_rows=None):
45
  self.key = key
@@ -49,25 +45,21 @@ class TDTrafficSpot:
49
  self.avg_vehicle_count = self.calculate_avg_vehicle_count()
50
  self.recent_display_rows = self.get_recent_display_rows()
51
 
52
- """
53
- Checks if the traffic spot has valid geographic coordinates.
54
 
55
- Returns:
56
- Boolean indicating whether latitude and longitude are valid
57
- """
58
 
59
  def is_valid(self):
60
  return self.latitude is not None and self.longitude is not None
61
 
62
- """
63
- Gets the most recent traffic observations for display purposes.
64
 
65
- Parameters:
66
- max_display: Maximum number of recent records to return (default: 2)
67
 
68
- Returns:
69
- List of the most recent traffic observation records
70
- """
71
 
72
  def get_recent_display_rows(self, max_display=2):
73
  if not self.dataset_rows:
@@ -76,12 +68,10 @@ class TDTrafficSpot:
76
  sorted_rows = sorted(self.dataset_rows, key=lambda x: x['capture_time'], reverse=True)
77
  return sorted_rows[:max_display]
78
 
79
- """
80
- Calculates the average vehicle count based on historical traffic observations.
81
 
82
- Returns:
83
- Float representing the average number of vehicles observed
84
- """
85
 
86
  def calculate_avg_vehicle_count(self):
87
  if not self.dataset_rows:
@@ -94,12 +84,10 @@ class TDTrafficSpot:
94
 
95
  return np.mean(vehicle_counts)
96
 
97
- """
98
- Determines the discount rate based on average traffic volume.
99
 
100
- Returns:
101
- Float representing the discount rate (0.0 to 0.20)
102
- """
103
 
104
  def get_discount_rate(self):
105
  if self.avg_vehicle_count < 2:
@@ -109,12 +97,10 @@ class TDTrafficSpot:
109
  else:
110
  return 0.0
111
 
112
- """
113
- Generates a human-readable description of the traffic-based discount.
114
 
115
- Returns:
116
- String describing the discount, if any
117
- """
118
 
119
  def get_discount_info(self):
120
  discount_rate = self.get_discount_rate()
@@ -124,12 +110,10 @@ class TDTrafficSpot:
124
 
125
  return f"{int(discount_rate * 100)}% discount! Low traffic area"
126
 
127
- """
128
- Creates HTML content for the traffic spot's popup on the map.
129
 
130
- Returns:
131
- HTML string for the Folium popup
132
- """
133
 
134
  def create_popup_content(self):
135
  discount_info = self.get_discount_info()
@@ -177,12 +161,10 @@ class TDTrafficSpot:
177
  html += "</div>"
178
  return html
179
 
180
- """
181
- Adds the traffic spot to a Folium map with appropriate styling.
182
 
183
- Parameters:
184
- folium_map: Folium map object to add the marker to
185
- """
186
 
187
  def add_to_map(self, folium_map):
188
  if self.is_valid():
@@ -202,16 +184,12 @@ class TDTrafficSpot:
202
 
203
 
204
  class TrafficSpotManager:
205
- """
206
- Manages a collection of traffic spots, handling data loading and map integration.
207
- """
208
 
209
- """
210
- Initializes the manager with database connection parameters and loads initial traffic spots.
211
 
212
- Parameters:
213
- connection_params: Dictionary containing Oracle database connection parameters
214
- """
215
 
216
  def __init__(self, connection_params):
217
  self.connection_params = connection_params
@@ -219,12 +197,10 @@ class TrafficSpotManager:
219
  self.spot_dict = {}
220
  self.load_limited_traffic_spots()
221
 
222
- """
223
- Loads a limited number of traffic spots for initial display.
224
 
225
- Parameters:
226
- limit: Maximum number of traffic spots to load initially (default: 10)
227
- """
228
 
229
  def load_limited_traffic_spots(self, limit=10):
230
  try:
@@ -286,12 +262,10 @@ class TrafficSpotManager:
286
  self.traffic_spots = []
287
  self.spot_dict = {}
288
 
289
- """
290
- Loads specific traffic spots by their keys when needed.
291
 
292
- Parameters:
293
- keys: List of traffic spot keys to load
294
- """
295
 
296
  def load_specific_traffic_spots(self, keys):
297
  needed_keys = [key for key in keys if key not in self.spot_dict]
@@ -341,13 +315,11 @@ class TrafficSpotManager:
341
  except Exception as e:
342
  logging.error(f"Error loading specific traffic spots: {str(e)}")
343
 
344
- """
345
- Adds traffic spots to a Folium map.
346
 
347
- Parameters:
348
- folium_map: Folium map object to add markers to
349
- spot_keys: Optional list of specific spot keys to add (default: None, adds all spots)
350
- """
351
 
352
  def add_spots_to_map(self, folium_map, spot_keys=None):
353
  if spot_keys is None:
@@ -358,15 +330,13 @@ class TrafficSpotManager:
358
  if key in self.spot_dict:
359
  self.spot_dict[key].add_to_map(folium_map)
360
 
361
- """
362
- Retrieves a traffic spot by its key, loading it if necessary.
363
 
364
- Parameters:
365
- key: The unique identifier of the traffic spot
366
 
367
- Returns:
368
- TDTrafficSpot object or None if not found
369
- """
370
 
371
  def get_spot_by_key(self, key):
372
  if key in self.spot_dict:
 
1
+ # td_traffic_spot_visualiser.py
 
2
 
3
+ # This module handles traffic data integration for the BNB+ platform, providing traffic-based
4
+ # discount calculations and map visualization of traffic spots. It includes classes for
5
+ # individual traffic spots and a manager to handle collections of spots.
6
 
7
+ # The module integrates with a dataset of traffic observations to determine traffic conditions
8
+ # and calculate eco-friendly discounts for BNB listings based on local traffic volume.
9
 
10
+ # Author: Gordon Li (20317033)
11
+ # Date: March 2025
12
 
 
13
  import folium
14
  import oracledb
15
  import logging
 
29
 
30
 
31
  class TDTrafficSpot:
32
+ # Initializes a traffic spot with location and historical traffic data.
 
33
 
34
+ # Parameters:
35
+ # key: Unique identifier for the traffic spot
36
+ # latitude: Geographic latitude of the traffic spot
37
+ # longitude: Geographic longitude of the traffic spot
38
+ # dataset_rows: List of dictionaries containing historical traffic observations (default: None)
 
39
 
40
  def __init__(self, key, latitude, longitude, dataset_rows=None):
41
  self.key = key
 
45
  self.avg_vehicle_count = self.calculate_avg_vehicle_count()
46
  self.recent_display_rows = self.get_recent_display_rows()
47
 
48
+ # Checks if the traffic spot has valid geographic coordinates.
 
49
 
50
+ # Returns:
51
+ # Boolean indicating whether latitude and longitude are valid
 
52
 
53
  def is_valid(self):
54
  return self.latitude is not None and self.longitude is not None
55
 
56
+ # Gets the most recent traffic observations for display purposes.
 
57
 
58
+ # Parameters:
59
+ # max_display: Maximum number of recent records to return (default: 2)
60
 
61
+ # Returns:
62
+ # List of the most recent traffic observation records
 
63
 
64
  def get_recent_display_rows(self, max_display=2):
65
  if not self.dataset_rows:
 
68
  sorted_rows = sorted(self.dataset_rows, key=lambda x: x['capture_time'], reverse=True)
69
  return sorted_rows[:max_display]
70
 
71
+ # Calculates the average vehicle count based on historical traffic observations.
 
72
 
73
+ # Returns:
74
+ # Float representing the average number of vehicles observed
 
75
 
76
  def calculate_avg_vehicle_count(self):
77
  if not self.dataset_rows:
 
84
 
85
  return np.mean(vehicle_counts)
86
 
87
+ # Determines the discount rate based on average traffic volume.
 
88
 
89
+ # Returns:
90
+ # Float representing the discount rate (0.0 to 0.20)
 
91
 
92
  def get_discount_rate(self):
93
  if self.avg_vehicle_count < 2:
 
97
  else:
98
  return 0.0
99
 
100
+ # Generates a human-readable description of the traffic-based discount.
 
101
 
102
+ # Returns:
103
+ # String describing the discount, if any
 
104
 
105
  def get_discount_info(self):
106
  discount_rate = self.get_discount_rate()
 
110
 
111
  return f"{int(discount_rate * 100)}% discount! Low traffic area"
112
 
113
+ # Creates HTML content for the traffic spot's popup on the map.
 
114
 
115
+ # Returns:
116
+ # HTML string for the Folium popup
 
117
 
118
  def create_popup_content(self):
119
  discount_info = self.get_discount_info()
 
161
  html += "</div>"
162
  return html
163
 
164
+ # Adds the traffic spot to a Folium map with appropriate styling.
 
165
 
166
+ # Parameters:
167
+ # folium_map: Folium map object to add the marker to
 
168
 
169
  def add_to_map(self, folium_map):
170
  if self.is_valid():
 
184
 
185
 
186
  class TrafficSpotManager:
187
+ # Manages a collection of traffic spots, handling data loading and map integration.
 
 
188
 
189
+ # Initializes the manager with database connection parameters and loads initial traffic spots.
 
190
 
191
+ # Parameters:
192
+ # connection_params: Dictionary containing Oracle database connection parameters
 
193
 
194
  def __init__(self, connection_params):
195
  self.connection_params = connection_params
 
197
  self.spot_dict = {}
198
  self.load_limited_traffic_spots()
199
 
200
+ # Loads a limited number of traffic spots for initial display.
 
201
 
202
+ # Parameters:
203
+ # limit: Maximum number of traffic spots to load initially (default: 10)
 
204
 
205
  def load_limited_traffic_spots(self, limit=10):
206
  try:
 
262
  self.traffic_spots = []
263
  self.spot_dict = {}
264
 
265
+ # Loads specific traffic spots by their keys when needed.
 
266
 
267
+ # Parameters:
268
+ # keys: List of traffic spot keys to load
 
269
 
270
  def load_specific_traffic_spots(self, keys):
271
  needed_keys = [key for key in keys if key not in self.spot_dict]
 
315
  except Exception as e:
316
  logging.error(f"Error loading specific traffic spots: {str(e)}")
317
 
318
+ # Adds traffic spots to a Folium map.
 
319
 
320
+ # Parameters:
321
+ # folium_map: Folium map object to add markers to
322
+ # spot_keys: Optional list of specific spot keys to add (default: None, adds all spots)
 
323
 
324
  def add_spots_to_map(self, folium_map, spot_keys=None):
325
  if spot_keys is None:
 
330
  if key in self.spot_dict:
331
  self.spot_dict[key].add_to_map(folium_map)
332
 
333
+ # Retrieves a traffic spot by its key, loading it if necessary.
 
334
 
335
+ # Parameters:
336
+ # key: The unique identifier of the traffic spot
337
 
338
+ # Returns:
339
+ # TDTrafficSpot object or None if not found
 
340
 
341
  def get_spot_by_key(self, key):
342
  if key in self.spot_dict: