[Mapbender-commits] r7544 - in trunk/mapbender/http: classes javascripts php

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Wed Feb 9 10:38:06 EST 2011


Author: armin11
Date: 2011-02-09 07:38:06 -0800 (Wed, 09 Feb 2011)
New Revision: 7544

Added:
   trunk/mapbender/http/classes/class_lzw_decompress.php
   trunk/mapbender/http/javascripts/lzw.js
Modified:
   trunk/mapbender/http/javascripts/mod_savewmc.js
   trunk/mapbender/http/php/mod_savewmc_server.php
Log:
New function to compress the mapObject when storing it to session by lzw compression. on small mapObjects ths will reduce the amount of traffic to the server for 20% on bigger docs this will become better. The little problem will be, that the server needs some more cpu to decompress the data.
The handlihg is managed thru an element_var lzwCompressed in the module savewmc.

Added: trunk/mapbender/http/classes/class_lzw_decompress.php
===================================================================
--- trunk/mapbender/http/classes/class_lzw_decompress.php	                        (rev 0)
+++ trunk/mapbender/http/classes/class_lzw_decompress.php	2011-02-09 15:38:06 UTC (rev 7544)
@@ -0,0 +1,127 @@
+<?php
+//class_lzw_decompress.php
+//
+/*function uniord($ch) {
+
+    $n = ord($ch{0});
+
+    if ($n < 128) {
+        return $n; // no conversion required
+    }
+
+    if ($n < 192 || $n > 253) {
+        return false; // bad first byte || out of range
+    }
+
+    $arr = array(1 => 192, // byte position => range from
+                 2 => 224,
+                 3 => 240,
+                 4 => 248,
+                 5 => 252,
+                 );
+
+    foreach ($arr as $key => $val) {
+        if ($n >= $val) { // add byte to the 'char' array
+            $char[] = ord($ch{$key}) - 128;
+            $range  = $val;
+        } else {
+            break; // save some e-trees
+        }
+    }
+
+    $retval = ($n - $range) * pow(64, sizeof($char));
+
+    foreach ($char as $key => $val) {
+        $pow = sizeof($char) - ($key + 1); // invert key
+        $retval += $val * pow(64, $pow);   // dark magic
+    }
+
+    return $retval;
+}
+*/
+/*function unichr($dec) {
+  if ($dec < 128) {
+    $utf = chr($dec);
+  } else if ($dec < 2048) {
+    $utf = chr(192 + (($dec - ($dec % 64)) / 64));
+    $utf .= chr(128 + ($dec % 64));
+  } else {
+    $utf = chr(224 + (($dec - ($dec % 4096)) / 4096));
+    $utf .= chr(128 + ((($dec % 4096) - ($dec % 64)) / 64));
+    $utf .= chr(128 + ($dec % 64));
+  }
+  return $utf;
+*/
+
+/*function uniord($c) {
+    $h = ord($c{0});
+    if ($h <= 0x7F) {
+        return $h;
+    } else if ($h < 0xC2) {
+        return false;
+    } else if ($h <= 0xDF) {
+        return ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
+    } else if ($h <= 0xEF) {
+        return ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6
+                                 | (ord($c{2}) & 0x3F);
+    } else if ($h <= 0xF4) {
+        return ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12
+                                 | (ord($c{2}) & 0x3F) << 6
+                                 | (ord($c{3}) & 0x3F);
+    } else {
+        return false;
+    }
+}
+*/
+/**
+ * Return unicode char by its code
+ *
+ * @param int $u
+ * @return char
+ */
+/*function unichr($u) {
+    return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
+}*/
+
+  function unichr($u) {
+    return mb_convert_encoding(pack("N",$u), mb_internal_encoding(), 'UCS-4BE');
+ }
+
+function lzw_decompress($compressed) {
+	// Build the dictionary.
+	$dictSize = 256;
+	$dictionary = array();
+	for ($i=0; $i < $dictSize; $i++)
+        {
+            $dictionary[$i] = unichr($i);
+	    //$e = new mb_exception('dictionary['.$i.']:'.$dictionary[$i]);
+ 	}
+	$w = (string)unichr($compressed[0]);
+        $result = $w;
+	for ($i=1; $i < count($compressed); $i++) {
+            $entry = "";
+            $k = $compressed[$i];
+            if (isset($dictionary[$k])) { //whats with null?
+		 
+        	$entry = $dictionary[$k];
+		
+	    }
+            else if ($k == $dictSize) { 
+                $entry = $w.$w[0];
+	    }
+            else {
+                
+            }
+	    
+            $result = $result.$entry;
+            
+            $dictionary[$dictSize++] = $w.$entry[0]; //for the first time 256 after that it will be increased
+	    
+            
+            $w = $entry;
+	    
+        }
+	
+        return $result;
+}
+?>

Added: trunk/mapbender/http/javascripts/lzw.js
===================================================================
--- trunk/mapbender/http/javascripts/lzw.js	                        (rev 0)
+++ trunk/mapbender/http/javascripts/lzw.js	2011-02-09 15:38:06 UTC (rev 7544)
@@ -0,0 +1,65 @@
+//LZW Compression/Decompression for Strings
+//http://rosettacode.org/wiki/LZW_compression#JavaScript
+function LZWCompress(uncompressed) 
+    {
+        // Build the dictionary.
+        var dictSize = 256;
+        var dictionary = {};
+        for (var i = 0; i < 256; i++)
+        {
+            dictionary[String.fromCharCode(i)] = i;
+        }
+ 
+        var w = "";
+        var result = [];
+        for (var i = 0; i < uncompressed.length; i++) 
+        {
+        	var c = uncompressed.charAt(i);
+            var wc = w + c;
+            if (dictionary[wc])
+                w = wc;
+            else {
+                result.push(dictionary[w]);
+                // Add wc to the dictionary.
+                dictionary[wc] = dictSize++;
+                w = "" + c;
+            }
+        }
+ 
+        // Output the code for w.
+        if (w != "")
+            result.push(dictionary[w]);
+        return result;
+    }
+ 
+ 
+function LZWDecompress(compressed) {
+        // Build the dictionary.
+        var dictSize = 256;
+        var dictionary = [];
+        for (var i = 0; i < 256; i++)
+        {
+            dictionary[i] = String.fromCharCode(i);
+ 	}
+ 
+        var w = String.fromCharCode(compressed[0]);
+        var result = w;
+        for (var i = 1; i < compressed.length; i++) {
+            var entry = "";
+            var k = compressed[i];
+            if (dictionary[k]) {
+                entry = dictionary[k];}
+            else if (k == dictSize)
+                entry = w + w.charAt(0);
+            else
+                return null;
+            result += entry;
+            dictionary[dictSize++] = w + entry.charAt(0);
+            w = entry;
+        }
+        return result;
+}
+
+
+
+

Modified: trunk/mapbender/http/javascripts/mod_savewmc.js
===================================================================
--- trunk/mapbender/http/javascripts/mod_savewmc.js	2011-02-08 09:36:24 UTC (rev 7543)
+++ trunk/mapbender/http/javascripts/mod_savewmc.js	2011-02-09 15:38:06 UTC (rev 7544)
@@ -16,9 +16,15 @@
  * > e_mb_mod, e_target, e_requires, e_url) VALUES('<gui_id>','savewmc',2,1,
  * > 'save workspace as WMC','Save workspace as web map context document',
  * > 'img','../img/button_blink_red/wmc_save_off.png','',870,60,24,24,1,'',
- * > '','','mod_savewmc.php','','mapframe1','mapframe1',
+ * > '','','mod_savewmc.php','','mapframe1','jq_ui_dialog,lzw_compression',
  * > 'http://www.mapbender.org/index.php/SaveWMC');
  * >
+ * > INSERT INTO gui_element(fkey_gui_id, e_id, e_pos, e_public, e_comment, e_title,
+ * > e_element, e_src, e_attributes, e_left, e_top, e_width, e_height, e_z_index,
+ * > e_more_styles, e_content, e_closetag, e_js_file, e_mb_mod, e_target, e_requires,
+ * > e_url) VALUES('gui1','lzw_compression',1,1,'','','','','',NULL ,NULL ,NULL ,NULL ,
+ * > NULL ,'','','','','lzw.js','','','');
+ * >
  * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, 
  * > context, var_type) VALUES('<gui_id>', 'savewmc', 'overwrite', '1', '',
  * > 'var');
@@ -26,6 +32,9 @@
  * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, 
  * > context, var_type) VALUES('<gui_id>', 'savewmc', 'saveInSession', '1', 
  * > '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, 
+ * > context, var_type) VALUES('<gui_id>', 'savewmc', 'lzwCompressed', 'false', 
+ * > '' ,'var');
  *
  * Help:
  * http://www.mapbender.org/index.php/SaveWMC
@@ -55,9 +64,13 @@
 // init element_vars
 //
 var overwrite = options.overwrite || false;
+
 var saveInSession = typeof options.saveInSession === "undefined" ?
 	0 : options.saveInSession;
 
+var lzwCompressed = typeof options.lzwCompressed === "undefined" ?
+	false : options.lzwCompressed;
+
 var browserCompatibilityMode = typeof options.browserCompatibilityMode === "undefined" ?
 	0 : options.browserCompatibilityMode;
 
@@ -99,6 +112,7 @@
 	
 	this.overwrite = overwrite;
 	this.saveInSession = saveInSession;
+	this.lzwCompressed = lzwCompressed;
 	this.events = {
 		saved: new Mapbender.Event()
 	};
@@ -116,16 +130,16 @@
 			return this;
 		}
 		if (obj.session === true) {
-			sendMapDataToServer("session", 1, function(result, status) {});
+			sendMapDataToServer("session", 1, function(result, status) {}, lzwCompressed);
 			return this;
 		}
 		if (typeof obj.attributes === "object" && typeof obj.callback === "function") {
-			sendMapDataToServer(obj.attributes, 0, obj.callback);
+			sendMapDataToServer(obj.attributes, 0, obj.callback, lzwCompressed);
 		}
 		return this;
 	};
 
-	var sendMapDataToServer = function (attributes, storeInSession, callbackFunction) {
+	var sendMapDataToServer = function (attributes, storeInSession, callbackFunction, beLzwCompressed) {
 		var	extensionDataString = "";
 		if (that.extensionData !== null) {
 			extensionDataString = $.toJSON(that.extensionData);
@@ -135,7 +149,7 @@
 			//alert('AJAX will be set to asyncron!');
 			$.ajaxSetup({async:false}); 
 		}
-	
+		
 		//
 		// WORKAROUND....cannot serialize map object,
 		// as it contains a jQuery collection, which is
@@ -148,7 +162,12 @@
 			$target.push(mb_mapObj[i].$target);
 			delete mb_mapObj[i].$target;
 		}
-	    
+	    	var mapObjectToSend = $.toJSON(mb_mapObj);
+		//if compression is demanded see http://rosettacode.org/wiki/LZW_compression#JavaScript
+		if (beLzwCompressed == 'true') { //
+			mapObjectToSend=LZWCompress(mapObjectToSend);
+			//alert(LZWDecompress(mapObjectToSend));
+		}
 		// actual save request
 		var req = new Mapbender.Ajax.Request({
 	        url: "../php/mod_savewmc_server.php",
@@ -156,9 +175,10 @@
 			parameters : {
 			  saveInSession:storeInSession, 
 			  attributes:attributes,
-			  overwrite: overwrite,
+			  overwrite:overwrite,
 			  extensionData:extensionDataString, 
-			  mapObject:$.toJSON(mb_mapObj)
+			  lzwCompressed:beLzwCompressed,
+			  mapObject:mapObjectToSend
 			},
 	        callback: function(result, status, message) {
 				callbackFunction(result, status, message);
@@ -392,7 +412,7 @@
 							that.save({
 								session : true
 							});
-							//alert('afterMapRequest Saving!');
+							alert('afterMapRequest Saving!');
 						}
 					});
 				});

Modified: trunk/mapbender/http/php/mod_savewmc_server.php
===================================================================
--- trunk/mapbender/http/php/mod_savewmc_server.php	2011-02-08 09:36:24 UTC (rev 7543)
+++ trunk/mapbender/http/php/mod_savewmc_server.php	2011-02-09 15:38:06 UTC (rev 7544)
@@ -11,6 +11,7 @@
 require_once(dirname(__FILE__)."/../classes/class_administration.php");
 require_once(dirname(__FILE__)."/../classes/class_wmc.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_lzw_decompress.php");
 
 $ajaxResponse = new AjaxResponse($_POST);
 if($ajaxResponse->getMethod() != "saveWMC") {
@@ -25,14 +26,31 @@
 // get data from POST and SESSION
 $userId = Mapbender::session()->get("mb_user_id");
 $mapObject = $ajaxResponse->getParameter('mapObject'); 
+$lzwCompressed = $ajaxResponse->getParameter('lzwCompressed');
 $saveInSession = $ajaxResponse->getParameter('saveInSession'); 
 $extensionData = $json->decode($ajaxResponse->getParameter('extensionData'));
 $attributes =  $ajaxResponse->getParameter('attributes');
 $overwrite = $ajaxResponse->getParameter('overwrite');
 $overwrite = $overwrite == "1" ? true : false;
+//for debugging, write mapObject to file
 
+if ($lzwCompressed == 'true') {
+	//$e = new mb_exception('mod_savewmc_server.php: mapObject: '.implode(',',$mapObject));
+	$mapObject = lzw_decompress($mapObject);
+	
+	//$e = new mb_exception('mod_savewmc_server.php: mapObject uncompressed: '.$mapObject);
+	//$filename = TMPDIR."/formerly_compressed_json.txt";//will be set to new one cause ?
+} else {
+	//$filename = TMPDIR."/formerly_uncompressed_json.txt";//will be set to new one cause ?
+}
+//file_put_contents($filename, $mapObject);
+
+
+//$e = new mb_exception('mod_savewmc_server.php: mapObject is here ;-)');
 $mapObject = $json->decode($mapObject);
 
+$e = new mb_exception('mod_savewmc_server.php: mapObject has been decoded from json');
+
 // create WMC object
 $wmc = new wmc();
 if($overwrite) {
@@ -60,7 +78,7 @@
     if(Mapbender::session()->get("mb_wmc")) {
         $filename = Mapbender::session()->get("mb_wmc");
     } else {
-        $filename = TMPDIR."/".time()."_".uniqid();
+        $filename = TMPDIR."/".time()."_".uniqid();//will be set to new one cause ?
     }
     file_put_contents($filename, $wmc->xml);
 	Mapbender::session()->set("mb_wmc",$filename);



More information about the Mapbender_commits mailing list