ajout d'une branche expérimentale pour le dev du clsutering de marqueurs côté serveur

v2_cluster
brunobergot@gmail.com 12 years ago
parent 24a134f6fc
commit 9c5d555b34

2
.gitattributes vendored

@ -6,6 +6,7 @@ action/kml_infos.php -text
action/supprimer_gis.php -text
base/gis.php -text
base/gis_upgrade.php -text
/cluster.html -text
fonds/cfg_gis.html -text
formulaires/config_gis.html -text
formulaires/config_gis_fonctions.php -text
@ -20,6 +21,7 @@ genie/gis_nettoyer_base.php -text
/gis_kml.html -text
/gis_options.php -text
/gis_pipelines.php -text
images/bg_cluster.png -text
images/gis-16.png -text
images/gis-24.png -text
images/gis.png -text

@ -0,0 +1,25 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR">
<head>
<title>Cluster - [(#NOM_SITE_SPIP|textebrut)]</title>
[<meta name="description" content="(#DESCRIPTIF_SITE_SPIP|couper{150}|attribut_html)" />]
<INCLURE{fond=inc-head}>
<meta name="robots" content="none" />
</head>
<body class="page_plan">
<div id="page">
<h1>Fais péter mémé !</h1>
<p>Ici on utilise le code de http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google-maps pour gérer des clusters côté serveur.</p>
[(#MODELE{carte_gis,objets=articles,limit=50000,cluster=oui})]
<p>La même sans cluster</p>
[(#MODELE{carte_gis,id_map=2,objets=articles,limit=50000})]
</div><!--#page-->
</body>
</html>

@ -145,4 +145,101 @@ function gis_api_utilisee(){
return $config['api'] ? $config['api'] : $defaut;
}
}
// Cluster côté serveur
// http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google-maps
define('OFFSET', 268435456);
define('RADIUS', 85445659.4471); /* $offset / pi() */
function lonToX($lon) {
return round(OFFSET + RADIUS * $lon * pi() / 180);
}
function latToY($lat) {
return round(OFFSET - RADIUS *
log((1 + sin($lat * pi() / 180)) /
(1 - sin($lat * pi() / 180))) / 2);
}
function pixelDistance($lat1, $lon1, $lat2, $lon2, $zoom) {
$x1 = lonToX($lon1);
$y1 = latToY($lat1);
$x2 = lonToX($lon2);
$y2 = latToY($lat2);
return sqrt(pow(($x1-$x2),2) + pow(($y1-$y2),2)) >> (21 - $zoom);
}
function filtre_gis_cluster($flux, $distance=40, $zoom=3) {
$json = json_decode($flux,true);
$markers = $json['features'];
spip_log("total markers avant cluster ".count($markers),"bb");
$clustered = array();
/* Loop until all markers have been compared. */
while (count($markers)) {
$marker = array_pop($markers);
$cluster = array();
/* Compare against all markers which are left. */
foreach ($markers as $key => $target) {
$pixels = pixelDistance($marker['geometry']['coordinates'][1], $marker['geometry']['coordinates'][0],
$target['geometry']['coordinates'][1], $target['geometry']['coordinates'][0],
$zoom);
/* If two markers are closer than given distance remove */
/* target marker from array and add it to cluster. */
if ($distance > $pixels) {
unset($markers[$key]);
$cluster[] = $target;
}
}
/* If a marker has been added to cluster, add also the one */
/* we were comparing to and remove the original from array. */
if (count($cluster) > 0) {
$cluster[] = $marker;
$clustered[] = $cluster;
} else {
$clustered[] = $marker;
}
}
$result = array();
spip_log("total markers apres cluster ".count($clustered),"bb");
// crer les markers pour les clusters
foreach ($clustered as $key => $cluster) {
if (is_array($cluster[0])) {
$nb_markers = count($cluster);
// le cluster est centré sur le dernier point du tableau
// car c'est le point de référence pour les calculs de distance
$result[$key] = array_pop($cluster);
// on colle le nombre de points du cluster dans le titre du marker
$result[$key]['properties']['title'] = json_encode($nb_markers);
// marquer les markers qui sont des clusters, attribut category dans mxn.addJSON()
$result[$key]['properties']['category'] = 'cluster';
// récupérer les bounds pour afficher l'enssemble des points du clusters
$bounds = array(
'sw_lat' => $result[$key]['geometry']['coordinates'][1],
'sw_lon' => $result[$key]['geometry']['coordinates'][0],
'ne_lat' => $result[$key]['geometry']['coordinates'][1],
'ne_lon' => $result[$key]['geometry']['coordinates'][0]
);
foreach ($cluster as $marker) {
if ($bounds['sw_lat'] > $marker['geometry']['coordinates'][1])
$bounds['sw_lat'] = $marker['geometry']['coordinates'][1];
if ($bounds['sw_lon'] > $marker['geometry']['coordinates'][0])
$bounds['sw_lon'] = $marker['geometry']['coordinates'][0];
if ($bounds['ne_lat'] < $marker['geometry']['coordinates'][1])
$bounds['ne_lat'] = $marker['geometry']['coordinates'][1];
if ($bounds['ne_lon'] < $marker['geometry']['coordinates'][0])
$bounds['ne_lon'] = $marker['geometry']['coordinates'][0];
}
// on passe les bounds du cluster dans le champ data du marker
$result[$key]['properties']['data'] = $bounds;
} else {
$result[$key] = $cluster;
}
}
$result = '{"type": "FeatureCollection", "features": ' . json_encode($result) .'}';
return $result;
}
?>

@ -3,4 +3,5 @@
"features": [
[(#INCLURE{fond=json/gis[_(#ENV{objets})],env})]
]
}
}
[(#ENV{cluster}|oui)#FILTRE{gis_cluster}]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

@ -1,4 +1,4 @@
var gis_get_navigator_location = function(map,zoom){
var gis_get_navigator_location = function(map,zoom) {
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
map.setCenterAndZoom(new mxn.LatLonPoint(position.coords.latitude,position.coords.longitude),zoom ? zoom : 0);
@ -24,4 +24,25 @@ function zoomIci(latit, lonxit, zoom, idmap) {
map.panTo(new GLatLng(latit, lonxit));
map.setZoom(zoom)
}
*/
*/
//mxn.addProxyMethods(Mapstraction,[addGeoJSON]);
function gis_cluster(map, img) {
//var map = eval('map'+ map);
for (i in map.markers) {
if (map.markers[i].attributes.category == 'cluster') {
var marker = map.markers[i];
map.removeMarker(marker);
marker.setIcon(img, [40,40], [20,20]);
marker.click.addHandler(function(event_name, event_source, event_args) {
console.log(event_source);
event_source.closeInfoBubble.fire();
map.removeAllMarkers();
var bounds = new mxn.BoundingBox(event_source.attributes.data.sw_lat, event_source.attributes.data.sw_lon, event_source.attributes.data.ne_lat, event_source.attributes.data.ne_lon);
map.setBounds(bounds);
});
map.addMarker(marker);
}
}
}

@ -1,20 +1,22 @@
<BOUCLE_art(ARTICLES){id_article ?}{id_rubrique ?}{id_secteur ?}{id_mot ?}{id_auteur ?}{recherche ?}{0, #ENV{limit}}{","}><BOUCLE_gis(GIS){id_article}{","}>
{"type": "Feature",
"geometry": {"type": "Point", "coordinates": [#LON, #LAT]},
"id":"#ID_GIS",
"title":[(#TITRE|sinon{#_art:TITRE}|supprimer_numero|json_encode)],
"description":[(#DESCRIPTIF|sinon{#_art:DESCRIPTIF}|json_encode)][(#SET{logo_doc,''})]
[(#LOGO_GIS|oui)
[(#SET{logo_doc,#LOGO_GIS|image_passe_partout{32,32}|image_recadre{32,32}})]]
[(#LOGO_GIS|non)
[(#CHEMIN{images/marker_defaut.png}|oui)
[(#SET{logo_doc,#CHEMIN{images/marker_defaut.png}|image_passe_partout{32,32}|image_recadre{32,32}})]
]]
[(#GET{logo_doc}|oui)
#SET{icon_w,#GET{logo_doc}|extraire_attribut{src}|largeur}
#SET{icon_h,#GET{logo_doc}|extraire_attribut{src}|hauteur}
#SET{icon_anchorPoint,''}
[,"icon": (#GET{logo_doc}|extraire_attribut{src}|url_absolue|json_encode)],
"icon_size": [(#VAL{91}|chr)]#GET{icon_w},#GET{icon_h}[(#VAL{93}|chr)],
"icon_anchor": [(#VAL{91}|chr)][(#GET{icon_w}|div{2})],[(#GET{icon_h})][(#VAL{93}|chr)]
]}</BOUCLE_gis></BOUCLE_art>
"properties": {
"id":"#ID_GIS",
"infoBubble":[(#TITRE|sinon{#_art:TITRE}|supprimer_numero|json_encode)],
"description":[(#DESCRIPTIF|sinon{#_art:DESCRIPTIF}|json_encode)][(#SET{logo_doc,''})]
[(#LOGO_GIS|oui)
[(#SET{logo_doc,#LOGO_GIS|image_passe_partout{32,32}|image_recadre{32,32}})]]
[(#LOGO_GIS|non)
[(#CHEMIN{images/marker_defaut.png}|oui)
[(#SET{logo_doc,#CHEMIN{images/marker_defaut.png}|image_passe_partout{32,32}|image_recadre{32,32}})]
]]
[(#GET{logo_doc}|oui)
#SET{icon_w,#GET{logo_doc}|extraire_attribut{src}|largeur}
#SET{icon_h,#GET{logo_doc}|extraire_attribut{src}|hauteur}
#SET{icon_anchorPoint,''}
[,"icon": (#GET{logo_doc}|extraire_attribut{src}|url_absolue|json_encode)],
"iconSize": [(#VAL{91}|chr)]#GET{icon_w},#GET{icon_h}[(#VAL{93}|chr)],
"iconAnchor": [(#VAL{91}|chr)][(#GET{icon_w}|div{2})],[(#GET{icon_h})][(#VAL{93}|chr)]
]}
}</BOUCLE_gis></BOUCLE_art>

@ -115,6 +115,7 @@ var map[(#GET{id})];
id_syndic : (#ENV{id_syndic}),][
id_forum : (#ENV{id_forum}),][
id_gis : (#ENV{id_gis}),][
cluster : "(#ENV{cluster})",][
recherche : "(#ENV{recherche})",][
limit : (#ENV{limit,#ENV{limite,500}})]
},
@ -128,6 +129,8 @@ var map[(#GET{id})];
} else {
map[(#GET{id})].autoCenterAndZoom();
}]
[(#ENV{cluster}|oui)
gis_cluster(map[(#GET{id})],'[(#CHEMIN{images/bg_cluster.png}|url_absolue)]');]
}
}
);]

@ -1,10 +1,10 @@
<plugin>
<nom>GIS</nom>
<auteur>b_b, kent1</auteur>
<version>2.0.9</version>
<version>2.1.0</version>
<version_base>2.0.2</version_base>
<licence>GNU/GPL</licence>
<etat>test</etat>
<etat>dev</etat>
<slogan>G&#233;olocaliser les objets SPIP</slogan>
<description>
<multi>
@ -85,7 +85,7 @@ _ Icon from [mattrich->http://mattrich.deviantart.com/art/Picnic-101256405] unde
<necessite id="saisies" version="[1.7.1;]" />
<necessite id="spip_bonux" version="[1.8;]" />
<necessite id="afficher_objets" version="[1.2.0;]" />
<necessite id="lib:mxn-gis-2.0.9" src="http://www.mediaspip.net/sites/www.mediaspip.net/squelettes/paquets/mxn-gis/mxn-gis-2.0.9.zip" />
<necessite id="lib:mxn-gis-cluster-2.0.9" src="https://github.com/downloads/brunob/mxn/mxn-gis-cluster-2.0.9.zip" />
<categorie>divers</categorie>
<traduire gestionnaire="salvatore" module="gis" reference="fr" />
</plugin>

Loading…
Cancel
Save