Skip to Content

moteur.js

//Variables globales
var mapPanel, store, gridPanel, mainPanel, exitPanel;
var map, vecLayer;
var buildStyle;
var popup;
var selectControl;
var selectedFeature;
var bPrecedent;
var zPrecedent;
var goBoucle;
var aec = "2007"; //Année en cours
var valeurs = new Array();
var tBoucle = 0;
 
function chargeDonnees(variable) {
	//Modification de la variable représentée, par changement du style de la couche des symboles.
	aec = variable;
	var style = vecLayer.styleMap.styles["default"].defaultStyle;
	if (aec != 'na') {
		document.getElementById('annee').innerHTML = aec;
		style.pointRadius = "${t"+aec+"}";
	} else {
		style.pointRadius = 4;
	}
	if (popup) {
		popup.feature = null;
	    map.removePopup(popup);
	}
	vecLayer.redraw(true);
};
 
var zoomHandler = function(button, event) {
	//Zoom pour afficher tous les symboles à l'écran.
	evl = new OpenLayers.Bounds();
	evl = vecLayer.getDataExtent();
	if (evl != null) {
		map.zoomToExtent(evl);
	}
}
 
function apresCharge() {
	//Après chargement des données, zoom et information.
	Ext.MessageBox.hide();
	zoomHandler();
	document.getElementById('annee').innerHTML = aec;
}
 
function getFeatureByValue(ar, na, vr) {
	//Recherche dans le tableau des valeurs du département selon son code, pour affichage sur la carte.
	var f = ar.features;
	for (var i=0; i<f.length; i++) {
		var feature = f[i];
		if(feature.attributes[na] == vr) {
			return feature;
		}
	}
}
 
Ext.onReady(function() {
	//Au chargement de la page, on prépare tous les éléments.
	var navt;
 
    //Carte OpenLayers, en Lambert 2 carto et avec les contrôles de navigation classiques.
    map = new OpenLayers.Map('map', {
        projection: new OpenLayers.Projection("EPSG:27572"),
        units: "m",
        maxResolution: "auto",
        maxExtent: new OpenLayers.Bounds(5000,1620000,1198000,2678000),
        controls: [
            new OpenLayers.Control.PanZoom()
        ],
        //On écoute le changement de zoom
        eventListeners:  {"zoomend": modifEchelle}
    });
 
	//Couche WMS des départements GeoFla IGN, diffusée par GéoSignal, avec un style TinyOWS.
    var base = new OpenLayers.Layer.WMS("OpenLayers WMS",
        "http://www.geosignal.org/cgi-bin/wmsmap?",
        {layers: "Regions,Departements",
	 projection:"EPSG:27572",
         units: "m",
	 maxResolution: "auto",
	 maxExtent: new OpenLayers.Bounds(5000,1620000,1198000,2678000),
	 sld: "http://www.tinyows.org/tracdocs/demo/OpenLayers-2.9/examples/sld.xml"
	}
    );
    map.addLayer(base);
 
 
    //Couche vectorielle qui va contenir les symboles.
    vecLayer = new OpenLayers.Layer.Vector("vector", {
    		styleMap: buildStyle("2007"),
    		projection: new OpenLayers.Projection("EPSG:27572")
    });
 
    map.addLayer(vecLayer);
 
	//Contrôle SelectFeature : liaison avec les fonctions d'écoute
	var options = {
	    hover: true,
	    onSelect: onFeatureSelect,
	    onUnselect: onFeatureUnselect
	};
 
	selectControl = new OpenLayers.Control.SelectFeature(vecLayer, options);
	map.addControl(selectControl);
	selectControl.activate();
 
	map.addControl(new OpenLayers.Control.LayerSwitcher());
 
	//On initialise la valeur du zoom, pour calculer la différence en cas de changement de niveau de zoom.
	zPrecedent = map.zoom;
 
    //Dimensionnement du panneau carte.
    mapPanel = new GeoExt.MapPanel({
        title: "Carte",
        region: "center",
        height: 600,
        width: 700,
        map: map,
        zoom: 1
    });
 
    //Le FeatureStore, lié au panneau Grid, et qui va chercher ses données en ajax après du script PHP getData.php.
    store = new GeoExt.data.FeatureStore({
        layer: vecLayer,
        fields: [
       		{name: 'codgeo', type: 'string'},
       		{name: 'nom', type: 'string'},
            {name: 'pop07', type: 'integer'},
            {name: 'pop99', type: 'integer'},
            {name: 'pop90', type: 'integer'},
            {name: 'pop82', type: 'integer'}
        ],
        proxy: new GeoExt.data.ProtocolProxy({
            protocol: new OpenLayers.Protocol.HTTP({
	            url: "getData.php",
	            format: new OpenLayers.Format.GeoJSON({
	                  'internalProjection': new OpenLayers.Projection("EPSG:27572"),
	                  'externalProjection': new OpenLayers.Projection("EPSG:27572")
	            })
            })
        }),
    	autoLoad: true
    });
    store.on('load', apresCharge, store);
 
    //Le panneau grid, un tableau interactif des valeurs attributaires, alimenté par le FeatureStore.
    gridPanel = new Ext.grid.EditorGridPanel({
        title: "D&eacute;partements",
        region: "east",
        store: store,
        width: 400,
        clicksToEdit: 1,        
        columns: [{
            header: "Code",
            sortable: true,
            width: 40,
            dataIndex: "codgeo"
        }, {
            header: "Nom",
            sortable: true,
            width: 120,
            dataIndex: "nom"
        }, {
            header: "2007",
            sortable: true,
            width: 40,
            dataIndex: "pop07"
        }, {
            header: "1999",
            sortable: true,
            width: 40,
            dataIndex: "pop99"
        }, {
            header: "1990",
            sortable: true,
            width: 40,
            dataIndex: "pop90"
        }, {
            header: "1982",
            sortable: true,
            width: 40,
            dataIndex: "pop82"
        }
        ],
        sm: new GeoExt.grid.FeatureSelectionModel(),
        listeners: {
        	//Réaction au clic sur une ligne : sélection d'un symbole sur la carte et recentrage sur celui-ci.
            cellmousedown: function(panel, rowIndex, cellIndex, e) {
                var idDept = store.data.items[rowIndex].data.codgeo;
				var fs = getFeatureByValue(vecLayer, 'codgeo', idDept);
                var fspos = fs.geometry.getCentroid();
                var rpan = new OpenLayers.LonLat(fspos.x, fspos.y);
                map.panTo(rpan);
            }
        }
 
    });
 
    //Panneau principal, contenant la carte et le tableau
    mainPanel = new Ext.Panel({
        renderTo: "mainpanel",
        layout: "border",
        height: 420,
        width: 880,
        items: [mapPanel, gridPanel]
    });
 
	//Réaction au clic/survol sur un symbole
	function onFeatureSelect(feature) {
		if (popup) {
			popup.feature = null;
		    map.removePopup(popup);
		}
	    var popupCloseBox = true;
	    selectedFeature = feature;
	    var locationAnnee = aec;
	    //Remplissage de l'info-bulle avec les données attributaires adaptées.
	    var locationValue = feature.attributes['pop' + aec.substring(2,4)];
	    popup = new OpenLayers.Popup.FramedCloud(feature.attributes.codgeo, feature.geometry.getBounds().getCenterLonLat(), null, "<div style='font-size:.8em; font-weight: bold'>" + feature.attributes.nom + " - " + locationAnnee + "<br />Population : " + locationValue + "</div>", null, popupCloseBox, onPopupClose);
	    feature.popup = popup;
	    popup.feature = feature;
	    map.addPopup(popup);
	}
 
	function onPopupClose(evt) {
	    selectControl.unselect(selectedFeature);
	    popup.feature = null;
	    map.removePopup(popup);
	}
 
	function onFeatureUnselect(feature) {
		if (feature.popup) {
			popup.feature = null;
		    map.removePopup(feature.popup);
		    feature.popup.destroy();
		    feature.popup = null;
		}
	}
 
	//Boucle d'affichage animé des années successives de population.
	laBoucle = function() {
		var annees = new Array ("1982", "1990", "1999", "2007");
		var posa = annees.indexOf(aec);
		if (posa < 3) {
			goAnnee(annees[posa + 1]);
		} else {
			goAnnee('1982');
		}
	}
 
	goBoucle = function() {
		var bBoucle = document.getElementById('bBoucle');
		if (tBoucle == 0) {
			bBoucle.style.fontWeight = "bold";
			tBoucle = setInterval("laBoucle()", 2000); //Deux secondes entre chaque années affichée.
		} else {
			clearInterval(tBoucle);
			bBoucle.style.fontWeight = "normal";
			tBoucle = 0;
		}
	}
 
	//Gestion de l'interface (sélection du bouton de l'année en cours) et mise à jour des symboles sur la carte.
	goAnnee = function (ap){
		if ((ap != 'na') && (ap != 'tp') && (ap != 'tm') && (ap != 'boucle')) {
			aec = ap;
			if (bPrecedent) {
				bPrecedent.style.color = "black";
				bPrecedent.style.fontWeight = "normal";
			}
			var bouton = document.getElementById("b" + aec);
			bPrecedent = bouton;
			bouton.style.color = "blue";
			bPrecedent.style.fontWeight = "bold";
		}
		if (popup) {
			popup.feature = null;
		    map.removePopup(popup);
		}
		chargeDonnees(ap);
	}
 
	//Modification de la taille des symboles après clic sur les boutons de l'interface html.
	modifTaille = function (tm){
		var cm = 0;
		if (tm == 'tp') {
			cm = 1.4;
		} else {
			cm = 0.7;
		}
		for (i = 0; i < vecLayer.features.length; i++) {
			vecLayer.features[i].attributes['t1982'] *= cm;
			vecLayer.features[i].attributes['t1990'] *= cm;
			vecLayer.features[i].attributes['t1999'] *= cm;
			vecLayer.features[i].attributes['t2007'] *= cm;
		}
		if (popup) {
			popup.feature = null;
		    map.removePopup(popup);
		}
		vecLayer.redraw();
	}
 
	//Modification de la taille des symboles en fonction du coef. basé sur le niveau de zoom.
	function modifEchelle (event){
		if (typeof(zPrecedent) != 'undefined') {
			var vz = map.zoom - zPrecedent;
			var coef = 1;
			if (vz < 0) {
				coef = 0.5;
			} else {
				coef = 2;
			}
			zPrecedent = map.zoom;
			//var va = 't'+aec.substring(2,4);
			if (aec != 'na') {
				for (i = 0; i < vecLayer.features.length; i++) {
					vecLayer.features[i].attributes['t2007'] *= coef;
					vecLayer.features[i].attributes['t1999'] *= coef;
					vecLayer.features[i].attributes['t1990'] *= coef;
					vecLayer.features[i].attributes['t1982'] *= coef;
				}
			}
			vecLayer.redraw();
		}
	}
 
	//Création du style par défaut d'affichage des symboles, et de la taille par défaut.
    function buildStyle (ap){
		var pubs = 0;
		if (ap == 'na') {
			popu = 4;
		} else {
			popu = '${t'+ap+'}';
		}
		var theme = new OpenLayers.Style({
				'pointRadius': popu
		});
 
	  	var orange = new OpenLayers.Rule({
		        symbolizer: {"Point": {'fillColor': '#ff4400', 'fillOpacity': 0.8, 'strokeWidth': 1, 'strokeColor': '#DDAA00'}}
	    	});
	    theme.addRules([orange]);
 
	    var stylemap = new OpenLayers.StyleMap({'default':theme, 'select': {'strokeColor': '#0000ff', 'fillColor': '#0000ff', 'strokeWidth': 2}});
	    return stylemap;
	}
 
});