summaryrefslogtreecommitdiff
path: root/ishtar_common/views_item.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/views_item.py')
-rw-r--r--ishtar_common/views_item.py152
1 files changed, 114 insertions, 38 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 4126219fd..bd8780ea9 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -32,6 +32,7 @@ import subprocess # nosec
from tempfile import NamedTemporaryFile
from osgeo import ogr, osr
import shutil
+from zipfile import ZipFile
from django.apps import apps
from django.conf import settings
@@ -2374,7 +2375,7 @@ def get_item(
EMPTY = "[]"
if not return_query and data_type not in (
- "json", "csv", "json-image", "json-map", "json-stats"):
+ "json", "csv", "json-image", "json-map", "json-stats", "gpkg"):
return HttpResponse(EMPTY, content_type="text/plain")
if data_type == "json-stats" and len(model.STATISTIC_MODALITIES) < 2:
@@ -2991,7 +2992,7 @@ def get_item(
items, query_table_cols, my_extra_request_keys,
geo_fields=geo_fields
)
- elif data_type != "csv" and getattr(model, "NEW_QUERY_ENGINE", False):
+ elif data_type not in ["csv", "gpkg"] and getattr(model, "NEW_QUERY_ENGINE", False):
datas = _get_data_from_query(items, query_table_cols, my_extra_request_keys)
else:
datas = _get_data_from_query_old(
@@ -3218,22 +3219,40 @@ def get_item(
except UnicodeEncodeError:
vals.append(unidecode(v).encode(ENCODING).decode(ENCODING))
writer.writerow(vals)
- #return response
+ return response
elif data_type == "gpkg":
# Work in progress
- # Creation of the .gpkg
+ # I. Preparations
driver = ogr.GetDriverByName("GPKG")
- root = settings.LIB_BASE_PATH + "ishtar_common/tests/"
- filename = os.path.join(root, "Finds.gpkg")
+ root = settings.LIB_BASE_PATH + "ishtar_common/qfield/"
+ # 1) Creation of the .gpkg
+ filename = os.path.join(root, "export", "Finds.gpkg")
# Verification to delete it if already existing
if os.path.exists(filename):
os.remove(filename)
datasource = driver.CreateDataSource(filename)
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
- # Layer creation
- layer = datasource.CreateLayer("Finds", srs, ogr.wkbPoint)
- # Getting all the column names (copy from below)
+ # 2) Preparations for the modification of the style in the .qgs file
+ qgs_path = os.path.join(root, "model", "Prospections.qgs")
+ new_qgs = os.path.join(root, "export", "Prospections.qgs")
+ if os.path.exists(new_qgs):
+ os.remove(new_qgs)
+ # 3) Duplication of the .zip for export
+ project = os.path.join(root, "model", "Prospections_qfield.zip")
+ duplicate = os.path.join(root, "export", "Prospections_qfield_export.zip")
+ if os.path.exists(duplicate):
+ os.remove(duplicate)
+ shutil.copyfile(project, duplicate)
+ # II. Populating of the .gpkg
+ # 1) Layer creation with verification of the type of geometry to create
+ if "base_finds__point_2d" in table_cols:
+ layer = datasource.CreateLayer("Finds", srs, ogr.wkbPoint)
+ elif any(elem in table_cols for elem in ["base_finds__point_3d", "_z"]):
+ layer = datasource.CreateLayer("Finds", srs, ogr.wkbPoint25D)
+ else:
+ layer = datasource.CreateLayer("Finds", srs, ogr.wkbPolygon)
+ # 2) Getting all the column names (copy from below)
if col_names:
col_names = [name for name in col_names]
else:
@@ -3258,44 +3277,101 @@ def get_item(
)
continue
col_names.append(str(field.verbose_name))
- # Creation of the columns
- for name in col_names:
- layer.CreateField(ogr.FieldDefn(name, ogr.OFTString))
+ # 3) Creation of the attributes
+ print("II.3)")
+ for idx in range(0, len(col_names)):
+ if any(elem in table_cols[idx] for elem in ["index", "order", "quantity", "taq", "tpq", "year"]):
+ layer.CreateField(ogr.FieldDefn(col_names[idx], ogr.OFTInteger64))
+ elif any(elem in table_cols[idx] for elem in ["_x", "_y", "_z", "circumference", "cost", "depth", "diameter", "height", "length", "number", "surface", "side", "thickness", "value", "volume", "weight", "width"]):
+ layer.CreateField(ogr.FieldDefn(col_names[idx], ogr.OFTReal))
+ elif "_date" in table_cols[idx]:
+ layer.CreateField(ogr.FieldDefn(col_names[idx], ogr.OFTDate))
+ elif "_datetime" in table_cols[idx]:
+ layer.CreateField(ogr.FieldDefn(col_names[idx], ogr.OFTDateTime))
+ elif any(elem in table_cols[idx] for elem in ["large_area_prescription", "is_complete", "executed"]):
+ layer.CreateField(ogr.FieldDefn(col_names[idx], ogr.OFTBinary))
+ else:
+ layer.CreateField(ogr.FieldDefn(col_names[idx], ogr.OFTString))
+ idx += 1
max = len(col_names)
- # Looping on all the datas extracted
+ # Looping on all the datas extracted to create features
for data in datas:
# Creation of a new feature
feature = ogr.Feature(layer.GetLayerDefn())
+ # Preparations for the geometry
+ point = ""
+ geom_x = ""
+ geom_y = ""
+ geom_z = ""
# Looping on the attributes to add them to the feature
- for n in range (0, max) :
- # +1 because the first value in the attributes is ''
- m = n + 1
- feature.SetField(col_names[n], str(data[m]))
- # First version to create the geometry of the feature
- # Work in progress
- if "x" in col_names[n] or "X" in col_names[n]:
- try:
- float(data[m])
- geom_x = data[m]
- except:
- pass
- if "y" in col_names[n] or "Y" in col_names[n]:
+ for idx in range (0, max) :
+ # 4) Completion of the attributes
+ if any(elem == table_cols[idx] for elem in ["_date", "_datetime"]):
+ # Preparations for specific values for the date and date_time
try:
- float(data[m])
- geom_y = data[m]
+ # First version if it has all the data necessary for an ogr.OFTDateTime
+ # +1 because the first value in the attributes is ''
+ feature.SetField(col_names[idx], data[idx + 1])
except:
- pass
- try:
- point = ogr.Geometry(ogr.wkbPoint)
- point.AddPoint(float(geom_x), float(geom_y))
- feature.SetGeometry(point)
- layer.CreateFeature(feature)
- except:
- pass
+ # Second version if some values are missing
+ # +1 because the first value in the attributes is ''
+ feature.SetField(col_names[idx], data[idx + 1].year, data[idx + 1].month, data[idx + 1].day, 0, 0, 0)
+ else:
+ # +1 because the first value in the attributes is ''
+ feature.SetField(col_names[idx], str(data[idx + 1]))
+ # 5) Gestion of the geometry
+ if any(elem in table_cols for elem in ["base_finds__point_2d", "base_finds__point_3d", "_line", "_points", "_polygon"]):
+ if table_cols[idx] in ["base_finds__point_2d", "base_finds__point_3d", "_line", "_points", "_polygon"]:
+ try:
+ point = ogr.CreateGeometryFromWkt(data[idx + 1].split(";")[1])
+ except:
+ pass
+ else:
+ if "base_finds__x" and "base_finds__y" in table_cols:
+ if table_cols[idx] == "base_finds__x":
+ geom_x = data[idx + 1]
+ elif table_cols[idx] == "base_finds__y":
+ geom_y = data[idx + 1]
+ if "base_finds__z" in table_cols:
+ if table_cols[idx] == "base_finds__z":
+ geom_z = data[idx + 1]
+ # Prevent problems when both x,y and geometry are present
+ if point == "" and geom_x != "" and geom_y != "":
+ if geom_z != "":
+ point = ogr.Geometry(ogr.wkbPoint25D)
+ point.AddPoint(float(geom_x), float(geom_y), float(geom_z))
+ else:
+ point = ogr.Geometry(ogr.wkbPoint)
+ point.AddPoint(float(geom_x), float(geom_y))
+ if point != "":
+ feature.SetGeometry(point)
+ layer.CreateFeature(feature)
feature = None
datasource = None
- # Missing : Part where the new .gpkg is moved to a copy of the QField folder
- # Work in progress
+ # 6) Modification of the style
+ list_ref = ["champ_id", "champ_date", "champ_datetime", "champ_x", "champ_y", "champ_z", "champ_media", "champ_wkt_2d", "champ_wkt_3d"]
+ list_search = ["label", "_date", "_datetime", "base_finds__x", "base_finds__y", "base_finds__z", "_image", "__point_2d", "__point_2d"]
+ text = open(qgs_path, encoding='utf-8').read()
+ for elem in list_search:
+ for col in table_cols:
+ if elem in col:
+ id_old = list_search.index(elem)
+ id_new = table_cols.index(col)
+ text = text.replace(list_ref[id_old], col_names[id_new])
+ else:
+ pass
+ with open(new_qgs, 'w', encoding='utf-8') as file:
+ file.write(text)
+ # III. Moving the .gpkg in a copy of the Qfield test project
+ with ZipFile(duplicate, 'a') as zip_file:
+ # Adding the .gpkg to the .zip
+ zip_file.write(filename, os.path.basename(filename))
+ zip_file.write(new_qgs, os.path.basename(new_qgs))
+ # Closing of the .zip
+ zip_file.close()
+ response = HttpResponse(open(duplicate, 'rb'), content_type='application/zip')
+ response['Content-Disposition'] = 'attachment; filename="Qfield_prospections.zip"'
+ return response
return HttpResponse("{}", content_type="text/plain")
return func