Visualisation des autres lieux

Amélioration de l'apparence des marqueurs

Fix #378
This commit is contained in:
Jean-Marie Favreau 2025-04-13 16:28:48 +02:00
parent 859cc246c9
commit 45eb1809c2
14 changed files with 235 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="6.6588149mm"
height="6.6588154mm"
viewBox="0 0 6.6588149 6.6588154"
version="1.1"
id="svg1"
xml:space="preserve"
sodipodi:docname="circle.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
inkscape:export-filename="circle-icon.png"
inkscape:export-xdpi="68.660866"
inkscape:export-ydpi="68.660866"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="11.421182"
inkscape:cx="-0.43778306"
inkscape:cy="-5.6036232"
inkscape:window-width="1920"
inkscape:window-height="1022"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs1" /><g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-88.769953,-87.648153)"><circle
style="fill:#ffffff;stroke:#666666;stroke-width:0.175756;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="path1"
cx="92.099358"
cy="90.977562"
r="3.241529" /><circle
style="fill:#009091;fill-opacity:1;stroke:#666666;stroke-width:0.175756;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="path1-4"
cx="92.099358"
cy="90.977562"
r="2.086432" /><circle
style="fill:none;fill-opacity:0;stroke:#ffffff;stroke-width:0.162737;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.50965822"
id="path1-4-4"
cx="92.099358"
cy="90.977562"
r="1.9318954" /></g></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg1"
width="25"
height="41"
viewBox="0 0 25 41"
sodipodi:docname="marker-icon.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
inkscape:export-filename="marker-icon.png"
inkscape:export-xdpi="99.839996"
inkscape:export-ydpi="99.839996"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="14.02141"
inkscape:cx="10.733585"
inkscape:cy="22.893561"
inkscape:window-width="1473"
inkscape:window-height="1080"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g1" /><g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g1"><path
id="path1"
style="opacity:1;fill:#f9f9f9;stroke:#666666;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-width:0.7;stroke-dasharray:none"
d="m 24.357934,12.431119 c 0,6.61485 -11.977245,28.095453 -11.977245,28.095453 0,0 -11.97724566,-21.480603 -11.97724566,-28.095453 -2e-7,-6.6148502 5.36239546,-11.97724573 11.97724566,-11.97724537 6.61485,0 11.977245,5.36239547 11.977245,11.97724537 z"
sodipodi:nodetypes="cccsc" /><path
id="path1-4"
style="fill:#009091;stroke:#666666;stroke-width:0.664275;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
d="m 20.319077,13.217866 c 0,4.355167 -7.885727,16.978964 -7.885727,16.978964 0,0 -7.8857276,-12.623797 -7.8857278,-16.978964 -1e-7,-4.3551672 3.5305606,-7.8857277 7.8857278,-7.8857275 4.355167,2e-7 7.885727,3.5305606 7.885727,7.8857275 z"
sodipodi:nodetypes="scsss" /><path
id="path1-4-4"
style="fill-opacity:0;stroke:#ffffff;stroke-width:0.615069;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.50980395"
d="m 19.735002,13.217866 c 0,4.032591 -7.301652,15.959062 -7.301652,15.959062 0,0 -7.3016523,-11.926471 -7.3016523,-15.959062 0,-4.0325912 3.2690611,-7.3016522 7.3016523,-7.301652 4.032591,0 7.301652,3.269061 7.301652,7.301652 z"
sodipodi:nodetypes="scsss" /></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 618 B

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -397,6 +397,26 @@ var SequentialLoader = function() {
map.addLayer(layer); map.addLayer(layer);
if ((window.other_markers !== null) && (window.other_markers.length > 0)) {
var layerGroup = L.layerGroup();
window.other_markers.forEach(x =>
layerGroup.addLayer(x)
);
map.on('zoomend', function () {
var currentZoom = map.getZoom();
if (currentZoom > 12) {
if (!map.hasLayer(layerGroup)) {
map.addLayer(layerGroup);
}
} else {
if (map.hasLayer(layerGroup)) {
map.removeLayer(layerGroup);
}
}
});
}
return map; return map;
}, },
@ -414,7 +434,8 @@ var SequentialLoader = function() {
_getMarker: function(map, center) { _getMarker: function(map, center) {
var self = this, var self = this,
markerOptions = { markerOptions = {
draggable: true draggable: true,
icon: window.pinIcon
}; };
var marker = L.marker(center, markerOptions).addTo(map); var marker = L.marker(center, markerOptions).addTo(map);

View File

@ -1356,9 +1356,11 @@ img.preview {
.leaflet-container { .leaflet-container {
width: 100%; width: 100%;
border-radius: var(--border-radius); border-radius: var(--border-radius);
[role="button"].leaflet-marker-icon { [role="button"].leaflet-marker-icon,
[role="button"].leaflet-marker-icon:focus {
background: none; background: none;
border: none; border: none;
--box-shadow: none;
} }
.leaflet-control { .leaflet-control {

View File

@ -80,13 +80,53 @@
<div> <div>
<div id="map_location"></div> <div id="map_location"></div>
<script> <script>
L.Icon.Default.imagePath = "{% static "location_field/leaflet/images/" %}"; var circleIcon = L.icon({
iconUrl: "{% static "images/leaflet/circle-icon.png" %}",
iconAnchor: "{% static "images/leaflet/circle-shadow.png" %}",
iconSize: [18, 18],
iconAnchor: [9, 9],
popupAnchor: [1, -7],
shadowSize: [19, 19]
});
var pinIcon = L.icon({
iconUrl: "{% static "images/leaflet/marker-icon.png" %}",
iconAnchor: "{% static "images/leaflet/marker-shadow.png" %}",
iconSize: [26, 43],
iconAnchor: [13, 43],
popupAnchor: [0, -25],
shadowSize: [41, 41]
});
var map = L.map('map_location').setView([{{ object.location|tocoords }}], 13); var map = L.map('map_location').setView([{{ object.location|tocoords }}], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19, maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map); }).addTo(map);
var marker = L.marker([{{ object.location|tocoords }}]).addTo(map); var marker = L.marker([{{ object.location|tocoords }}],
{ icon: pinIcon }).bindPopup('{{ object.name }}<br />{% if object.address %}{{ object.address }}, {% endif %}{{ object.city }}').addTo(map);
var layerGroup = L.layerGroup();
{% if place_list %}
{% for place in place_list %}
layerGroup.addLayer(L.marker([{{ place.location|tocoords }}], { icon: circleIcon }).bindPopup('<a href="{{ place.get_absolute_url }}">{{ place.name }}</a><br />{% if place.address %}{{ place.address }}, {% endif %}{{ place.city }}'));
{% endfor %}
{% endif %}
map.on('zoomend', function () {
var currentZoom = map.getZoom();
if (currentZoom > 15) {
if (!map.hasLayer(layerGroup)) {
map.addLayer(layerGroup);
}
} else {
if (map.hasLayer(layerGroup)) {
map.removeLayer(layerGroup);
}
}
});
</script> </script>
<p> <p>
Voir aussi <a href="{% url 'view_places' %}">les autres lieux</a> Voir aussi <a href="{% url 'view_places' %}">les autres lieux</a>

View File

@ -1,5 +1,7 @@
{% extends "agenda_culturel/page.html" %} {% extends "agenda_culturel/page.html" %}
{% load static %} {% load static %}
{% load cache %}
{% load utils_extra %}
{% block title %} {% block title %}
{% block og_title %} {% block og_title %}
{% if form.instance.pk %} {% if form.instance.pk %}
@ -15,6 +17,39 @@
{% css_categories %} {% css_categories %}
<script src="/static/admin/js/vendor/jquery/jquery.js"></script> <script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script> <script src="/static/admin/js/jquery.init.js"></script>
<script src="{% static 'location_field/leaflet/leaflet.js' %}"></script>
<script>
window.pinIcon = L.icon({
iconUrl: "{% static "images/leaflet/marker-icon.png" %}",
iconAnchor: "{% static "images/leaflet/marker-shadow.png" %}",
iconSize: [26, 43],
iconAnchor: [13, 43],
popupAnchor: [0, -25],
shadowSize: [41, 41]
});
var circleIcon = L.icon({
iconUrl: "{% static "images/leaflet/circle-icon.png" %}",
iconAnchor: "{% static "images/leaflet/circle-shadow.png" %}",
iconSize: [18, 18],
iconAnchor: [9, 9],
popupAnchor: [1, -7],
shadowSize: [19, 19]
});
window.other_markers = [];
{% with cache_timeout=user.is_authenticated|yesno:"300,6000" %}
{% cache cache_timeout place_lists_js user.is_authenticated %}
{% if place_list %}
{% for place in place_list %}
window.other_markers.push(L.marker([{{ place.location|tocoords }}], {'icon': circleIcon}).bindPopup('<a href="{{ place.get_absolute_url }}">{{ place.name }}</a><br />{% if place.address %}{{ place.address }}, {% endif %}{{ place.city }}'));
{% endfor %}
{% endif %}
{% endcache %}
{% endwith %}
</script>
<link href="{% static 'css/django_better_admin_arrayfield.min.css' %}" <link href="{% static 'css/django_better_admin_arrayfield.min.css' %}"
type="text/css" type="text/css"
media="all" media="all"

View File

@ -9,6 +9,7 @@
{% block entete_header %} {% block entete_header %}
{% css_categories %} {% css_categories %}
<script src="/static/admin/js/vendor/jquery/jquery.js"></script> <script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<script src="{% static 'location_field/leaflet/leaflet.js' %}"></script> <script src="{% static 'location_field/leaflet/leaflet.js' %}"></script>
<script src="{% static 'js/leaflet.markercluster.js' %}"></script> <script src="{% static 'js/leaflet.markercluster.js' %}"></script>
<link href="{% static 'location_field/leaflet/leaflet.css' %}" <link href="{% static 'location_field/leaflet/leaflet.css' %}"
@ -72,9 +73,18 @@
</div> </div>
</article> </article>
<script> <script>
L.Icon.Default.imagePath = "{% static "images/" %}";
var pinIcon = L.icon({
iconUrl: "{% static "images/leaflet/marker-icon.png" %}",
iconAnchor: "{% static "images/leaflet/marker-shadow.png" %}",
iconSize: [26, 43],
iconAnchor: [13, 43],
popupAnchor: [0, -25],
shadowSize: [41, 41]
});
var map = L.map('map_location'); var map = L.map('map_location');
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19, maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map); }).addTo(map);
@ -83,10 +93,10 @@
window.mMapping = {}; window.mMapping = {};
{% if object_list %} {% if object_list %}
{% for place in object_list %} {% for place in object_list %}
markerArray.push(L.marker([{{ place.location|tocoords }}]).bindPopup('<a href="{{ place.get_absolute_url }}">{{ place.name }}</a><br />{% if place.address %}{{ place.address }}, {% endif %}{{ place.city }}')) markerArray.push(L.marker([{{ place.location|tocoords }}], {'icon': pinIcon}).bindPopup('<a href="{{ place.get_absolute_url }}">{{ place.name }}</a><br />{% if place.address %}{{ place.address }}, {% endif %}{{ place.city }}'))
markers.addLayer(markerArray[markerArray.length - 1]); markers.addLayer(markerArray[markerArray.length - 1]);
window.mMapping[{{ place.id }}] = markerArray[markerArray.length - 1]; window.mMapping[{{ place.id }}] = markerArray[markerArray.length - 1];
window.jQuery('a#open-map-{{ place.id }}').click(function(){ window.django.jQuery('a#open-map-{{ place.id }}').click(function(){
window.mMapping[{{ place.id }}].openPopup(); window.mMapping[{{ place.id }}].openPopup();
map.panTo(window.mMapping[{{ place.id }}].getLatLng()); map.panTo(window.mMapping[{{ place.id }}].getLatLng());
}); });

View File

@ -42,6 +42,7 @@ from django.db.models.aggregates import StdDev
from django.db.models import Avg, Max, Min from django.db.models import Avg, Max, Min
from django.db.models import Aggregate, FloatField from django.db.models import Aggregate, FloatField
from django.db.models.functions import ExtractDay from django.db.models.functions import ExtractDay
from django.contrib.gis.measure import D
from .calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek from .calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
from .celery import app as celery_app from .celery import app as celery_app
@ -2495,6 +2496,10 @@ class PlaceDetailView(ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["object"] = self.place context["object"] = self.place
context["place_list"] = Place.objects.filter(
~Q(pk=self.place.pk)
& Q(location__distance_lte=(self.place.location, D(m=4000)))
).only("location", "name", "pk")
return context return context
@ -2561,6 +2566,11 @@ class PlaceCreateView(
success_message = _("The place has been successfully created.") success_message = _("The place has been successfully created.")
form_class = PlaceForm form_class = PlaceForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["place_list"] = Place.objects.all().only("location", "name", "pk")
return context
class PlaceDeleteView(PermissionRequiredMixin, DeleteView): class PlaceDeleteView(PermissionRequiredMixin, DeleteView):
model = Place model = Place