-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
__init__.py
106 lines (96 loc) · 3.29 KB
/
__init__.py
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
from datasette import hookimpl
from datasette.filters import FilterArguments
from jinja2.utils import htmlsafe_json_dumps
import json
import textwrap
async def geometry_columns_for_table(datasette, database, table):
# Returns [{"column": spatial_index_enabled (boolean)}]
sql = """
select f_geometry_column, spatial_index_enabled
from geometry_columns
where lower(f_table_name) = lower(:table)
"""
db = datasette.get_database(database)
return {
r["f_geometry_column"]: bool(r["spatial_index_enabled"])
for r in await db.execute(sql, {"table": table})
}
@hookimpl
def filters_from_request(request, database, table, datasette):
async def inner():
geometry_columns = await geometry_columns_for_table(datasette, database, table)
if not geometry_columns:
return
freedraw = request.args.get("_freedraw", "")
try:
geojson = json.loads(freedraw)
except ValueError:
return
# Just use the first geometry column
column, spatial_index_enabled = list(geometry_columns.items())[0]
where_clauses = [
"Intersects(GeomFromGeoJSON(:freedraw), [{}]) = 1".format(column)
]
params = {"freedraw": json.dumps(geojson)}
# Spatial index support, if possible
if spatial_index_enabled:
where_clauses.append(
textwrap.dedent(
"""
[{table}].rowid in (select rowid from SpatialIndex where f_table_name = :freedraw_table
and search_frame = GeomFromGeoJSON(:freedraw))
""".format(
table=table
)
).strip()
)
params["freedraw_table"] = table
return FilterArguments(
where_clauses,
params=params,
human_descriptions=["geometry intersects the specified map area"],
)
return inner
@hookimpl
def extra_js_urls(view_name, datasette):
if view_name in ("database", "table"):
return [
{
"url": datasette.urls.static_plugins(
"datasette-leaflet-freedraw", "datasette-leaflet-freedraw.js"
),
"module": True,
}
]
@hookimpl
def extra_body_script(request, datasette, database, table):
async def inner():
has_geometry = False
if table:
has_geometry = bool(
await geometry_columns_for_table(datasette, database, table)
)
current_geojson = None
freedraw = request.args.get("_freedraw")
if freedraw:
try:
current_geojson = json.loads(freedraw)
except ValueError:
pass
return textwrap.dedent(
"""
window.datasette = window.datasette || {{}};
datasette.leaflet_freedraw = {{
FREEDRAW_URL: '{}',
show_for_table: {},
current_geojson: {}
}};
""".format(
datasette.urls.static_plugins(
"datasette-leaflet-freedraw", "leaflet-freedraw.esm.js"
),
"true" if has_geometry else "false",
htmlsafe_json_dumps(current_geojson),
)
)
return inner