Skip to content

Commit

Permalink
Merge pull request #125 from nossas/feat/map-plugin
Browse files Browse the repository at this point in the history
Feat: Adiciona Plugin de Mapa com Leaflet.js e autocomplete.js
  • Loading branch information
igr-santos authored Oct 2, 2023
2 parents c40c3af + b068600 commit 2b00137
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 1 deletion.
Empty file.
6 changes: 6 additions & 0 deletions app/contrib/frontend/maps/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class MapsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'contrib.frontend.maps'
16 changes: 16 additions & 0 deletions app/contrib/frontend/maps/cms_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django import forms
from django.conf import settings
from django.contrib.sites.models import Site

from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool

from .models import Maps

@plugin_pool.register_plugin
class LeafletMapPlugin(CMSPluginBase):
name = "Mapa"
module = "Frontend"
model = Maps
render_template = "maps/plugins/map.html"

27 changes: 27 additions & 0 deletions app/contrib/frontend/maps/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 3.2 on 2023-09-29 20:11

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('cms', '0022_auto_20180620_1551'),
]

operations = [
migrations.CreateModel(
name='Maps',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='maps_maps', serialize=False, to='cms.cmsplugin')),
('geojson', models.FileField(upload_to='maps/geojson/')),
],
options={
'abstract': False,
},
bases=('cms.cmsplugin',),
),
]
Empty file.
6 changes: 6 additions & 0 deletions app/contrib/frontend/maps/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.db import models

from cms.plugin_base import CMSPlugin

class Maps(CMSPlugin):
geojson = models.FileField(upload_to="maps/geojson/")
3 changes: 3 additions & 0 deletions app/contrib/frontend/maps/static/maps/css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#map {
height: 800px;
}
145 changes: 145 additions & 0 deletions app/contrib/frontend/maps/static/maps/js/maps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
let config = {
minZoom: 7,
maxZoom: 18,
zoomControl: false,
};

const zoom = 18;
const lat = -23.55016;
const lng = -46.63366;

const mapWrapper = document.querySelector("#map");

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`
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);

// ------------------------------------------------------------
L.control.zoom({ position: "topright" }).addTo(map);

// --------------------------------------------------------------
L.Control.Search = L.Control.extend({
options: {
position: "topleft",
},
onAdd: function () {
const container = L.DomUtil.create("div", "autocomplete-container");

L.DomEvent.disableClickPropagation(container);

container.insertAdjacentHTML(
"beforeend",
`<div class="auto-search-wrapper loupe">
<input type="text" id="local" autocomplete="off" placeholder="Enter e or p" />
</div>`
);

return container;
},
});

new L.Control.Search().addTo(map);

// --------------------------------------------------------------
let geojsonarray = [];

new Autocomplete("local", {
onSearch: ({ currentValue }) => {

const api = mapWrapper.dataset.mapsGeojson;
return new Promise((resolve) => {
fetch(api)
.then((response) => response.json())
.then((data) => {
const result = data.features
.sort((a, b) =>
a.properties.title.localeCompare(b.properties.title)
)
.filter((element) => {
return element.properties.title.match(
new RegExp(currentValue, "gi")
);
});
resolve(result);
})
.catch((error) => {
console.error(error);
});
});
},

onResults: ({ matches, template }) => {
return matches === 0
? template
: matches
.map((el) => {
const icon =
el.properties.type === "rectangle"
? "polygon"
: el.properties.type.toLowerCase();
return `
<li>
<div class="title">${el.properties.title}</div>
</li>`;
})
.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();

layer.bindPopup(
"<span>Informações:<br>" + "oiee<br>" + "</span>"
);
},
});

map.fitBounds(geojsonlayer.getBounds(), { padding: [150, 150] });

if (geojsonarray.includes(object.properties.id)) return;
geojsonarray.push(object.properties.id);

geojsonlayer.addTo(map);
},

noResults: ({ currentValue, template }) =>
template(`<li>No results found: "${currentValue}"</li>`),

onReset: () => {
// remove all layers
map.eachLayer(function (layer) {
if (!!layer.toGeoJSON) {
map.removeLayer(layer);
}
});
geojsonarray = [];
},
});
17 changes: 17 additions & 0 deletions app/contrib/frontend/maps/templates/maps/plugins/map.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% load static sekizai_tags %}

{% addtoblock "css" %}
<link rel="stylesheet" href="{% static "maps/css/styles.css" %}">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/tomickigrzegorz/[email protected]/dist/css/autocomplete.min.css"/>
{% endaddtoblock %}

<div id="map" data-maps-geojson="{{ instance.geojson.url }}"></div>

{% addtoblock "js" %}
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script src="https://cdn.jsdelivr.net/gh/tomickigrzegorz/[email protected]/dist/js/autocomplete.min.js"></script>
<script src="{% static "maps/js/maps.js" %}"></script>
{% endaddtoblock %}
1 change: 1 addition & 0 deletions app/project/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"contrib.frontend",
"contrib.frontend.landpage",
"contrib.frontend.grid",
"contrib.frontend.maps",
"contrib.ga",
# Experimentação
"eleicao",
Expand Down
2 changes: 1 addition & 1 deletion app/project/settings/cms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
CMS_PLACEHOLDER_CONF = {
"content": {
"name": "Blocos",
"plugins": ["BlockPlugin", "BlockPressurePlugin", "EleicaoCandidateListPlugin", "EleicaoCarouselPlugin", "EleicaoVoterFormPlugin"],
"plugins": ["BlockPlugin", "BlockPressurePlugin", "EleicaoCandidateListPlugin", "EleicaoCarouselPlugin", "EleicaoVoterFormPlugin", "LeafletMapPlugin"],
},
"navigation": {
"name": "Navegação",
Expand Down

0 comments on commit 2b00137

Please sign in to comment.