async def read_population_heatmap( *, db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends(deps.get_current_active_user), modus: CalculationTypes, scenario_id: Optional[int] = Query( description= "The scenario id to calculate the heatmap in case the modus is 'scenario' or 'comparison'", default=0, example=1, ), return_type: ReturnType = Query(description="Return type of the response", default=ReturnType.geojson), ) -> Any: """ Retrieve the population heatmap. """ scenario_id = await deps.check_user_owns_scenario( db=db, current_user=current_user, scenario_id=scenario_id) template_sql = SQLReturnTypes[return_type.value].value heatmap = await db.execute( text(template_sql % """ SELECT * FROM basic.heatmap_population(:active_study_area_id, :modus, :scenario_id) """), { "active_study_area_id": current_user.active_study_area_id, "modus": modus.value, "scenario_id": scenario_id, }, ) heatmap = heatmap.fetchall()[0][0] return return_geojson_or_geobuf(heatmap, return_type.value)
async def read_local_accessibility_heatmap( *, db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends(deps.get_current_active_user), heatmap_type: AccessibilityHeatmapTypes, modus: CalculationTypes, scenario_id: Optional[int] = Query( description= "The scenario id to calculate the heatmap in case the modus is 'scenario' or 'comparison'", default=0, example=1, ), heatmap_configuration: str = Query( ..., description= "The configuration per POI category to create the dynamic heatmap.", example=request_examples["heatmap_configuration"], ), return_type: ReturnType = Query(description="Return type of the response", default=ReturnType.geojson), ) -> Any: """ Retrieve the local accessibility heatmap. """ scenario_id = await deps.check_user_owns_scenario( db=db, current_user=current_user, scenario_id=scenario_id) if check_dict_schema(HeatmapConfiguration, json.loads(heatmap_configuration)) == False: raise HTTPException(status_code=400, detail="Heatmap configuration is not valid.") active_data_uploads_study_area = await db.execute( func.basic.active_data_uploads_study_area(current_user.id)) active_data_uploads_study_area = active_data_uploads_study_area.scalar() if active_data_uploads_study_area == None: active_data_uploads_study_area = [] query_params = { "heatmap_configuration": heatmap_configuration, "user_id": current_user.id, "active_study_area_id": current_user.active_study_area_id, "modus": modus.value, "scenario_id": scenario_id, "data_upload_ids": active_data_uploads_study_area, } template_sql = SQLReturnTypes[return_type.value].value heatmap = await db.execute( text(template_sql % f""" SELECT * FROM basic.{heatmap_type.value}((:heatmap_configuration)::jsonb, :user_id, :active_study_area_id, :modus, :scenario_id, :data_upload_ids) """), query_params, ) heatmap = heatmap.fetchall()[0][0] return return_geojson_or_geobuf(heatmap, return_type.value)
async def static_vector_layer(*, db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends( deps.get_current_active_user), layer_name: str, return_type: str): """Return selected layers in different vector formats""" layer_to_return = await crud.layer.static_vector_layer( db, current_user, layer_name, return_type) return return_geojson_or_geobuf(layer_to_return, return_type)
async def calculate_reached_network( *, db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends(deps.get_current_active_user), isochrone_calculation_id: int = Path( ..., description="Isochrone Calculation ID", example=1), modus: CalculationTypes = Path(..., description="Calculation modus"), return_type: ReturnWithoutDbGeobufEnum = Query( description="Return type of the response", default=ReturnWithoutDbGeobufEnum.geojson), ) -> Any: """ Calculate the reached network for a single isochrone. """ await deps.check_user_owns_isochrone_calculation( db=db, isochrone_calculation_id=isochrone_calculation_id, current_user=current_user) isochrone_calc_obj = await crud.isochrone_calculation.get_by_key( db=db, key="id", value=isochrone_calculation_id) isochrone_calc_obj = isochrone_calc_obj[0] isochrone_feature_obj = await crud.isochrone_feature.get_by_key( db=db, key="isochrone_calculation_id", value=isochrone_calculation_id) minutes = int(max([obj.step for obj in isochrone_feature_obj]) / 60) x, y = isochrone_calc_obj.starting_point.replace("POINT (", "").replace(")", "").split(" ") obj_calculation = IsochroneSingle( minutes=minutes, speed=3.6 * isochrone_calc_obj.speed, n=len(isochrone_feature_obj), modus=modus.value, x=x, y=y, user_id=current_user.id, routing_profile=isochrone_calc_obj.routing_profile, active_upload_ids=current_user.active_data_upload_ids, scenario_id=isochrone_calc_obj.scenario_id, ) network = await crud.isochrone.calculate_reached_network( db=db, obj_in=obj_calculation) return return_geojson_or_geobuf( json.JSONDecoder().decode(json.dumps(network)), return_type.value)
async def poi_aoi_visualization( return_type: ReturnType, scenario_id: Optional[int] = Query( description="The scenario id to get the POIs in case the modus is 'scenario' or 'comparison'.", default=0, example=1, ), db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Visualize POIs and AOIs based on settings specified by the user. """ scenario_id = await deps.check_user_owns_scenario(db, scenario_id, current_user) pois = await crud.poi_aoi.poi_aoi_visualization( db=db, scenario_id=scenario_id, current_user=current_user, return_type=return_type ) return return_geojson_or_geobuf(pois, return_type)
async def read_scenario_features( *, db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends(deps.get_current_active_user), scenario_id: int = Path( ..., description="Scenario ID", example=request_examples["read_features"]["scenario_id"] ), layer_name: schemas.ScenarioLayersNoPoisEnum = Path( ..., description="Scenario layer name to read", example=request_examples["read_features"]["layer_name"], ), intersect: Optional[str] = Query( default=None, description="WKT Geometry to intersect with layer. Geometry must be in EPSG:4326. If not specified, all features are returned (only for _modified tables).", example=request_examples["read_features"]["intersect"], ), return_type: ReturnWithoutDbGeobufEnum = Query( default=ReturnWithoutDbGeobufEnum.geojson, description="Return type of the response" ), ) -> Any: """ Get features from scenario layers (default or modified). """ scenario = await crud.scenario.get_by_multi_keys( db, keys={"id": scenario_id, "user_id": current_user.id} ) if len(scenario) == 0: raise HTTPException(status_code=400, detail="Scenario not found") result = await crud.scenario.read_scenario_features( db, current_user, scenario_id, layer_name, intersect ) features = to_feature_collection( result, exclude_properties=["coordinates_3857", "node_source", "node_target"] ) if return_type.value == ReturnWithoutDbGeobufEnum.geojson.value: features = jsonable_encoder(features) return return_geojson_or_geobuf(features, return_type.value)
async def read_connectivity_heatmap( *, db: AsyncSession = Depends(deps.get_db), current_user: models.User = Depends(deps.get_current_active_user), return_type: ReturnType = Query(description="Return type of the response", default=ReturnType.geojson), ) -> Any: """ Retrieve the connectivity heatmap. """ template_sql = SQLReturnTypes[return_type.value].value heatmap = await db.execute( text(template_sql % """ SELECT g.id AS grid_visualization_id, g.percentile_area_isochrone, g.area_isochrone, 'default' AS modus, g.geom FROM basic.grid_visualization g, basic.study_area_grid_visualization s WHERE g.id = s.grid_visualization_id AND s.study_area_id = :active_study_area_id """), {"active_study_area_id": current_user.active_study_area_id}, ) heatmap = heatmap.fetchall()[0][0] return return_geojson_or_geobuf(heatmap, return_type.value)