]> dev.renevier.net Git - syp.git/blobdiff - js/admin.js
multi user administration
[syp.git] / js / admin.js
index 259c914ae8c446165e8a5c613463687845c5612c..d950aeba91275e5055d3f0dda8f87508d8e3ea6b 100644 (file)
@@ -55,11 +55,11 @@ OpenLayers.Control.SypDragFeature = OpenLayers.Class (OpenLayers.Control.DragFea
 });
 
 var Admin = {
-    Settings: {
-        MARKER_ICON: "media/marker-normal.png",
-        MARKER_SELECT_ICON: "media/marker-selected.png",
-        MARKER_TEMPORARY_ICON: "media/marker-temp.png",
-        MARKER_HEIGHT: 25
+    Markers: {
+        ICON: "media/marker-normal.png",
+        SELECT_ICON: "media/marker-selected.png",
+        TEMPORARY_ICON: "media/marker-temp.png",
+        HEIGHT: 25
     },
 
     map: null,
@@ -83,37 +83,14 @@ var Admin = {
          });
 
          this.baseLayer = this.createBaseLayer ();
-         this.dataLayer = this.createDataLayer ();
-         this.map.addLayers([this.baseLayer, this.dataLayer]);
+         this.map.addLayer(this.baseLayer);
 
-         // controls
-         this.selFeatureControl = this.createSelectFeatureControl();
-         this.map.addControl(this.selFeatureControl);
-         this.moveFeatureControl = this.createMoveFeatureControl();
-         this.map.addControl(this.moveFeatureControl);
-         this.addFeatureControl = this.createNewfeatureControl();
-         this.map.addControl(this.addFeatureControl);
-
-         // position
-         var centerBounds = new OpenLayers.Bounds();
-
-         var mapProj = this.map.getProjectionObject();
-         var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
-
-         var bottomLeft = new OpenLayers.LonLat(sypOrig[0],sypOrig[1]);
-         bottomLeft = bottomLeft.transform(sypOrigProj, mapProj);
-         var topRight = new OpenLayers.LonLat(sypOrig[2],sypOrig[3])
-         topRight = topRight.transform(sypOrigProj, mapProj);
-
-         centerBounds.extend(bottomLeft);
-         centerBounds.extend(topRight);
-
-         // at that moment, ie does not know size of the map, we need to update
-         // manually
-         this.map.updateSize();
-         this.map.zoomToExtent(centerBounds);
-
-         this.reset();
+         this.map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+         if (sypSettings.loggedUser) {
+            this.dataLayer = this.createDataLayer (sypSettings.loggedUser);
+            this.map.addLayer(this.dataLayer);
+            this.reset();
+         }
     },
 
     reset: function() {
@@ -131,44 +108,52 @@ var Admin = {
         return new OpenLayers.Layer.OSM("OSM");
     },
 
-    createDataLayer: function () {
+    createDataLayer: function (user) {
         var styleMap = new OpenLayers.StyleMap (
                         {"default": {
-                             externalGraphic: this.Settings.MARKER_ICON,
-                             graphicHeight: this.Settings.MARKER_HEIGHT || 32 
+                             externalGraphic: this.Markers.ICON,
+                             graphicHeight: this.Markers.HEIGHT || 32 
                                 },
                          "temporary": { 
-                             externalGraphic: this.Settings.MARKER_TEMPORARY_ICON,
-                             graphicHeight: this.Settings.MARKER_HEIGHT || 32 
+                             externalGraphic: this.Markers.TEMPORARY_ICON,
+                             graphicHeight: this.Markers.HEIGHT || 32 
                          },
                          "select": { 
-                             externalGraphic: this.Settings.MARKER_SELECT_ICON,
-                             graphicHeight: this.Settings.MARKER_HEIGHT || 32 
+                             externalGraphic: this.Markers.SELECT_ICON,
+                             graphicHeight: this.Markers.HEIGHT || 32 
                     }});
 
-        var layer = new OpenLayers.Layer.GML("KML", "items.php", 
+        var layer = new OpenLayers.Layer.GML("KML", "items.php?from_user=" + encodeURIComponent(user),
            {
             styleMap: styleMap,
             format: OpenLayers.Format.KML, 
             projection: this.map.displayProjection,
             eventListeners: { scope: this,
-                loadend: this.checkForFeatures
+                loadend: this.dataLayerEndLoad
             }
        });
 
+        // controls
+        this.selFeatureControl = this.createSelectFeatureControl(layer)
+        this.map.addControl(this.selFeatureControl);
+        this.moveFeatureControl = this.createMoveFeatureControl(layer)
+        this.map.addControl(this.moveFeatureControl);
+        this.addFeatureControl = this.createNewfeatureControl();
+        this.map.addControl(this.addFeatureControl);
+
         return layer;
     },
 
-    createMoveFeatureControl: function () {
+    createMoveFeatureControl: function (layer) {
         var control = new OpenLayers.Control.SypDragFeature(
-                this.dataLayer, {
+                layer, {
                          });
         return control;
     },
 
-    createSelectFeatureControl: function () {
+    createSelectFeatureControl: function (layer) {
         var control = new OpenLayers.Control.SelectFeature(
-                this.dataLayer, {
+                layer, {
                         onSelect: OpenLayers.Function.bind(this.onFeatureSelect, this)
                          });
         return control;
@@ -243,10 +228,38 @@ var Admin = {
         $("#title").select().focus(); 
     },
 
+    dataLayerEndLoad: function() {
+        // only set zoom extent once
+        this.dataLayer.events.unregister('loadend', this, this.dataLayerEndLoad);
+        this.dataLayer.events.register('loadend', this, this.checkForFeatures);
+
+        if (!this.checkForFeatures()) {
+            return;
+        }
+
+        var map = this.map;
+        var orig = this.Utils.mbr (this.dataLayer);
+        var centerBounds = new OpenLayers.Bounds();
+
+        var mapProj = map.getProjectionObject();
+        var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
+
+        var bottomLeft = new OpenLayers.LonLat(orig[0],orig[1]);
+        bottomLeft = bottomLeft.transform(sypOrigProj, mapProj);
+        var topRight = new OpenLayers.LonLat(orig[2],orig[3])
+        topRight = topRight.transform(sypOrigProj, mapProj);
+
+        centerBounds.extend(bottomLeft);
+        centerBounds.extend(topRight);
+        map.zoomToExtent(centerBounds);
+    },
+
     checkForFeatures: function () {
-        if (this.dataLayer.features.length != 0) {
+        var features = this.dataLayer.features;
+        if (features.length != 0) {
             $("#instructions").text(SypStrings.SelectHowto);
         }
+        return !!features.length;
     },
 
     addNewFeature: function () {
@@ -290,6 +303,59 @@ var Admin = {
     },
 
     Utils: {
+        /* minimum bounds rectangle containing all feature locations.
+         * FIXME: if two features are close, but separated by 180th meridian,
+         * their mbr will span the whole earth. Actually, 179° lon and -170°
+         * lon are considerated very near.
+         */
+        mbr: function (layer) {
+            var features = [];
+            var map = layer.map;
+
+            var mapProj = map.getProjectionObject();
+            var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
+
+            for (var i =0; i < layer.features.length; i++) {
+                if (layer.features[i].cluster) {
+                    features = features.concat(layer.features[i].cluster);
+                } else {
+                    features = features.concat(layer.features);
+                }
+            }
+
+            var minlon = 180;
+            var minlat = 88;
+            var maxlon = -180;
+            var maxlat = -88;
+
+            if (features.length == 0) {
+                // keep default values
+            } else if (features.length == 1) {
+                // in case there's only one feature, we show an area of at least 
+                // 4 x 4 degrees
+                var pos = features[0].geometry.getBounds().getCenterLonLat().clone();
+                var lonlat = pos.transform(mapProj, sypOrigProj);
+
+                minlon = Math.max (lonlat.lon - 2, -180);
+                maxlon = Math.min (lonlat.lon + 2, 180);
+                minlat = Math.max (lonlat.lat - 2, -90);
+                maxlat = Math.min (lonlat.lat + 2, 90);
+            } else {
+                for (var i = 0; i < features.length; i++) {
+                    var pos = features[i].geometry.getBounds().getCenterLonLat().clone();
+                    var lonlat = pos.transform(mapProj, sypOrigProj);
+                    minlon = Math.min (lonlat.lon, minlon);
+                    minlat = Math.min (lonlat.lat, minlat);
+                    maxlon = Math.max (lonlat.lon, maxlon);
+                    maxlat = Math.max (lonlat.lat, maxlat);
+                }
+            }
+
+            return [minlon, minlat, maxlon, maxlat];
+
+        },
+
+
         escapeHTML: function (str) {
             if (!str) {
                 return "";
@@ -404,6 +470,8 @@ var FeatureMgr = {
                 switch (xml.documentElement.getAttribute("reason")) {
                     case "unauthorized":
                         $("#login_area").show();
+                        $("#password").val("");
+                        $("#user").val(sypSettings.loggedUser).focus().select();
                         $("#cookie_warning").show();
                         this.reset();
                         Admin.cancelCurrentFeature();
@@ -593,7 +661,7 @@ var pwdMgr = {
 
     init: function () {
         $("#login_form").submit(this.submit);
-        $("#password").focus().select();
+        $("#user").focus().select();
     },
 
     reset: function() {
@@ -613,8 +681,8 @@ var pwdMgr = {
                     window.setTimeout(function() { 
                             // removes focus from #password before disabling it. Otherwise, opera
                             // prevents re-focusing it after re-enabling it.
-                            $("#password").blur(); 
-                            $("#login_submit, #password").attr("disabled", "disabled");
+                            $("#user, #password").blur(); 
+                            $("#login_submit, #user, #password").attr("disabled", "disabled");
                     }, 0)
                 },
                 oncomplete: OpenLayers.Function.bind(pwdMgr.ajaxReply, pwdMgr)
@@ -629,14 +697,14 @@ var pwdMgr = {
         $("#pwd_throbber").css("visibility", "hidden");
         // here, we need a timeout because onsend timeout sometimes has not been triggered yet
         window.setTimeout(function() {
-            $("#login_submit, #password").removeAttr("disabled");
+            $("#login_submit, #user, #password").removeAttr("disabled");
         }, 0);
 
         if (!data) {
             this.commError(SypStrings.ServerError);
             $("#login_error").show();
             window.setTimeout(function() {
-                    $("#password").focus().select();
+                    $("#user").focus().select();
             }, 0);
             return;
         }
@@ -660,12 +728,32 @@ var pwdMgr = {
                 }
                 $("#login_error").show();
                 window.setTimeout(function() {
-                        $("#password").focus().select();
+                        $("#user").focus().select();
                 }, 0);
             break;
             case "success":
-                this.reset();
                 $("#login_area").hide();
+
+                user = $(xml).find("USER,user").text();
+                sypSettings.loggedUser = user;
+
+                if (Admin.selFeatureControl) {
+                    Admin.selFeatureControl.destroy();
+                }
+                if (Admin.moveFeatureControl) {
+                    Admin.moveFeatureControl.destroy();
+                }
+                if (Admin.addFeatureControl) {
+                    Admin.addFeatureControl.destroy();
+                }
+                if (Admin.dataLayer) {
+                    Admin.dataLayer.destroy();
+                }
+
+                Admin.dataLayer = Admin.createDataLayer(user);
+                Admin.map.addLayer(Admin.dataLayer);
+                Admin.reset();
+
             break;
             default:
                 this.commError(SypStrings.UnconsistentError);