geo-activity-playground 0.35.0__py3-none-any.whl → 0.36.0__py3-none-any.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.
- geo_activity_playground/__main__.py +12 -0
- geo_activity_playground/core/activities.py +21 -13
- geo_activity_playground/core/raster_map.py +246 -0
- geo_activity_playground/core/tiles.py +6 -50
- geo_activity_playground/explorer/video.py +1 -1
- geo_activity_playground/heatmap_video.py +93 -0
- geo_activity_playground/importers/activity_parsers.py +1 -1
- geo_activity_playground/importers/directory.py +6 -15
- geo_activity_playground/webui/activity/blueprint.py +3 -10
- geo_activity_playground/webui/activity/controller.py +10 -71
- geo_activity_playground/webui/app.py +32 -22
- geo_activity_playground/webui/{auth/blueprint.py → auth_blueprint.py} +1 -1
- geo_activity_playground/webui/calendar/blueprint.py +2 -5
- geo_activity_playground/webui/{eddington/controller.py → eddington_blueprint.py} +17 -13
- geo_activity_playground/webui/equipment/blueprint.py +2 -8
- geo_activity_playground/webui/explorer/blueprint.py +2 -10
- geo_activity_playground/webui/heatmap/blueprint.py +36 -10
- geo_activity_playground/webui/heatmap/heatmap_controller.py +151 -71
- geo_activity_playground/webui/heatmap/templates/heatmap/index.html.j2 +30 -12
- geo_activity_playground/webui/{search/blueprint.py → search_blueprint.py} +1 -1
- geo_activity_playground/webui/settings/blueprint.py +1 -2
- geo_activity_playground/webui/square_planner_blueprint.py +118 -0
- geo_activity_playground/webui/{summary/controller.py → summary_blueprint.py} +23 -24
- geo_activity_playground/webui/templates/page.html.j2 +11 -0
- geo_activity_playground/webui/tile_blueprint.py +42 -0
- geo_activity_playground/webui/upload_blueprint.py +1 -3
- {geo_activity_playground-0.35.0.dist-info → geo_activity_playground-0.36.0.dist-info}/METADATA +1 -1
- {geo_activity_playground-0.35.0.dist-info → geo_activity_playground-0.36.0.dist-info}/RECORD +36 -43
- geo_activity_playground/core/heatmap.py +0 -194
- geo_activity_playground/webui/eddington/__init__.py +0 -0
- geo_activity_playground/webui/eddington/blueprint.py +0 -19
- geo_activity_playground/webui/square_planner/__init__.py +0 -0
- geo_activity_playground/webui/square_planner/blueprint.py +0 -38
- geo_activity_playground/webui/square_planner/controller.py +0 -101
- geo_activity_playground/webui/summary/__init__.py +0 -0
- geo_activity_playground/webui/summary/blueprint.py +0 -17
- geo_activity_playground/webui/tile/__init__.py +0 -0
- geo_activity_playground/webui/tile/blueprint.py +0 -32
- geo_activity_playground/webui/tile/controller.py +0 -36
- /geo_activity_playground/webui/{auth/templates → templates}/auth/index.html.j2 +0 -0
- /geo_activity_playground/webui/{eddington/templates → templates}/eddington/index.html.j2 +0 -0
- /geo_activity_playground/webui/{search/templates → templates}/search/index.html.j2 +0 -0
- /geo_activity_playground/webui/{square_planner/templates → templates}/square_planner/index.html.j2 +0 -0
- /geo_activity_playground/webui/{summary/templates → templates}/summary/index.html.j2 +0 -0
- {geo_activity_playground-0.35.0.dist-info → geo_activity_playground-0.36.0.dist-info}/LICENSE +0 -0
- {geo_activity_playground-0.35.0.dist-info → geo_activity_playground-0.36.0.dist-info}/WHEEL +0 -0
- {geo_activity_playground-0.35.0.dist-info → geo_activity_playground-0.36.0.dist-info}/entry_points.txt +0 -0
@@ -12,8 +12,6 @@ import pandas as pd
|
|
12
12
|
from PIL import Image
|
13
13
|
from PIL import ImageDraw
|
14
14
|
|
15
|
-
from ...explorer.grid_file import make_grid_file_geojson
|
16
|
-
from ...explorer.grid_file import make_grid_points
|
17
15
|
from geo_activity_playground.core.activities import ActivityMeta
|
18
16
|
from geo_activity_playground.core.activities import ActivityRepository
|
19
17
|
from geo_activity_playground.core.activities import make_geojson_color_line
|
@@ -21,14 +19,13 @@ from geo_activity_playground.core.activities import make_geojson_from_time_serie
|
|
21
19
|
from geo_activity_playground.core.activities import make_speed_color_bar
|
22
20
|
from geo_activity_playground.core.config import Config
|
23
21
|
from geo_activity_playground.core.heart_rate import HeartRateZoneComputer
|
24
|
-
from geo_activity_playground.core.heatmap import build_map_from_tiles_around_center
|
25
|
-
from geo_activity_playground.core.heatmap import GeoBounds
|
26
|
-
from geo_activity_playground.core.heatmap import OSM_MAX_ZOOM
|
27
|
-
from geo_activity_playground.core.heatmap import OSM_TILE_SIZE
|
28
|
-
from geo_activity_playground.core.heatmap import PixelBounds
|
29
|
-
from geo_activity_playground.core.heatmap import TileBounds
|
30
22
|
from geo_activity_playground.core.privacy_zones import PrivacyZone
|
31
|
-
from geo_activity_playground.core.
|
23
|
+
from geo_activity_playground.core.raster_map import map_image_from_tile_bounds
|
24
|
+
from geo_activity_playground.core.raster_map import OSM_MAX_ZOOM
|
25
|
+
from geo_activity_playground.core.raster_map import OSM_TILE_SIZE
|
26
|
+
from geo_activity_playground.core.raster_map import tile_bounds_around_center
|
27
|
+
from geo_activity_playground.explorer.grid_file import make_grid_file_geojson
|
28
|
+
from geo_activity_playground.explorer.grid_file import make_grid_points
|
32
29
|
from geo_activity_playground.explorer.tile_visits import TileVisitAccessor
|
33
30
|
|
34
31
|
logger = logging.getLogger(__name__)
|
@@ -412,62 +409,6 @@ def name_minutes_plot(meta: pd.DataFrame) -> str:
|
|
412
409
|
)
|
413
410
|
|
414
411
|
|
415
|
-
def make_pixel_bounds_square(bounds: PixelBounds) -> PixelBounds:
|
416
|
-
x_radius = (bounds.x_max - bounds.x_min) // 2
|
417
|
-
y_radius = (bounds.y_max - bounds.y_min) // 2
|
418
|
-
x_center = (bounds.x_max + bounds.x_min) // 2
|
419
|
-
y_center = (bounds.y_max + bounds.y_min) // 2
|
420
|
-
|
421
|
-
radius = max(x_radius, y_radius)
|
422
|
-
|
423
|
-
return PixelBounds(
|
424
|
-
x_min=x_center - radius,
|
425
|
-
y_min=y_center - radius,
|
426
|
-
x_max=x_center + radius,
|
427
|
-
y_max=y_center + radius,
|
428
|
-
)
|
429
|
-
|
430
|
-
|
431
|
-
def make_tile_bounds_square(bounds: TileBounds) -> TileBounds:
|
432
|
-
x_radius = (bounds.x_tile_max - bounds.x_tile_min) / 2
|
433
|
-
y_radius = (bounds.y_tile_max - bounds.y_tile_min) / 2
|
434
|
-
x_center = (bounds.x_tile_max + bounds.x_tile_min) / 2
|
435
|
-
y_center = (bounds.y_tile_max + bounds.y_tile_min) / 2
|
436
|
-
|
437
|
-
radius = max(x_radius, y_radius)
|
438
|
-
|
439
|
-
return TileBounds(
|
440
|
-
zoom=bounds.zoom,
|
441
|
-
x_tile_min=int(x_center - radius),
|
442
|
-
y_tile_min=int(y_center - radius),
|
443
|
-
x_tile_max=int(np.ceil(x_center + radius)),
|
444
|
-
y_tile_max=int(np.ceil(y_center + radius)),
|
445
|
-
)
|
446
|
-
|
447
|
-
|
448
|
-
def get_crop_mask(geo_bounds: GeoBounds, tile_bounds: TileBounds) -> PixelBounds:
|
449
|
-
min_x, min_y = compute_tile_float(
|
450
|
-
geo_bounds.lat_max, geo_bounds.lon_min, tile_bounds.zoom
|
451
|
-
)
|
452
|
-
max_x, max_y = compute_tile_float(
|
453
|
-
geo_bounds.lat_min, geo_bounds.lon_max, tile_bounds.zoom
|
454
|
-
)
|
455
|
-
|
456
|
-
crop_mask = PixelBounds(
|
457
|
-
int((min_x - tile_bounds.x_tile_min) * OSM_TILE_SIZE),
|
458
|
-
int((max_x - tile_bounds.x_tile_min) * OSM_TILE_SIZE),
|
459
|
-
int((min_y - tile_bounds.y_tile_min) * OSM_TILE_SIZE),
|
460
|
-
int((max_y - tile_bounds.y_tile_min) * OSM_TILE_SIZE),
|
461
|
-
)
|
462
|
-
crop_mask = make_pixel_bounds_square(crop_mask)
|
463
|
-
|
464
|
-
return crop_mask
|
465
|
-
|
466
|
-
|
467
|
-
def pixels_in_bounds(bounds: PixelBounds) -> int:
|
468
|
-
return (bounds.x_max - bounds.x_min) * (bounds.y_max - bounds.y_min)
|
469
|
-
|
470
|
-
|
471
412
|
def make_sharepic_base(time_series_list: list[pd.DataFrame], config: Config):
|
472
413
|
all_time_series = pd.concat(time_series_list)
|
473
414
|
tile_x = all_time_series["x"]
|
@@ -496,13 +437,11 @@ def make_sharepic_base(time_series_list: list[pd.DataFrame], config: Config):
|
|
496
437
|
(tile_yz.max() + tile_yz.min()) / 2,
|
497
438
|
)
|
498
439
|
|
499
|
-
|
500
|
-
tile_xz_center,
|
501
|
-
zoom,
|
502
|
-
(target_width, target_height),
|
503
|
-
(target_width, target_map_height),
|
504
|
-
config,
|
440
|
+
tile_bounds = tile_bounds_around_center(
|
441
|
+
tile_xz_center, (target_width, target_height - footer_height), zoom
|
505
442
|
)
|
443
|
+
tile_bounds.y2 += footer_height / OSM_TILE_SIZE
|
444
|
+
background = map_image_from_tile_bounds(tile_bounds, config)
|
506
445
|
|
507
446
|
img = Image.fromarray((background * 255).astype("uint8"), "RGB")
|
508
447
|
draw = ImageDraw.Draw(img, mode="RGBA")
|
@@ -10,24 +10,28 @@ from flask import Flask
|
|
10
10
|
from flask import render_template
|
11
11
|
|
12
12
|
from ..core.activities import ActivityRepository
|
13
|
+
from ..core.config import Config
|
14
|
+
from ..core.config import ConfigAccessor
|
13
15
|
from ..explorer.tile_visits import TileVisitAccessor
|
14
16
|
from .activity.blueprint import make_activity_blueprint
|
17
|
+
from .activity.controller import ActivityController
|
18
|
+
from .auth_blueprint import make_auth_blueprint
|
19
|
+
from .authenticator import Authenticator
|
15
20
|
from .calendar.blueprint import make_calendar_blueprint
|
16
|
-
from .
|
21
|
+
from .calendar.controller import CalendarController
|
22
|
+
from .eddington_blueprint import make_eddington_blueprint
|
17
23
|
from .entry_controller import EntryController
|
18
24
|
from .equipment.blueprint import make_equipment_blueprint
|
25
|
+
from .equipment.controller import EquipmentController
|
19
26
|
from .explorer.blueprint import make_explorer_blueprint
|
27
|
+
from .explorer.controller import ExplorerController
|
20
28
|
from .heatmap.blueprint import make_heatmap_blueprint
|
21
|
-
from .
|
22
|
-
from .
|
23
|
-
from .
|
24
|
-
from .
|
29
|
+
from .search_blueprint import make_search_blueprint
|
30
|
+
from .settings.blueprint import make_settings_blueprint
|
31
|
+
from .square_planner_blueprint import make_square_planner_blueprint
|
32
|
+
from .summary_blueprint import make_summary_blueprint
|
33
|
+
from .tile_blueprint import make_tile_blueprint
|
25
34
|
from .upload_blueprint import make_upload_blueprint
|
26
|
-
from geo_activity_playground.core.config import Config
|
27
|
-
from geo_activity_playground.core.config import ConfigAccessor
|
28
|
-
from geo_activity_playground.webui.auth.blueprint import make_auth_blueprint
|
29
|
-
from geo_activity_playground.webui.authenticator import Authenticator
|
30
|
-
from geo_activity_playground.webui.settings.blueprint import make_settings_blueprint
|
31
35
|
|
32
36
|
|
33
37
|
def route_start(app: Flask, repository: ActivityRepository, config: Config) -> None:
|
@@ -77,26 +81,32 @@ def web_ui_main(
|
|
77
81
|
|
78
82
|
authenticator = Authenticator(config_accessor())
|
79
83
|
|
84
|
+
config = config_accessor()
|
85
|
+
activity_controller = ActivityController(repository, tile_visit_accessor, config)
|
86
|
+
calendar_controller = CalendarController(repository)
|
87
|
+
equipment_controller = EquipmentController(repository, config)
|
88
|
+
explorer_controller = ExplorerController(
|
89
|
+
repository, tile_visit_accessor, config_accessor
|
90
|
+
)
|
91
|
+
|
80
92
|
route_start(app, repository, config_accessor())
|
81
93
|
|
82
94
|
app.register_blueprint(make_auth_blueprint(authenticator), url_prefix="/auth")
|
83
|
-
|
84
95
|
app.register_blueprint(
|
85
|
-
make_activity_blueprint(
|
86
|
-
repository, tile_visit_accessor, config_accessor(), authenticator
|
87
|
-
),
|
96
|
+
make_activity_blueprint(activity_controller, repository, authenticator),
|
88
97
|
url_prefix="/activity",
|
89
98
|
)
|
90
|
-
app.register_blueprint(
|
99
|
+
app.register_blueprint(
|
100
|
+
make_calendar_blueprint(calendar_controller), url_prefix="/calendar"
|
101
|
+
)
|
91
102
|
app.register_blueprint(
|
92
103
|
make_eddington_blueprint(repository), url_prefix="/eddington"
|
93
104
|
)
|
94
105
|
app.register_blueprint(
|
95
|
-
make_equipment_blueprint(
|
106
|
+
make_equipment_blueprint(equipment_controller), url_prefix="/equipment"
|
96
107
|
)
|
97
108
|
app.register_blueprint(
|
98
|
-
make_explorer_blueprint(
|
99
|
-
url_prefix="/explorer",
|
109
|
+
make_explorer_blueprint(explorer_controller), url_prefix="/explorer"
|
100
110
|
)
|
101
111
|
app.register_blueprint(
|
102
112
|
make_heatmap_blueprint(repository, tile_visit_accessor, config_accessor()),
|
@@ -107,7 +117,7 @@ def web_ui_main(
|
|
107
117
|
url_prefix="/settings",
|
108
118
|
)
|
109
119
|
app.register_blueprint(
|
110
|
-
make_square_planner_blueprint(
|
120
|
+
make_square_planner_blueprint(tile_visit_accessor),
|
111
121
|
url_prefix="/square-planner",
|
112
122
|
)
|
113
123
|
app.register_blueprint(
|
@@ -115,10 +125,10 @@ def web_ui_main(
|
|
115
125
|
url_prefix="/search",
|
116
126
|
)
|
117
127
|
app.register_blueprint(
|
118
|
-
make_summary_blueprint(repository,
|
119
|
-
url_prefix="/summary",
|
128
|
+
make_summary_blueprint(repository, config), url_prefix="/summary"
|
120
129
|
)
|
121
|
-
|
130
|
+
|
131
|
+
app.register_blueprint(make_tile_blueprint(config), url_prefix="/tile")
|
122
132
|
app.register_blueprint(
|
123
133
|
make_upload_blueprint(
|
124
134
|
repository, tile_visit_accessor, config_accessor(), authenticator
|
@@ -4,7 +4,7 @@ from flask import render_template
|
|
4
4
|
from flask import request
|
5
5
|
from flask import url_for
|
6
6
|
|
7
|
-
from
|
7
|
+
from .authenticator import Authenticator
|
8
8
|
|
9
9
|
|
10
10
|
def make_auth_blueprint(authenticator: Authenticator) -> Blueprint:
|
@@ -1,15 +1,12 @@
|
|
1
1
|
from flask import Blueprint
|
2
2
|
from flask import render_template
|
3
3
|
|
4
|
-
from
|
5
|
-
from .controller import CalendarController
|
4
|
+
from geo_activity_playground.webui.calendar.controller import CalendarController
|
6
5
|
|
7
6
|
|
8
|
-
def make_calendar_blueprint(
|
7
|
+
def make_calendar_blueprint(calendar_controller: CalendarController) -> Blueprint:
|
9
8
|
blueprint = Blueprint("calendar", __name__, template_folder="templates")
|
10
9
|
|
11
|
-
calendar_controller = CalendarController(repository)
|
12
|
-
|
13
10
|
@blueprint.route("/")
|
14
11
|
def index():
|
15
12
|
return render_template(
|
@@ -1,17 +1,19 @@
|
|
1
1
|
import altair as alt
|
2
2
|
import numpy as np
|
3
3
|
import pandas as pd
|
4
|
+
from flask import Blueprint
|
5
|
+
from flask import render_template
|
4
6
|
|
5
|
-
from
|
7
|
+
from geo_activity_playground.core.activities import ActivityRepository
|
6
8
|
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
self._repository = repository
|
10
|
+
def make_eddington_blueprint(repository: ActivityRepository) -> Blueprint:
|
11
|
+
blueprint = Blueprint("eddington", __name__, template_folder="templates")
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
@blueprint.route("/")
|
14
|
+
def index():
|
15
|
+
activities = repository.meta.loc[
|
16
|
+
repository.meta["consider_for_achievements"]
|
15
17
|
].copy()
|
16
18
|
activities["day"] = [start.date() for start in activities["start"]]
|
17
19
|
|
@@ -67,11 +69,13 @@ class EddingtonController:
|
|
67
69
|
.interactive()
|
68
70
|
.to_json(format="vega")
|
69
71
|
)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
return render_template(
|
73
|
+
"eddington/index.html.j2",
|
74
|
+
eddington_number=en,
|
75
|
+
logarithmic_plot=logarithmic_plot,
|
76
|
+
eddington_table=eddington.loc[
|
75
77
|
(eddington["distance_km"] > en) & (eddington["distance_km"] <= en + 10)
|
76
78
|
].to_dict(orient="records"),
|
77
|
-
|
79
|
+
)
|
80
|
+
|
81
|
+
return blueprint
|
@@ -1,18 +1,12 @@
|
|
1
1
|
from flask import Blueprint
|
2
2
|
from flask import render_template
|
3
3
|
|
4
|
-
from
|
5
|
-
from .controller import EquipmentController
|
6
|
-
from geo_activity_playground.core.config import Config
|
4
|
+
from geo_activity_playground.webui.equipment.controller import EquipmentController
|
7
5
|
|
8
6
|
|
9
|
-
def make_equipment_blueprint(
|
10
|
-
repository: ActivityRepository, config: Config
|
11
|
-
) -> Blueprint:
|
7
|
+
def make_equipment_blueprint(equipment_controller: EquipmentController) -> Blueprint:
|
12
8
|
blueprint = Blueprint("equipment", __name__, template_folder="templates")
|
13
9
|
|
14
|
-
equipment_controller = EquipmentController(repository, config)
|
15
|
-
|
16
10
|
@blueprint.route("/")
|
17
11
|
def index():
|
18
12
|
return render_template(
|
@@ -4,20 +4,12 @@ from flask import render_template
|
|
4
4
|
from flask import Response
|
5
5
|
from flask import url_for
|
6
6
|
|
7
|
-
from
|
8
|
-
from ...explorer.tile_visits import TileVisitAccessor
|
9
|
-
from .controller import ExplorerController
|
10
|
-
from geo_activity_playground.core.config import ConfigAccessor
|
7
|
+
from geo_activity_playground.webui.explorer.controller import ExplorerController
|
11
8
|
|
12
9
|
|
13
10
|
def make_explorer_blueprint(
|
14
|
-
|
15
|
-
tile_visit_accessor: TileVisitAccessor,
|
16
|
-
config_accessor: ConfigAccessor,
|
11
|
+
explorer_controller: ExplorerController,
|
17
12
|
) -> Blueprint:
|
18
|
-
explorer_controller = ExplorerController(
|
19
|
-
repository, tile_visit_accessor, config_accessor
|
20
|
-
)
|
21
13
|
blueprint = Blueprint("explorer", __name__, template_folder="templates")
|
22
14
|
|
23
15
|
@blueprint.route("/<zoom>")
|
@@ -1,12 +1,13 @@
|
|
1
|
+
import dateutil.parser
|
1
2
|
from flask import Blueprint
|
2
3
|
from flask import render_template
|
3
4
|
from flask import request
|
4
5
|
from flask import Response
|
5
6
|
|
6
|
-
from
|
7
|
-
from ...explorer.tile_visits import TileVisitAccessor
|
8
|
-
from .heatmap_controller import HeatmapController
|
7
|
+
from geo_activity_playground.core.activities import ActivityRepository
|
9
8
|
from geo_activity_playground.core.config import Config
|
9
|
+
from geo_activity_playground.explorer.tile_visits import TileVisitAccessor
|
10
|
+
from geo_activity_playground.webui.heatmap.heatmap_controller import HeatmapController
|
10
11
|
|
11
12
|
|
12
13
|
def make_heatmap_blueprint(
|
@@ -21,21 +22,46 @@ def make_heatmap_blueprint(
|
|
21
22
|
def index():
|
22
23
|
return render_template(
|
23
24
|
"heatmap/index.html.j2",
|
24
|
-
**heatmap_controller.render(
|
25
|
+
**heatmap_controller.render(
|
26
|
+
[int(k) for k in request.args.getlist("kind")],
|
27
|
+
request.args.get(
|
28
|
+
"date-start", type=dateutil.parser.parse, default=None
|
29
|
+
),
|
30
|
+
request.args.get("date-end", type=dateutil.parser.parse, default=None),
|
31
|
+
)
|
25
32
|
)
|
26
33
|
|
27
|
-
@blueprint.route("/tile/<z>/<x>/<y
|
28
|
-
def tile(x:
|
34
|
+
@blueprint.route("/tile/<int:z>/<int:x>/<int:y>.png")
|
35
|
+
def tile(x: int, y: int, z: int):
|
29
36
|
return Response(
|
30
|
-
heatmap_controller.render_tile(
|
37
|
+
heatmap_controller.render_tile(
|
38
|
+
x,
|
39
|
+
y,
|
40
|
+
z,
|
41
|
+
[int(k) for k in request.args.getlist("kind")],
|
42
|
+
request.args.get(
|
43
|
+
"date-start", type=dateutil.parser.parse, default=None
|
44
|
+
),
|
45
|
+
request.args.get("date-end", type=dateutil.parser.parse, default=None),
|
46
|
+
),
|
31
47
|
mimetype="image/png",
|
32
48
|
)
|
33
49
|
|
34
|
-
@blueprint.route(
|
35
|
-
|
50
|
+
@blueprint.route(
|
51
|
+
"/download/<float:north>/<float:east>/<float:south>/<float:west>/heatmap.png"
|
52
|
+
)
|
53
|
+
def download(north: float, east: float, south: float, west: float):
|
36
54
|
return Response(
|
37
55
|
heatmap_controller.download_heatmap(
|
38
|
-
|
56
|
+
north,
|
57
|
+
east,
|
58
|
+
south,
|
59
|
+
west,
|
60
|
+
[int(k) for k in request.args.getlist("kind")],
|
61
|
+
request.args.get(
|
62
|
+
"date-start", type=dateutil.parser.parse, default=None
|
63
|
+
),
|
64
|
+
request.args.get("date-end", type=dateutil.parser.parse, default=None),
|
39
65
|
),
|
40
66
|
mimetype="image/png",
|
41
67
|
headers={"Content-disposition": 'attachment; filename="heatmap.png"'},
|