source: spip-zone/_plugins_/gis/trunk/modeles/carte_gis.html @ 70457

Last change on this file since 70457 was 70457, checked in by cedric@…, 7 years ago

Refactoring du js du modele carte_gis :
Plutot que generer plein de JS specifique a la carte, on rend tout le js generique et on lui passe simplement un tableau de configuration contenant toutes les specificites de la carte a afficher
par compatibilite l'objet map construit reste attache a la globale map#ENV{id} mais il est aussi attache a l'objet du DOM qui porte la carte.
On peut donc toujours le retrouver par $('#maptruc').get(0).map ce qui est plus generique
Les methodes AddJSON et removeAllMarkers compatibilite GIS 3 y sont attaches
Les methodes setGeoJsonFeatureIcon, setGeoJsonFeaturePopup et parseGeoJson y sont egalement attachees (on peut donc avoir une map avec cluster et une map sans cluster dans la meme page sans risque de conflit de fonction)

La lib leafclusterer.js est inclue par gis.js a la demande (via argument de #PRODUIRE_FOND) ce qui evite de charger les libs en 2 hits quand on utilise les clusters

File size: 14.6 KB
Line 
1[(#REM)
2
3Modele carte_gis
4----------------
5
6Parametres possibles :
7
8- id_map|id_carte_gis = 1          id de la carte
9- lat|latit|latitude = 48.3        latitude du centre de la carte
10- lon|lonxit|longitude = -4.7      longitude du centre de la carte
11- zoom = 5                         zoom de la carte
12- maxZoom = 13                     zoom maximum autorisé
13
14- sw_lat = lat - 10°               latitude du sud-ouest de la bounding box
15- sw_lon = lon - 10°               longitude du sud-ouest de la bounding box
16- ne_lat = lat + 10°               latitude du nord-est de la bounding box
17- ne_lon = lon + 10°               longitude du nord-est de la bounding box
18
19- width|largeur = 100%             largeur de la carte, 100% par defaut
20- height|hauteur = 400px           hauteur de la carte, 400px par defaut
21- style = non                      ne pas styler la carte
22
23- fullscreen = oui                     afficher un bouton pour passer la carte en plein écran
24- zoom_molette|zoom_wheel = non        désactiver le zoom avec la molette de la souris, actif par defaut
25- control_type|controle_type = non     ne pas afficher les controles de changement de type
26- no_control|aucun_controle = oui      ne pas afficher les controles de la carte
27- scale = oui                          afficher l'échelle de la carte
28- overview = oui                       afficher une mini carte de situation
29
30- autocenterandzoom|centrer_auto = oui        centrer et zoomer la carte automatiquement pour afficher tous les marqueurs
31- localize_visitor|localiser_visiteur = oui   centrer la carte sur la position du visiteur (API geolocation HTML5)
32- id_a_ouvrir                                 id_gis de l'infobulle à afficher au chargement(marqueur uniquement)
33
34- objets = gis                     type d'objets à afficher (fichier json/gis_xx qui génère la source de donnees)
35- limit|limite = 500               nombre max de marqueurs à afficher, 500 par defaut
36- kml = 12                         kml à superposer à la carte (id_document ou url ou liste d'url)
37- gpx = 12                         gpx à superposer à la carte (id_document ou url ou liste d'url)
38- centrer_fichier = non            permet de ne pas centrer la carte automatiquement sur les fichiers kml/gpx surperposés
39- point = non                      si elle vaut "non" cette option n'affichera pas de points du tout (utile pour n'afficher qu'un kml par exemple)
40
41- media = non                      permet de passer le critère 'media' (pour les documents)
42- mots = #LISTE{1,4,7}             plugin critere {mots} http://contrib.spip.net/Critere-mots
43- path_styles=#ARRAY{color,#fff}   options de style des éléments de la couche GeoJSON (voir http://leafletjs.com/reference.html#path-options)
44
45Uniquement si objets = point_libre :
46- icone = chemin/vers/image        image utilisée pour le marker
47- titre                            titre du point
48- description                      description du point
49
50Clustering (regroupement de points proches) :
51- cluster = oui                    Active le clustering
52- clusterMaxZoom = 11              Regroupe les points jusque à ce zoom, mais pas au delà
53- clusterStyles = #ARRAY{}         Styles appliqués aux clusters
54
55]
56
57[(#SET{width,#ENV{width,#ENV{largeur,100%}}})]
58[(#SET{height,#ENV{height,#ENV{hauteur,400px}}})]
59[(#SET{id,#ENV{id_carte_gis,#ENV{id_map,#ENV{id,1}}}})]
60[(#REM) -- compat gis v1 -- ]
61[(#SET{lat,#ENV{lat,#ENV{latit,#ENV{latitude,#CONFIG{gis/lat,0}}}}})]
62[(#SET{lon,#ENV{lon,#ENV{lonxit,#ENV{longitude,#CONFIG{gis/lon,0}}}}})]
63[(#REM) On utilise la bounding box seulement si le centre n'a pas été donné et si les quatre valeurs de la bounding box sont renseignées
64    les valeurs par defaut sont "centre +/- 10°", ce qui est naze, mais c'est un cas normalement impossible
65]
66[(#ENV{lat}|ou{#ENV{lon}}|non|et{#ENV{sw_lat}}|et{#ENV{sw_lon}}|et{#ENV{ne_lat}}|et{#ENV{ne_lon}})
67        #SET{utiliser_bb, oui}
68        #SET{sw_lat,#ENV{sw_lat,#GET{lat}|moins{10}}}
69        #SET{sw_lon,#ENV{sw_lon,#GET{lon}|moins{10}}}
70        #SET{ne_lat,#ENV{ne_lat,#GET{lat}|plus{10}}}
71        #SET{ne_lon,#ENV{ne_lon,#GET{lon}|plus{10}}}
72]
73
74<div id="map[(#GET{id})]" class="carte_gis p"[(#ENV{style}|!={'non'}|?{' '})style="[width:(#GET{width});][ height:(#GET{height});]"]></div>
75
76<script type="text/javascript">/*<!\[CDATA\[*/
77var map[(#GET{id})];
78var map_cfg = {
79"mapid":"map[(#GET{id})]",
80"scrollWheelZoom": [(#ENV{zoom_molette,#ENV{zoom_wheel}}|=={non}|?{false,true})],
81"zoomControl": [(#ENV{no_control,#ENV{aucun_controle}}|!={oui}|?{true,false})][,
82"maxZoom": (#ENV{maxZoom})],
83"utiliser_bb":[(#GET{utiliser_bb}|?{true,false})],
84"lat":[(#GET{lat})][,
85"sw_lat":(#GET{sw_lat})][,
86"ne_lat":(#GET{ne_lat})],
87"lon":[(#GET{lon})][,
88"sw_lon":(#GET{sw_lon})][,
89"ne_lon":(#GET{ne_lon})],
90"zoom":[(#ENV{zoom,#CONFIG{gis/zoom,0}})],
91"default_layer":"[(#REM|gis_layer_defaut)]",
92"layers":#EVAL{json_encode($GLOBALS['gis_layers'])},
93"affiche_layers":[(#CONFIG{gis/layers,#ARRAY}|json_encode)],
94"control_type":[(#ENV{control_type,#ENV{controle_type}}|=={non}|?{false,true})],
95"no_control":[(#ENV{no_control,#ENV{aucun_controle}}|=={oui}|?{true,false})],
96"scale":[(#ENV{scale}|=={oui}|?{true,false})],
97"fullscreen":[(#ENV{fullscreen}|=={oui}|?{true,false})],
98"cluster":[(#ENV{cluster}|=={oui}|?{true,false})],
99"clusterMaxZoom":[(#ENV{clusterMaxZoom, #ENV{maxZoom}|?{#ENV{maxZoom}|moins{2},0}})],
100"path_styles":[(#ENV*{path_styles}|json_encode)],
101"autocenterandzoom":[(#ENV{autocenterandzoom,#ENV{centrer_auto}}|?{true,false})],
102"open_id":"[(#ENV{id_a_ouvrir,''})]",
103"clusterStyles":[(#ENV*{clusterStyles,#ARRAY}|json_encode)],
104"affiche_points":[(#ENV{point,''}|=={non}|?{false,true})],
105"json_points":{
106        "url":"[(#URL_PAGE{gis_json}|url_absolue)]",
107        "objets":"(#ENV{objets,#ENV{class}}|trim)",
108        "limit":[(#ENV{limit,#ENV{limite,500}}|trim)],
109        "env":[(#ENV{args,#ENV}|gis_modele_url_json_env|json_encode)][,
110        "titre" : (#ENV{titre}|json_encode)][,
111        "description" : (#ENV{description}|json_encode)][,
112        "icone" : (#ENV{icone}|json_encode)]
113        },
114"localize_visitor":[(#ENV{localize_visitor,#ENV{localiser_visiteur}}|?{true,false})],
115"kml":[(#ENV{kml,''}|?{[(#ENV{kml}|is_array|?{#ENV{kml},#LISTE{#ENV{kml}}}|gis_kml_to_urls|json_encode)],false})],
116"gpx":[(#ENV{gpx,''}|?{[(#ENV{gpx}|is_array|?{#ENV{gpx},#LISTE{#ENV{gpx}}}|gis_kml_to_urls|json_encode)],false})]
117};
118if (typeof(callback_map[(#GET{id})]) === "function") {
119        map_cfg['callback']=callback_map[(#GET{id})];
120}
121
122(function($){
123
124        var gis_init_map = function(mapcfg) {
125                var map_container = mapcfg["mapid"];
126
127                // Création de la carte Leafleat
128                var map = new L.Map(map_container,{
129                        scrollWheelZoom: mapcfg["scrollWheelZoom"],
130                        zoomControl: mapcfg["zoomControl"],
131                        maxZoom: mapcfg["maxZoom"]
132                });
133                // affecter sur la globale homonyme a mapid/map_container (compat ascendante)
134                eval(map_container+"=map;");
135                // affecter sur l'objet du DOM
136                $("#"+map_container).get(0).map=map;
137
138                // Appeler l'éventuelle fonction de callback et trigger "load"
139                map.on('load',function(e){
140                        if (mapcfg["callback"] && typeof(mapcfg["callback"]) === "function") {
141                                var callback = mapcfg["callback"];
142                                callback(e.target);
143                        }
144                        $("#"+map_container).trigger('load',e.target);
145                });
146
147                // Déterminer la position initiale de la carte
148                if (!mapcfg['utiliser_bb']){
149                        map.setView(new L.LatLng(mapcfg['lat'], mapcfg['lon']), mapcfg['zoom']);
150                }
151                else {
152                        map.fitBounds(
153                                new L.LatLngBounds(
154                                        new L.LatLng(mapcfg['sw_lat'], mapcfg['sw_lon']),
155                                        new L.LatLng(mapcfg['ne_lat'], mapcfg['ne_lon'])
156                                )
157                        );
158                }
159
160                var get_layer=function(name){
161                        var layer;
162                        if (typeof mapcfg['layers'][name]!=="undefined")
163                        eval("layer=new "+ mapcfg['layers'][name]["layer"]+";");
164                        return layer;
165                }
166
167                // Fond de carte par défaut (layer)
168                var default_layer = get_layer(mapcfg['default_layer']);
169                map.addLayer(default_layer);
170
171                if (mapcfg['control_type'] && !mapcfg['no_control'] && mapcfg['affiche_layers'].length>1){
172                        var layers_control = new L.Control.Layers();
173                        layers_control.addBaseLayer(default_layer,mapcfg['layers'][mapcfg['default_layer']]["nom"]);
174                        for(var l in mapcfg['affiche_layers']){
175                                if (mapcfg['affiche_layers'][l]!==mapcfg['default_layer']){
176                                        var layer = get_layer(mapcfg['affiche_layers'][l]);
177                                        if (typeof layer!=="undefined")
178                                                layers_control.addBaseLayer(layer,mapcfg['layers'][mapcfg['affiche_layers'][l]]["nom"]);
179                                }
180                        }
181                        map.addControl(layers_control);
182                        // ajouter l'objet du controle de layers à la carte pour permettre d'y accéder depuis le callback
183                        map.layersControl = layers_control;
184                        // classe noajax sur le layer_control pour éviter l'ajout de hidden par SPIP
185                        $(layers_control._form).addClass('noajax');
186                }
187
188                map.setView(new L.LatLng(mapcfg['lat'],mapcfg['lon']),mapcfg['zoom']);
189                map.attributionControl.setPrefix('');
190
191                // Ajout des contrôles de la carte
192                if (!mapcfg['no_control']){
193                        if (mapcfg['scale'])
194                                map.addControl(new L.Control.Scale());
195                        if (mapcfg['fullscreen'])
196                                map.addControl(new L.Control.FullScreen());
197                        if (mapcfg['overview']){
198                                var minimap_layer = get_layer(mapcfg['default_layer']);
199                                var miniMap = new L.Control.MiniMap(minimap_layer,{width: 100,height: 100}).addTo(map);
200                        }
201                }
202
203                // API setGeoJsonFeatureIcon : Pour Ajouter l'icone d'un point (feature = item d'un GeoJson)
204                map.setGeoJsonFeatureIcon = function (feature, layer) {
205                        // Déclarer l'icone du points, si défini
206                        if (feature.properties && feature.properties.icon){
207                                layer.setIcon(new L.Icon({
208                                        iconUrl: feature.properties.icon,
209                                        iconSize: new L.Point( feature.properties.icon_size[0], feature.properties.icon_size[1] ),
210                                        iconAnchor: new L.Point( feature.properties.icon_anchor[0], feature.properties.icon_anchor[1] ),
211                                        popupAnchor: new L.Point( feature.properties.popup_anchor[0], feature.properties.popup_anchor[1] )
212                                }));
213                        }
214                }
215
216                // API setGeoJsonFeaturePopup : Pour Ajouter le texte de popup d'un point (feature = item d'un GeoJson)
217                map.setGeoJsonFeaturePopup = function (feature, layer) {
218                        // Déclarer le contenu de la popup s'il y en a
219                        if (feature.properties && (feature.properties.title || feature.properties.description)){
220                                var popupContent = '';
221                                if (feature.properties.title)
222                                        popupContent = '<strong class="title">' + feature.properties.title + '</strong>';
223                                if (feature.properties.description)
224                                        popupContent = popupContent + feature.properties.description;
225                                layer.bindPopup(popupContent);
226                        }
227                }
228
229                /*
230                        Il y a pour le moment 2 façons d'analyser le GeoJson calculé
231                        en fonction de si on veut faire du clustering (regrouper les points proches)
232                        ou non. Il y a certainement moyen de regrouper en un seul élément
233                        la plupart du code, en se passant du js L.geoJson même hors clustering.
234                        À réfléchir.
235                */
236                // API parseGeoJson
237                if (!mapcfg['cluster']){
238                        // Analyse des points et déclaration (sans regroupement des points en cluster)
239                        map.parseGeoJson = function(data) {
240                                var geojson = new L.geoJson('', {
241                                        style: mapcfg['path_styles'],
242                                        onEachFeature: function (feature, layer) {
243                                                // Déclarer l'icone du point
244                                                map.setGeoJsonFeatureIcon(feature, layer);
245                                                // Déclarer le contenu de la popup s'il y en a
246                                                map.setGeoJsonFeaturePopup(feature, layer);
247                                        }
248                                }).addTo(map);
249                                geojson.addData(data);
250                                if (mapcfg['autocenterandzoom'])
251                                        map.fitBounds(geojson.getBounds());
252                                if (mapcfg['open_id'].length)
253                                        gis_focus_marker(mapcfg['open_id'],map_container);
254                        }
255                }
256                else {
257                        // Analyse des points et déclaration (en regroupant les points en cluster)
258                        map.parseGeoJson = function(data) {
259                                map.markers = [];
260                                /* Pour chaque points présents, on crée un marqueur */
261                                $.each(data.features, function(i, feature) {
262                                        if (feature.geometry.coordinates[0]) {
263                                                var latlng = new L.LatLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]);
264                                                var marker = new L.Marker(latlng);
265                                                // Déclarer l'icone du point
266                                                map.setGeoJsonFeatureIcon(feature, marker);
267                                                // Déclarer le contenu de la popup s'il y en a
268                                                map.setGeoJsonFeaturePopup(feature, marker);
269
270                                                marker.id = feature.id;
271                                                map.markers.push(marker);
272                                        }
273                                });
274                                /* Ajout des marqueurs dans un clustering JS client */
275                                var options = {};
276                                if (mapcfg["clusterMaxZoom"])
277                                        options["maxZoom"] = mapcfg["clusterMaxZoom"];
278                                if (mapcfg["clusterStyles"].length)
279                                        options["styles"] = mapcfg["clusterStyles"];
280                                map.markerCluster = new L.Marker.Clusterer(map, markers, options);
281                        }
282                }
283
284                // API Compat Gis3 : addJSON et removeAllMarkers
285                map.addJSON = map.parseGeoJson
286                map.removeAllMarkers = function(){
287                        for(l in this._layers)
288                        if (this._layers[l]._layers){
289                         this.removeLayer(this._layers[l]);
290                        }
291                }
292
293                if (mapcfg['affiche_points'] && mapcfg['json_points'].length){
294                        // Récupération des points à mettre sur la carte, via json externe
295                        var args = mapcfg['json_points']['env'];
296                        args["objets"] = mapcfg['json_points']['objets'];
297                        args["limit"] = mapcfg['json_points']['limit'];
298                        if (args["objets"]=="point_libre"){
299                                args["lat"]=mapcfg['lat'];
300                                args["lon"]=mapcfg['lon'];
301                                args["titre"]=mapcfg['json_points']['titre'];
302                                args["description"]=mapcfg['json_points']['description'];
303                                args["icone"]=mapcfg['json_points']['icone'];
304                        }
305                        jQuery.getJSON(mapcfg['json_points']['url'],args,
306                                function(data) {
307                                        if (data){
308                                                // Charger le json (data) et déclarer les points
309                                                map.parseGeoJson(data);
310                                                $("#"+map_container).trigger('ready',map);
311                                        }
312                                }
313                        );
314                }
315
316                if (mapcfg['kml'] && mapcfg['kml'].length){
317                        map.kml = {};
318                        for(var i in mapcfg['kml']){
319                                map.kml[i] = new L.KML(mapcfg['kml'][i], {async: true});
320                                map.kml[i].on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
321                                map.addLayer(map.kml[i]);
322                        }
323                }
324                if (mapcfg['gpx'] && mapcfg['gpx'].length){
325                        map.gpx = {};
326                        for(var i in mapcfg['gpx']){
327                                map.gpx[i] = new L.GPX(mapcfg['gpx'][i], {async: true});
328                                map.gpx[i].on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
329                                map.addLayer(map.gpx[i]);
330                        }
331                }
332
333                if (mapcfg['localize_visitor'])
334                        map.locate({setView: true, maxZoom: mapcfg['zoom']});
335
336                // si pas de points trigger ici
337                if (!mapcfg['affiche_points'] || !mapcfg['json_points'].length)
338                        $("#"+map_container).trigger('ready',map);
339        }
340
341
342        // Charger le javascript de GIS et initialiser la carte
343        $(function(){
344                jQuery.getScript('[(#PRODUIRE{fond=javascript/gis.js,cluster=#ENV{cluster,non}})]',function(){
345                        gis_init_map(map_cfg);
346                });
347        });
348
349})(jQuery);
350/*\]\]>*/
351</script>
Note: See TracBrowser for help on using the repository browser.