Repository navigation
Expand file tree
/
Copy pathlocation.py
More file actions
191 lines (170 loc) · 5.87 KB
/
Copy pathlocation.py
File metadata and controls
191 lines (170 loc) · 5.87 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# ===============================================================================
# Copyright 2025 ross
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ===============================================================================
from fastapi import APIRouter
from fastapi import Query, Response
from fastapi_pagination.ext.sqlalchemy import paginate
from sqlalchemy import select, func
from starlette import status
from api.pagination import CustomPage
from core.constants import SRID_WGS84
from core.dependencies import (
session_dependency,
admin_dependency,
editor_dependency,
viewer_dependency,
)
from db.location import Location
from schemas.location import CreateLocation, LocationResponse, UpdateLocation
from services.crud_helper import model_patcher, model_deleter, model_adder
from services.geospatial_helper import make_within_wkt
from services.location_helper import set_geographic_attributes
from services.query_helper import make_query, order_sort_filter, simple_get_by_id
router = APIRouter(prefix="/location", tags=["location"])
@router.post(
"",
# response_model=GetLocation,
summary="Create a new sample location",
status_code=status.HTTP_201_CREATED,
)
def create_location(
location_data: CreateLocation, session: session_dependency, user: admin_dependency
) -> LocationResponse:
"""
Create a new sample location in the database.
"""
location = model_adder(session, Location, location_data, user=user)
set_geographic_attributes(session, location_data, location)
return location
@router.patch(
"/{location_id}",
summary="Update a location",
)
def update_location(
location_id: int,
location_data: UpdateLocation,
session: session_dependency,
user: editor_dependency,
) -> LocationResponse:
"""
Update a sample location in the database.
"""
location = model_patcher(session, Location, location_id, location_data, user=user)
set_geographic_attributes(session, location_data, location)
return location
# @router.get("/shapefile", summary="Get location as shapefile")
# async def get_location_shapefile(
# query: str = None, session: Session = Depends(get_db_session)
# ) -> FileResponse:
# """
# Retrieve all sample locations as a shapefile.
# """
# sql = select(Location)
# if query:
# sql = sql.where(make_query(Location, query))
#
# result = session.execute(sql)
# locations = result.scalars().all()
# # create a shapefile from the locations
#
# create_shapefile(locations, "locations.shp")
# # Return the shapefile as a zip (optional: zip the .shp, .shx, .dbf files)
# import zipfile
#
# with zipfile.ZipFile("locations.zip", "w") as zf:
# for ext in ["shp", "shx", "dbf"]:
# zf.write(f"locations.{ext}")
# return FileResponse(
# "locations.zip", media_type="application/zip", filename="locations.zip"
# )
# @router.get("/feature_collection", summary="Get location feature collection")
# async def get_location_feature_collection(
# query: str = None, session: Session = Depends(get_db_session)
# ) -> dict:
# """
# Retrieve all sample locations as a GeoJSON FeatureCollection.
# """
# sql = select(Location, geofunc.ST_AsGeoJSON(Location.point).label("geojson"))
# if query:
# sql = sql.where(make_query(Location, query))
#
# result = session.execute(sql)
# locations = result.all()
#
# features = []
# for location, geojson in locations:
# feature = {
# "type": "Feature",
# "geometry": json.loads(geojson),
# }
# features.append(feature)
#
# return {
# "type": "FeatureCollection",
# "features": features,
# }
@router.get(
"",
summary="Get all locations",
)
def get_location(
session: session_dependency,
user: viewer_dependency,
nearby_point: str = None,
nearby_distance_km: float = 1,
within: str = None,
query: str = None,
sort: str = None,
order: str = None,
filter_: str = Query(alias="filter", default=None),
) -> CustomPage[LocationResponse]:
"""
Retrieve all wells from the database.
"""
sql = select(Location)
if query:
sql = sql.where(make_query(Location, query))
elif nearby_point:
nearby_point = func.ST_GeomFromText(nearby_point, SRID_WGS84)
sql = sql.where(
# func.ST_Distance(SampleLocation.point, nearby_point) <= nearby_distance_km
func.ST_Distance(nearby_point, Location.point)
<= nearby_distance_km
)
elif within:
sql = make_within_wkt(sql, within)
sql = order_sort_filter(sql, Location, sort, order, filter_)
return paginate(query=sql, conn=session)
@router.get(
"/{location_id}",
summary="Get location by ID",
)
def get_location_by_id(
location_id: int, session: session_dependency, user: viewer_dependency
) -> LocationResponse:
"""
Retrieve a sample location by ID from the database.
"""
location = simple_get_by_id(session, Location, location_id)
return location
@router.delete("/{location_id}", summary="Delete location by ID")
def delete_location(
location_id: int, session: session_dependency, user: admin_dependency
) -> Response:
"""
Delete a sample location by ID from the database.
"""
return model_deleter(session, Location, location_id)
# ============= EOF =============================================