Compare commits

..

2 Commits

Author SHA1 Message Date
Juan Burgos
70460b3310 Adición del modo mapa satelital 2026-08-05 13:13:04 +00:00
Juan Burgos
e31ab73c05 Adición del modo mapa satelital 2026-08-05 13:12:42 +00:00
7 changed files with 109 additions and 32 deletions

View File

@@ -12,8 +12,10 @@ define([
//console.log('Params:', params);
this.anexarUbic = ko.observable(false);
this.satMap = ko.observable(false);
this.anexarImagenes = ko.observable(false);
this.anexarPdfs = ko.observable(false);
const boolToStr = (bool) => bool ? "1" : "0";
self.resourceId = ko.observable(
@@ -23,7 +25,7 @@ define([
self.exportPDF = function() {
var id = self.resourceId();
if (id) {
var url = '/export/pdf/' + id + '/' + boolToStr(self.anexarUbic()) + '/' + boolToStr(self.anexarImagenes()) + '/' + boolToStr(self.anexarPdfs()) + '/';
var url = '/export/pdf/' + id + '/' + boolToStr(self.anexarUbic()) + '/' + boolToStr(self.satMap()) + '/' + boolToStr(self.anexarImagenes()) + '/' + boolToStr(self.anexarPdfs()) + '/';
window.open(url, '_blank');
} else {
alert('No se encontró el ID del recurso.');

View File

@@ -12,9 +12,61 @@ from zoneinfo import ZoneInfo
from functools import reduce
from operator import getitem
from pypdf import PdfReader, PdfWriter
import urllib.parse
import requests
import base64
import json
import ast
def static_map_view(geojson_colec, sat_map):
geojson_dict = ast.literal_eval(geojson_colec)
if sat_map:
for geo in geojson_dict['features'] :
if geo['geometry'].get('type') == 'Polygon':
geo['properties'] = {
"stroke": "#00ffff",
"stroke-width": 2,
"stroke-opacity": 0.8,
"fill": "#00ffff",
"fill-opacity": 0.3
}
elif geo['geometry'].get('type') == 'Point':
geo['properties'] = {
"marker-color": "#ff0000",
"marker-size": "small"
}
elif geo['geometry'].get('type') == 'LineString':
geo['properties'] = {
"stroke": "#0000ff",
"stroke-width": 2,
"stroke-opacity": 0.8
}
geojson_string = json.dumps(geojson_dict, separators=(',', ':'))
encoded_geojson = urllib.parse.quote(geojson_string)
username = "mapbox"
if sat_map:
style_id = "satellite-streets-v12" # streets-v12 | outdoors-v11 | satellite-streets-v12
else:
style_id = "light-v11"
width, height = 340, 340
# Procedimiento pendiente para extraer el token desde la configuración del sistema
access_token = 'pk.eyJ1IjoianNidXJnb3N2IiwiYSI6ImNsaWhoN3ZtMTBxeHUzZm1xaGM0cGpxOXIifQ.ki3vldVB5MwZMqDSpLSjLg'
mapbox_url = (
f"https://api.mapbox.com/styles/v1/{username}/{style_id}/static/"
f"geojson({encoded_geojson})/auto/{width}x{height}"
f"?access_token={access_token}"
)
response = requests.get(mapbox_url)
return base64.b64encode(response.content).decode('utf-8')
def ajustar_medios(resource_media_rel, medios_list):
medios = []
img=["image/bmp", "image/gif", "image/jpg", "image/jpeg", "image/png", "image/tif", "image/tiff"]
@@ -83,12 +135,13 @@ def strdict_to_dict(strdict):
pass
return value
def export_resource_pdf(request, resourceid, printubic, printimgs, printpdfs):
def export_resource_pdf(request, resourceid, printubic, satmap, printimgs, printpdfs):
resource = Resource.objects.get(pk=resourceid)
resource_data = resource.to_json()
# Corrección de medios relacionados, se normalizan claves y se adicionan propiedades
ruta_medios = find_key_path( resource_data, "Medio de información")
if ruta_medios is not None:
valor_medios=reduce(lambda dict_layer, key: dict_layer[key], ruta_medios, resource_data)
resource_rel=resource.get_related_resources(user=request.user,resourceinstance_graphid='6afc4e9e-727e-4152-8084-309267752650')
@@ -96,6 +149,7 @@ def export_resource_pdf(request, resourceid, printubic, printimgs, printpdfs):
reduce(getitem, ruta_medios[:-1], resource_data)[ruta_medios[-1]] = ajustar_medios(resource_rel,valor_medios)
# Cambio de datos gis en texto a formato json
ruta_gis = find_key_path( resource_data, "Coordenadas / Geometría")
if ruta_gis is not None:
valor_gis=reduce(lambda dict_layer, key: dict_layer[key], ruta_gis, resource_data)["@value"]
@@ -111,7 +165,13 @@ def export_resource_pdf(request, resourceid, printubic, printimgs, printpdfs):
# Fecha del informe
sprpcb_url=request.build_absolute_uri('/')[:-1]
fecha=datetime.now(ZoneInfo("America/La_Paz"))
map_img = None
if ruta_gis is not None and bool(int(printubic)) :
if reduce(getitem, ruta_gis[:-1], resource_data)[ruta_gis[-1]]["@value"] :
map_img = static_map_view(reduce(getitem, ruta_gis[:-1], resource_data)[ruta_gis[-1]]["@value"], bool(int(satmap)))
resources = [{
'resourceinstanceid': str(resource.resourceinstanceid),
'graph_id': str(resource.graph_id),
@@ -120,8 +180,10 @@ def export_resource_pdf(request, resourceid, printubic, printimgs, printpdfs):
'sprpcb_url': sprpcb_url,
'fecha': fecha,
'eta_group': eta_group,
'print_ubic': bool(int(printubic)),
'print_imgs': bool(int(printimgs)),
'print_pdfs': bool(int(printpdfs))
'print_pdfs': bool(int(printpdfs)),
'map_img': map_img
}]
context = {'resources': resources}
@@ -151,16 +213,18 @@ def export_resource_pdf(request, resourceid, printubic, printimgs, printpdfs):
root_path = Path(__file__).resolve().parent.parent
for medio in reduce(getitem, ruta_medios[:-1], resource_data)[ruta_medios[-1]] :
if medio['formato'] == 'application/pdf' and bool(int(printpdfs)) :
merger.append(PdfReader(f'{root_path}/uploadedfiles/{medio["file"]}'))
output_buffer = io.BytesIO()
merger.write(output_buffer)
merger.close()
else:
output_buffer = io.BytesIO()
merger.write(output_buffer)
merger.close()
if ruta_medios is not None and bool(int(printpdfs)) :
for medio in reduce(getitem, ruta_medios[:-1], resource_data)[ruta_medios[-1]] :
if medio['formato'] == 'application/pdf' :
merger.append(PdfReader(f'{root_path}/uploadedfiles/{medio["file"]}'))
output_buffer = io.BytesIO()
merger.write(output_buffer)
merger.close()
else:
output_buffer = io.BytesIO()
merger.write(output_buffer)
merger.close()
response = HttpResponse(output_buffer.getvalue(), content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="{nombre_pdf}.pdf"'
return response

View File

@@ -16,14 +16,15 @@
h3 { font-size: 12pt;}
h4 { font-size: 11pt;}
.tiles-grid-grp { display: grid; grid-template-columns: 3fr 2fr; grid-template-rows: auto auto; gap: 2px;}
.tiles-grid-grp { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; gap: 2px;}
.tiles-grid-grp-col { grid-column: 2; grid-row: 1 / span 2; }
.tile-block { border: 1px solid var(--ceniza); border-radius: 4px; padding: 2px; margin: 2px 0; background-color: var(--claro);}
.tile-title { font-size: 11pt; font-weight: bold; color: var(--oscuro); border-bottom: 1px solid var(--ceniza); padding-bottom: 2px; margin-bottom: 5px;}
.data-row { display: flex; padding: 2px 0; border-bottom: 1px solid var(--claro);}
.data-label { font-weight: 600; letter-spacing: -0.05em; width: 40%; color: var(--oscuro);}
.data-value { width: 40%; letter-spacing: -0.05em; word-wrap: break-word;}
.data-value { width: 60%; font-size:.9em; word-wrap: break-word;}
.no-data { color: var(--ceniza); font-style: italic;}
.tiles-grid-grp-col .tile-block img { object-fit: cover; width: 330px; max-height: 230px;}
@page {
@top-left { background: var(--resaltado); content: counter(page); height: 1cm; text-align: center; width: 1cm;}
@@ -117,7 +118,7 @@
{% with gis_vector=resource_data|val_from_key:"Ubicación simple"|val_from_key:"Coordenadas / Geometría"|val_from_key:"@value"|json_to_obj %}
{% for gis in gis_vector.features %}
<div class="data-row">
<span class="data-value" style="width: 100%;">{{ gis.geometry }}</span>
<span class="data-value" style="width: 100%; font-size: .72em;">{{ gis.geometry|truncatewords:24 }}</span>
</div>
{% endfor %}
{% endwith %}
@@ -131,6 +132,7 @@
<div class="tiles-grid-grp-col">
<div class="tile-block">
<div class="data-label">Mapa de referencia</div>
<img src="data:image/png;base64,{{ resource.map_img }}">
</div>
</div>
</div>

View File

@@ -162,7 +162,7 @@
{% with gis_vector=resource_data|val_from_key:"Ubicación BIM"|val_from_key:"Coordenadas / Geometría"|val_from_key:"@value"|json_to_obj %}
{% for gis in gis_vector.features %}
<div class="data-row">
<span class="data-value" style="width: 100%;">{{ gis.geometry }}</span>
<span class="data-value" style="width: 100%; font-size: .72em;">{{ gis.geometry|truncatewords:24 }}</span>
</div>
{% endfor %}
{% endwith %}
@@ -175,6 +175,7 @@
<div class="tiles-grid-grp-col">
<div class="tile-block">
<div class="tile-title">Mapa de referencia</div>
<img src="data:image/png;base64,{{ resource.map_img }}">
</div>
</div>
</div>

View File

@@ -152,15 +152,17 @@
<span class="data-label">Espacio: </span>
<span class="data-value">{{ resource_data|val_from_key:"Localización"|val_from_key:"Espacio" }}</span>
</div>
<div class="data-row">
<span class="data-label">Inmueble: </span>
<span class="data-value">{{ resource_data|val_from_key:"Localización"|val_from_key:"Inmueble" }}</span>
</div>
<div class="data-row">
<span class="data-label">Colección: </span>
<span class="data-value">{{ resource_data|val_from_key:"Localización"|val_from_key:"Colección" }}</span>
</div>
{% if resource_data|val_from_key:"Localización"|has_key:"Ubicación" %}
{% if resource.print_ubic %}
<div class="data-row">
<span class="data-label">Inmueble: </span>
<span class="data-value">{{ resource_data|val_from_key:"Localización"|val_from_key:"Inmueble" }}</span>
</div>
<div class="data-row">
<span class="data-label">Colección: </span>
<span class="data-value">{{ resource_data|val_from_key:"Localización"|val_from_key:"Colección" }}</span>
</div>
{% endif %}
{% if resource_data|val_from_key:"Localización"|has_key:"Ubicación" and resource.print_ubic %}
<div class="data-row" style="margin-left: 15px;">
<span class="data-value" style="width: 100%;"><b>Ambiente : </b> {{resource_data|val_from_key:"Localización"|val_from_key:"Ubicación"|val_from_key:"Ambiente" }}</span>
</div>
@@ -180,11 +182,11 @@
<div class="data-row">
<span class="data-label" style="width: 100%;">Coordenadas / Geometría: </span>
</div>
{% if resource_data|val_from_key:"Localización"|has_key:"Coordenadas / Geometría" %}
{% if resource_data|val_from_key:"Localización"|has_key:"Coordenadas / Geometría" and resource.print_ubic %}
{% with gis_vector=resource_data|val_from_key:"Localización"|val_from_key:"Coordenadas / Geometría"|val_from_key:"@value"|json_to_obj %}
{% for gis in gis_vector.features %}
<div class="data-row">
<span class="data-value" style="width: 100%;">{{ gis.geometry }}</span>
<span class="data-value" style="width: 100%; font-size: .72em;">{{ gis.geometry|truncatewords:24 }}</span>
</div>
{% endfor %}
{% endwith %}
@@ -197,6 +199,7 @@
<div class="tiles-grid-grp-col">
<div class="tile-block">
<div class="tile-title">Mapa de referencia</div>
<img src="data:image/png;base64,{{ resource.map_img }}">
</div>
</div>
</div>

View File

@@ -126,7 +126,7 @@
{% with gis_vector=resource_data|val_from_key:"Ubicación 2"|val_from_key:"Coordenadas / Geometría"|val_from_key:"@value"|json_to_obj %}
{% for gis in gis_vector.features %}
<div class="data-row">
<span class="data-value" style="width: 100%;">{{ gis.geometry }}</span>
<span class="data-value" style="width: 100%; font-size: .72em;">{{ gis.geometry|truncatewords:24 }}</span>
</div>
{% endfor %}
{% endwith %}
@@ -140,6 +140,7 @@
<div class="tiles-grid-grp-col">
<div class="tile-block">
<div class="tile-title">Mapa de referencia</div>
<img src="data:image/png;base64,{{ resource.map_img }}">
</div>
</div>
</div>

View File

@@ -15,11 +15,15 @@
</div>
<div class="report-print-date" data-bind="component: {
name: 'views/components/simple-switch',
params: { value: anexarImagenes, config:{ label: 'Incluir imágenes adjuntas'}}}">
params: { value: satMap, config:{ label: 'Mapa satelital'}}}">
</div>
<div class="report-print-date" data-bind="component: {
name: 'views/components/simple-switch',
params: { value: anexarPdfs, config:{ label: 'Incluir documentos (pdf) adjuntos'}}}">
params: { value: anexarImagenes, config:{ label: 'Adjuntar imágenes'}}}">
</div>
<div class="report-print-date" data-bind="component: {
name: 'views/components/simple-switch',
params: { value: anexarPdfs, config:{ label: 'Adjuntar documentos (pdf)'}}}">
</div>
</div>
</div>