Skip to content
This repository has been archived by the owner on Oct 5, 2024. It is now read-only.

Commit

Permalink
Change key/value to tags
Browse files Browse the repository at this point in the history
  • Loading branch information
emi420 committed Sep 17, 2023
1 parent 1f3b036 commit 774ae6f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 73 deletions.
109 changes: 53 additions & 56 deletions python/dbapi/api/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,26 @@

from .db import UnderpassDB

RESULTS_PER_PAGE = 25
RESULTS_PER_PAGE = 100

# TODO: improve this code
def tagsQueryFilter(tagsQuery, table):
query = ""
tags = tagsQuery.split(",")
keyValue = tags[0].split("=")

if len(keyValue) == 2:
query += "{0}.tags->'{1}' ~* '^{2}'".format(table, keyValue[0], keyValue[1])
else:
query += "{0}.tags ? '{1}'".format(table, keyValue[0])

for tag in tags[1:]:
keyValue = tag.split("=")
if len(keyValue) == 2:
query += "OR {0}.tags->'{!}' ~* '^{2}'".format(table, keyValue[0], keyValue[1])
else:
query += "OR {0}.tags ? '{1}'".format(table, keyValue[0])
return query

class Raw:
def __init__(self, db):
Expand All @@ -28,8 +47,7 @@ def __init__(self, db):
def getPolygons(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
Expand All @@ -38,25 +56,23 @@ def getPolygons(
SELECT 'Polygon' as type, ways_poly.osm_id as id, ways_poly.timestamp, geom as geometry, tags, status FROM ways_poly \
LEFT JOIN validation ON validation.osm_id = ways_poly.osm_id \
WHERE \
{0} {1} {2} {3} \
{0} {1} {2} \
), \
t_features AS ( \
SELECT jsonb_build_object( 'type', 'Feature', 'id', id, 'properties', to_jsonb(t_ways) \
- 'geometry' , 'geometry', ST_AsGeoJSON(geometry)::jsonb ) AS feature FROM t_ways \
) SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', jsonb_agg(t_features.feature) ) \
as result FROM t_features;".format(
"ST_Intersects(\"geom\", ST_GeomFromText('POLYGON(({0}))', 4326) )".format(area) if area else "1=1 ",
"and ways_poly.tags ? '{0}'".format(key) if key and not value else "",
"and ways_poly.tags->'{0}' ~* '^{1}'".format(key, value) if key and value else "",
"ORDER BY ways_poly.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE) + " OFFSET {0}".format(page * RESULTS_PER_PAGE) if page else "",
"AND (" + tagsQueryFilter(tags, "ways_poly") + ")" if tags else "",
"ORDER BY ways_poly.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE),
)
return self.underpassDB.run(query, responseType, True)

def getLines(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
Expand All @@ -65,25 +81,23 @@ def getLines(
SELECT 'LineString' as type, ways_line.osm_id as id, ways_line.timestamp, geom as geometry, tags, status FROM ways_line \
LEFT JOIN validation ON validation.osm_id = ways_line.osm_id \
WHERE \
{0} {1} {2} {3} \
{0} {1} {2} \
), \
t_features AS ( \
SELECT jsonb_build_object( 'type', 'Feature', 'id', id, 'properties', to_jsonb(t_ways) \
- 'geometry' , 'geometry', ST_AsGeoJSON(geometry)::jsonb ) AS feature FROM t_ways \
) SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', jsonb_agg(t_features.feature) ) \
as result FROM t_features;".format(
"ST_Intersects(\"geom\", ST_GeomFromText('POLYGON(({0}))', 4326) )".format(area) if area else "1=1 ",
"and ways_line.tags ? '{0}'".format(key) if key and not value else "",
"and ways_line.tags->'{0}' ~* '^{1}'".format(key, value) if key and value else "",
"ORDER BY ways_line.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE) + " OFFSET {0}".format(page * RESULTS_PER_PAGE) if page else "",
"AND (" + tagsQueryFilter(tags, "ways_line") + ")" if tags else "",
"ORDER BY ways_line.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE),
)
return self.underpassDB.run(query, responseType, True)

def getNodes(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
Expand All @@ -92,99 +106,89 @@ def getNodes(
SELECT 'Point' as type, nodes.osm_id as id, nodes.timestamp, geom as geometry, tags, status FROM nodes \
LEFT JOIN validation ON validation.osm_id = nodes.osm_id \
WHERE \
{0} {1} {2} {3} \
{0} {1} {2} \
), \
t_features AS ( \
SELECT jsonb_build_object( 'type', 'Feature', 'id', id, 'properties', to_jsonb(t_nodes) \
- 'geometry' - 'osm_id' , 'geometry', ST_AsGeoJSON(geometry)::jsonb ) AS feature FROM t_nodes \
) SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', jsonb_agg(t_features.feature) ) \
as result FROM t_features;".format(
"ST_Intersects(\"geom\", ST_GeomFromText('POLYGON(({0}))', 4326) )".format(area) if area else "1=1 ",
"and nodes.tags ? '{0}'".format(key) if key and not value else "",
"and nodes.tags->'{0}' ~* '^{1}'".format(key, value) if key and value else "",
"ORDER BY nodes.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE) + " OFFSET {0}".format(page * RESULTS_PER_PAGE) if page else "",
"AND (" + tagsQueryFilter(tags, "nodes") + ")" if tags else "",
"ORDER BY nodes.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE),
)
return self.underpassDB.run(query, responseType, True)

def getAll(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
):

polygons = self.getPolygons(
area,
key,
value,
tags,
hashtag,
responseType,
page)

lines = self.getLines(
area,
key,
value,
tags,
hashtag,
responseType,
page)

nodes = self.getNodes(
area,
key,
value,
tags,
hashtag,
responseType,
page)

result = {'type': 'FeatureCollection', 'features': []}

if polygons['features']:
if 'features' in polygons and polygons['features']:
result['features'] = result['features'] + polygons['features']

if lines['features']:
if 'features' in lines and lines['features']:
result['features'] = result['features'] + lines['features']

elif nodes['features']:
elif 'features' in nodes and nodes['features']:
result['features'] = result['features'] + nodes['features']

return result

def getPolygonsList(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
):
if page == 0:
page = 1

query = "with t_ways AS ( \
SELECT 'way' as type, 'Polygon' as geotype, ways_poly.osm_id as id, ST_X(ST_Centroid(geom)) as lat, ST_Y(ST_Centroid(geom)) as lon, ways_poly.timestamp, tags, status FROM ways_poly \
LEFT JOIN validation ON validation.osm_id = ways_poly.osm_id \
WHERE \
{0} {1} {2} {3} \
{0} {1} {2} \
), t_features AS ( \
SELECT to_jsonb(t_ways) as feature from t_ways \
) SELECT jsonb_agg(t_features.feature) as result FROM t_features;".format(
"ST_Intersects(\"geom\", ST_GeomFromText('POLYGON(({0}))', 4326) )".format(area) if area else "1=1 ",
"and ways_poly.tags ? '{0}'".format(key) if key and not value else "",
"and ways_poly.tags->'{0}' ~* '^{1}'".format(key, value) if key and value else "",
"ORDER BY ways_poly.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE) + " OFFSET {0}".format(page * RESULTS_PER_PAGE) if page else "",
"AND (" + tagsQueryFilter(tags, "ways_poly") + ")" if tags else "",
"ORDER BY ways_poly.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE),
)
return self.underpassDB.run(query, responseType, True)

def getLinesList(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
Expand All @@ -196,22 +200,20 @@ def getLinesList(
SELECT 'way' as type, 'LineString' as geotype, ways_line.osm_id as id, ST_X(ST_Centroid(geom)) as lat, ST_Y(ST_Centroid(geom)) as lon, ways_line.timestamp, tags, status FROM ways_line \
LEFT JOIN validation ON validation.osm_id = ways_line.osm_id \
WHERE \
{0} {1} {2} {3} \
{0} {1} {2} \
), t_features AS ( \
SELECT to_jsonb(t_lines) as feature from t_lines \
) SELECT jsonb_agg(t_features.feature) as result FROM t_features;".format(
"ST_Intersects(\"geom\", ST_GeomFromText('POLYGON(({0}))', 4326) )".format(area) if area else "1=1 ",
"and ways_line.tags ? '{0}'".format(key) if key and not value else "",
"and ways_line.tags->'{0}' ~* '^{1}'".format(key, value) if key and value else "",
"AND (" + tagsQueryFilter(tags, "ways_line") + ")" if tags else "",
"ORDER BY ways_line.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE) + " OFFSET {0}".format(page * RESULTS_PER_PAGE) if page else "",
)
return self.underpassDB.run(query, responseType, True)

def getNodesList(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
Expand All @@ -222,48 +224,43 @@ def getNodesList(
query = "with t_nodes AS ( \
SELECT 'node' as type, 'Point' as geotype, nodes.osm_id as id, ST_X(ST_Centroid(geom)) as lat, ST_Y(ST_Centroid(geom)) as lon, nodes.timestamp, tags, status FROM nodes \
LEFT JOIN validation ON validation.osm_id = nodes.osm_id \
WHERE {0} {1} {2} {3} \
WHERE {0} {1} {2} \
), \
t_features AS ( \
SELECT to_jsonb(t_nodes) AS feature FROM t_nodes \
) SELECT jsonb_agg(t_features.feature) as result FROM t_features;".format(
"ST_Intersects(\"geom\", ST_GeomFromText('POLYGON(({0}))', 4326) )".format(area) if area else "1=1 ",
"and nodes.tags ? '{0}'".format(key) if key and not value else "",
"and nodes.tags->'{0}' ~* '^{1}'".format(key, value) if key and value else "",
"AND (" + tagsQueryFilter(tags, "nodes") + ")" if tags else "",
"ORDER BY nodes.timestamp DESC LIMIT " + str(RESULTS_PER_PAGE) + " OFFSET {0}".format(page * RESULTS_PER_PAGE) if page else "",
)
return self.underpassDB.run(query, responseType, True)

def getAllList(
self,
area = None,
key = None,
value = None,
tags = None,
hashtag = None,
responseType = "json",
page = None
):

polygons = self.getPolygonsList(
area,
key,
value,
tags,
hashtag,
responseType,
page)

lines = self.getLinesList(
area,
key,
value,
tags,
hashtag,
responseType,
page)

nodes = self.getNodesList(
area,
key,
value,
tags,
hashtag,
responseType,
page)
Expand Down
27 changes: 10 additions & 17 deletions python/restapi/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
allow_headers=["*"]
)

db = UnderpassDB(config.UNDERPASS_DB)
Expand Down Expand Up @@ -157,8 +157,7 @@ def osmchangeValidate(request: OsmchangeValidateRequest):
def getPolygons(request: RawRequest):
results = rawer.getPolygons(
area = request.area or None,
key = request.key or "",
value = request.value or "",
tags = request.tags or "",
page = request.page
)
return results
Expand All @@ -167,8 +166,7 @@ def getPolygons(request: RawRequest):
def getNodes(request: RawRequest):
results = rawer.getNodes(
area = request.area,
key = request.key or "",
value = request.value or "",
tags = request.tags or "",
page = request.page
)
return results
Expand All @@ -177,8 +175,7 @@ def getNodes(request: RawRequest):
def getLines(request: RawRequest):
results = rawer.getLines(
area = request.area,
key = request.key or "",
value = request.value or "",
tags = request.tags or "",
page = request.page
)
return results
Expand All @@ -187,8 +184,7 @@ def getLines(request: RawRequest):
def getLines(request: RawRequest):
results = rawer.getAll(
area = request.area,
key = request.key or "",
value = request.value or "",
tags = request.tags or "",
page = request.page
)
return results
Expand All @@ -197,8 +193,7 @@ def getLines(request: RawRequest):
def getPolygonsList(request: RawRequest):
results = rawer.getPolygonsList(
area = request.area or None,
key = request.key or "",
value = request.value or "",
tags = request.tags or "",
page = request.page
)
return results
Expand All @@ -207,8 +202,7 @@ def getPolygonsList(request: RawRequest):
def getNodesList(request: RawRequest):
results = rawer.getNodesList(
area = request.area or None,
key = request.key or "",
value = request.value or "",
tags = request.tags or "",
page = request.page
)
return results
Expand All @@ -217,8 +211,7 @@ def getNodesList(request: RawRequest):
def getAllList(request: RawRequest):
results = rawer.getAllList(
area = request.area or None,
key = request.key or "",
value = request.value or "",
page = request.page
tags = request.tags or "",
page = request.page,
)
return results
return results

0 comments on commit 774ae6f

Please sign in to comment.