-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathtasks.py
129 lines (108 loc) · 4.12 KB
/
tasks.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import shutil
import traceback
from celery import group, task
from django.conf import settings
from raster.tiles.const import GLOBAL_MAX_ZOOM_LEVEL, MIN_ZOOMLEVEL_TASK_PARALLEL
from raster.tiles.parser import RasterLayerParser
@task
def create_tiles(rasterlayer_id, zoom, extract_metadata=False):
"""
Create all tiles for a raster layer at the input zoom level.
"""
try:
parser = RasterLayerParser(rasterlayer_id)
# Open raster file and extract metadata if requested.
if extract_metadata:
parser.open_raster_file()
parser.extract_metadata()
# Check if zoom level should be built.
if zoom is None:
zoom = parser.max_zoom
elif isinstance(zoom, (int, float)):
if zoom > parser.max_zoom:
return
else:
zoom = [zl for zl in zoom if zl <= parser.max_zoom]
if not len(zoom):
return
# Open raster file if not open already.
if not extract_metadata:
parser.open_raster_file()
parser.reproject_rasterfile()
parser.create_tiles(zoom)
except:
parser.log(
traceback.format_exc(),
status=parser.rasterlayer.parsestatus.FAILED
)
raise
finally:
if hasattr(parser, 'tmpdir'):
shutil.rmtree(parser.tmpdir)
@task
def clear_tiles(rasterlayer_id):
"""
Drop all tiles of a rasterlayer.
"""
parser = RasterLayerParser(rasterlayer_id)
parser.drop_all_tiles()
@task
def send_success_signal(rasterlayer_id):
"""
Drop empty tiles of a raster layer and send parse succes signal.
"""
parser = RasterLayerParser(rasterlayer_id)
parser.send_success_signal()
@task
def all_in_one(rasterlayer_id, zoom_range):
"""
Parses raster in a single task.
"""
clear_tiles(rasterlayer_id)
create_tiles(rasterlayer_id, zoom_range, True)
send_success_signal(rasterlayer_id)
def parse(rasterlayer_id):
"""
Parse raster layer to extract metadata and create tiles.
"""
parser = RasterLayerParser(rasterlayer_id)
parser.log('Started parsing raster.')
# Create array of all allowed zoom levels
if parser.rasterlayer.build_pyramid:
zoom_range = list(range(GLOBAL_MAX_ZOOM_LEVEL + 1))
else:
if parser.rasterlayer.max_zoom is not None:
zoom_range = (parser.rasterlayer.max_zoom, )
else:
zoom_range = None
# Check if parsing should happen asynchronously
parse_async = getattr(settings, 'RASTER_USE_CELERY', False)
parse_single_task = getattr(settings, 'RASTER_PARSE_SINGLE_TASK', False)
if parse_async and not parse_single_task:
if zoom_range is not None:
# Bundle the first five raster layers to one task. For low zoom
# levels, downloading is more costly than parsing.
create_tiles_chain = create_tiles.si(rasterlayer_id, zoom_range[:MIN_ZOOMLEVEL_TASK_PARALLEL], True)
# Run the higher level zooms in parallel tasks through a task group.
if len(zoom_range) > MIN_ZOOMLEVEL_TASK_PARALLEL:
high_zoom_level_group = group(
create_tiles.si(rasterlayer_id, zoom) for zoom in zoom_range[MIN_ZOOMLEVEL_TASK_PARALLEL:]
)
# Combine bundle and middle levels to priority group.
create_tiles_chain = (create_tiles_chain | high_zoom_level_group)
else:
create_tiles_chain = create_tiles.si(rasterlayer_id, None, True)
# Setup the parser logic as parsing chain
parsing_task_chain = (
clear_tiles.si(rasterlayer_id)
| create_tiles_chain
| send_success_signal.si(rasterlayer_id)
)
# Apply the parsing chain
parser.log('Parse task queued, waiting for worker availability.')
parsing_task_chain.apply_async()
elif parse_async and parse_single_task:
parser.log('Parse task queued in all-in-one mode, waiting for worker availability.')
all_in_one.delay(rasterlayer_id, zoom_range)
else:
all_in_one(rasterlayer_id, zoom_range)