agentsay commited on
Commit
19e0077
·
verified ·
1 Parent(s): 454cc21

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +28 -7
main.py CHANGED
@@ -12,6 +12,9 @@ app = FastAPI(title="GeoJSON and Heatmap API", description="API for random coord
12
  # Global variable to store the last selected coordinate
13
  last_coordinate: List[float] = None
14
 
 
 
 
15
  # Load GeoJSON data from file
16
  def load_geojson_data(file_path: str = "synthetic_ps_points.geojson") -> Dict[str, Any]:
17
  try:
@@ -35,6 +38,19 @@ def load_csv_data(file_path: str = "synthetic_ps_points.csv") -> pd.DataFrame:
35
  def calculate_distance(coord1: List[float], coord2: List[float]) -> float:
36
  return math.sqrt((coord2[0] - coord1[0]) ** 2 + (coord2[1] - coord1[1]) ** 2)
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  # Find the closest feature to a given coordinate
39
  def find_closest_feature(coord: List[float], features: List[Dict]) -> Dict:
40
  min_distance = float('inf')
@@ -57,14 +73,14 @@ def generate_path(start_coord: List[float], end_coord: List[float], num_steps: i
57
  path.append({"step": i, "coordinates": [lon, lat]})
58
  return path
59
 
60
- # Endpoint to get a single random coordinate, ensuring separation from the last coordinate
61
  @app.get("/get-coordinates", response_model=dict)
62
- async def get_random_coordinates(min_distance: float = 0.01):
63
  """
64
- Returns a single random coordinate with associated properties, ensuring a minimum distance from the last selected coordinate.
65
 
66
  Parameters:
67
- - min_distance: Minimum distance from the last coordinate in degrees (default: 0.01)
68
  """
69
  global last_coordinate
70
  data = load_geojson_data()
@@ -72,12 +88,17 @@ async def get_random_coordinates(min_distance: float = 0.01):
72
  if not features:
73
  raise HTTPException(status_code=400, detail="No features found in GeoJSON data")
74
 
 
 
 
 
 
75
  selected_feature = None
76
  attempts = 0
77
- max_attempts = 100 # Prevent infinite loops
78
 
79
  while attempts < max_attempts:
80
- random_feature = random.choice(features)
81
  random_coord = random_feature["geometry"]["coordinates"]
82
 
83
  # Check distance from last coordinate (if it exists)
@@ -197,7 +218,7 @@ async def root():
197
  return {
198
  "message": "Welcome to the GeoJSON and Heatmap API",
199
  "endpoints": {
200
- "/get-coordinates": "Returns a single random coordinate with associated properties, ensuring separation from the last coordinate",
201
  "/simulate-worker-path": "Simulates a worker's path from a normal risk to a high risk zone",
202
  "/heatmap": "Returns raw HTML for a Folium heatmap of PS data"
203
  }
 
12
  # Global variable to store the last selected coordinate
13
  last_coordinate: List[float] = None
14
 
15
+ # Polygon bounds for Singrauli
16
+ POLYGON_BOUNDS = [(82.5065, 22.3105), (82.628, 22.3105), (82.628, 22.3421), (82.5065, 22.3421)]
17
+
18
  # Load GeoJSON data from file
19
  def load_geojson_data(file_path: str = "synthetic_ps_points.geojson") -> Dict[str, Any]:
20
  try:
 
38
  def calculate_distance(coord1: List[float], coord2: List[float]) -> float:
39
  return math.sqrt((coord2[0] - coord1[0]) ** 2 + (coord2[1] - coord1[1]) ** 2)
40
 
41
+ # Point-in-polygon check using ray-casting algorithm
42
+ def is_point_in_polygon(point: List[float], polygon: List[tuple]) -> bool:
43
+ x, y = point[0], point[1]
44
+ n = len(polygon)
45
+ inside = False
46
+ j = n - 1
47
+ for i in range(n):
48
+ if ((polygon[i][1] > y) != (polygon[j][1] > y)) and \
49
+ (x < (polygon[j][0] - polygon[i][0]) * (y - polygon[i][1]) / (polygon[j][1] - polygon[i][1]) + polygon[i][0]):
50
+ inside = not inside
51
+ j = i
52
+ return inside
53
+
54
  # Find the closest feature to a given coordinate
55
  def find_closest_feature(coord: List[float], features: List[Dict]) -> Dict:
56
  min_distance = float('inf')
 
73
  path.append({"step": i, "coordinates": [lon, lat]})
74
  return path
75
 
76
+ # Endpoint to get a single random coordinate, ensuring wide separation from the last coordinate
77
  @app.get("/get-coordinates", response_model=dict)
78
+ async def get_random_coordinates(min_distance: float = 0.05):
79
  """
80
+ Returns a single random coordinate within the Singrauli polygon, ensuring a minimum distance from the last selected coordinate.
81
 
82
  Parameters:
83
+ - min_distance: Minimum distance from the last coordinate in degrees (default: 0.05, ~5.5 km)
84
  """
85
  global last_coordinate
86
  data = load_geojson_data()
 
88
  if not features:
89
  raise HTTPException(status_code=400, detail="No features found in GeoJSON data")
90
 
91
+ # Filter features within the Singrauli polygon
92
+ valid_features = [f for f in features if is_point_in_polygon(f["geometry"]["coordinates"], POLYGON_BOUNDS)]
93
+ if not valid_features:
94
+ raise HTTPException(status_code=400, detail="No features found within the Singrauli polygon")
95
+
96
  selected_feature = None
97
  attempts = 0
98
+ max_attempts = 200 # Increased to handle sparse valid selections
99
 
100
  while attempts < max_attempts:
101
+ random_feature = random.choice(valid_features)
102
  random_coord = random_feature["geometry"]["coordinates"]
103
 
104
  # Check distance from last coordinate (if it exists)
 
218
  return {
219
  "message": "Welcome to the GeoJSON and Heatmap API",
220
  "endpoints": {
221
+ "/get-coordinates": "Returns a single random coordinate within the Singrauli polygon, widely spaced from the last coordinate",
222
  "/simulate-worker-path": "Simulates a worker's path from a normal risk to a high risk zone",
223
  "/heatmap": "Returns raw HTML for a Folium heatmap of PS data"
224
  }