diff --git a/app/contrib/frontend/maps/migrations/0002_auto_20231005_1254.py b/app/contrib/frontend/maps/migrations/0002_auto_20231005_1254.py new file mode 100644 index 00000000..2c0a8798 --- /dev/null +++ b/app/contrib/frontend/maps/migrations/0002_auto_20231005_1254.py @@ -0,0 +1,34 @@ +# Generated by Django 3.2 on 2023-10-05 12:54 + +import colorfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('maps', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='maps', + name='lineColor', + field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=[('#FFFFFF', 'white'), ('#000000', 'black')], verbose_name='Cor da borda'), + ), + migrations.AddField( + model_name='maps', + name='pointA', + field=models.FileField(blank=True, null=True, upload_to='maps/icons/'), + ), + migrations.AddField( + model_name='maps', + name='pointB', + field=models.FileField(blank=True, null=True, upload_to='maps/icons/'), + ), + migrations.AlterField( + model_name='maps', + name='geojson', + field=models.FileField(blank=True, null=True, upload_to='maps/geojson/'), + ), + ] diff --git a/app/contrib/frontend/maps/migrations/0003_auto_20231005_1327.py b/app/contrib/frontend/maps/migrations/0003_auto_20231005_1327.py new file mode 100644 index 00000000..39e3609b --- /dev/null +++ b/app/contrib/frontend/maps/migrations/0003_auto_20231005_1327.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2 on 2023-10-05 13:27 + +import colorfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('maps', '0002_auto_20231005_1254'), + ] + + operations = [ + migrations.RenameField( + model_name='maps', + old_name='pointB', + new_name='point_a', + ), + migrations.RenameField( + model_name='maps', + old_name='pointA', + new_name='point_b', + ), + migrations.RemoveField( + model_name='maps', + name='lineColor', + ), + migrations.AddField( + model_name='maps', + name='line_color', + field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=[('#FFFFFF', 'white'), ('#000000', 'black')], verbose_name='Cor da linha'), + ), + ] diff --git a/app/contrib/frontend/maps/models.py b/app/contrib/frontend/maps/models.py index dc41fc1c..80971811 100644 --- a/app/contrib/frontend/maps/models.py +++ b/app/contrib/frontend/maps/models.py @@ -2,5 +2,27 @@ from cms.plugin_base import CMSPlugin +from colorfield.fields import ColorField + +STYLED_COLOR_PALLETE = [ + ( + "#FFFFFF", + "white", + ), + ( + "#000000", + "black", + ), +] + class Maps(CMSPlugin): - geojson = models.FileField(upload_to="maps/geojson/") \ No newline at end of file + geojson = models.FileField(upload_to="maps/geojson/", blank=True, null=True) + line_color = ColorField( + verbose_name="Cor da linha", + samples=STYLED_COLOR_PALLETE, + format="hexa", + blank=True, + null=True, + ) + point_a = models.FileField(upload_to="maps/icons/", blank=True, null=True) + point_b = models.FileField(upload_to="maps/icons/", blank=True, null=True) diff --git a/app/contrib/frontend/maps/static/maps/js/maps.js b/app/contrib/frontend/maps/static/maps/js/maps.js index 1933f0a1..2d31a501 100644 --- a/app/contrib/frontend/maps/static/maps/js/maps.js +++ b/app/contrib/frontend/maps/static/maps/js/maps.js @@ -2,6 +2,8 @@ let config = { minZoom: 7, maxZoom: 18, zoomControl: false, + autoPan: false, + scrollWheelZoom: false }; const zoom = 18; @@ -10,16 +12,17 @@ const lng = -46.63366; const mapWrapper = document.querySelector("#map"); +// Adiciona o mapa const map = L.map("map", config).setView([lat, lng], zoom); -// Used to load and display tile layers on the map -// Most tile servers require attribution, which you can set under `Layer` +// Carrega e mostra o layer L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution: '© OpenStreetMap contributors', }).addTo(map); // ------------------------------------------------------------ + L.control.zoom({ position: "topright" }).addTo(map); // -------------------------------------------------------------- @@ -35,7 +38,7 @@ L.Control.Search = L.Control.extend({ container.insertAdjacentHTML( "beforeend", `
- +
` ); @@ -46,11 +49,73 @@ L.Control.Search = L.Control.extend({ new L.Control.Search().addTo(map); // -------------------------------------------------------------- +let startPoint, endPoint, polylineGeoJSON; let geojsonarray = []; +function addMarkers(coordinates) { + let LeafIcon = L.Icon.extend({ + options: { + iconSize: [40, 40], + iconAnchor: [22, 50], + popupAnchor: [-3, -76] + } + }); + + // Remove marcadores existentes + if (startPoint) map.removeLayer(startPoint); + if (endPoint) map.removeLayer(endPoint); + + startPoint = L.marker([coordinates[0][1], coordinates[0][0]]); + endPoint = L.marker([coordinates[coordinates.length - 1][1], coordinates[coordinates.length - 1][0]]); + + // Adiciona marcadores nos pontos inicial e final + if (mapWrapper.dataset.mapsIconsPointA) { + let startIcon = new LeafIcon({iconUrl: mapWrapper.dataset.mapsIconsPointA}) + startPoint = L.marker([coordinates[0][1], coordinates[0][0]], {icon: startIcon}); + } + if (mapWrapper.dataset.mapsIconsPointB) { + let endIcon = new LeafIcon({iconUrl: mapWrapper.dataset.mapsIconsPointB}) + endPoint = L.marker([coordinates[coordinates.length - 1][1], coordinates[coordinates.length - 1][0]], {icon: endIcon}); + } + + // Adiciona marcadores ao mapa + startPoint.addTo(map); + endPoint.addTo(map); +} + +function addPolyline(coordinates, properties) { + const lineColor = mapWrapper.dataset.mapsLinecolor; + + // Remove linha existente + if (polylineGeoJSON) map.removeLayer(polylineGeoJSON); + + // Adiciona linha ao mapa + polylineGeoJSON = L.geoJSON({ + type: "LineString", + coordinates: coordinates, + }, { + style: { + color: lineColor || "red", + weight: 3, + opacity: 1, + fillOpacity: 0.5, + }, + onEachFeature: function (feature, layer) { + const linhaNum = properties.ln_codigo.toString(); + const linhaName = properties.title.toString(); + const linhaEmpresa = properties.ln_empresa.toString(); + + layer.bindPopup( + "Número:\n" + linhaNum + "
" + + "Nome:\n" + linhaName + "
" + + "Empresa responsável:\n" + linhaEmpresa + "
" + ); + }, + }).addTo(map); +} + new Autocomplete("local", { onSearch: ({ currentValue }) => { - const api = mapWrapper.dataset.mapsGeojson; return new Promise((resolve) => { fetch(api) @@ -77,69 +142,40 @@ new Autocomplete("local", { return matches === 0 ? template : matches - .map((el) => { - const icon = - el.properties.type === "rectangle" - ? "polygon" - : el.properties.type.toLowerCase(); - return ` + .map((el) => { + return `
  • ${el.properties.title}
  • `; - }) - .join(""); + }) + .join(""); }, onSubmit: ({ object }) => { - const geojsonlayer = L.geoJSON(object, { - style: function (feature) { - return { - color: feature.properties.color || "red", - weight: 7, - opacity: 1, - fillOpacity: 0.7, - }; - }, - pointToLayer: (feature, latlng) => { - if (feature.properties.type === "circle") { - return new L.circle(latlng, { - radius: feature.properties.radius, - }); - } else if (feature.properties.type === "circlemarker") { - return new L.circleMarker(latlng, { - radius: 20, - }); - } else { - return new L.Marker(latlng); - } - }, - onEachFeature: function (feature, layer) { - // const infos = feature.properties.layer.toString(); + const coordinates = object.geometry.coordinates; + const properties = object.properties; - layer.bindPopup( - "Informações:
    " + "oiee
    " + "
    " - ); - }, - }); + // Adiciona marcadores nos pontos inicial e final + addMarkers(coordinates); + + // Adiciona linha ao mapa + addPolyline(coordinates, properties); - map.fitBounds(geojsonlayer.getBounds(), { padding: [150, 150] }); + map.fitBounds(polylineGeoJSON.getBounds(), { padding: [150, 150] }); if (geojsonarray.includes(object.properties.id)) return; geojsonarray.push(object.properties.id); - - geojsonlayer.addTo(map); }, noResults: ({ currentValue, template }) => - template(`
  • No results found: "${currentValue}"
  • `), + template(`
  • Sem resultados: "${currentValue}"
  • `), onReset: () => { - // remove all layers - map.eachLayer(function (layer) { - if (!!layer.toGeoJSON) { - map.removeLayer(layer); - } - }); + // Remove marcadores e linha + if (startPoint) map.removeLayer(startPoint); + if (endPoint) map.removeLayer(endPoint); + if (polylineGeoJSON) map.removeLayer(polylineGeoJSON); + geojsonarray = []; }, }); diff --git a/app/contrib/frontend/maps/templates/maps/plugins/map.html b/app/contrib/frontend/maps/templates/maps/plugins/map.html index dd21a8a7..850daa77 100644 --- a/app/contrib/frontend/maps/templates/maps/plugins/map.html +++ b/app/contrib/frontend/maps/templates/maps/plugins/map.html @@ -8,7 +8,12 @@ {% endaddtoblock %} -
    +
    +
    {% addtoblock "js" %} diff --git a/app/contrib/frontend/migrations/0004_auto_20231005_1254.py b/app/contrib/frontend/migrations/0004_auto_20231005_1254.py new file mode 100644 index 00000000..ff0862c6 --- /dev/null +++ b/app/contrib/frontend/migrations/0004_auto_20231005_1254.py @@ -0,0 +1,29 @@ +# Generated by Django 3.2 on 2023-10-05 12:54 + +import colorfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('frontend', '0003_alter_button_font'), + ] + + operations = [ + migrations.AlterField( + model_name='button', + name='background_color', + field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=[('#FFFFFF', 'white'), ('#000000', 'black')], verbose_name='Cor de fundo'), + ), + migrations.AlterField( + model_name='button', + name='border_color', + field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=[('#FFFFFF', 'white'), ('#000000', 'black')], verbose_name='Cor da borda'), + ), + migrations.AlterField( + model_name='button', + name='color', + field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=[('#FFFFFF', 'white'), ('#000000', 'black')], verbose_name='Cor da fonte'), + ), + ]