From 8088908a3b53dcaeee518e51b8716158d663380f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Thu, 19 Dec 2024 10:23:27 -0300 Subject: [PATCH] =?UTF-8?q?Mapa=20de=20atua=C3=A7=C3=A3o=20do=20Interlegis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/home/static/home/css/openmap.css | 15 +- sigi/apps/home/static/home/js/openmap.js | 174 ++++++++++++++++++ sigi/apps/home/templates/home/mapfilter.html | 123 +++++++++++++ sigi/apps/home/templates/home/openmap.html | 87 +++++++++ .../home/templates/home/openmapdetail.html | 47 +++++ sigi/apps/home/views.py | 24 ++- 6 files changed, 455 insertions(+), 15 deletions(-) create mode 100644 sigi/apps/home/static/home/js/openmap.js create mode 100644 sigi/apps/home/templates/home/mapfilter.html create mode 100644 sigi/apps/home/templates/home/openmap.html create mode 100644 sigi/apps/home/templates/home/openmapdetail.html diff --git a/sigi/apps/home/static/home/css/openmap.css b/sigi/apps/home/static/home/css/openmap.css index 81712ac..f50742a 100644 --- a/sigi/apps/home/static/home/css/openmap.css +++ b/sigi/apps/home/static/home/css/openmap.css @@ -6,8 +6,13 @@ html, width: 100%; } -#content { - height: calc(100% - 60px); +#content, +.content { + height: 100%; +} + +.main { + height: calc(100% - 80px); } .filterwrap { @@ -134,4 +139,10 @@ li>a.clear-filters>i.material-icons { .embed-map-content { height: 100% !important; +} + +.ui-autocomplete { + overflow-y: auto; + overflow-x: hidden; + z-index: 1000; } \ No newline at end of file diff --git a/sigi/apps/home/static/home/js/openmap.js b/sigi/apps/home/static/home/js/openmap.js new file mode 100644 index 0000000..5775ae3 --- /dev/null +++ b/sigi/apps/home/static/home/js/openmap.js @@ -0,0 +1,174 @@ +const stadia_tiles_options = { + attribution: + ` + © Stadia Maps + © Stamen Design + © OpenMapTiles + © OpenStreetMap contributors" + ` +}; +var mymap; +var orgao_layer_group = L.layerGroup(); +var map_center = [-14.235004, -51.92528]; +var options = { color: 'blue', fillColor: 'red', fillOpacity: 0.4, radius: 500 }; +var unfiltred_options = { color: 'red', fillColor: 'red', fillOpacity: 0, radius: 1000 }; +$(document).ready(function () { + $("input[type=checkbox]").change(filtra); + var search_field = $("#map-search"); + + if (search_field) { + search_field.autocomplete({ + source: search_field.attr("data-source"), + minLength: 3, + select: function (event, ui) { + map_fly_to(ui.item); + } + }); + } + + var base_layers = { + "Toner": L.tileLayer( + "https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}{r}.png", + stadia_tiles_options, + ), + "Toner lite": L.tileLayer( + "https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png", + stadia_tiles_options, + ), + "Terrain": L.tileLayer( + "https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png", + stadia_tiles_options, + ), + "Water color": L.tileLayer( + "https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg", + stadia_tiles_options, + ), + "Open street": L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: 'Map data and imagery © OpenStreetMap contributors, ', + tileSize: 512, + zoomOffset: -1 + }), + }; + + mymap = L.map('map', { + center: map_center, + zoom: 4.5, + zoomSnap: 0.01, + layers: [base_layers.Terrain, orgao_layer_group] + }); + + mymap.zoomControl.options.zoomInTitle = "{% trans 'Aproximar' %}"; + mymap.zoomControl.options.zoomOutTitle = "{% trans 'Afastar' %}"; + mymap.zoomControl.setPosition("bottomright"); + + L.control.layers(base_layers).addTo(mymap); + + mymap.on("popupopen", function (e) { + var popup = e.popup; + mark = popup._source; + $.ajax({ + type: "GET", + url: window.__openmapdetail_prefix__.replace("changeme", mark.orgao_id), + encode: true + }).done(function (content) { + popup.setContent(content); + }) + }) + + filtra(); + + function filtra() { + var name = $(this).attr("name"), + value = $(this).attr("value"), + checked = $(this).prop("checked"); + + if (name) { + $(`input[type=checkbox][name=${name}][value=${value}]`).prop("checked", checked); + } + + if (value == "ignore") { + controls = $(this).attr("data-controls"); + $("input[type=checkbox][name='" + controls + "']").prop("disabled", checked); + } + + if (value == "none") { + $("input[type=checkbox][name='" + name + "'][value!='none']").prop("checked", !checked); + } else { + if (checked) { + $("input[type=checkbox][name='" + name + "'][value='none']").prop("checked", false); + } + } + + if (name == 'regiao') { + $("input[type=checkbox][name='uf'][data-regiao='" + value + "']").prop('checked', checked); + } + + if (name == 'uf') { + var sigla_regiao = $(this).attr('data-regiao'), + regiao = $("input[type=checkbox][value='" + sigla_regiao + "']"); + if ($("input[type=checkbox][name='uf'][data-regiao='" + sigla_regiao + "']:checked").length == 0) { + $(regiao).prop('checked', false).prop("indeterminate", false); + } else if ($("input[type=checkbox][name='uf'][data-regiao='" + sigla_regiao + "']:not(:checked)").length == 0) { + $(regiao).prop('checked', true).prop("indeterminate", false); + } else { + $(regiao).prop("indeterminate", true) + } + } + + var formData = $("#filterForm").serializeArray(); + $("#filter-spinner").toggleClass("d-none d-flex"); + $.ajax({ + type: "GET", + url: window.__openmapdata__, + data: formData, + dataType: "json", + encode: true, + }).done(function (returnedData) { + $("#filter-spinner").toggleClass("d-none d-flex"); + $("#totalOrgao").text(returnedData.length); + var new_data_layer = L.layerGroup(); + returnedData.forEach(function (casa) { + if (casa[2] === null || casa[3] === null) { + alert(casa[1] + " está sem coordenadas geográficas e não será plotada"); + } else { + var mark = L.circle([casa[2], casa[3]], options).bindTooltip(casa[1]).bindPopup('
').addTo(new_data_layer); + mark.orgao_id = casa[0] + } + }); + orgao_layer_group.clearLayers(); + orgao_layer_group.addLayer(new_data_layer); + }) + } + + $("#clear-filters").click(function (event) { + event.preventDefault(); + $("input[type=checkbox][name=tipo_orgao]").prop('checked', false); + $("input[type=checkbox][name=tipo_servico]").prop('checked', false); + $("input[type=checkbox][name=tipo_convenio]").prop('checked', false); + $("input[type=checkbox][name=regiao]").prop('checked', false); + $("input[type=checkbox][name=uf]").prop('checked', false); + $("input[type=checkbox][name=gerente]").prop('checked', false); + filtra(); + }); + $("#center-map").click(function (event) { + event.preventDefault(); + mymap.flyTo(map_center, 4.5); + }); +}); +function map_fly_to(obj) { + mymap.flyTo([obj.lat, obj.lng], 8.5); + var encontrado = false; + mymap.eachLayer(function (layer) { + if (layer instanceof L.Circle) { + if (layer.orgao_id == obj.id) { + layer.openPopup(); + encontrado = true; + } + } + }); + if (!encontrado) { + var mark = L.circle([obj.lat, obj.lng], unfiltred_options).bindTooltip(obj.label).bindPopup("").addTo(mymap); + mark.orgao_id = obj.id + mark.openPopup(); + } +} \ No newline at end of file diff --git a/sigi/apps/home/templates/home/mapfilter.html b/sigi/apps/home/templates/home/mapfilter.html new file mode 100644 index 0000000..9cf8b0d --- /dev/null +++ b/sigi/apps/home/templates/home/mapfilter.html @@ -0,0 +1,123 @@ +{% load i18n %} + +
{{ csrftoken }} +
+
+

+ +

+
+
+ {% for o in tipos_orgao %} +
+ + +
+ {% endfor %} +
+
+
+
+

+ +

+
+
+
+ + +
+
+ + +
+ {% for s in tipos_servico %} +
+ + +
+ {% endfor %} +
+
+
+
+

+ +

+
+
+
+ + +
+
+ + +
+ {% for c in tipos_convenio %} +
+ + +
+ {% endfor %} +
+
+
+
+

+ +

+
+
+ {% for s, n, ufs in regioes %} +
+ + +
+
+ {% for uf in ufs %} +
+ + +
+ {% endfor %} +
+ {% endfor %} +
+
+
+
+

+ +

+
+
+
+ + +
+
+ + +
+ {% for g in gerentes %} +
+ + +
+ {% endfor %} +
+
+
+
+
\ No newline at end of file diff --git a/sigi/apps/home/templates/home/openmap.html b/sigi/apps/home/templates/home/openmap.html new file mode 100644 index 0000000..a792c26 --- /dev/null +++ b/sigi/apps/home/templates/home/openmap.html @@ -0,0 +1,87 @@ +{% extends "base.html" %} +{% load static i18n djbs_extras %} + +{% block extrastyle %} + {{ block.super }} + + + +{% endblock %} + +{% block extrahead %} + {{ block.super }} + + + + + + + + + +{% endblock %} + +{% block nav-breadcrumbs %}{% endblock %} + +{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} + +{% block navbar-branding %} + + + {{ site_header|default:_('Django administration') }} + + {{ block.super }} +{% endblock %} + +{% block toolclass %}{{ block.super }} ms-auto{% endblock %} + +{% block nav-global %} +{% icon "map-cross" %} {% trans 'Centralizar o mapa' %} +{% icon "filter" %} {% trans "Filtrar dados" %} +{% icon "error" %} {% trans 'Remover todos os filtros' %} +{% icon "login" %} {% trans "Login" %} +{% endblock %} + +{% block side_nav %}{% endblock %} + +{% block menu %}{% endblock %} +{% block coltype %}py-2{% endblock %} + +{% block search %} + + +{% endblock search %} + +{% block content %} +
+
+ {% trans "Loading..." %} +
+
+
+ +
+{% endblock %} + +{% block sidebar-title %}{% translate "Filtrar" %}{% endblock sidebar-title %} + +{% block sidebar-body %} +
+ Total de Órgãos selecionados: + - +
+ {% include "home/mapfilter.html" %} +{% endblock sidebar-body %} \ No newline at end of file diff --git a/sigi/apps/home/templates/home/openmapdetail.html b/sigi/apps/home/templates/home/openmapdetail.html new file mode 100644 index 0000000..b8c613e --- /dev/null +++ b/sigi/apps/home/templates/home/openmapdetail.html @@ -0,0 +1,47 @@ + + + + + + {% if telefones %} + + + + + {% endif %} + {% if orgao.email %}{% endif %} + {% if orgao.convenio_set.all %} + + + + + {% endif %} + {% if orgao.servico_set.all %} + + {% endif %} +
+ {% if user.is_staff %} + {% url "admin:casas_orgao_change" orgao.id as orgao_url %} + {% else %} + {% url "servicos_casas_atendidas" orgao.id as orgao_url %} + {% endif %} + + {{ orgao }} + +
Endereço
{{ orgao.logradouro }}, {{ orgao.bairro }}, {{ orgao.municipio.nome }}, {{ orgao.municipio.uf.sigla }}, CEP: {{ orgao.cep }}
Telefones + {% for telefone in telefones %} + {{ telefone }} + {% if not forloop.last %}, {% endif %} + {% endfor %} +
E-mail{{ orgao.email }}
Convênios + {% for c in orgao.convenio_set.all %} + {% if user.is_staff %} + + {{ c.projeto.sigla }} ({{ c.get_status }}) + + {% else %} + {{ c.projeto.sigla }} ({{ c.get_status }}) + {% endif %} + {% if not forloop.last %}, {% endif %} + {% endfor %} +
Serviços{% for s in servicos.all %}{% if s.url %}{{ s }}{% else %}{{ s }}{% endif %}{% if not forloop.last %}, {% endif %}{% endfor %}
\ No newline at end of file diff --git a/sigi/apps/home/views.py b/sigi/apps/home/views.py index db36011..2da59f3 100644 --- a/sigi/apps/home/views.py +++ b/sigi/apps/home/views.py @@ -346,28 +346,26 @@ def openmapdetail(request, orgao_id): def openmapsearch(request): - q = request.GET.get("q", "") + q = request.GET.get("q", request.GET.get("term", "")) if len(q) < 3: return JsonResponse({"result": "unsearchable"}) - dados = Orgao.objects.filter( - tipo__legislativo=True, search_text__icontains=to_ascii(q) - )[:10] - dados = dados.values( - "id", - "nome", - "municipio__uf__sigla", - "municipio__latitude", - "municipio__longitude", - ) dados = [ { "id": d["id"], - "label": f"{d['nome']} - {d['municipio__uf__sigla']}", + "label": f"{d['nome']}, {d['municipio__uf__sigla']}", "lat": d["municipio__latitude"], "lng": d["municipio__longitude"], } - for d in dados + for d in Orgao.objects.filter( + tipo__legislativo=True, search_text__icontains=to_ascii(q) + )[:10].values( + "id", + "nome", + "municipio__uf__sigla", + "municipio__latitude", + "municipio__longitude", + ) ] return JsonResponse(list(dados), safe=False)