pycityagent 2.0.0a65__cp310-cp310-macosx_11_0_arm64.whl → 2.0.0a67__cp310-cp310-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pycityagent/agent/agent.py +157 -57
- pycityagent/agent/agent_base.py +316 -43
- pycityagent/cityagent/bankagent.py +49 -9
- pycityagent/cityagent/blocks/__init__.py +1 -2
- pycityagent/cityagent/blocks/cognition_block.py +54 -31
- pycityagent/cityagent/blocks/dispatcher.py +22 -17
- pycityagent/cityagent/blocks/economy_block.py +46 -32
- pycityagent/cityagent/blocks/mobility_block.py +209 -105
- pycityagent/cityagent/blocks/needs_block.py +101 -54
- pycityagent/cityagent/blocks/other_block.py +42 -33
- pycityagent/cityagent/blocks/plan_block.py +59 -42
- pycityagent/cityagent/blocks/social_block.py +167 -126
- pycityagent/cityagent/blocks/utils.py +13 -6
- pycityagent/cityagent/firmagent.py +17 -35
- pycityagent/cityagent/governmentagent.py +3 -3
- pycityagent/cityagent/initial.py +79 -49
- pycityagent/cityagent/memory_config.py +123 -94
- pycityagent/cityagent/message_intercept.py +0 -4
- pycityagent/cityagent/metrics.py +41 -0
- pycityagent/cityagent/nbsagent.py +24 -36
- pycityagent/cityagent/societyagent.py +9 -4
- pycityagent/cli/wrapper.py +2 -2
- pycityagent/economy/econ_client.py +407 -81
- pycityagent/environment/__init__.py +0 -3
- pycityagent/environment/sim/__init__.py +0 -3
- pycityagent/environment/sim/aoi_service.py +2 -2
- pycityagent/environment/sim/client.py +3 -31
- pycityagent/environment/sim/clock_service.py +2 -2
- pycityagent/environment/sim/lane_service.py +8 -8
- pycityagent/environment/sim/light_service.py +8 -8
- pycityagent/environment/sim/pause_service.py +9 -10
- pycityagent/environment/sim/person_service.py +20 -20
- pycityagent/environment/sim/road_service.py +2 -2
- pycityagent/environment/sim/sim_env.py +21 -5
- pycityagent/environment/sim/social_service.py +4 -4
- pycityagent/environment/simulator.py +249 -27
- pycityagent/environment/utils/__init__.py +2 -2
- pycityagent/environment/utils/geojson.py +2 -2
- pycityagent/environment/utils/grpc.py +4 -4
- pycityagent/environment/utils/map_utils.py +2 -2
- pycityagent/llm/embeddings.py +147 -28
- pycityagent/llm/llm.py +178 -111
- pycityagent/llm/llmconfig.py +5 -0
- pycityagent/llm/utils.py +4 -0
- pycityagent/memory/__init__.py +0 -4
- pycityagent/memory/const.py +2 -2
- pycityagent/memory/faiss_query.py +140 -61
- pycityagent/memory/memory.py +394 -91
- pycityagent/memory/memory_base.py +140 -34
- pycityagent/memory/profile.py +13 -13
- pycityagent/memory/self_define.py +13 -13
- pycityagent/memory/state.py +14 -14
- pycityagent/message/message_interceptor.py +253 -3
- pycityagent/message/messager.py +133 -6
- pycityagent/metrics/mlflow_client.py +47 -4
- pycityagent/pycityagent-sim +0 -0
- pycityagent/pycityagent-ui +0 -0
- pycityagent/simulation/__init__.py +3 -2
- pycityagent/simulation/agentgroup.py +150 -54
- pycityagent/simulation/simulation.py +276 -66
- pycityagent/survey/manager.py +45 -3
- pycityagent/survey/models.py +42 -2
- pycityagent/tools/__init__.py +1 -2
- pycityagent/tools/tool.py +93 -69
- pycityagent/utils/avro_schema.py +2 -2
- pycityagent/utils/parsers/code_block_parser.py +1 -1
- pycityagent/utils/parsers/json_parser.py +2 -2
- pycityagent/utils/parsers/parser_base.py +2 -2
- pycityagent/workflow/block.py +64 -13
- pycityagent/workflow/prompt.py +31 -23
- pycityagent/workflow/trigger.py +91 -24
- {pycityagent-2.0.0a65.dist-info → pycityagent-2.0.0a67.dist-info}/METADATA +2 -2
- pycityagent-2.0.0a67.dist-info/RECORD +97 -0
- pycityagent/environment/interact/__init__.py +0 -0
- pycityagent/environment/interact/interact.py +0 -198
- pycityagent/environment/message/__init__.py +0 -0
- pycityagent/environment/sence/__init__.py +0 -0
- pycityagent/environment/sence/static.py +0 -416
- pycityagent/environment/sidecar/__init__.py +0 -8
- pycityagent/environment/sidecar/sidecarv2.py +0 -109
- pycityagent/environment/sim/economy_services.py +0 -192
- pycityagent/metrics/utils/const.py +0 -0
- pycityagent-2.0.0a65.dist-info/RECORD +0 -105
- {pycityagent-2.0.0a65.dist-info → pycityagent-2.0.0a67.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a65.dist-info → pycityagent-2.0.0a67.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a65.dist-info → pycityagent-2.0.0a67.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a65.dist-info → pycityagent-2.0.0a67.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ import asyncio
|
|
4
4
|
import logging
|
5
5
|
import os
|
6
6
|
from datetime import datetime, timedelta
|
7
|
+
import time
|
7
8
|
from typing import Any, Optional, Union, cast
|
8
9
|
|
9
10
|
from mosstool.type import TripMode
|
@@ -20,11 +21,18 @@ from .utils.const import *
|
|
20
21
|
|
21
22
|
logger = logging.getLogger("pycityagent")
|
22
23
|
|
24
|
+
__all__ = [
|
25
|
+
"Simulator",
|
26
|
+
]
|
27
|
+
|
23
28
|
|
24
29
|
class Simulator:
|
25
30
|
"""
|
26
|
-
|
27
|
-
|
31
|
+
Main class of the simulator.
|
32
|
+
|
33
|
+
- **Description**:
|
34
|
+
- This class is the core of the simulator, responsible for initializing and managing the simulation environment.
|
35
|
+
- It reads parameters from a configuration dictionary, initializes map data, and starts or connects to a simulation server as needed.
|
28
36
|
"""
|
29
37
|
|
30
38
|
def __init__(self, config: dict, secure: bool = False) -> None:
|
@@ -106,33 +114,74 @@ class Simulator:
|
|
106
114
|
poi["id"]: poi["aoi_id"] for _, poi in self.map.pois.items()
|
107
115
|
}
|
108
116
|
self._environment_prompt:dict[str, str] = {}
|
117
|
+
self._log_list = []
|
118
|
+
|
119
|
+
def get_log_list(self):
|
120
|
+
return self._log_list
|
121
|
+
|
122
|
+
def clear_log_list(self):
|
123
|
+
self._log_list = []
|
109
124
|
|
110
125
|
@property
|
111
|
-
def environment(self):
|
126
|
+
def environment(self) -> dict[str, str]:
|
127
|
+
"""
|
128
|
+
Get the current state of environment variables.
|
129
|
+
"""
|
112
130
|
return self._environment_prompt
|
113
|
-
|
131
|
+
|
114
132
|
def set_environment(self, environment: dict[str, str]):
|
133
|
+
"""
|
134
|
+
Set the entire dictionary of environment variables.
|
135
|
+
|
136
|
+
- **Args**:
|
137
|
+
- `environment` (`Dict[str, str]`): Key-value pairs of environment variables.
|
138
|
+
"""
|
115
139
|
self._environment_prompt = environment
|
116
140
|
|
117
|
-
def sence(self, key: str):
|
141
|
+
def sence(self, key: str) -> str:
|
142
|
+
"""
|
143
|
+
Retrieve the value of an environment variable by its key.
|
144
|
+
|
145
|
+
- **Args**:
|
146
|
+
- `key` (`str`): The key of the environment variable.
|
147
|
+
|
148
|
+
- **Returns**:
|
149
|
+
- `str`: The value of the corresponding key, or an empty string if not found.
|
150
|
+
"""
|
118
151
|
return self._environment_prompt.get(key, "")
|
119
|
-
|
152
|
+
|
120
153
|
def update_environment(self, key: str, value: str):
|
154
|
+
"""
|
155
|
+
Update the value of a single environment variable.
|
156
|
+
|
157
|
+
- **Args**:
|
158
|
+
- `key` (`str`): The key of the environment variable.
|
159
|
+
- `value` (`str`): The new value to set.
|
160
|
+
"""
|
121
161
|
self._environment_prompt[key] = value
|
122
162
|
|
123
163
|
# * Agent相关
|
124
164
|
def find_agents_by_area(self, req: dict, status=None):
|
125
165
|
"""
|
126
|
-
|
127
|
-
Get agents/persons in the provided area
|
166
|
+
Find agents/persons within a specified area.
|
128
167
|
|
129
|
-
Args
|
130
|
-
|
131
|
-
|
168
|
+
- **Args**:
|
169
|
+
- `req` (`dict`): A dictionary that describes the area. Refer to
|
170
|
+
https://cityproto.sim.fiblab.net/#city.person.1.GetPersonByLongLatBBoxRequest.
|
171
|
+
- `status` (`Optional[int]`): An integer representing the status of the agents/persons to filter by.
|
172
|
+
If provided, only persons with the given status will be returned.
|
173
|
+
Refer to https://cityproto.sim.fiblab.net/#city.agent.v2.Status.
|
132
174
|
|
133
|
-
Returns
|
134
|
-
|
175
|
+
- **Returns**:
|
176
|
+
- The response from the GetPersonByLongLatBBox method, possibly filtered by status.
|
177
|
+
Refer to https://cityproto.sim.fiblab.net/#city.person.1.GetPersonByLongLatBBoxResponse.
|
135
178
|
"""
|
179
|
+
start_time = time.time()
|
180
|
+
log = {
|
181
|
+
"req": "find_agents_by_area",
|
182
|
+
"start_time": start_time,
|
183
|
+
"consumption": 0
|
184
|
+
}
|
136
185
|
loop = asyncio.get_event_loop()
|
137
186
|
resp = loop.run_until_complete(
|
138
187
|
self._client.person_service.GetPersonByLongLatBBox(req=req)
|
@@ -146,6 +195,8 @@ class Simulator:
|
|
146
195
|
if agent.status in status:
|
147
196
|
motions.append(agent)
|
148
197
|
resp.motions = motions # type: ignore
|
198
|
+
log["consumption"] = time.time() - start_time
|
199
|
+
self._log_list.append(log)
|
149
200
|
return resp
|
150
201
|
|
151
202
|
def get_poi_categories(
|
@@ -153,6 +204,23 @@ class Simulator:
|
|
153
204
|
center: Optional[Union[tuple[float, float], Point]] = None,
|
154
205
|
radius: Optional[float] = None,
|
155
206
|
) -> list[str]:
|
207
|
+
"""
|
208
|
+
Retrieve unique categories of Points of Interest (POIs) around a central point.
|
209
|
+
|
210
|
+
- **Args**:
|
211
|
+
- `center` (`Optional[Union[Tuple[float, float], Point]]`): The central point as a tuple or Point object.
|
212
|
+
Defaults to (0, 0) if not provided.
|
213
|
+
- `radius` (`Optional[float]`): The search radius in meters. If not provided, all POIs are considered.
|
214
|
+
|
215
|
+
- **Returns**:
|
216
|
+
- `List[str]`: A list of unique POI category names.
|
217
|
+
"""
|
218
|
+
start_time = time.time()
|
219
|
+
log = {
|
220
|
+
"req": "get_poi_categories",
|
221
|
+
"start_time": start_time,
|
222
|
+
"consumption": 0
|
223
|
+
}
|
156
224
|
categories: list[str] = []
|
157
225
|
if center is None:
|
158
226
|
center = (0, 0)
|
@@ -164,23 +232,31 @@ class Simulator:
|
|
164
232
|
for poi in _pois:
|
165
233
|
catg = poi["category"]
|
166
234
|
categories.append(catg.split("|")[-1])
|
235
|
+
log["consumption"] = time.time() - start_time
|
236
|
+
self._log_list.append(log)
|
167
237
|
return list(set(categories))
|
168
238
|
|
169
239
|
async def get_time(
|
170
240
|
self, format_time: bool = False, format: str = "%H:%M:%S"
|
171
241
|
) -> Union[int, str]:
|
172
242
|
"""
|
173
|
-
|
174
|
-
默认返回以00:00:00为始的, 以s为单位的时间(int)
|
175
|
-
支持格式化时间
|
243
|
+
Get the current time of the simulator.
|
176
244
|
|
177
|
-
|
178
|
-
- format_time (bool): 是否格式化 format or not
|
179
|
-
- format (str): 格式化模板,默认为"Hour:Minute:Second" the formation
|
245
|
+
By default, returns the number of seconds since midnight. Supports formatted output.
|
180
246
|
|
181
|
-
|
182
|
-
|
247
|
+
- **Args**:
|
248
|
+
- `format_time` (`bool`): Whether to return the time in a formatted string. Defaults to `False`.
|
249
|
+
- `format` (`str`): The format string for formatting the time. Defaults to "%H:%M:%S".
|
250
|
+
|
251
|
+
- **Returns**:
|
252
|
+
- `Union[int, str]`: The current simulation time either as an integer representing seconds since midnight or as a formatted string.
|
183
253
|
"""
|
254
|
+
start_time = time.time()
|
255
|
+
log = {
|
256
|
+
"req": "get_time",
|
257
|
+
"start_time": start_time,
|
258
|
+
"consumption": 0
|
259
|
+
}
|
184
260
|
now = await self._client.clock_service.Now({})
|
185
261
|
now = cast(dict[str, int], now)
|
186
262
|
self.time = now["t"]
|
@@ -189,44 +265,133 @@ class Simulator:
|
|
189
265
|
start_of_day = datetime.combine(current_date, datetime.min.time())
|
190
266
|
current_time = start_of_day + timedelta(seconds=now["t"])
|
191
267
|
formatted_time = current_time.strftime(format)
|
268
|
+
log["consumption"] = time.time() - start_time
|
269
|
+
self._log_list.append(log)
|
192
270
|
return formatted_time
|
193
271
|
else:
|
272
|
+
log["consumption"] = time.time() - start_time
|
273
|
+
self._log_list.append(log)
|
194
274
|
return int(now["t"])
|
195
275
|
|
196
276
|
async def pause(self):
|
277
|
+
"""
|
278
|
+
Pause the simulation.
|
279
|
+
|
280
|
+
This method sends a request to the simulator's pause service to pause the simulation.
|
281
|
+
"""
|
282
|
+
start_time = time.time()
|
283
|
+
log = {
|
284
|
+
"req": "pause",
|
285
|
+
"start_time": start_time,
|
286
|
+
"consumption": 0
|
287
|
+
}
|
197
288
|
await self._client.pause_service.pause()
|
289
|
+
log["consumption"] = time.time() - start_time
|
290
|
+
self._log_list.append(log)
|
198
291
|
|
199
292
|
async def resume(self):
|
293
|
+
"""
|
294
|
+
Resume the simulation.
|
295
|
+
|
296
|
+
This method sends a request to the simulator's pause service to resume the simulation.
|
297
|
+
"""
|
298
|
+
start_time = time.time()
|
299
|
+
log = {
|
300
|
+
"req": "resume",
|
301
|
+
"start_time": start_time,
|
302
|
+
"consumption": 0
|
303
|
+
}
|
200
304
|
await self._client.pause_service.resume()
|
305
|
+
log["consumption"] = time.time() - start_time
|
306
|
+
self._log_list.append(log)
|
201
307
|
|
202
308
|
async def get_simulator_day(self) -> int:
|
203
309
|
"""
|
204
|
-
|
310
|
+
Get the current day of the simulation.
|
311
|
+
|
312
|
+
- **Returns**:
|
313
|
+
- `int`: The day number since the start of the simulation.
|
205
314
|
"""
|
315
|
+
start_time = time.time()
|
316
|
+
log = {
|
317
|
+
"req": "get_simulator_day",
|
318
|
+
"start_time": start_time,
|
319
|
+
"consumption": 0
|
320
|
+
}
|
206
321
|
now = await self._client.clock_service.Now({})
|
207
322
|
now = cast(dict[str, int], now)
|
208
323
|
day = now["day"]
|
324
|
+
log["consumption"] = time.time() - start_time
|
325
|
+
self._log_list.append(log)
|
209
326
|
return day
|
210
327
|
|
211
328
|
async def get_simulator_second_from_start_of_day(self) -> int:
|
212
329
|
"""
|
213
|
-
|
330
|
+
Get the number of seconds elapsed from the start of the current day in the simulation.
|
331
|
+
|
332
|
+
- **Returns**:
|
333
|
+
- `int`: The number of seconds from 00:00:00 of the current day.
|
214
334
|
"""
|
335
|
+
start_time = time.time()
|
336
|
+
log = {
|
337
|
+
"req": "get_simulator_second_from_start_of_day",
|
338
|
+
"start_time": start_time,
|
339
|
+
"consumption": 0
|
340
|
+
}
|
215
341
|
now = await self._client.clock_service.Now({})
|
216
342
|
now = cast(dict[str, int], now)
|
343
|
+
log["consumption"] = time.time() - start_time
|
344
|
+
self._log_list.append(log)
|
217
345
|
return now["t"] % 86400
|
218
346
|
|
219
347
|
async def get_person(self, person_id: int) -> dict:
|
220
|
-
|
348
|
+
"""
|
349
|
+
Retrieve information about a specific person by ID.
|
350
|
+
|
351
|
+
- **Args**:
|
352
|
+
- `person_id` (`int`): The ID of the person to retrieve information for.
|
353
|
+
|
354
|
+
- **Returns**:
|
355
|
+
- `Dict`: Information about the specified person.
|
356
|
+
"""
|
357
|
+
start_time = time.time()
|
358
|
+
log = {
|
359
|
+
"req": "get_person",
|
360
|
+
"start_time": start_time,
|
361
|
+
"consumption": 0
|
362
|
+
}
|
363
|
+
person = await self._client.person_service.GetPerson(
|
221
364
|
req={"person_id": person_id}
|
222
365
|
) # type:ignore
|
366
|
+
log["consumption"] = time.time() - start_time
|
367
|
+
self._log_list.append(log)
|
368
|
+
return person
|
223
369
|
|
224
370
|
async def add_person(self, person: Any) -> dict:
|
371
|
+
"""
|
372
|
+
Add a new person to the simulation.
|
373
|
+
|
374
|
+
- **Args**:
|
375
|
+
- `person` (`Any`): The person object to add. If it's an instance of `person_pb2.Person`,
|
376
|
+
it will be wrapped in an `AddPersonRequest`. Otherwise, `person` is expected to already be a valid request object.
|
377
|
+
|
378
|
+
- **Returns**:
|
379
|
+
- `Dict`: Response from adding the person.
|
380
|
+
"""
|
381
|
+
start_time = time.time()
|
382
|
+
log = {
|
383
|
+
"req": "add_person",
|
384
|
+
"start_time": start_time,
|
385
|
+
"consumption": 0
|
386
|
+
}
|
225
387
|
if isinstance(person, person_pb2.Person):
|
226
388
|
req = person_service.AddPersonRequest(person=person)
|
227
389
|
else:
|
228
390
|
req = person
|
229
|
-
|
391
|
+
person_id = await self._client.person_service.AddPerson(req) # type:ignore
|
392
|
+
log["consumption"] = time.time() - start_time
|
393
|
+
self._log_list.append(log)
|
394
|
+
return person_id
|
230
395
|
|
231
396
|
async def set_aoi_schedules(
|
232
397
|
self,
|
@@ -237,6 +402,24 @@ class Simulator:
|
|
237
402
|
departure_times: Optional[list[float]] = None,
|
238
403
|
modes: Optional[list[TripMode]] = None,
|
239
404
|
):
|
405
|
+
"""
|
406
|
+
Set schedules for a person to visit Areas of Interest (AOIs).
|
407
|
+
|
408
|
+
- **Args**:
|
409
|
+
- `person_id` (`int`): The ID of the person whose schedule is being set.
|
410
|
+
- `target_positions` (`Union[List[Union[int, Tuple[int, int]]], Union[int, Tuple[int, int]]]`):
|
411
|
+
A list of AOI or POI IDs or tuples of (AOI ID, POI ID) that the person will visit.
|
412
|
+
- `departure_times` (`Optional[List[float]]`): Departure times for each trip in the schedule.
|
413
|
+
If not provided, current time will be used for all trips.
|
414
|
+
- `modes` (`Optional[List[TripMode]]`): Travel modes for each trip.
|
415
|
+
Defaults to `TRIP_MODE_DRIVE_ONLY` if not specified.
|
416
|
+
"""
|
417
|
+
start_time = time.time()
|
418
|
+
log = {
|
419
|
+
"req": "set_aoi_schedules",
|
420
|
+
"start_time": start_time,
|
421
|
+
"consumption": 0
|
422
|
+
}
|
240
423
|
cur_time = float(await self.get_time())
|
241
424
|
if not isinstance(target_positions, list):
|
242
425
|
target_positions = [target_positions]
|
@@ -286,6 +469,8 @@ class Simulator:
|
|
286
469
|
)
|
287
470
|
req = {"person_id": person_id, "schedules": _schedules}
|
288
471
|
await self._client.person_service.SetSchedule(req)
|
472
|
+
log["consumption"] = time.time() - start_time
|
473
|
+
self._log_list.append(log)
|
289
474
|
|
290
475
|
async def reset_person_position(
|
291
476
|
self,
|
@@ -295,6 +480,22 @@ class Simulator:
|
|
295
480
|
lane_id: Optional[int] = None,
|
296
481
|
s: Optional[float] = None,
|
297
482
|
):
|
483
|
+
"""
|
484
|
+
Reset the position of a person within the simulation.
|
485
|
+
|
486
|
+
- **Args**:
|
487
|
+
- `person_id` (`int`): The ID of the person whose position is being reset.
|
488
|
+
- `aoi_id` (`Optional[int]`): The ID of the Area of Interest (AOI) where the person should be placed.
|
489
|
+
- `poi_id` (`Optional[int]`): The ID of the Point of Interest (POI) within the AOI.
|
490
|
+
- `lane_id` (`Optional[int]`): The ID of the lane on which the person should be placed.
|
491
|
+
- `s` (`Optional[float]`): The longitudinal position along the lane.
|
492
|
+
"""
|
493
|
+
start_time = time.time()
|
494
|
+
log = {
|
495
|
+
"req": "reset_person_position",
|
496
|
+
"start_time": start_time,
|
497
|
+
"consumption": 0
|
498
|
+
}
|
298
499
|
reset_position = {}
|
299
500
|
if aoi_id is not None:
|
300
501
|
reset_position["aoi_position"] = {"aoi_id": aoi_id}
|
@@ -323,6 +524,8 @@ class Simulator:
|
|
323
524
|
logger.debug(
|
324
525
|
f"Neither aoi or lane pos provided for person {person_id} position reset!!"
|
325
526
|
)
|
527
|
+
log["consumption"] = time.time() - start_time
|
528
|
+
self._log_list.append(log)
|
326
529
|
|
327
530
|
def get_around_poi(
|
328
531
|
self,
|
@@ -330,9 +533,26 @@ class Simulator:
|
|
330
533
|
radius: float,
|
331
534
|
poi_type: Union[str, list[str]],
|
332
535
|
) -> list[dict]:
|
536
|
+
"""
|
537
|
+
Get Points of Interest (POIs) around a central point based on type.
|
538
|
+
|
539
|
+
- **Args**:
|
540
|
+
- `center` (`Union[Tuple[float, float], Point]`): The central point as a tuple or Point object.
|
541
|
+
- `radius` (`float`): The search radius in meters.
|
542
|
+
- `poi_type` (`Union[str, List[str]]`): The category or categories of POIs to filter by.
|
543
|
+
|
544
|
+
- **Returns**:
|
545
|
+
- `List[Dict]`: A list of dictionaries containing information about the POIs found.
|
546
|
+
"""
|
547
|
+
start_time = time.time()
|
548
|
+
log = {
|
549
|
+
"req": "get_around_poi",
|
550
|
+
"start_time": start_time,
|
551
|
+
"consumption": 0
|
552
|
+
}
|
333
553
|
if isinstance(poi_type, str):
|
334
554
|
poi_type = [poi_type]
|
335
|
-
transformed_poi_type = []
|
555
|
+
transformed_poi_type: list[str] = []
|
336
556
|
for t in poi_type:
|
337
557
|
if t not in self.poi_cate:
|
338
558
|
transformed_poi_type.append(t)
|
@@ -352,4 +572,6 @@ class Simulator:
|
|
352
572
|
if catg.split("|")[-1] not in poi_type_set:
|
353
573
|
continue
|
354
574
|
pois.append(poi)
|
355
|
-
|
575
|
+
log["consumption"] = time.time() - start_time
|
576
|
+
self._log_list.append(log)
|
577
|
+
return pois
|
@@ -4,11 +4,11 @@ utilities
|
|
4
4
|
"""
|
5
5
|
|
6
6
|
from .geojson import wrap_feature_collection
|
7
|
-
from .base64 import encode_to_base64
|
8
7
|
from .port import find_free_port
|
8
|
+
from .base64 import encode_to_base64
|
9
9
|
|
10
10
|
__all__ = [
|
11
11
|
"wrap_feature_collection",
|
12
12
|
"find_free_port",
|
13
|
-
"
|
13
|
+
"encode_to_base64",
|
14
14
|
]
|
@@ -6,11 +6,11 @@ def wrap_feature_collection(features: list[dict], name: str):
|
|
6
6
|
将 GeoJSON Feature 集合包装为 FeatureCollection
|
7
7
|
Wrap GeoJSON Feature collection as FeatureCollection
|
8
8
|
|
9
|
-
Args
|
9
|
+
- **Args**:
|
10
10
|
- features: GeoJSON Feature 集合。GeoJSON Feature collection.
|
11
11
|
- name: FeatureCollection 名称。FeatureCollection name.
|
12
12
|
|
13
|
-
Returns
|
13
|
+
- **Returns**:
|
14
14
|
- dict: GeoJSON FeatureCollection
|
15
15
|
"""
|
16
16
|
return {
|
@@ -8,11 +8,11 @@ def create_channel(server_address: str, secure: bool = False) -> grpc.Channel:
|
|
8
8
|
创建一个grpc的channel
|
9
9
|
Create a grpc channel
|
10
10
|
|
11
|
-
Args
|
11
|
+
- **Args**:
|
12
12
|
- server_address (str): 服务器地址。server address.
|
13
13
|
- secure (bool, optional): 是否使用安全连接. Defaults to False. Whether to use a secure connection. Defaults to False.
|
14
14
|
|
15
|
-
Returns
|
15
|
+
- **Returns**:
|
16
16
|
- grpc.Channel: grpc的channel。grpc channel.
|
17
17
|
"""
|
18
18
|
if server_address.startswith("http://"):
|
@@ -35,11 +35,11 @@ def create_aio_channel(server_address: str, secure: bool = False) -> grpc.aio.Ch
|
|
35
35
|
创建一个grpc的异步channel
|
36
36
|
Create a grpc asynchronous channel
|
37
37
|
|
38
|
-
Args
|
38
|
+
- **Args**:
|
39
39
|
- server_address (str): 服务器地址。server address.
|
40
40
|
- secure (bool, optional): 是否使用安全连接. Defaults to False. Whether to use a secure connection. Defaults to False.
|
41
41
|
|
42
|
-
Returns
|
42
|
+
- **Returns**:
|
43
43
|
- grpc.aio.Channel: grpc的异步channel。grpc asynchronous channel.
|
44
44
|
"""
|
45
45
|
if server_address.startswith("http://"):
|
@@ -13,12 +13,12 @@ def point_on_line_given_distance(start_node, end_node, distance):
|
|
13
13
|
Given two points (start_point and end_point) defining a line, and a distance s to travel along the line,
|
14
14
|
return the coordinates of the point reached after traveling s units along the line, starting from start_point.
|
15
15
|
|
16
|
-
Args
|
16
|
+
- **Args**:
|
17
17
|
start_point (tuple): tuple of (x, y) representing the starting point on the line.
|
18
18
|
end_point (tuple): tuple of (x, y) representing the ending point on the line.
|
19
19
|
distance (float): Distance to travel along the line, starting from start_point.
|
20
20
|
|
21
|
-
Returns
|
21
|
+
- **Returns**:
|
22
22
|
tuple: tuple of (x, y) representing the new point reached after traveling s units along the line.
|
23
23
|
"""
|
24
24
|
|