Skip to content

Commit

Permalink
Attempt to create layer groups when uploading maps
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed May 28, 2024
1 parent cb54f3a commit f000388
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 6 deletions.
60 changes: 60 additions & 0 deletions felt/core/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class FeltApiClient:
RECENT_MAPS_ENDPOINT = '/maps/recent'
UPLOAD_V2_ENDPOINT = '/maps/{}/upload'
PATCH_STYLE_ENDPOINT = '/maps/{}/layers/{}/style'
UPDATE_LAYER_ENDPOINT = '/maps/{}/layers'
LAYER_GROUPS_ENDPOINT = '/maps/{}/layer_groups'

def __init__(self):
# default headers to add to all requests
Expand Down Expand Up @@ -431,6 +433,64 @@ def patch_style(self,
json.dumps(style_post_data).encode()
)

def update_layer_details(self,
map_id: str,
layer_id: str,
layer_group_id: Optional[str] = None,
name: Optional[str] = None,
ordering_key: Optional[int] = None,
subtitle: Optional[str] = None) \
-> QgsNetworkReplyContent:
"""
Updates a layer's details
"""
request = self._build_request(
self.UPDATE_LAYER_ENDPOINT.format(map_id),
{'Content-Type': 'application/json'},
version=2
)

layer_details = {
'id': layer_id
}
if layer_group_id:
layer_details['layer_group_id'] = layer_group_id
if name:
layer_details['name'] = name
if ordering_key:
layer_details['ordering_key'] = ordering_key
if subtitle:
layer_details['subtitle'] = subtitle

post_data = [layer_details]

return QgsNetworkAccessManager.instance().blockingPost(
request,
json.dumps(post_data).encode()
)

def create_layer_groups(self,
map_id: str,
layer_group_names: List[str]) \
-> QgsNetworkReplyContent:
"""
Creates layer groups for a map
"""
request = self._build_request(
self.LAYER_GROUPS_ENDPOINT.format(map_id),
{'Content-Type': 'application/json'},
version=2
)

group_post_data = [
{'name': g} for g in layer_group_names
]

return QgsNetworkAccessManager.instance().blockingPost(
request,
json.dumps(group_post_data).encode()
)

def report_usage(self,
content: str,
usage_type: UsageType = UsageType.Info) -> QNetworkReply:
Expand Down
1 change: 1 addition & 0 deletions felt/core/layer_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class ZippedExportResult:
error_message: str
qgis_style_xml: str
style: Optional[LayerStyle] = None
group_name: Optional[str] = None


class LayerExporter(QObject):
Expand Down
75 changes: 69 additions & 6 deletions felt/core/map_uploader.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
QgsFeedback,
QgsBlockingNetworkRequest,
QgsReferencedRectangle,
QgsRasterLayer
QgsRasterLayer,
QgsLayerTree
)
from qgis.utils import iface

Expand Down Expand Up @@ -76,7 +77,8 @@ def __init__(self,
project.transformContext()
)
self.layers = [
MapUploaderTask.clone_layer(layer) for layer in layers
MapUploaderTask.layer_and_group(project, layer) for layer
in layers
]
self.unsupported_layer_details = {}
else:
Expand All @@ -96,15 +98,16 @@ def __init__(self,
]

self.layers = [
MapUploaderTask.clone_layer(layer) for layer in visible_layers
MapUploaderTask.layer_and_group(project, layer) for layer
in visible_layers
if
LayerExporter.can_export_layer(layer)[
0] == LayerSupport.Supported
]

self._build_unsupported_layer_details(project, visible_layers)

for layer in self.layers:
for layer, _ in self.layers:
layer.moveToThread(None)

self.transform_context = project.transformContext()
Expand Down Expand Up @@ -139,6 +142,31 @@ def __init__(self,
self.feedback: Optional[QgsFeedback] = None
self.was_canceled = False

@staticmethod
def layer_and_group(project: QgsProject, layer: QgsMapLayer) \
-> Tuple[QgsMapLayer, Optional[str]]:
"""
Clones a layer, and returns the layer and the corresponding top
level group
"""
res = MapUploaderTask.clone_layer(layer)

layer_tree_root = project.layerTreeRoot()

layer_tree_layer = layer_tree_root.findLayer(layer)
parent = layer_tree_layer.parent()
while parent:
if parent.parent() == layer_tree_root:
break

parent = parent.parent()

group_name = None
if parent != layer_tree_root and QgsLayerTree.isGroup(parent):
group_name = parent.name()

return res, group_name

@staticmethod
def clone_layer(layer: QgsMapLayer) -> QgsMapLayer:
"""
Expand Down Expand Up @@ -268,7 +296,7 @@ def run(self):
)
self.feedback.progressChanged.connect(self.setProgress)

for layer in self.layers:
for layer, _ in self.layers:
layer.moveToThread(QThread.currentThread())

if self.isCanceled():
Expand Down Expand Up @@ -326,7 +354,8 @@ def run(self):

to_upload = {}

for layer in self.layers:
all_group_names = []
for layer, group_name in self.layers:
if self.isCanceled():
return False

Expand Down Expand Up @@ -368,16 +397,32 @@ def run(self):

return False

result.group_name = group_name
layer.moveToThread(None)
to_upload[layer] = result

if group_name and group_name not in all_group_names:
all_group_names.append(group_name)

multi_step_feedback.step_finished()

if self.isCanceled():
return False

rate_limit_counter = 0

if all_group_names:
reply = API_CLIENT.create_layer_groups(
map_id=self.associated_map.id,
layer_group_names=all_group_names
)
group_details = json.loads(reply.content().data().decode())
group_ids = {
group['name']: group['id'] for group in group_details
}
else:
group_ids = {}

for layer, details in to_upload.items():
if self.isCanceled():
return False
Expand Down Expand Up @@ -514,6 +559,24 @@ def _upload_progress(sent, total):
reply.finished.connect(loop.exit)
loop.exec()

if details.group_name:
group_id = group_ids[details.group_name]
reply = API_CLIENT.update_layer_details(
map_id=self.associated_map.id,
layer_id=layer_id,
layer_group_id=group_id
)
if reply.error() != QNetworkReply.NoError:
self.error_string = reply.errorString()
Logger.instance().log_error_json(
{
'type': Logger.MAP_EXPORT,
'error': 'Error updating layer group: {}'.format(
self.error_string)
}
)
return False

multi_step_feedback.step_finished()

return True
Expand Down

0 comments on commit f000388

Please sign in to comment.