[Mapbender-commits] r5375 - in trunk/mapbender/http/print: . img

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Wed Jan 20 09:32:41 EST 2010


Author: christoph
Date: 2010-01-20 09:32:41 -0500 (Wed, 20 Jan 2010)
New Revision: 5375

Added:
   trunk/mapbender/http/print/mapbender_template.json
   trunk/mapbender/http/print/mod_printPDF_div.js
   trunk/mapbender/http/print/printFactory.php
   trunk/mapbender/http/print/printPDF_download.php
   trunk/mapbender/http/print/printbox.js
Modified:
   trunk/mapbender/http/print/img/northarrow.png
   trunk/mapbender/http/print/mod_printPDF.php
Log:


Modified: trunk/mapbender/http/print/img/northarrow.png
===================================================================
(Binary files differ)

Added: trunk/mapbender/http/print/mapbender_template.json
===================================================================
--- trunk/mapbender/http/print/mapbender_template.json	                        (rev 0)
+++ trunk/mapbender/http/print/mapbender_template.json	2010-01-20 14:32:41 UTC (rev 5375)
@@ -0,0 +1,149 @@
+{
+    "type" : "templatePDF",
+    "orientation" : "P",
+    "units" : "mm",
+    "format" : "a4",
+    "controls" : [
+    	{
+    		"id" : "title",
+    		"label" : "Titel",
+    		"type" : "text",
+    		"size" : 20,
+    		"pageElementsLink" : {
+    			"titel" : "value"
+    		}
+    	},
+    	{
+    		"id" : "dpi",
+    		"label" : "DPI",
+    		"type" : "select",
+    		"size" : 20,
+    		"pageElementsLink" : {
+    			"karte" : "res_dpi"
+    		},
+    		"options" : [
+    			{
+    			"value" : "56",
+    			"label" : "niedrig (56)"
+    			},{
+    			"value" : "72",
+    			"label" : "normal (72)"
+    			},{
+    			"value" : "144",
+    			"label" : "hoch (dpi)"
+    			}
+    		]
+    	},
+    	{
+    		"id" : "comment",
+    		"label" : "Kommentar",
+    		"type" : "textarea",
+    		"size" : 5,
+    		"pageElementsLink" : {
+    			"kommentar" : "value"
+    		}
+    	},
+    	{
+    		"id" : "angle",
+    		"type" : "hidden",
+    		"pageElementsLink" : {
+    			"nordpfeil" : "angle",
+    			"karte" : "angle",
+    			"minikarte" : "angle"
+    		}
+    	},
+    	{
+    		"id" : "coordinates",
+    		"type" : "hidden"
+    	},
+    	{
+    		"id" : "scale",
+    		"type" : "hidden",
+    		"pageElementsLink" : {
+    			"scale" : "value"
+    		}    		
+    	}    	    		
+    ],
+    "pages" : [
+    	{
+    	 "tpl" : "mapbender_template2.pdf",
+    	 "useTplPage" : 1,
+    	 "elements" : {
+	    	 "karte" : {
+    			"type" : "map",
+    			"res_dpi" : 72, 
+    			"x_ul" : 11.7,
+	    		"y_ul" : 23.1,
+	    		"width" : 186.5,
+    			"height" : 253.9,
+    			"coords" : 1,
+    			"coords_font_family" : "Arial",
+    			"coords_font_size" : 6
+	   			},
+	   		"messung" : {
+    			"type" : "measure",
+    			"do_fill" : 0,
+    			"fill_color" : {
+    				"r" : 255,
+    				"g" : 0,
+    				"b" : 0
+    				},
+    			"do_stroke" : 0,
+    			"stroke_color" : {
+    				"r" : 0,
+    				"g" : 0,
+    				"b" : 0
+    				},
+    			"line_style" : {
+    				"width" : 1.0
+    				}    			
+	   			},	   			
+	   		"minikarte" : {
+    			"type" : "overview",
+    			"res_dpi" : 72, 
+    			"x_ul" : 11.6,
+	    		"y_ul" : 227,
+	    		"width" : 50,
+    			"height" : 50
+	   			},
+	   		"titel" : {
+    			"type" : "text", 
+    			"x_ul" : 11.5,
+	    		"y_ul" : 13,
+	    		"font_family" : "Arial",
+	    		"font_size" : 14
+	   			},
+	   		"kommentar" : {
+    			"type" : "para", 
+    			"x_ul" : 45,
+	    		"y_ul" : 285,
+	    		"font_family" : "Arial",
+	    		"font_size" : 11,
+	    		"width" : 120,
+	    		"height" : 12,
+	    		"align" : "C",
+	    		"border" : 0,
+	    		"fill" : 1,
+	    		"border_width" : 0.5
+	   			},
+	   		"scale" : {
+    			"type" : "text", 
+    			"x_ul" : 100.2,
+	    		"y_ul" : 281.4,
+	    		"font_family" : "Arial",
+	    		"font_size" : 11,
+				"value" : "scale"
+	   		},
+	   		"nordpfeil" : {
+    			"type" : "image", 
+    			"x_ul" : 190,
+	    		"y_ul" : 257,
+	    		"width" : 8,
+	    		"height" : 18,
+	    		"angle" : 0,
+				"filename" : "./img/northarrow.png"
+	   			}		   						
+	   		}
+	   	}
+	]
+}
\ No newline at end of file


Property changes on: trunk/mapbender/http/print/mapbender_template.json
___________________________________________________________________
Added: svn:mergeinfo
   + 

Modified: trunk/mapbender/http/print/mod_printPDF.php
===================================================================
--- trunk/mapbender/http/print/mod_printPDF.php	2010-01-20 13:47:49 UTC (rev 5374)
+++ trunk/mapbender/http/print/mod_printPDF.php	2010-01-20 14:32:41 UTC (rev 5375)
@@ -103,7 +103,7 @@
 					var title = pt.mb_mapObj[ind].wms[i].getTitleByLayerName(layers[j]);
 					var layerStyle = pt.mb_mapObj[ind].wms[i].getCurrentStyleByLayerName(layers[j]);
 					if(layerStyle==false){
-						var temp_legendurl = pt.mb_mapObj[ind].wms[i].getLegendUrlByGuiLayerStyle(layers[j],"");
+						var temp_legendurl = pt.mb_mapObj[ind].wms[i].getLegendUrlByGuiLayerStyle(layers[j],"default");
 					}
 					else{
 						var temp_legendurl = pt.mb_mapObj[ind].wms[i].getLegendUrlByGuiLayerStyle(layers[j],layerStyle);

Added: trunk/mapbender/http/print/mod_printPDF_div.js
===================================================================
--- trunk/mapbender/http/print/mod_printPDF_div.js	                        (rev 0)
+++ trunk/mapbender/http/print/mod_printPDF_div.js	2010-01-20 14:32:41 UTC (rev 5375)
@@ -0,0 +1,444 @@
+/**
+ * Package: printPDF
+ *
+ * Description:
+ * Mapbender print PDF with PDF templates module.
+ * 
+ * Files:
+ *  - http/print/mod_printPDF_div.js
+ *  - http/print/classes
+ *  - http/print/printFactory.php
+ *  - http/print/printPDF_download.php
+ *  - http/print/printbox.js
+ *
+ * SQL:
+ * > 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('gui2','printPDF',2,1,'pdf print','Print','div','','',1,1,2,2,5,'','<div id="printPDF_working_bg"></div>
+ * > <div id="printPDF_working">
+ * > <img src="../img/indicator_wheel.gif" style="padding:10px 0 0 10px">
+ * > Generating PDF
+ * > </div>
+ * > <div id="printPDF_input">
+ * > <form id="printPDF_form" action="../print/printFactory.php">
+ * > <div id="printPDF_selector"></div>
+ * > <div class="print_option">
+ * > <input type="hidden" id="map_url" name="map_url" value=""/>
+ * > <input type="hidden" id="overview_url" name="overview_url" value=""/>
+ * > <input type="hidden" name="measured_x_values" />
+ * > <input type="hidden" name="measured_y_values" /><br />
+ * > </div>
+ * > <div class="print_option" id="printPDF_formsubmit">
+ * > <input id="submit" type="submit" value="Print"><br />
+ * > </div>
+ * > </form>
+ * > <div id="printPDF_result">
+ * > </div>
+ * > </div>','div','../print/mod_printPDF_div.js','','mapframe1','','http://www.mapbender.org/index.php/Print');
+ * >  
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui2', 'printPDF', 'mbPrintConfigFilenames', '["testConfigTemplate.json"]', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui2', 'printPDF', 'mbPrintConfigTitles', '["Standard"]', '' ,'var');
+ *
+ * Help:
+ * http://www.mapbender.org/PrintPDF_with_template
+ *
+ * Maintainer:
+ * http://www.mapbender.org/User:Michael_Schulz
+ * 
+ * Parameters:
+ * mbPrintConfigFilenames      - *[optional]* JSON string array / filenames of the json configuration files
+ * mbPrintConfigTitles         - *[optional]* JSON string array / title of the template to be shown in a select box in a mapbender application
+ *
+ * License:
+ * Copyright (c) 2009, Open Source Geospatial Foundation
+ * This program is dual licensed under the GNU General Public License 
+ * and Simplified BSD license.  
+ * http://svn.osgeo.org/mapbender/trunk/mapbender/license/license.txt
+ */
+
+var myTarget = options.target ? options.target[0] : "mapframe1";
+var myId = options ? options.id : "printPDF";
+
+
+/* the array of json print config files */
+
+if (typeof mbPrintConfigFilenames === "undefined") {
+	mbPrintConfigFilenames = ["mapbender_template.json"];
+}
+
+if (typeof mbPrintConfigTitles === "undefined") {
+	mbPrintConfigTitles = ["Default"];
+}
+
+
+var mbPrintConfigPath = "../print/";
+
+
+/* ------------- printbox addition ------------- */
+
+var PrintPDF = function (options) {
+
+	var that = this;
+	
+	/**
+ 	 * Property: actualConfig
+	 * 
+	 * object, holds the actual configuration after loading the json file
+	 */
+	var actualConfig;
+
+	/**
+ 	 * constructor
+	 */
+	eventInit.register(function () {
+		mod_printPDF_init();
+	});
+	
+	/**
+ 	 * Property: printBox
+	 * 
+	 * the movable printframe
+	 */	
+	var printBox = null;
+	
+	eventAfterMapRequest.register(function () {
+		if (printBox !== null) {
+			printBox.repaint();
+		}
+	});
+	/**
+ 	 * Method: createPrintBox
+	 * 
+	 * creates a printBox in the current view, calculates the scale 
+	 * (tbd. if not set from the config) so that the printbox fits in the mapframe.
+	 * Width and height are taken from the configuration.
+	 */
+	this.createPrintBox = function () {
+		size = "A4";
+		//document.form1.size.value = size;
+		format = "portrait";
+		var w, h;
+		//validate();
+		var map = getMapObjByName(myTarget);
+		var map_el = map.getDomElement();
+		var jqForm = $("#"+myId+"_form");
+		var $scaleInput = $("#scale");
+
+		if (printBox !== null) {
+			printBox.destroy();
+			printBox = null;
+			jqForm[0].scale.value = "";
+			jqForm[0].coordinates.value = "";
+			jqForm[0].angle.value = "";
+		}
+		else {
+			printBox = createBox({
+				target : myTarget,
+				printWidth : getPDFMapSize("width")/10,
+				printHeight : getPDFMapSize("height")/10,
+				scale : $scaleInput.size() > 0 && !isNaN(parseInt($scaleInput.val(), 10)) ? 
+					parseInt($scaleInput.val(), 10) : 
+					Math.pow(10, Math.floor(Math.log(map.getScale())/Math.LN10)),
+				afterChangeAngle : function (obj) {
+					if (typeof(obj) == "object") {
+						if (typeof(obj.angle) == "number") {
+							jqForm[0].angle.value = obj.angle;
+						}
+						if (obj.coordinates) {
+							jqForm[0].coordinates.value = String(obj.coordinates);
+						}
+					}
+				},
+				afterChangeSize : function (obj) {
+					if (typeof(obj) == "object") {
+						if (obj.scale) {
+							jqForm[0].scale.value = parseInt(obj.scale / 100, 10) * 100;
+						}
+						if (obj.coordinates) {
+							jqForm[0].coordinates.value = String(obj.coordinates);
+						}
+					}
+				}
+			});
+		}
+	};
+
+	/**
+ 	 * Method: getPDFMapSize
+	 * 
+	 * checks the actual config for the size w/h values.
+	 *
+	 * Parameters:
+	 * key      - string, the key which value to retrieve (currently width or height)
+	 */	
+	var getPDFMapSize = function (key) {
+		for (var page in actualConfig.pages) {
+			for (var pageElement in actualConfig.pages[page].elements) {
+				if (actualConfig.pages[page].elements[pageElement].type == "map") {
+					return actualConfig.pages[page].elements[pageElement][key];
+				}
+			}
+		} 
+	};
+
+	/**
+ 	 * Method: destroyPrintBox
+	 * 
+	 * removes an existing printBox.
+	 */	
+	var destroyPrintBox = function () {
+		if (printBox) {
+			printBox.destroy();
+		}
+	};
+	
+	/**
+ 	 * Method: mod_printPDF_init
+	 * 
+	 * initializes the print modules, generates template chooser and loads first configuration.
+	 */	
+	var mod_printPDF_init = function () {
+		/* first we'd need to build the configuration selection */
+		buildConfigSelector();	
+		/* second we'd need to read the json configuration */
+		that.loadConfig(mbPrintConfigFilenames[0]);
+	};
+
+	/**
+ 	 * Method: loadConfig
+	 * 
+	 * GETs the config, build corresponding form, remove an existing printBox
+	 */		
+	this.loadConfig = function (configFilename, callback) {
+		$.get(mbPrintConfigPath + configFilename, function(json, status){
+		    actualConfig = $.parseJSON(json);
+		    buildForm(); 
+		    hookForm();
+			if (typeof callback === "function") {
+				printBox = null;
+				callback();
+			}
+		});
+		destroyPrintBox();
+	};
+
+	/**
+ 	 * Method: hookForm
+	 * 
+	 * utility method to connect the form plugin to the print form.
+	 */	
+	var hookForm = function () {
+		var options = { 
+	   		url:			'../print/printFactory.php', 
+	   		type:			'post',
+	   		dataType:		'json',
+	   		beforeSubmit: 	validate,
+	   		success:    	showResult
+		};
+		$("#"+myId+"_form").ajaxForm(options);	
+	};
+	
+	/**
+	 * Change status of the working elements. These should begin with "$myId_working" 
+	 *
+	 * @param {String} newStatus either "hide or "show"
+	 */
+	var showHideWorking = function (newStatus) {
+		if (newStatus=="hide") {
+	    	$("[id^='"+myId+"_working']").hide();
+		}
+	    else {
+	    	$("[id^='"+myId+"_working']").show();	
+		}
+	};
+	
+	/**
+	 * update form values helper function
+	 *
+	 */
+	var updateFormField = function (formData, key, value) {
+		for(var j=0; j < formData.length; j++){
+			if (formData[j].name == key) {
+				formData[j].value = value;
+				break;
+			}
+		}	
+	};
+	
+	
+	/**
+	 * Validates and updates form data values.
+	 * Adds the elements before the submit button.
+	 *
+	 * @see jquery.forms#beforeSubmitHandler
+	 */
+	var validate = function (formData, jqForm, options) {
+		showHideWorking("show");
+		
+		// map urls
+		var ind = getMapObjIndexByName(myTarget);
+		var f = jqForm[0];
+		f.map_url.value = '';
+		f.overview_url.value = '';
+		for(var i=0; i < mb_mapObj[ind].wms.length; i++){
+			if(mb_mapObj[ind].wms[i].gui_wms_visible > 0){
+				if(mb_mapObj[ind].wms[i].mapURL != false && mb_mapObj[ind].wms[i].mapURL != 'false' && mb_mapObj[ind].wms[i].mapURL != ''){   
+					if(f.map_url.value != ""){
+						f.map_url.value += '___';
+					}      
+					f.map_url.value += mb_mapObj[ind].wms[i].mapURL;
+				}
+			}
+		}
+		updateFormField(formData, "map_url", f.map_url.value);
+		
+		//overview_url
+		var ind_overview = getMapObjIndexByName('overview');
+		if(mb_mapObj[ind_overview].mapURL != false ){
+		    f.overview_url.value = mb_mapObj[ind_overview].mapURL;
+			updateFormField(formData, "overview_url", f.overview_url.value);
+		}
+		
+		updateFormField(formData, "map_scale", mb_getScale(myTarget));
+		// write the measured coordinates
+		if (typeof(mod_measure_RX) !== "undefined") {
+			var tmp_x = '';
+			var tmp_y = '';
+			for(i = 0; i < mod_measure_RX.length; i++) {
+				if(tmp_x != '') {
+					tmp_x += ',';
+				}
+				tmp_x += mod_measure_RX[i];
+			}
+			for(i = 0; i < mod_measure_RY.length; i++) {
+				if(tmp_y != '') {
+					tmp_y += ',';
+				}
+				tmp_y += mod_measure_RY[i];
+			}
+			updateFormField(formData, "measured_x_values", tmp_x);
+			updateFormField(formData, "measured_y_values", tmp_y);
+		}	
+		
+		
+		if (f.map_url.value!="") {
+			//return true;
+		} else {
+		    showHideWorking("hide");
+			return false;
+		}
+			
+	};
+
+	/**
+ 	 * Method: showResult
+	 * 
+	 * load the generated PDF from the returned URL as an attachment, 
+	 * that triggers a download popup or is displayed in PDF plugin.
+	 */		
+	var showResult = function (res, text) {
+		if (text == 'success') {
+			var $downloadFrame = $("#" + myId + "_frame");
+			if ($downloadFrame.size() === 0) {
+				$downloadFrame = $(
+					"<iframe id='" + myId + "_frame' name='" + 
+					myId + "_frame' width='0' height='0' style='display:none'></iframe>"
+				).appendTo("body");
+			}
+			if ($.browser.msie && $.browser.version === "6.0") {
+				var newWin = window.open(stripslashes(res.outputFileName), "Druckausgabe", "width=200,height=200,left=700,top=200,resizable=yes");
+			}
+			else {
+				window.frames[myId + "_frame"].location.href = 
+					stripslashes(res.outputFileName);
+			}
+			showHideWorking("hide");	
+		}
+		else {
+			/* something went wrong */
+			$("#"+myId+"_result").html(text);
+		}
+	};
+	
+	/**
+	 * Generates form elements as specified in the config controls object.
+	 * Adds the elements before the submit button.
+	 * 
+	 * @param {Object} json the config object in json
+	 */
+	var buildForm = function () {
+		$(".print_option_dyn").remove();
+		var str = "";
+		for (var item in actualConfig.controls) {
+			var element = actualConfig.controls[item];
+			var element_id = myId + "_" + element.id;
+			if (element.type != "hidden") {
+				str += '<div class="print_option_dyn">\n';	
+				str += '<label class="print_label" for="'+element.id+'">'+element.label+'</label>\n';
+			} else {
+				str += '<div class="print_option_dyn" style="display:none;">\n';	
+			}
+			switch (element.type) {
+				case "text":
+					str += '<input type="'+element.type+'" name="'+element.id+'" id="'+element.id+'" size="'+element.size+'"><br>\n';
+					break;
+				case "hidden":
+					str += '<input type="'+element.type+'" name="'+element.id+'" id="'+element.id+'">\n';
+					break;				
+				case "textarea":
+					str += '<textarea id="'+element.id+'" name="'+element.id+'" size="'+element.size+'"></textarea><br>\n';
+					break;				
+				case "select":
+					str += '<select id="'+element.id+'" name="'+element.id+'" size="1">\n';
+					for (var option_index in element.options) {
+						option = element.options[option_index];
+						str += '<option value="'+option.value+'">'+option.label+'</option>\n';
+					}
+					str += '</select><br>\n';
+					break;
+			}
+			str += '</div>\n';
+		}
+		if (str) {
+			$("#" + myId + "_formsubmit").before(str);
+			$("#scale").keydown(function (e) {
+				if (e.keyCode !== 13) {
+					return;
+				}
+				var scale = parseInt(this.value, 10);
+				if (isNaN(scale) || typeof printBox === "undefined") {
+					return false;
+				}
+				printBox.setScale(scale);
+				return false;
+			});
+		}
+	};
+	
+	/**
+	 * Generates the configuration select element from the gui element vars
+	 * mbPrintConfigFilenames and mbPrintConfigTitles
+	 */
+	var buildConfigSelector = function () {
+		var str = "";
+		str += '<label class="print_label" for="printPDF_template">Vorlage</label>\n';
+		str += '<select id="printPDF_template" name="printPDF_template" size="1" onchange="printObj.loadConfig(mbPrintConfigFilenames[this.selectedIndex], function () {printObj.createPrintBox()});">\n';
+		for (var i = 0; i < mbPrintConfigFilenames.length; i++) {
+			str += '<option value="'+mbPrintConfigFilenames[i]+'">'+mbPrintConfigTitles[i]+'</option>\n';
+		}
+		str += '</select><img src="../print/img/shape_handles.png" onclick="try{printObj.createPrintBox();}catch(exc){alert(printObj);}" title="Use printbox">\n';
+		if (str) {
+			$("#printPDF_selector").append(str);
+			$("#printPDF_working").bgiframe({ 
+				src: "BLOCKED SCRIPT'&lt;html&gt;&lt;/html&gt;';",
+				width: 200,
+				height: 200
+			});
+		}
+	};
+	
+	var stripslashes = function ( str ) {
+	    return (str+'').replace(/\0/g, '0').replace(/\\([\\'"])/g, '$1');
+	};
+
+};
+
+var printObj = new PrintPDF();

Added: trunk/mapbender/http/print/printFactory.php
===================================================================
--- trunk/mapbender/http/print/printFactory.php	                        (rev 0)
+++ trunk/mapbender/http/print/printFactory.php	2010-01-20 14:32:41 UTC (rev 5375)
@@ -0,0 +1,12 @@
+<?php
+
+require_once(dirname(__FILE__)."/classes/factoryClasses.php");
+
+$pf = new mbPdfFactory();
+$pdf = $pf->create($_REQUEST["printPDF_template"]);
+
+$pdf->render();
+$pdf->save();
+
+print $pdf->returnAbsoluteUrl();
+?>
\ No newline at end of file

Added: trunk/mapbender/http/print/printPDF_download.php
===================================================================
--- trunk/mapbender/http/print/printPDF_download.php	                        (rev 0)
+++ trunk/mapbender/http/print/printPDF_download.php	2010-01-20 14:32:41 UTC (rev 5375)
@@ -0,0 +1,19 @@
+<?php
+require_once(dirname(__FILE__)."/../php/mb_validateSession.php");
+
+if (isset($_REQUEST["f"]) && $_REQUEST["f"]!="" && file_exists(TMPDIR."/".$_REQUEST["f"])) {
+	$filename = TMPDIR."/".$_REQUEST["f"];
+	header("Pragma: private");
+	header("Cache-control: private, must-revalidate");
+	header("Content-Type: x-type/subtype");
+	header("Content-Disposition: attachment; filename=\"".basename($filename)."\"");	
+	
+    ob_clean();
+    flush();
+    readfile($filename);
+    exit;
+}
+else {
+	echo "not found";
+}
+?>
\ No newline at end of file

Added: trunk/mapbender/http/print/printbox.js
===================================================================
--- trunk/mapbender/http/print/printbox.js	                        (rev 0)
+++ trunk/mapbender/http/print/printbox.js	2010-01-20 14:32:41 UTC (rev 5375)
@@ -0,0 +1,709 @@
+function createBox (options) {
+	myPrintBox = new PrintBox(options);
+	myPrintBox.paintPoints();
+	myPrintBox.paintBox();	
+	return myPrintBox;
+}
+
+function PrintBox (options) {
+	if (!options) {
+		options = {};
+	}
+
+	var target = options.target || "mapframe1";
+	var map = getMapObjByName(target);
+//	var map = Mapbender.modules[target];
+	var map_el = map.getDomElement();
+
+	// Default is portrait, A4, unit seems to be cm
+	var printWidth = options.printWidth || 21;
+	var printHeight = options.printHeight || 29.7;
+
+	// initialised in setScale()
+	var boxWidth, boxHeight; 
+
+	var scale = options.scale || 100000;
+
+	// behaviour
+	var afterChangeAngle = options.afterChangeAngle || function (obj) {};
+	var afterChangeSize = options.afterChangeSize || function (obj) {};
+	
+	// styles
+	var opacity = options.boxOpacity || 0.6;
+	var boxColour = options.boxColour || "#9999FF";
+	var frameColour = options.frameColour || "#000000";
+	var pointColour = options.pointColour || "#DD0000";
+	var circleColour = options.circleColour || "#DD0000";
+	var circleWidth = options.circleWidth || 4;
+
+	// attributes
+	this.id = "printbox";
+	var angle = 0;
+	var totalAngle = 0;
+
+	// the four points of the box as pixel coordinates (incl rotation),
+	// with (0,0) as center. This is important for angle calculations.
+	var pointArray = [];
+
+	// The pointArray is moved by the center vector.
+	// default: place box in the center of the map
+	var center = options.center || new Point(map.width/2,map.height/2);
+
+	// the center in real world coordinates
+	var centerMap = null;
+
+	// the four points of the box as pixel coordinates (NO ROTATION)
+	var startPointPixArray = [];
+
+	// the four points of the box as real world coordinates (NO ROTATION)
+	var startPointMapArray = [];
+	var that = this;
+
+	// if the box is smaller than this, the circle will not be drawn
+	var MIN_BOX_WIDTH_OR_HEIGHT = 10;
+
+	// if the box is larger than this, the box will not be filled
+	var MAX_BOX_WIDTH_OR_HEIGHT = 800;
+
+	this.toString = function () {
+		var str = "";
+		str += "Center: " + getCenter() + "\n";
+		str += "Radius: " + radius + "\n";
+		str += "StartRadius: " + startRadius + "\n";
+		str += "Pixelpos: " + String(pointArray) + "\n";
+		str += "StartPixelpos: " + String(startPointPixArray) + "\n";
+		str += "Mappos: " + String(startPointMapArray) + "\n";
+		return str;
+	};
+	
+	var initBehaviour = function () {
+		initMoveBehaviour();
+		initResizeBehaviour();
+		initRotateBehaviour();
+	};
+
+	var initRotateBehaviour = function () {
+		$circleCanvas.css("z-index", "110").mousedown(function (e) {
+			circleCanvas.clear();	
+	
+			var newCenter = getCenter();
+	
+			var mouseMoveStart = map.getMousePos(e);
+			var vectorA = pointArray[0].minus(newCenter);
+			
+			var currentPos = map.getMousePos(e);
+			var vectorCurrent = currentPos.minus(newCenter);
+			
+			angle = Math.ceil(getAngle(vectorA, vectorCurrent));
+			
+			$(document).mousemove(function (e) {
+				var currentPos = map.getMousePos(e);
+				var vectorCurrent = currentPos.minus(newCenter);
+				var currentAngle = Math.ceil(getAngle(vectorA, vectorCurrent));
+				var diffAngle = currentAngle - angle;
+				if (Math.abs(diffAngle) >= 1) {
+					angle = currentAngle;
+					totalAngle = ((totalAngle + diffAngle) +360 )% 360;
+					that.rotate(totalAngle);
+				}
+				return false;
+			}).mouseup(function (e) {
+				angle = 0;
+				$(document).unbind("mousemove");
+				$(document).unbind("mouseup");
+				afterChangeAngle({
+					angle: totalAngle,
+					coordinates: that.getStartCoordinates()
+				});
+				that.paintBox();
+				return false;
+			});	
+			return false;
+		}).css("cursor", "move");
+	};
+
+	var initMoveBehaviour = function () {
+		$boxCanvas.mousedown(function (e) {
+			circleCanvas.clear();	
+	
+			var mouseMoveStart = map.getMousePos(e);
+	
+			var containerStart = new Point(
+				parseInt($container.css("left"), 10),
+				parseInt($container.css("top"), 10)
+			);
+
+			var diff;
+	
+			$(document).mousemove(function (e) {
+				diff = (map.getMousePos(e)).minus(mouseMoveStart);
+	
+				$container.css({
+					"top": (containerStart.y + diff.y) + "px",
+					"left": (containerStart.x + diff.x) + "px"
+				});
+				return false;
+	
+			}).mouseup(function (e) {
+				$(document).unbind("mousemove");
+				$(document).unbind("mouseup");
+				recalculateMapPositions();
+				that.rotate(totalAngle);
+				that.paintBox();
+				return false;
+			});	
+			return false;
+		});
+	};
+
+	var initResizeBehaviour = function () {
+		$pointCanvas.css("z-index", "120").mousedown(function (e) {
+			circleCanvas.clear();	
+
+			var vectorA = getCenter();
+	
+			resizeRatio = 1;
+			mouseMoveStart = map.getMousePos(e);
+			$(document).mousemove(function (e) {
+				var newRadius = vectorA.dist(map.getMousePos(e));
+				var resizeRatio = newRadius / radius;
+				if (resizeRatio < 0.98 || resizeRatio > 1.02) {
+					for (var i = 0; i < pointArray.length; i++) {
+						pointArray[i].x *= resizeRatio;
+						pointArray[i].y *= resizeRatio;
+						startPointPixArray[i].x *= resizeRatio;
+						startPointPixArray[i].y *= resizeRatio;
+					}
+					radius *= resizeRatio;
+					that.paintPoints();
+				}
+				return false;
+			});
+			$(document).mouseup(function (e) {
+				$(document).unbind("mousemove");
+				$(document).unbind("mouseup");
+
+				recalculateMapPositions();
+				recalculatePixPositions();
+				afterChangeSize({
+					scale: that.getScale(),
+					coordinates: that.getStartCoordinates()
+				});
+				that.rotate(totalAngle);
+				that.paintBox();
+				return false;
+			});
+			return false;
+		}).css("cursor", "move");
+	};
+
+	var setCenter = function (inputCenter) {
+		center = inputCenter.minus(
+			new Point(
+				parseInt($container.css("left"), 10), 
+				parseInt($container.css("top"), 10)
+			)
+		);
+	};
+	
+	var getCenter = function () {
+		var c = center.plus(
+			new Point(
+				parseInt($container.css("left"), 10), 
+				parseInt($container.css("top"), 10)
+			)
+		);
+		return c;
+	};
+
+	/**
+	 * Calculates the angle (-180 < angle <= 180) between two vectors.
+	 * 
+	 * @param {Point} a
+	 * @param {Point} b
+	 */
+	var getAngle = function (a, b) {
+		var undirectedAngle = 180 * Math.acos(
+				(a.x * b.x + a.y * b.y) 
+				/
+				(
+					Math.sqrt(
+						a.x * a.x
+					+ 
+					 	a.y * a.y
+					) * 
+					Math.sqrt(
+						b.x * b.x
+					+ 
+						b.y * b.y
+					)
+				)
+			) / Math.PI;
+
+		if ((a.x*b.y - a.y*b.x) > 0) {
+			return -1 * undirectedAngle;
+		}
+		return undirectedAngle;
+		
+	};
+	
+	/**
+	 * To be replaced by the map objects native getMousePosition
+	 * 
+	 * @param {Event} e
+	 
+	var getMousePos = function (e) {
+		if ($.msie) {
+			return new Point(event.clientX, event.clientY);
+		}
+		return new Point(e.pageX, e.pageY);
+	};
+	 */
+
+	var recalculateMapPositions = function () {
+		for (var i = 0; i < pointArray.length; i++) {
+			startPointMapArray[i] = convertPixelToMap(startPointPixArray[i].plus(getCenter()));
+		}
+		centerMap = convertPixelToMap(getCenter());
+		
+	};
+
+	var recalculatePixPositions = function () {
+		setCenter(convertMapToPixel(centerMap));
+		for (var i = 0; i < startPointMapArray.length; i++) {
+			pointArray[i] = convertMapToPixel(startPointMapArray[i]).minus(getCenter());
+			startPointPixArray[i] = convertMapToPixel(startPointMapArray[i]).minus(getCenter());
+		}
+		radius = pointArray[0].dist(new Point(0,0));
+		startRadius = radius;
+		boxWidth = pointArray[2].x - pointArray[0].x;
+		boxHeight = pointArray[0].y - pointArray[2].y;
+	};
+
+	var initPoints = function () {
+		var w = parseInt((boxWidth/2), 10);
+		var h = parseInt((boxHeight/2), 10);
+
+		pointArray[0] = new Point(-w,  h);
+		pointArray[1] = new Point( w,  h);
+		pointArray[2] = new Point( w, -h);
+		pointArray[3] = new Point(-w, -h);
+
+		startPointPixArray[0] = (new Point(-w,  h));
+		startPointPixArray[1] = (new Point( w,  h));
+		startPointPixArray[2] = (new Point( w, -h));
+		startPointPixArray[3] = (new Point(-w, -h));
+
+		radius = pointArray[0].dist(new Point(0,0));
+		startRadius = radius;
+
+		recalculateMapPositions();
+
+		scale = that.getScale();
+	};
+
+	var switchBoxDimensions = function () {
+		setBoxDimensions(boxHeight, boxWidth);
+		afterChangeSize({
+			scale: that.getScale(),
+			coordinates: that.getStartCoordinates()
+		});
+	};
+
+	this.setPortrait = function () {
+		this.setAngle(0);
+		if (boxWidth > boxHeight) {
+			switchBoxDimensions();
+		}
+	};
+	
+	this.setLandscape = function () {
+		this.setAngle(0);
+		if (boxWidth < boxHeight) {
+			switchBoxDimensions();
+		}
+	};
+	
+	this.setPrintWidthAndHeight = function (width, height) {
+		var currentScale = this.getScale();
+		printWidth = width;
+		printHeight = height;
+		this.setScale(currentScale);
+	};
+	
+	var convertMapToPixel = function (aPoint) {
+		var pArray = makeRealWorld2mapPos(map.elementName, aPoint.x, aPoint.y);
+		return new Point(pArray[0], pArray[1]);
+	};
+	
+	var convertPixelToMap = function (aPoint) {
+		var pArray = makeClickPos2RealWorldPos(map.elementName, aPoint.x, aPoint.y);
+		return new Point(pArray[0], pArray[1]);
+	};
+	
+	/**
+	 * Sets the box width and box height (calculated in setScale)
+	 * 
+	 * @param {Integer} inputWidth
+	 * @param {Integer} inputHeight
+	 */
+	var setBoxDimensions = function (inputWidth, inputHeight) {
+		boxWidth = inputWidth;
+		boxHeight = inputHeight;
+		
+		initPoints();
+		that.rotate(totalAngle);
+
+		afterChangeSize({
+			scale: that.getScale(),
+			coordinates: that.getStartCoordinates()
+		});
+
+		that.paintBox();
+	};
+
+	/**
+	 * Returns an array of two points, the lower left and upper right of the initial box
+	 */
+	this.getStartCoordinates = function () {
+		var a = startPointMapArray[0];
+		var b = startPointMapArray[2];
+		if (!a || !b) {
+			return null;
+		}
+		var returnString =  a.x + "," + a.y + "," + b.x + "," + b.y;
+		return returnString;
+	};
+
+	/**
+	 * Returns the current scale of the print box
+	 */
+	this.getScale = function () {
+/*
+		var coords = this.getStartCoordinates();
+		var coordsArray = coords.split(",");		
+
+		var ext = mapObj.getExtentInfos();
+		var extMinX = ext.minx;
+		var extMaxX = ext.maxx;
+		
+		var x = (ext.minx + ext.maxx)/2;
+		var y = (ext.miny + ext.maxy)/2;
+		var scale1 = (x - coordsArray[0]) * (mb_resolution * 100 *2) / mapObj.width;
+		var scale2 = (coordsArray[2] - x) * (mb_resolution * 100 *2) / mapObj.width;
+		scale = Math.round(scale1/2 + scale2/2);
+		return scale;
+*/
+		var coords = this.getStartCoordinates();
+		var coordsArray = coords.split(",");		
+	
+		xtentx =  coordsArray[2] - coordsArray[0];
+		scale = parseInt(Math.ceil(xtentx / (printWidth / 100)), 10);
+		return scale;
+	};
+
+	/**
+	 * Repaints the Box with the current scale. Can be called from outside, 
+	 * for example after zoom in.
+	 */
+	this.repaint = function () {
+		recalculatePixPositions();
+		this.rotate(totalAngle);
+		this.paintBox();
+	};
+	
+	/**
+	 * Sets the current scale, and repaints the box
+	 * 
+	 * @param {Integer} inputScale
+	 */
+	this.setScale = function (inputScale) {
+		if (typeof(inputScale) == "number") {
+/*			
+			var arrayBBox = mapObj.extent.split(",");
+			x = parseFloat(arrayBBox[0]) + ((parseFloat(arrayBBox[2]) - parseFloat(arrayBBox[0]))/2);
+			y = parseFloat(arrayBBox[1]) + ((parseFloat(arrayBBox[3]) - parseFloat(arrayBBox[1]))/2);
+			
+			var minx = parseFloat(x) - (mapObj.width / (mb_resolution * 100 *2) * inputScale);
+			var miny = parseFloat(y) -  (mapObj.height / (mb_resolution * 100 *2) * inputScale);
+			var maxx = parseFloat(x) + (mapObj.width / (mb_resolution * 100 *2) * inputScale);
+			var maxy = parseFloat(y) +  (mapObj.height / (mb_resolution * 100 *2) * inputScale);
+
+			var newMinPos = makeRealWorld2mapPos(mapObj.frameName, minx, miny);
+			var newMaxPos = makeRealWorld2mapPos(mapObj.frameName, maxx, maxy);
+			var newBoxWidth = newMaxPos[0] - newMinPos[0];
+			var newBoxHeight = newBoxWidth * (printHeight / printWidth);
+*/
+			var mapWidthInM = printWidth / 100;
+			var realWidthInM = inputScale * mapWidthInM;
+			var mapHeightInM = printHeight / 100;
+			var realHeightInM = inputScale * mapHeightInM;
+			
+			var coords = this.getStartCoordinates();
+			if (coords !== null) {
+				var coordsArray = coords.split(",");
+				var oldMin = new Point(parseFloat(coordsArray[0]), parseFloat(coordsArray[1]));
+				var oldMax = new Point(parseFloat(coordsArray[2]), parseFloat(coordsArray[3]));
+				centerMap = (oldMin.times(0.5)).plus(oldMax.times(0.5));
+				
+			}
+			else {
+				centerMap = convertPixelToMap(getCenter());
+			}
+			
+			var newMin = new Point(centerMap.x - 0.5 * realWidthInM, centerMap.y - 0.5 * realHeightInM);
+			var newMax = new Point(centerMap.x + 0.5 * realWidthInM, centerMap.y + 0.5 * realHeightInM);
+
+			startPointMapArray[0] = new Point(newMin.x, newMin.y);
+			startPointMapArray[1] = new Point(newMax.x, newMin.y);
+			startPointMapArray[2] = new Point(newMax.x, newMax.y);
+			startPointMapArray[3] = new Point(newMin.x, newMax.y);
+
+			this.getStartCoordinates();
+			var newMinPos = convertMapToPixel(newMin);
+			var newMaxPos = convertMapToPixel(newMax);
+			boxWidth = newMaxPos.x - newMinPos.x;
+			boxHeight = newMinPos.y - newMaxPos.y;
+
+			var w = parseInt(0.5 * boxWidth, 10);
+			var h = parseInt(0.5 * boxHeight, 10);
+
+			pointArray[0] = new Point(-w,  h);
+			pointArray[1] = new Point( w,  h);
+			pointArray[2] = new Point( w, -h);
+			pointArray[3] = new Point(-w, -h);
+	
+			startPointPixArray[0] = (new Point(-w,  h));
+			startPointPixArray[1] = (new Point( w,  h));
+			startPointPixArray[2] = (new Point( w, -h));
+			startPointPixArray[3] = (new Point(-w, -h));
+	
+			radius = pointArray[0].dist(new Point(0,0));
+			startRadius = radius;
+	
+			this.rotate(totalAngle);
+	
+	
+			afterChangeSize({
+				scale: that.getScale(),
+				coordinates: that.getStartCoordinates()
+			});
+	
+			that.paintBox();
+
+			return true;
+		}
+		return false;
+	};
+
+	/**
+	 * Sets the angle of the box to a specific angle.
+	 * 
+	 * @param {Integer} angle
+	 */
+	this.setAngle = function (angle) {
+		if (typeof(angle) == "number" && angle >= -360) {
+			totalAngle = (360 + angle) % 360;
+			this.rotate(totalAngle);
+			this.paintBox();
+			afterChangeAngle({
+				angle: totalAngle,
+				coordinates: that.getStartCoordinates()
+			});
+			return true;
+		}
+		return false;
+	};
+
+
+	//
+	//
+	// VIEW
+	//
+	//
+
+	/**
+	 * Rotates the box by a given degree (0 <= degree < 360), 
+	 * and paints the corner points.
+	 * 
+	 * @param {Integer} degree
+	 */
+	this.rotate = function (degree) {
+		var rotationAngle = (Math.PI * parseFloat(degree))/180;
+		var resizeRatio = radius / startRadius;
+
+		for (var i = 0; i < pointArray.length; i++) {
+			var p = (convertMapToPixel(startPointMapArray[i])).minus(getCenter());
+			var newx = p.x * Math.cos(rotationAngle) + p.y * Math.sin(rotationAngle);
+			var newy = p.x * -Math.sin(rotationAngle) + p.y * Math.cos(rotationAngle);
+			pointArray[i] = (new Point(newx, newy)).times(resizeRatio);
+		}
+		afterChangeAngle({
+			angle: degree,
+			coordinates: this.getStartCoordinates()
+		});
+		this.paintPoints();
+	};
+
+	/**
+	 * Paints the four corner points of the print box.
+	 */
+	this.paintPoints = function () {
+
+		switchActiveCanvas();
+		var c = center;
+		for (var i = 0; i < pointArray.length; i++) {
+			activeCanvas.fillEllipse(
+				pointArray[i].x + c.x - 4,
+				pointArray[i].y + c.y - 4,
+				8,
+				8
+			);
+		}
+		activeCanvas.paint();
+		passiveCanvas.clear();
+	};
+
+	var boxTooBig = function () {
+		if (boxWidth > MAX_BOX_WIDTH_OR_HEIGHT || boxHeight > MAX_BOX_WIDTH_OR_HEIGHT) {
+			return true;
+		}
+		return false;
+	}
+
+	var boxTooSmall = function () {
+		if (boxWidth < MIN_BOX_WIDTH_OR_HEIGHT || boxHeight < MIN_BOX_WIDTH_OR_HEIGHT) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Paints the box itself. Plus the circle.
+	 */
+	this.paintBox = function () {
+		var r = Math.round(0.75 * radius);
+		var c = center;
+		circleCanvas.clear();	
+		if (!boxTooSmall() && !boxTooBig()) {
+			circleCanvas.drawEllipse(c.x-r, c.y-r, 2*r, 2*r);
+		}
+		else {
+			new Mb_warning("The print box is too small or too big. The rotate circle is not shown.");
+		}
+		circleCanvas.paint();
+
+		boxCanvas.clear();
+		if (!boxTooBig()) {
+			boxCanvas.fillPolygon([
+				pointArray[0].x + c.x,
+				pointArray[1].x + c.x,
+				pointArray[2].x + c.x,
+				pointArray[3].x + c.x
+			], 
+			[
+				pointArray[0].y + c.y,
+				pointArray[1].y + c.y,
+				pointArray[2].y + c.y,
+				pointArray[3].y + c.y
+			]);
+		}
+		else {
+			new Mb_warning("The print box is too big. The box is not filled.");
+		}
+		
+		// frame
+		boxCanvas.setColor(frameColour);	
+		for (var i = 0; i < pointArray.length; i++) {
+			var indexA = i % 4;
+			var a = pointArray[indexA].plus(center);
+			var indexB = (i + 1) % 4;
+			var b = pointArray[indexB].plus(center);
+			boxCanvas.drawLine(a.x, a.y, b.x, b.y);
+		}
+		
+		boxCanvas.setColor(boxColour);	
+		boxCanvas.paint();
+	};
+	
+	/**
+	 * Clears all canvases, to be performed onunload.
+	 */
+	this.destroy = function () {
+		circleCanvas.clear();	
+		boxCanvas.clear();
+		activeCanvas.clear();
+		passiveCanvas.clear();
+		$("#" + this.id).remove();
+	};
+
+	var switchActiveCanvas = function () {
+		if (canvasNr == 1) {
+			canvasNr = 2;
+			activeCanvas = jg[2];
+			passiveCanvas = jg[1];
+		}
+		else {
+			canvasNr = 1;
+			activeCanvas = jg[1];
+			passiveCanvas = jg[2];
+		}
+	};
+
+
+	var $container = $("<div id='" + this.id + "' style='position:relative;top:0px;left:0px;" + 
+		"'></div>");
+		
+	var $superContainer = $("<div id='container_" + this.id + "' style='position:absolute;z-index:1000;'></div>");
+	$superContainer.append($container);
+	//$("#"+map.elementName).append($superContainer);
+	$(map_el).append($superContainer);
+	
+	var canvasName = [
+		this.id + "_canvas_box",
+		this.id + "_canvas_points1",
+		this.id + "_canvas_points2",
+		this.id + "_canvas_circle"
+	];
+
+	var jg = [];
+	
+	var canvasNr = 1;
+
+	for (var i = 0; i < canvasName.length; i++) {
+		$container.append(
+			$("<div id='" + canvasName[i] + "'></div>")
+		);
+		jg[i] = new jsGraphics(canvasName[i]);
+	}
+
+	$circleCanvas = $("#" + canvasName[3]);
+	$pointCanvas = $("#" + canvasName[1] +  ", #" + canvasName[2]);
+	$boxCanvas = $("#" + canvasName[0]);
+	$boxCanvas.css({
+		"opacity" : opacity, 
+		"filter" : "alpha(opacity=" + (opacity * 100) + ")"
+	});
+		
+	var boxCanvas = jg[0];
+	boxCanvas.setColor(boxColour);	
+	var activeCanvas = jg[1];
+	activeCanvas.setColor(pointColour);
+	var passiveCanvas = jg[2];
+	passiveCanvas.setColor(pointColour);
+	var circleCanvas = jg[3];
+	circleCanvas.setColor(circleColour);
+	circleCanvas.setStroke(circleWidth);	
+
+	var mouseMoveStart = [];	
+
+	var radius = 0;
+	var startRadius = 0;
+
+	// "constructor" functions
+	initBehaviour();
+
+	this.setScale(scale);
+	mb_registerPanSubElement($superContainer.get(0).id);
+
+}
\ No newline at end of file



More information about the Mapbender_commits mailing list