[Mapbender-commits] r8819 - in trunk/mapbender/http: css plugins widgets

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Wed May 7 01:47:30 PDT 2014


Author: hwbllmnn
Date: 2014-05-07 01:47:30 -0700 (Wed, 07 May 2014)
New Revision: 8819

Added:
   trunk/mapbender/http/plugins/mb_digitize_widget.php
   trunk/mapbender/http/widgets/w_digitize.js
Modified:
   trunk/mapbender/http/css/kmltree.css
   trunk/mapbender/http/plugins/kmlTree.js
Log:
duplicated measure module as new kml digitizer

Modified: trunk/mapbender/http/css/kmltree.css
===================================================================
--- trunk/mapbender/http/css/kmltree.css	2014-05-07 08:45:03 UTC (rev 8818)
+++ trunk/mapbender/http/css/kmltree.css	2014-05-07 08:47:30 UTC (rev 8819)
@@ -13,7 +13,7 @@
 /*	background-image: url("http://localhost:8888/vertical_dots.png");*/
 	background-repeat: repeat-y	;
 	background-position: 20px;
-	
+
 }
 ul.kmlTree, ul.kmlTree ul {
 	list-style-type: none;
@@ -100,6 +100,18 @@
 	background-position: 0 0;
 }
 
+ul.kmlTree li button.digitize-layer {
+    background-image: url('../img/button_digitize/polygon_off.png');
+    background-repeat: no-repeat;
+    background-position: 0 0;
+    width: 28px;
+    height: 27px;
+}
+
+ul.kmlTree li button.digitize-layer.active {
+    background-image: url('../img/button_digitize/polygon_on.png');
+}
+
 ul.kmlTree li.open, ul.kmlTree li.closed {
 /*	background-image: url("http://localhost:8888/vertical_dots.png");*/
 	background-repeat: repeat-x	;

Modified: trunk/mapbender/http/plugins/kmlTree.js
===================================================================
--- trunk/mapbender/http/plugins/kmlTree.js	2014-05-07 08:45:03 UTC (rev 8818)
+++ trunk/mapbender/http/plugins/kmlTree.js	2014-05-07 08:47:30 UTC (rev 8819)
@@ -3,23 +3,23 @@
   *
   * Description:
   * Module to load KML temporary in a tree
-  * 
+  *
   * Files:
   *  - mapbender/http/plugins/kmlTree.js
   *  - mapebnder/lib/mb.ui.displayKmlFeatures.js
   *  - mapbender/http/css/kmltree.css
   *
   * 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, 
+  * > 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('<app_id>',
   * > 'kmlTree',2,1,'Displays KML on the map','KML','ul','','',1,1,200,200,NULL ,
   * > 'visibility:visible','','ul','../plugins/kmlTree.js','../../lib/mb.ui.displayKmlFeatures.js',
   * > 'mapframe1','jq_ui_widget','http://www.mapbender.org/Loadkml');
-  * > 
+  * >
   * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui', 'kmlTree',
   * > 'buffer', '100', '' ,'var');
-  * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) 
+  * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
   * > VALUES('gui', 'kmlTree', 'styles', '../css/kmltree.css', '' ,'file/css');
   *
   * Help:
@@ -27,12 +27,12 @@
   *
   * Maintainer:
   * http://www.mapbender.org/User:Armin_Retterath
-  * 
   *
+  *
   * License:
   * Copyright (c) 2009, Open Source Geospatial Foundation
-  * This program is dual licensed under the GNU General Public License 
-  * and Simplified BSD license.  
+  * 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
   */
 
@@ -58,22 +58,22 @@
 	$KMLfolder.find("a").after($addButton);
 
 
-	
-	
+
+
 	o.$target.bind('kml:loaded',function(e,obj){
 		//console.log(obj);
 		var checked = obj.display ? 'checked="checked"':'';
 
 
 		title = obj.url;
-		abbrevTitle = title.length < 20 ?  title : title.substr(0,17) + "...";
-		$kmlEntry = $('<li title="'+ title +'" class="open"><button class="toggle" name="toggle" value="toggle" ></button> <input type="checkbox"'+checked  +'/><button class="remove" name="remove" value="remove" ></button><a href="#">'+abbrevTitle+'</a></li>');
+	    abbrevTitle = title.length < 20 ?  title : title.substr(0,17) + "...";
+            $kmlEntry = $('<li title="'+ title +'" class="open"><button class="toggle" name="toggle" value="toggle" ></button> <input type="checkbox"'+checked  +'/><button class="digitize-layer" name="digitize-layer" value="digitize-layer"></button><button class="remove" name="remove" value="remove" ></button><a href="#">'+abbrevTitle+'</a></li>');
 		$KMLfolder.children("ul").append($kmlEntry);
 		$kmlEntry.find("a").bind("click",(function(jsonFeatureCollection){return function(){
 				var map = o.$target.mapbender();
 				var g = new GeometryArray();
 				g.importGeoJSON(jsonFeatureCollection,false);
-		
+
 				var bbox = g.getBBox();
 				var bufferFloat = parseFloat(o.buffer);
 				var buffer = new Point(bufferFloat,bufferFloat);
@@ -85,10 +85,10 @@
 				  new Mapbender.Extent(bbox[0], bbox[1])
 				);
 				map.setMapRequest();
-	
+
 				};
 		})(obj.data));
-		
+
 		$featureList = $("<ul />");
 		$kmlEntry.append($featureList);
 		for(var i = 0;i < obj.data.features.length;i++){
@@ -99,12 +99,12 @@
 			$featureList.append($feature);
 			title = obj.data.features[i].properties.name;
 			$feature.bind('click',(function(jsonFeature){return function(){
-				
+
 				var map = o.$target.mapbender();
 				var g = new GeometryArray();
 				g.importGeoJSON(jsonFeature,false);
 				var feature = g.get(0);
-		
+
 				var bbox = feature.getBBox();
 				var bufferFloat = parseFloat(o.buffer);
 				var buffer = new Point(bufferFloat,bufferFloat);
@@ -116,16 +116,16 @@
 				  new Mapbender.Extent(bbox[0], bbox[1])
 				);
 				map.setMapRequest();
-	
+
 				};
 			})(obj.data.features[i]));
-			
+
 			$feature.bind('mouseout',(function(jsonFeature){return function(){
 				var map = o.$target.mapbender();
 				var g = new GeometryArray();
 				g.importGeoJSON(jsonFeature,false);
 				var feature = g.get(0);
-				
+
 				if(feature.geomType != "point"){
 					var me = $kmlTree.mapbender();
 					me.resultHighlight.clean();
@@ -137,26 +137,30 @@
 				var g = new GeometryArray();
 				g.importGeoJSON(jsonFeature,false);
 				var feature = g.get(0);
-			
+
 				if(feature.geomType != "point"){
 					var me = $kmlTree.mapbender();
 					feature = feature.getBBox4();
 					me.resultHighlight = new Highlight(
 							[o.target],
-							"KmlTreeHighlight", 
-							{"position":"absolute", "top":"0px", "left":"0px", "z-index":100}, 
+							"KmlTreeHighlight",
+							{"position":"absolute", "top":"0px", "left":"0px", "z-index":100},
 							2);
-				
+
 					me.resultHighlight.add(feature, "#00ff00");
 					me.resultHighlight.paint();
 				}
 				else if(feature.geomType == "point"){
 
 				}
-	
+
 				};
 			})(obj.data.features[i]));
 
+        $('button.digitize-layer', $kmlEntry).bind('click', function() {
+            $(this).toggleClass('active');
+        });
+
         $('#kmlTree > li > ul').sortable({
             update: function() {
                 var kml = $('#mapframe1').data('kml');
@@ -178,7 +182,7 @@
 				o.$target.kml('hide',obj.url);
 			}
 		});
-		
+
 		$("button.toggle",$kmlEntry).bind('click', function(){
 			if($(this).parent().hasClass("open")){
 				$(this).parent().removeClass("open");
@@ -195,7 +199,7 @@
 			$(this).parent().remove();
 		});
 
-		
+
 	});
 
 };

Added: trunk/mapbender/http/plugins/mb_digitize_widget.php
===================================================================
--- trunk/mapbender/http/plugins/mb_digitize_widget.php	                        (rev 0)
+++ trunk/mapbender/http/plugins/mb_digitize_widget.php	2014-05-07 08:47:30 UTC (rev 8819)
@@ -0,0 +1,331 @@
+/**
+ * Package: digitize_widget
+ *
+ * Description:
+ * Digitize module with jQuery UI widget factory and RaphaelJS
+ *
+ * Files:
+ *  - http/plugins/mb_digitize_widget.js
+ *  - http/widgets/w_digitize.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('<appId>','digitize_widget',2,1,'Digitize',
+ * > 'Digitize distance','img','../img/button_blue_red/digitize_off.png','',
+ * > NULL ,NULL ,NULL ,NULL ,1,'','','','../plugins/mb_digitize_widget.php',
+ * > '../widgets/w_digitize.js,../extensions/RaphaelJS/raphael-1.4.7.min.js',
+ * > 'mapframe1','jq_ui_dialog,jq_ui_widget','http://www.mapbender.org/index.php/Digitize');
+ * >
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'lineStrokeDefault', '#808080', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'lineStrokeSnapped', '#F30', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'lineStrokeWidthDefault', '2', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'lineStrokeWidthSnapped', '2', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'digitizePointDiameter', '7', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'opacity', '0.5', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'pointFillDefault', '#B2DFEE', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'pointFillSnapped', '#FF0000', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'pointStrokeDefault', '#FF0000', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'pointStrokeSnapped', '#FF0000', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'pointStrokeWidthDefault', '2', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'polygonFillDefault', '#B2DFEE', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'polygonFillSnapped', '#FC3', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'polygonStrokeWidthDefault', '1', '' ,'var');
+ * > INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type)
+ * > VALUES('<app_id>', 'digitize_widget', 'polygonStrokeWidthSnapped', '3', '' ,'var');
+ *
+ * Help:
+ * http://www.mapbender.org/Digitize_widget
+ *
+ * Maintainer:
+ * http://www.mapbender.org/User:Christoph_Baudson
+ *
+ * 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 $digitize = $(this);
+
+var DigitizeApi = function (o) {
+
+	var digitizeDialog,
+		button,
+		that = this,
+		inProgress = false,
+		title = o.title,
+		defaultHtml = "<div title='" + title + "'>" +
+			"<div class='mb-digitize-text'><?php
+				echo nl2br(htmlentities(_mb("Click in the map to start measuring."), ENT_QUOTES, "UTF-8"));
+			?></div></div>",
+		informationHtml =
+			"<div><?php
+				echo nl2br(htmlentities(_mb("Last point: "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-clicked-point' /></div>" +
+			"<div><?php
+				echo nl2br(htmlentities(_mb("Current point: "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-current-point' /></div>" +
+			"<div><?php
+				echo nl2br(htmlentities(_mb("Distance (to last point): "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-distance-last' />  <span class='mb-digitize-distance-last-unit' /></div>" +
+			"<div><?php
+				echo nl2br(htmlentities(_mb("Distance (total): "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-distance-total' /> <span class='mb-digitize-distance-total-unit' /></div>" +
+			"<div><?php
+				echo nl2br(htmlentities(_mb("Perimeter: "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-perimeter' /> <span class='mb-digitize-perimeter-unit' /></div>" +
+			"<div><?php
+				echo nl2br(htmlentities(_mb("Area: "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-area' /> <span class='mb-digitize-area-unit' /></div>" +
+                        "<div><?php
+				echo nl2br(htmlentities(_mb("Angle: "), ENT_QUOTES, "UTF-8"));
+			?><span class='mb-digitize-angle' /> <span class='mb-digitize-angle-unit' /></div>";
+
+	var hideDigitizeData = function () {
+		digitizeDialog.find(".mb-digitize-clicked-point").parent().hide();
+		digitizeDialog.find(".mb-digitize-current-point").parent().hide();
+		digitizeDialog.find(".mb-digitize-distance-last").parent().hide();
+		digitizeDialog.find(".mb-digitize-distance-total").parent().hide();
+		digitizeDialog.find(".mb-digitize-perimeter").parent().hide();
+		digitizeDialog.find(".mb-digitize-area").parent().hide();
+                digitizeDialog.find(".mb-digitize-angle").parent().hide();
+
+	};
+
+	var changeDialogContent = function () {
+		digitizeDialog.html(informationHtml);
+		hideDigitizeData();
+
+		o.$target.unbind("click", changeDialogContent);
+	};
+
+	var create = function () {
+		//
+		// Initialise digitize dialog
+		//
+		digitizeDialog = $(defaultHtml);
+		digitizeDialog.dialog({
+			autoOpen: false,
+			position: [o.$target.offset().left, o.$target.offset().top]
+		}).bind("dialogclose", function () {
+			button.stop();
+			that.destroy();
+		});
+
+		//
+		// Initialise button
+		//
+		button = new Mapbender.Button({
+			domElement: $digitize.get(0),
+			over: o.src.replace(/_off/, "_over"),
+			on: o.src.replace(/_off/, "_on"),
+			off: o.src,
+			name: o.id,
+			go: that.activate,
+			stop: that.deactivate
+		});
+	};
+
+	var updateCurrentPoint = function (evt, data) {
+		if (data.pos) {
+			var p = data.pos;
+			digitizeDialog.find(".mb-digitize-current-point").text(
+				p.pos.x + " " + p.pos.y
+			).parent().show();
+		}
+	};
+
+	var updateClickedPoint = function (evt, data) {
+		if (data.pos) {
+			var p = data.pos;
+			digitizeDialog.find(".mb-digitize-clicked-point").text(
+				p.pos.x + " " + p.pos.y
+			).parent().show();
+
+
+                        var digitizedX = $('input[name="digitized_x_values"]').val();
+                        if(digitizedX != "") {
+                            digitizedX += ",";
+		}
+                        digitizedX += p.pos.x;
+                        $('input[name="digitized_x_values"]').val(digitizedX)
+
+                        var digitizedY = $('input[name="digitized_y_values"]').val();
+                        if(digitizedY != "") {
+                            digitizedY += ",";
+                        }
+                        digitizedY += p.pos.y;
+                        $('input[name="digitized_y_values"]').val(digitizedY);
+		}
+	};
+
+	var updateCurrentDistance = function (evt, data) {
+		if (data.currentDistance) {
+			var lastDistanceUnit = "m";
+			var displayDistance = data.currentDistance;
+			if (displayDistance > 10000){
+				displayDistance /= 1000;
+				lastDistanceUnit = "km";
+			}
+			digitizeDialog.find(".mb-digitize-distance-last-unit").html(lastDistanceUnit);
+			digitizeDialog.find(".mb-digitize-distance-last").text(Math.round(displayDistance*10)/10).parent().show();
+		}
+	};
+
+	var updateTotalDistance = function (evt, data) {
+		if (data.totalDistance) {
+			var totalDistanceUnit = "m";
+			var displayTotalDistance = data.totalDistance;
+			if (displayTotalDistance > 10000){
+				displayTotalDistance = displayTotalDistance / 1000;
+				totalDistanceUnit = "km";
+			}
+			digitizeDialog.find(".mb-digitize-distance-total-unit").html(totalDistanceUnit);
+			digitizeDialog.find(".mb-digitize-distance-total").text(Math.round(displayTotalDistance*10)/10).parent().show();
+		}
+		else {
+			digitizeDialog.find(".mb-digitize-distance-total").parent().hide();
+		}
+	};
+
+	var updatePerimeter = function (evt, data) {
+		if (data.perimeter) {
+			var unit = "m";
+			var displayPerimeter = data.perimeter;
+			if (displayPerimeter > 10000){
+				displayPerimeter = displayPerimeter / 1000;
+				unit = "km";
+			}
+			digitizeDialog.find(".mb-digitize-perimeter-unit").html(unit);
+			digitizeDialog.find(".mb-digitize-perimeter").text(Math.round(displayPerimeter*10)/10).parent().show();
+
+		}
+		else {
+			//digitizeDialog.find(".mb-digitize-perimeter").parent().hide();
+		}
+	};
+
+	var updateArea = function (evt, data) {
+		if (data.area) {
+			var areaUnit = "m&sup2;";
+			var area = data.area;
+			if (area > 10000000){
+				area /= 1000000;
+				areaUnit = "km&sup2;";
+			}
+			else if (area > 100000){
+				area /= 10000;
+				areaUnit = "ha";
+			}
+			area = Math.round(area*10)/10;
+
+			digitizeDialog.find(".mb-digitize-area-unit").html(areaUnit);
+			digitizeDialog.find(".mb-digitize-area").text(area).parent().show();
+		}
+		else {
+			digitizeDialog.find(".mb-digitize-area").parent().hide();
+		}
+	};
+
+        var updateAngle = function (evt, data) {
+        	if (data.currentAngle) {
+			var unit = "°";
+			var displayAngle = data.currentAngle;
+                        digitizeDialog.find(".mb-digitize-angle-unit").html(unit);
+			digitizeDialog.find(".mb-digitize-angle").text(Math.round(displayAngle*10)/10).parent().show();
+
+		}
+		else {
+			//digitizeDialog.find(".mb-digitize-angle").parent().hide();
+		}
+	};
+
+	var updateView = function (evt, data) {
+		updateCurrentPoint(evt, data);
+		updateCurrentDistance(evt, data);
+		updateTotalDistance(evt, data);
+		updateArea(evt, data);
+		updatePerimeter(evt, data);
+                updateAngle(evt, data);
+	};
+
+	var finishDigitize = function () {
+		inProgress = false;
+		that.deactivate();
+	};
+
+	var reinitializeDigitize = function () {
+		inProgress = false;
+		that.deactivate();
+		that.activate();
+	};
+
+	this.activate = function () {
+                //remove digitized x and y values from print dialog
+                $('input[name="digitized_x_values"]').val("");
+                $('input[name="digitized_y_values"]').val("");
+
+		if (o.$target.size() > 0) {
+			o.$target
+				.mb_digitize(o)
+				.bind("mb_digitizeupdate", updateView)
+				.bind("mb_digitizepointadded", updateClickedPoint)
+				.bind("mb_digitizelastpointadded", finishDigitize)
+				.bind("mb_digitizereinitialize", reinitializeDigitize)
+				.bind("click", changeDialogContent);
+		}
+		if (!inProgress) {
+			inProgress = true;
+			digitizeDialog.html(defaultHtml);
+		}
+
+		digitizeDialog.dialog("open");
+	};
+
+	this.destroy = function () {
+		if (o.$target.size() > 0) {
+			o.$target.mb_digitize("destroy")
+				.unbind("mb_digitizeupdate", updateView)
+				.unbind("mb_digitizepointadded", updateClickedPoint)
+				.unbind("mb_digitizelastpointadded", finishDigitize)
+				.unbind("mb_digitizereinitialize", reinitializeDigitize);
+		}
+		hideDigitizeData();
+
+		if (digitizeDialog.dialog("isOpen")) {
+			digitizeDialog.dialog("close");
+		}
+		digitizeDialog.html(defaultHtml);
+
+                //remove digitized x and y values from print dialog
+                $('input[name="digitized_x_values"]').val("");
+                $('input[name="digitized_y_values"]').val("");
+	};
+
+	this.deactivate = function () {
+		if (o.$target.size() > 0) {
+			o.$target.mb_digitize("deactivate");
+		}
+	};
+
+	create();
+};
+
+$digitize.mapbender(new DigitizeApi(options));

Added: trunk/mapbender/http/widgets/w_digitize.js
===================================================================
--- trunk/mapbender/http/widgets/w_digitize.js	                        (rev 0)
+++ trunk/mapbender/http/widgets/w_digitize.js	2014-05-07 08:47:30 UTC (rev 8819)
@@ -0,0 +1,541 @@
+$.widget("mapbender.mb_digitize", {
+	options: {
+		opacity: 0.6,
+		digitizePointDiameter: 10,
+		polygonFillSnapped: "#FC3",
+		polygonFillDefault: "#FFF",
+		polygonStrokeWidthDefault: 1,
+		polygonStrokeWidthSnapped: 5,
+		lineStrokeDefault: "#C9F",
+		lineStrokeSnapped: "#F30",
+		lineStrokeWidthDefault: 3,
+		lineStrokeWidthSnapped: 5,
+		pointFillSnapped: "#F90",
+		pointFillDefault: "#CCF",
+                pointStrokeDefault: "#FC3",
+                pointStrokeSnapped: "#F30",
+                pointStrokeWidthDefault: 2
+	},
+	_digitizePoints: [],
+	_map: undefined,
+	_srs: undefined,
+	_currentDistance: 0,
+        _currentAngle: 0,
+	_totalDistance: 0,
+	_polygonIsInvalid: false,
+	_currentPolygonIsInvalid: false,
+	_canvas: undefined,
+	_isPolygon: function (pos) {
+
+		var len = this._digitizePoints.length;
+
+		var max = pos ? len - 1 : len - 2;
+
+		if (pos && len < 2 || !pos && len < 3) {
+			return false;
+		}
+
+		var posLocal = pos ? pos : this._digitizePoints[len - 1];
+
+		var p0 = this._digitizePoints[0].pos;
+		var pn = this._digitizePoints[max].pos;
+		for (var i = 0; i < max; i++)  {
+			var pi = this._digitizePoints[i].pos;
+			var pj = this._digitizePoints[i + 1].pos;
+
+			if (i > 0 && this._lineIntersect(
+				pi.x, pi.y, pj.x, pj.y,
+				p0.x, p0.y, posLocal.x, posLocal.y)
+			) {
+				return false;
+			}
+			if (this._lineIntersect(
+				pi.x, pi.y, pj.x, pj.y,
+				pn.x, pn.y, posLocal.x, posLocal.y)
+			) {
+				this._currentPolygonIsInvalid = true;
+				return false;
+			}
+		}
+		this._currentPolygonIsInvalid = false;
+		return true;
+	},
+	_lineIntersect: function ( x1, y1, x2, y2, x3, y3, x4, y4 ) {
+		var isOnSegment = function (xi, yi, xj, yj, xk, yk) {
+			// changed <= to < so the segments are allowed to touch!
+			 return (xi < xk || xj < xk) &&
+					(xk < xi || xk < xj) &&
+			        (yi < yk || yj < yk) &&
+					(yk < yi || xk < yj);
+		};
+
+		var computeDirection = function (xi, yi, xj, yj, xk, yk) {
+			var a = (xk - xi) * (yj - yi);
+			var b = (xj - xi) * (yk - yi);
+			return a < b ? -1 : a > b ? 1 : 0;
+		};
+
+		var e1 = computeDirection(x3, y3, x4, y4, x1, y1);
+		var e2 = computeDirection(x3, y3, x4, y4, x2, y2);
+		var e3 = computeDirection(x1, y1, x2, y2, x3, y3);
+		var e4 = computeDirection(x1, y1, x2, y2, x4, y4);
+		return (((e1 > 0 && e2 < 0) || (e1 < 0 && e2 > 0)) &&
+			((e3 > 0 && e4 < 0) || (e3 < 0 && e4 > 0))) ||
+			(e1 === 0 && isOnSegment(x3, y3, x4, y4, x1, y1)) ||
+			(e2 === 0 && isOnSegment(x3, y3, x4, y4, x2, y2)) ||
+			(e3 === 0 && isOnSegment(x1, y1, x2, y2, x3, y3)) ||
+			(e4 === 0 && isOnSegment(x1, y1, x2, y2, x4, y4));
+	},
+	_toRad: function (deg) {
+		return deg * Math.PI/180;
+	},
+	//
+	// calculate area
+	//
+	_calculateAreaMetric: function (pos) {
+		if (this._digitizePoints.length < 2) {
+			return null;
+		}
+		this._digitizePoints.push(pos);
+		var part, area = 0;
+		var p0 = this._digitizePoints[0].pos, pi, pj;
+		for (var i = 0; i < this._digitizePoints.length - 1; i++)  {
+			pi = this._digitizePoints[i].pos;
+			pj = this._digitizePoints[i + 1].pos;
+			part = (pi.y + pj.y) * (pi.x - pj.x) / 2;
+			area += part;
+		}
+		part = (pj.y + p0.y) * (pj.x - p0.x) / 2;
+		area += part;
+		this._digitizePoints.pop();
+		return Math.abs(area);
+	},
+	_calculateAreaGeographic: function (pos) {
+		if (this._digitizePoints.length < 2) {
+			return null;
+		}
+
+		// add current point and first point
+		this._digitizePoints.push({
+			pos: pos
+		});
+		this._digitizePoints.push(this._digitizePoints[0]);
+
+        var area = 0.0;
+        var p1, p2;
+        for(var i=0; i<this._digitizePoints.length-1; i++) {
+            p1 = this._digitizePoints[i].pos;
+            p2 = this._digitizePoints[i+1].pos;
+			var c = this._toRad(p2.x - p1.x) *
+                    (2 + Math.sin(toRad(p1.y)) +
+                    Math.sin(toRad(p2.y)));
+            area += c;
+        }
+        area = area * 6378137.0 * 6378137.0 / 2.0;
+
+		// remove current point and first point
+		this._digitizePoints.pop();
+		this._digitizePoints.pop();
+
+		return Math.abs(area);
+	},
+	_calculateArea: function (pos) {
+		switch (this._map.getSrs()) {
+			case "EPSG:4326":
+				return this._calculateAreaGeographic(pos);
+			default:
+				return this._calculateAreaMetric(pos);
+		}
+		return null;
+	},
+	//
+	// calculate distance
+	//
+	_calculateDistanceGeographic: function (a, b) {
+		var lon_from = this._toRad(a.x);
+		var lat_from = this._toRad(a.y);
+		var lon_to = this._toRad(b.x);
+		var lat_to = this._toRad(b.y);
+		return Math.abs(6371229 * Math.acos(
+			Math.sin(lat_from) * Math.sin(lat_to) +
+			Math.cos(lat_from) * Math.cos(lat_to) *
+			Math.cos(lon_from - lon_to)
+		));
+	},
+	_calculateDistanceMetric: function (a, b) {
+		return Math.abs(Math.sqrt(
+			Math.pow(Math.abs(b.x - a.x), 2) +
+			Math.pow(Math.abs(b.y - a.y), 2)
+		));
+	},
+	_calculateDistance: function (a, b) {
+		if (a !== null && b !== null) {
+			switch (this._map.getSrs()) {
+				case "EPSG:4326":
+					return this._calculateDistanceGeographic(a, b);
+				default:
+					return this._calculateDistanceMetric(a, b);
+			}
+		}
+		return null;
+	},
+        _calculateAngle: function (a, b, c) {
+		if (a !== null && b !== null && c !== null) {
+                        function angleAt(a,b,c){
+                            var vectorAB = [b.x- a.x,b.y-a.y];
+                            //var vectorBC = [c.x- b.x,c.y-b.y];
+                            var vectorBC = [b.x- c.x,b.y-c.y];
+                            var cosalpha = scalarProduct(vectorAB,vectorBC)/
+                                (vectorlen(vectorAB)*vectorlen(vectorBC));
+
+                            var acosalpha = Math.acos(cosalpha);
+                            return (acosalpha/Math.PI)*180;
+                        }
+
+                        function scalarProduct(va,vb){
+                                return va[0]*vb[0] + va[1]*vb[1];
+                        }
+
+                        function vectorlen(v) {
+                                return  Math.sqrt(v[0]*v[0] + v[1]*v[1]);
+                        }
+
+                        var angle = angleAt(a,b,c);
+                        return angle;
+		}
+		return null;
+	},
+	_isPointSnapped: function (p1, p2) {
+		return p1.dist(p2) <= this.options.digitizePointDiameter/2;
+	},
+	_isFirstPointSnapped: function (p) {
+		if (this._digitizePoints.length > 0 ) {
+			var pos0 = this._digitizePoints[0].mousePos;
+			if (this._digitizePoints.length > 2 && this._isPointSnapped(pos0, p)) {
+				return true;
+			}
+		}
+		return false;
+	},
+	_isLastPointSnapped: function (p) {
+		if (this._digitizePoints.length > 0 ) {
+			var posn = this._digitizePoints[this._digitizePoints.length - 1].mousePos;
+			if (this._digitizePoints.length > 1 && this._isPointSnapped(posn, p)) {
+				return true;
+			}
+		}
+		return false;
+	},
+	_draw: function (pos, drawOptions) {
+		this._canvas.clear();
+
+		var str_path = "";
+
+		if (pos && drawOptions && !drawOptions.highlightFirst) {
+			this._digitizePoints.push(pos);
+		}
+
+		var len = this._digitizePoints.length;
+		if (len > 0) {
+			for (var k=0; k < len; k++) {
+				var pk = this._digitizePoints[k].pos;
+				var q = this._digitizePoints[k].mousePos;
+
+				str_path += (k === 0) ? 'M' : 'L';
+				str_path += q.x + ' ' + q.y;
+
+				if (drawOptions.highlightFirst && k === len - 1) {
+					var p0 = this._digitizePoints[0].mousePos;
+					str_path += 'L' + p0.x + ' ' + p0.y;
+
+				}
+				if (drawOptions && drawOptions.highlightLast && k === len - 1) {
+					continue;
+				}
+
+				if (drawOptions && drawOptions.drawPoints &&
+					(k === 0 && !this._polygonIsInvalid || k >= len - 2 && !drawOptions.highlightFirst)) {
+
+					var circle = this._canvas.circle(q.x, q.y, this.options.digitizePointDiameter);
+
+					if (k === 0) {
+						circle.attr({
+							fill: drawOptions && drawOptions.highlightFirst ?
+								this.options.pointFillSnapped : this.options.pointFillDefault,
+                                                        "fill-opacity": this.options.opacity,
+							stroke: drawOptions.highlightFirst || drawOptions.highlightLast ?
+                                                                this.options.pointStrokeSnapped: this.options.pointStrokeDefault,
+                                                        "stroke-width": this.options.pointStrokeWidthDefault
+						});
+					}
+					else {
+						circle.attr({
+							fill: drawOptions && drawOptions.highlightLast && k === len - 2 ?
+								this.options.pointFillSnapped : this.options.pointFillDefault,
+                                                        "fill-opacity": this.options.opacity,
+							stroke: drawOptions.highlightFirst || drawOptions.highlightLast ?
+                                                                this.options.pointStrokeSnapped: this.options.pointStrokeDefault,
+                                                        "stroke-width": this.options.pointStrokeWidthDefault
+						});
+					}
+				}
+			}
+		}
+		if (pos && drawOptions && !drawOptions.highlightFirst) {
+			this._digitizePoints.pop();
+		}
+
+
+		if (this._isPolygon(this._digitizePoints, pos) && drawOptions && !drawOptions.highlightLast && !this.polygonIsInvalid) {
+			var poly = this._canvas.path(str_path + 'Z');
+			poly.attr({
+				fill: drawOptions.highlightFirst ?
+					this.options.polygonFillSnapped : this.options.polygonFillDefault,
+				stroke: drawOptions.highlightFirst || drawOptions.highlightLast ?
+					this.options.lineStrokeSnapped: this.options.lineStrokeDefault,
+				"stroke-width": drawOptions.highlightFirst ?
+					this.options.polygonStrokeWidthSnapped : this.options.polygonStrokeWidthDefault,
+				opacity: this.options.opacity
+			});
+		}
+
+		var line = this._canvas.path(str_path);
+		line.attr({
+			stroke: drawOptions && (drawOptions.highlightFirst || drawOptions.highlightLast) ?
+				this.options.lineStrokeSnapped : this.options.lineStrokeDefault,
+			"stroke-width": drawOptions && drawOptions.highlightLast ?
+				this.options.lineStrokeWidthSnapped : this.options.lineStrokeWidthDefault
+		});
+		line.toFront();
+	},
+	_digitize: function (e) {
+		var mousePos = this._map.getMousePosition(e);
+		var firstPointSnapped = this._isFirstPointSnapped(mousePos)
+			&& !this._polygonIsInvalid;
+		var lastPointSnapped = this._isLastPointSnapped(mousePos);
+
+		var digitizeData = {
+			pos: {
+				mousePos: mousePos,
+				pos: firstPointSnapped ?
+					this._digitizePoints[0].pos : lastPointSnapped ?
+						this._digitizePoints[this._digitizePoints.length - 1].pos :
+						this._map.convertPixelToReal(mousePos)
+			}
+		};
+
+		//
+		// calculate distance
+		//
+		var len = this._digitizePoints.length;
+		var previousPoint = len > 0 ?
+			this._digitizePoints[len - 1].pos : null;
+
+		this._currentDistance = this._calculateDistance(
+			previousPoint,
+			digitizeData.pos.pos
+		);
+
+		//
+		// calculate total distance and perimeter
+		//
+		if (len > 0) {
+			digitizeData.currentDistance = this._currentDistance;
+			this._totalDistance = this._currentDistance;
+
+			if (!firstPointSnapped) {
+				digitizeData.totalDistance = this._totalDistance ;
+			}
+
+			if (len > 1) {
+				this._totalDistance = this._digitizePoints[len - 1].totalDistance + this._currentDistance;
+				if (!firstPointSnapped) {
+					digitizeData.totalDistance = this._totalDistance;
+				}
+				if (!lastPointSnapped) {
+					digitizeData.perimeter = digitizeData.totalDistance + this._calculateDistance(
+						this._digitizePoints[0].pos,
+						digitizeData.pos.pos
+					);
+				}
+
+                                this._currentAngle = this._calculateAngle(
+                                    this._digitizePoints[len-2].pos,
+                                    previousPoint,
+                                    digitizeData.pos.pos
+                                );
+                                digitizeData.currentAngle  = this._currentAngle;
+			}
+		}
+
+		//
+		// calculate area
+		//
+		if (this._isPolygon(this._digitizePoints, digitizeData.pos) && !this._polygonIsInvalid) {
+			this._currentArea = this._calculateArea(digitizeData.pos);
+			if (!lastPointSnapped) {
+				digitizeData.area = this._currentArea;
+			}
+		}
+
+		this._trigger("update", null, digitizeData);
+
+		this._draw(digitizeData.pos, {
+			highlightFirst: firstPointSnapped,
+			highlightLast: lastPointSnapped,
+			drawPoints: true
+		});
+	},
+	_reinitialize: function (e) {
+		this.element
+			.unbind("click", $.proxy(this, "_reinitialize"))
+		this._trigger("reinitialize", e);
+		return false;
+	},
+	_addLastPoint: function (e) {
+		this._trigger("lastpointadded", e);
+
+		this.element.unbind("click", this._addPoint)
+			.unbind("mousemove", this._digitize)
+			.css("cursor", "auto")
+			.bind("click", $.proxy(this, "_reinitialize"));
+	},
+	_addPoint: function (e) {
+		var mousePos = this._map.getMousePosition(e);
+
+		var len = this._digitizePoints.length;
+
+		var data = {
+			pos: {
+				mousePos: mousePos,
+				pos: this._map.convertPixelToReal(mousePos)
+			}
+		};
+
+		if (this._totalDistance) {
+			data.pos.totalDistance = this._totalDistance;
+		}
+
+		this._trigger("pointadded", e, data);
+
+		var firstPointSnapped = this._isFirstPointSnapped(mousePos);
+		var lastPointSnapped = this._isLastPointSnapped(mousePos);
+
+		this._isPolygon(this._digitizePoints, data.pos);
+		if (this._currentPolygonIsInvalid) {
+			this._polygonIsInvalid = true;
+		}
+		this._currentPolygonIsInvalid = false;
+
+		if (lastPointSnapped || firstPointSnapped) {
+			this._draw(data.pos, {
+				highlightFirst: firstPointSnapped,
+				highlightLast: lastPointSnapped,
+				drawPoints: false
+			});
+			this._addLastPoint(e);
+			this._digitizePoints.closedPolygon = firstPointSnapped;
+			this._digitizePoints.closedLine = lastPointSnapped;
+		}
+		else {
+			this._digitizePoints.push(data.pos);
+
+			this._totalDistance += this._currentDistance;
+			this._currentDistance = 0;
+
+			lastPointSnapped = this._isLastPointSnapped(mousePos);
+			this._draw(data.pos, {
+				highlightFirst: firstPointSnapped,
+				highlightLast: lastPointSnapped,
+				drawPoints: true
+			});
+		}
+		return true;
+	},
+	_redraw: function () {
+		if (!$(this.element).data("mb_digitize")) {
+			return;
+		}
+		var len = this._digitizePoints.length;
+		if (len === 0) {
+			return;
+		}
+		for (var i = 0; i < len; i++) {
+			var p = this._digitizePoints[i];
+			p.mousePos = this._map.convertRealToPixel(p.pos);
+		}
+		if (this._digitizePoints.closedPolygon) {
+			this._draw(undefined, {
+				highlightFirst: true,
+				highlightLast: false,
+				drawPoints: false
+			});
+		}
+		else if (this._digitizePoints.closedLine) {
+			this._draw(undefined, {
+				highlightFirst: false,
+				highlightLast: true,
+				drawPoints: false
+			});
+		}
+		else {
+			this._draw(undefined, {
+				highlightFirst: false,
+				highlightLast: false,
+				drawPoints: false
+			});
+		}
+	},
+	_init: function () {
+		if (this._digitizePoints.closedLine || this._digitizePoints.closedPolygon) {
+			this._digitizePoints = [];
+			this._canvas.clear();
+		}
+		this.element
+			.bind("click", $.proxy(this, "_addPoint"))
+			.bind("mousemove", $.proxy(this, "_digitize"))
+			.css("cursor", "crosshair");
+
+	},
+	_create: function () {
+		this._digitizePoints = [];
+
+		// ":maps" is a Mapbender selector which
+		// checks if an element is a Mapbender map
+		this.element = this.element.filter(":maps");
+
+		if (!this.element.jquery || this.element.size() === 0) {
+			$.error("This widget must be applied to a Mapbender map.");
+		}
+
+		this._map = this.element.mapbender();
+		this._map.events.afterMapRequest.register($.proxy(this._redraw, this));
+		this._srs = this._map.getSrs();
+
+		this._$canvas = $("<div id='digitize_canvas' />").css({
+			"z-index": 1000,
+			"position": "absolute"
+		}).appendTo(this.element);
+		this._canvas = Raphael(this._$canvas.get(0), this._map.getWidth(), this._map.getHeight());
+		mb_registerPanSubElement($(this._canvas.canvas).parent().get(0));
+	},
+	// the digitized geometry will be available, the events will be deleted
+	deactivate: function () {
+		this.element
+			.unbind("click", this._addPoint)
+			.unbind("mousemove", this._digitize)
+			.unbind("click", this._reinitialize)
+			.css("cursor", "default");
+	},
+	// delete everything
+	destroy: function () {
+		this.deactivate();
+		this._canvas.clear();
+		this._digitizePoints = [];
+		this._$canvas.remove();
+		this._map.events.afterMapRequest.unregister($.proxy(this._redraw, this));
+
+		$.Widget.prototype.destroy.apply(this, arguments); // default destroy
+		$(this.element).data("mb_digitize", null);
+	}
+});



More information about the Mapbender_commits mailing list