Commit 275598af authored by fred.perso's avatar fred.perso

improve place search tools

parent 369b6a48
# -*- coding: utf-8 -*-
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from djgeojson.views import GeoJSONLayerView
from djgeojson.views import GeoJSONLayerView, TiledGeoJSONLayerView
from sights.models import Territory, Municipality
from sights.models import Territory, Municipality, Place
from .views import placeasgeojson, PlaceAutocomplete, AllUserAutocomplete, ActiveUserAutocomplete, \
MunicipalityAutocomplete, TerritoryAutocomplete, TaxaAutocomplete
urlpatterns = [
# url(r'^place.geojson$',
# login_required(GeoJSONLayerView.as_view(model=Place, properties=('name', 'pk', 'municipality'), simplify=0.5)),
# GeoJSONPlaceData.as_view(),
# name='geodata_place'),
url(r'^municipality.geojson$', login_required(
GeoJSONLayerView.as_view(model=Municipality, precision=3, simplify=0.5, properties=('name', 'code'))),
......@@ -18,6 +18,8 @@ urlpatterns = [
GeoJSONLayerView.as_view(model=Territory, precision=3, simplify=0.5, properties=('name', 'code'))),
name='geodata_territory'),
url(r'^place.geojson$', placeasgeojson, name='geodata_place'),
# url(r'^place/(?P<z>\d+)/(?P<x>\d+)/(?P<y>\d+).geojson$',
# TiledGeoJSONLayerView.as_view(model=Place), name='placetiled'),
url(
r'^active-user-autocomplete/$',
ActiveUserAutocomplete.as_view(),
......
......@@ -107,15 +107,41 @@ class GeoJSONData(LoginRequiredMixin, GeoJSONLayerView):
pass
#
# class GeoJSONPlaceData(LoginRequiredMixin, GeoJSONLayerView):
# model = Place
# properties = ('pk', 'name', 'type')
# simplify = 0.5
#
# def get_queryset(self):
# loggeduser = self.request.user
# user = get_user_model().objects.get(id=loggeduser.id)
# if user.access_all_data == True:
# print('Chargement de la carte pour l\'utilisateur avec accès total')
# new_context = Place.objects.all()
# elif user.is_resp:
# print('Chargement de la carte pour le Coordinateur')
# print(user.id)
# print(loggeduser.id)
# respterritory = user.resp_territory.all()
# new_context = Place.objects.filter(Q(territory__in=respterritory) | (
# (~Q(territory__in=respterritory) & (
# Q(is_hidden=False) | (
# Q(is_hidden=True) & (Q(created_by=loggeduser) | Q(authorized_user=loggeduser)))))))
# else:
# print('Chargement de la carte pour l\'obs lambda')
# new_context = Place.objects.filter(
# Q(is_hidden=False) | (Q(is_hidden=True) & Q(authorized_user__username__contains=loggeduser.username)))
# return new_context
class TiledGeoJSONData(LoginRequiredMixin, TiledGeoJSONLayerView):
pass
# class GeoJSONTiledPlaceData(TiledGeoJSONLayerView):
# model = Place
# properties = ('pk', 'name', 'type')
@login_required
def placeasgeojson(request):
......
......@@ -80,17 +80,41 @@ header {
margin: 0px;
text-align: center;
color: #fff;
height: 200px;
height: 170px;
box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
}
.page-header h1 {
color: #fff;
size:0.8rem;
}
.page-header img {
margin-top: 20px;
height: 100px;
height: 80px;
}
/* xs < 768 */
@media screen and (max-width: 1280px) {
.page-header {
/*background-color: #1a1a1a;*/
margin: 0px;
text-align: center;
color: #fff;
height: 100px;
box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
}
.page-header h1 {
color: #fff;
font-size: 25px;
margin-top: 5px;
}
.page-header img {
margin-top: 10px;
height: 50px;
}
}
/* Formulaires */
......@@ -401,7 +425,7 @@ BS Full screen Modal
.sidebar-nav > .sidebar-brand {
/*height: 150px;*/
font-size: 30px;
line-height: 179px;
line-height: 150px;
background-color: #1a1a1a;
color: #eeeeee;
}
......@@ -437,6 +461,16 @@ BS Full screen Modal
padding: 5px 30px;
}
@media screen and (max-width: 1280px) {
.sidebar-nav > .sidebar-brand {
/*height: 150px;*/
font-size: 25px;
line-height: 80px;
background-color: #1a1a1a;
color: #eeeeee;
}
}
/*-------------------------------*/
/* Hamburger-Cross */
/*-------------------------------*/
......
......@@ -10,14 +10,10 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import json
import os
from os.path import abspath, dirname, join
from pathlib import Path
from .configuration import config
from .configuration import config
from django.core.exceptions import ImproperlyConfigured
def root(*dirs):
base_dir = join(dirname(__file__), '../..')
......@@ -34,9 +30,8 @@ BASE_DIR = root()
# setting_file = 'settings/settings.json'
# with open(root(setting_file)) as f:
# params = json.loads(f.read())
# params = json.loads(f.read())
#
# def get_setting(setting, params=params):
......@@ -74,7 +69,7 @@ MAIN_APPS = [
'ckeditor',
'leaflet',
'crispy_forms',
# 'crispy_forms_foundation',
# 'crispy_forms_foundation',
'djgeojson',
'django_tables2',
'django_filters',
......@@ -260,10 +255,10 @@ mapboxAPIkey = config.MAPBOX_API_KEY
# MapLayers
TILES = [('OpenStreetMap Mapnik', 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'),
('OpenTopoMap', 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>'),
]
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'),
('OpenTopoMap', 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>'),
]
MAPBOX_TILES = [
# Fond aérien, nécessite un compte MapBox pour obtenir la clé.
......@@ -286,16 +281,17 @@ IGN_TILES = [ # Fond SCAN IGN, nécessite un compte IGN pour obtenir la clé.
]
if ignAPIkey != 'yourapikey':
TILES = TILES+IGN_TILES
TILES = TILES + IGN_TILES
if mapboxAPIkey != 'yourapikey':
TILES = TILES+MAPBOX_TILES
TILES = TILES + MAPBOX_TILES
LEAFLET_CONFIG = {
'DEFAULT_CENTER': (config.MAP_Y, config.MAP_X),
'DEFAULT_ZOOM': config.MAP_DEFAULT_ZOOM,
'MIN_ZOOM': 3,
'MAX_ZOOM': 19,
'MAX_ZOOM': 18
,
'MINIMAP': True,
'TILES': TILES,
'SCALE': 'both',
......@@ -325,6 +321,7 @@ LEAFLET_CONFIG = {
}
}
# CkEditor Settings
AUTHENTICATION_BACKENDS = (
......
This diff is collapsed.
......@@ -73,11 +73,17 @@ class PlaceTable(tables.Table):
</div>
{% endif %}
'''
MAPLOCATION ='''
{% if record.geom %}
<a href="#" class="btn btn-primary btn-xs map-navigation" data-zoom="15" data-position="{{ record.geom.y}}-{{ record.geom.x}}"><i class="fa fa-map-marker"></i></a>
{% endif %}
'''
# id = tables.Column(accessor='id_place', verbose_name='id')
nbsession = tables.Column(accessor='session_set.all.count',
verbose_name="Sessions", orderable=False)
name = tables.LinkColumn('sights:place_detail', args=[
A('id_place')], accessor='name')
maplocation = tables.TemplateColumn(MAPLOCATION, verbose_name="Carte", orderable=False)
actions = tables.TemplateColumn(
ACTIONS, verbose_name="Actions", orderable=False)
type = tables.Column(accessor='type.descr', verbose_name="Type de gîte")
......@@ -88,7 +94,7 @@ class PlaceTable(tables.Table):
model = Place
template = 'table_bootstrap.html'
attrs = {'class': 'table table-striped table-condensed'}
fields = ('actions', 'name', 'is_hidden', 'municipality', 'type', 'altitude', 'created_by',
fields = ('actions','maplocation','name', 'is_hidden', 'municipality', 'type', 'altitude', 'created_by',
'nbsession', 'comment')
......
......@@ -31,6 +31,8 @@ urlpatterns = [
# Place views
url(r'^place/map$', login_required(TemplateView.as_view(
template_name='sights/place_map.html')), name='place_map'),
url(r'^place/tiledmap$', login_required(TemplateView.as_view(
template_name='sights/place_map_tiled.html')), name='place_tiled_map'),
url(r'^place/tilemap$', login_required(TemplateView.as_view(
template_name='sights/place_tilemap.html')), name='place_tilemap', ),
url(r'^place/add$', PlaceCreate.as_view(), name='place_create'),
......
......@@ -205,7 +205,10 @@ class PlaceDelete(PlaceEditAuthMixin, DeleteView):
class PlaceList(LoginRequiredMixin, FilterView, ExportMixin, SingleTableView):
table_class = PlaceTable
model = Place
template_name = 'table.html'
template_name = 'sights/place_search.html'
table_pagination = {
'per_page': 15
}
filterset_class = PlaceFilter
......@@ -234,6 +237,7 @@ class PlaceList(LoginRequiredMixin, FilterView, ExportMixin, SingleTableView):
context = super(PlaceList, self).get_context_data(**kwargs)
context['icon'] = 'fa fa-fw fa-map'
context['title'] = _('Rechercher une localité')
context['createplacebtn'] = True
context['js'] = """
"""
return context
......@@ -242,7 +246,11 @@ class PlaceList(LoginRequiredMixin, FilterView, ExportMixin, SingleTableView):
class PlaceMyList(LoginRequiredMixin, FilterView, ExportMixin, SingleTableView):
table_class = PlaceTable
model = Place
template_name = 'table.html'
template_name = 'sights/place_search.html'
table_pagination = {
'per_page': 15
}
filterset_class = PlaceFilter
......
{% extends 'base_leaflet.html' %}
{% load leaflet_tags %}
{% leaflet_js %}
{% leaflet_css %}
{% load geojson_tags %}
{% block content %}
<h1><i class="fa fa-fw fa-map"></i> Carte des localités</h1>
<div id="progress">
<div id="progress-bar"></div>
</div>
{% leaflet_map "main" %}
<br/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-tilelayer-geojson/1.0.4/TileLayer.GeoJSON.min.js"></script>
<script type="text/javascript">
var dataurl = '{% url "api:geodata_place" %}';
window.addEventListener("map:init", function (event) {
var style = {
"clickable": true,
"color": "#00D",
"fillColor": "#00D",
"weight": 1.0,
"opacity": 0.3,
"fillOpacity": 0.2
};
var hoverStyle = {
"fillOpacity": 0.5
};
var geojsonURL = 'http://127.0.0.1:8000/place/api/{z}/{x}/{y}.geojson';
var geojsonTileLayer = new L.TileLayer.GeoJSON(geojsonURL, {
credentials: true,
clipTiles: true,
unique: function (feature) {
return feature.id;
}
}, {
style: style,
onEachFeature: function (feature, layer) {
if (feature.properties) {
var popupString = '<div class="popup">';
for (var k in feature.properties) {
var v = feature.properties[k];
popupString += k + ': ' + v + '<br />';
}
popupString += '</div>';
layer.bindPopup(popupString);
}
if (!(layer instanceof L.Point)) {
layer.on('mouseover', function () {
layer.setStyle(hoverStyle);
});
layer.on('mouseout', function () {
layer.setStyle(style);
});
}
}
}
).addTo(map);
{#map.addLayer(geojsonTileLayer);#}
});
</script>
{% endblock %}
\ No newline at end of file
{% extends 'base_fullwidth_leaflet.html' %}
{% load leaflet_tags %}
{% leaflet_js %}
{% leaflet_css %}
{% load geojson_tags %}
{% load i18n staticfiles crispy_forms_tags django_tables2 %}
{% block content %}
<style>
.leaflet-container-default {
min-height: 800px;
}
</style>
<h1>{% if createplacebtn %}<a href="{% url 'sights:place_create' %}" class="btn btn-primary pull-right"><i
class="fa fa-fw fa-map-marker"></i>{% trans 'Créer une localité' %}</a>{% endif %}<i
class="{{ icon | safe }}"></i> {{ title | safe }}</h1>
{% comment %}Tableau de recherche avec filtrage {% endcomment %}
<div class="col-sm-12 col-md-6 col-lg-7">
{% if filter %}
<div class="panel panel-default">
<div class="panel-body">
<form action="" method="get">
{% crispy filter.form %}
</form>
</div>
</div>
{% endif %}
{% if count %}
<div class="panel panel-default">
<div class="panel-body">
{% if export %}
<div class="btn-group btn-group-xs pull-right">
<button type="button" class="btn btn-primary btn-xs dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
{% trans 'Exporter' %} <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="{% querystring '_export'='csv' %}"> download as csv</a></li>
<li><a href="{% querystring '_export'='ods' %}"> download as ods</a></li>
<li><a href="{% querystring '_export'='xls' %}"> download as xlsx</a></li>
<li><a href="{% querystring '_export'='xlsx' %}"> download as xls</a></li>
</ul>
</div>
{% endif %}
{{ counttitle }} : <b>{{ count }}</b>
</div>
</div>
{% endif %}
<div class="panel panel-default">
{% render_table table %}
</div>
</div>
<script type="text/javascript">
{{ js | safe }}
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
$(function () {
$('[data-toggle="popover"]').popover()
})
</script>
{% if filter %}
<link rel="stylesheet" href="{% static 'css/select2-bootstrap.min.css' %}">
<script type="text/javascript">
{{ js | safe }}
$.fn.select2.defaults.set("theme", "bootstrap");
</script>
{% endif %}
{# Carte de recherche#}
<div class="col-sm-12 col-md-6 col-lg-5">
{% leaflet_map "main" %}
</div>
<script type="text/javascript">
var dataurl = '{% url "api:geodata_place" %}';
var circlemarker = null;
window.addEventListener("map:init", function (event) {
var markers = L.markerClusterGroup({chunkedLoading: true, spiderfyDistanceMultiplier: 3});
var style_data = {
radius: 8,
fillColor: "#ff4c41",
color: "#ddd",
weight: 2,
opacity: 1,
fillOpacity: 0.8
};
var map = event.detail.map;
var handler = function (e) {
var position = e.target.getAttribute('data-position');
console.log('position : ' + position)
var zoom = e.target.getAttribute('data-zoom');
console.log('zoom : ' + zoom)
if (position && zoom) {
console.log('if spoition && zoom')
var location = position.replace(/,/g, '.').split('-');
console.log('location : ' + location)
if (circlemarker !== null) {
map.removeLayer(circlemarker);
}
// var marker = L.marker(location).addTo(map);
circlemarker = new L.circleMarker(location,
{
radius: 20,
color: 'red',
fillColor: 'transparent',
})
.addTo(map)
// .bindPopup('<a class="button" href="popup link">lien</a>')
// .openPopup()
;
console.log('circlemarker')
map.setView(location, 15, {
animation: true,
});
console.log('zoom')
}
}
var elements = document.getElementsByClassName('map-navigation');
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = handler;
}
// Download GeoJSON data with Ajax
fetch(dataurl, {
credentials: "include"
})
.then(function (resp) {
return resp.json();
})
.then(function (data) {
markers.addLayer(L.geoJson(data, {
onEachFeature: function onEachFeature(feature, layer) {
var props = feature.properties;
var content = `<a class="btn btn-primary btn-sm btn-block" align="center" style="color:white;" href="/place/${props.pk}/detail" target="_blank" style="font-color:white"><strong>${props.name}</strong></a>`;
layer.bindPopup(content);
}
,
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, style_data);
}
})).addTo(map);
});
{#map.fitBounds(markers.getBounds());#}
map.addControl(new L.Control.Fullscreen());
});
</script>
{% endblock %}
\ No newline at end of file
{% load django_tables2 %}
{% load geojson_tags %}
{% load i18n %}
<div class="table-responsive">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment