[Mapbender-commits] r6604 - trunk/mapbender/http/plugins

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Thu Jul 15 13:17:47 EDT 2010


Author: christoph
Date: 2010-07-15 17:17:47 +0000 (Thu, 15 Jul 2010)
New Revision: 6604

Added:
   trunk/mapbender/http/plugins/mb_measure.js
Log:
new version

Added: trunk/mapbender/http/plugins/mb_measure.js
===================================================================
--- trunk/mapbender/http/plugins/mb_measure.js	                        (rev 0)
+++ trunk/mapbender/http/plugins/mb_measure.js	2010-07-15 17:17:47 UTC (rev 6604)
@@ -0,0 +1,330 @@
+var $measure = $(this);
+
+var MeasureApi = function (o) {
+
+	var measureDialog, 
+		measurePoints = [],
+		button, 
+		canvases = {},
+		that = this,
+		opacity = 0.4,
+		srs;
+	
+	var hideMeasureData = function () {
+		measureDialog.find(".mb-measure-clicked-point").parent().hide();
+		measureDialog.find(".mb-measure-current-point").parent().hide();
+		measureDialog.find(".mb-measure-distance").parent().hide();
+		measureDialog.find(".mb-measure-area").parent().hide();		
+	};
+	
+	var create = function () {
+		//
+		// Initialise measure dialog
+		//
+		
+		var html = "<div>" + 
+			"<p class='mb-measure-text'>Fahren Sie mit der Maus &uuml;ber die Karte, um die Koordinaten anzuzeigen.<br> Klicken Sie, um eine Messung zu starten</p>" + 
+			"<p>Letzter Punkt: <span class='mb-measure-clicked-point' /></p>" + 
+			"<p>Aktuelle Koordinaten: <span class='mb-measure-current-point' /></p>" + 
+			"<p>Distanz: <span class='mb-measure-distance' /> m</p>" + 
+			"<p>Fläche: <span class='mb-measure-area' /> <span class='mb-measure-area-unit' /></p>" + 
+		"</div>";
+		
+		measureDialog = $(html).appendTo(o.$target);
+
+		measureDialog.dialog({
+			autoOpen: false
+		}).bind("dialogclose", function () {
+			button.stop();
+		});
+
+		// Initialise Raphael canvas
+		Mapbender.events.init.register(function () {
+			o.$target.each(function () {
+				var map = $(this).mapbender();
+				var $canvas = $("<div />").css({
+					"z-index": 100,
+					"position": "relative"
+				}).appendTo(this);
+				canvases[map.elementName] = 
+					Raphael($canvas.get(0), map.getWidth(), map.getHeight());
+			});
+		});
+
+		//
+		// Initialise button
+		//
+		button = new Mapbender.Button({
+			domElement: $measure.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 draw = function (map, pos) {
+		var canvas = canvases[map.elementName];
+		canvas.clear();
+		
+		var str_path = "";
+
+		measurePoints.push(pos);
+
+		var len = measurePoints.length;
+		if (len > 0){
+			for (var k=0; k < len; k++) {
+				var pk = measurePoints[k];
+
+				var q = map.convertRealToPixel(pk);
+				if (k === 0) { 
+					str_path += 'M';
+				} 
+				else {
+					str_path += 'L';
+				}
+				str_path += q.x + ' ' + q.y;
+				
+				var circle = canvas.circle(q.x, q.y, 3);
+
+				if (k === 0) { 
+					circle.attr({
+						fill: "#f00", 
+						stroke: "none", 
+						opacity: opacity
+					});
+				}
+				else {
+					circle.attr({
+						fill: "#f00", 
+						stroke: "none", 
+						opacity: opacity
+					});
+				}
+			}
+		}
+		measurePoints.pop();
+		
+		if (isPolygon(measurePoints, pos)) {
+			var poly = canvas.path(str_path + 'Z');
+			poly.attr({
+				fill: "#0f0", 
+				opacity: opacity
+			});
+		}
+
+		var line = canvas.path(str_path);
+		line.attr({
+			stroke: "#00f", 
+			"stroke-width": 2, 
+			opacity: opacity
+		});
+		line.toFront();   
+	};
+
+	var updateCurrentPoint = function (p) {
+		measureDialog.find(".mb-measure-current-point").text(
+			p.x + " " + p.y
+		).parent().show();
+	};
+
+	var updateClickedPoint = function (p) {
+		measureDialog.find(".mb-measure-clicked-point").text(
+			p.x + " " + p.y
+		).parent().show();
+	};
+
+	var updateDistance = function (dist) {
+		if (!dist) {
+			return;
+		}
+		measureDialog.find(".mb-measure-distance").text(Math.abs(dist)).parent().show();
+	};
+
+	var updateArea = function (area) {
+		if (area === null) {
+			return;
+		}
+		var areaUnit = "m&sup2;";
+		if (area > 10000000){
+			area /= 1000000; 
+			areaUnit = "km&sup2;";
+		} 
+		else if (area > 100000){
+			area /= 10000;
+			areaUnit = "ha";
+		} 
+		area = Math.round(area*10)/10;
+
+		measureDialog.find(".mb-measure-area-unit").html(areaUnit);
+		measureDialog.find(".mb-measure-area").text(area).parent().show();
+	};
+
+	var calculateDistanceGeographic = function (a, b) {
+		var lon_from = (a.x * Math.PI) / 180;
+		var lat_from = (a.y * Math.PI) / 180;
+		var lon_to = (b.x * Math.PI) / 180;
+		var lat_to = (b.y * Math.PI) / 180;
+		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)
+		));
+	};
+
+	var 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)
+		));
+	};
+	
+	var calculateDistance = function (map, a, b) {
+		if (a !== null && b !== null) {
+			switch (map.getSrs()) {
+				case "EPSG:4326":
+					return calculateDistanceGeographic(a, b);
+				default:	
+					return calculateDistanceMetric(a, b);
+			}
+		}
+		return null;
+	};
+	
+	var calculateArea = function (pos) {
+		if (measurePoints.length < 2) {
+			return null;
+		}
+		
+		var area = 0;
+		var p0 = measurePoints[0], pi, pj;
+		for (var i = 0; i < measurePoints.length - 1; i++)  {
+			pi = measurePoints[i];
+			pj = measurePoints[i + 1];
+			area += (pi.y + pj.y) * (pi.x - pj.x) / 2;
+		}
+		area += (p0.y + pj.y) * (p0.x - pj.x) / 2;
+		return Math.abs(area);
+	};
+
+	var isPolygon = function (measurePoints, pos) {
+
+		var len = measurePoints.length;
+		if (len < 2) {
+			return false;
+		}
+/*
+		var pn = measurePoints[len - 1];
+
+		for (var i = 0; i < measurePoints.length - 2; i++)  {
+			var p1 = measurePoints[i];
+			var p2 = measurePoints[i + 1];
+
+			if (lineIntersect(p1.x, p1.y, p2.x, p2.y, pn.x, pn.y, pos.x, pos.y)) {
+				return false;
+			}
+		}
+*/
+		return true;
+	};
+	
+	var lineIntersect = function ( a1, a2, b1, b2, c1, c2, d1, d2 ) {
+		var s, t, N = (b1-a1)*(d2-c2)-(b2-a2)*(d1-c1);
+		if (N === 0) {
+			// parallel
+			return false;
+		} 
+		s = ((c1-a1)*(d2-c2)-(c2-a2)*(d1-c1)) / N;
+		t = (a1-c1 + s*(b1-a1)) / (d1-c1);
+
+		if (s <= 1 && s>=0 && t <= 1 && t>=0) {
+			return true;
+		}
+		return false;
+	};
+
+	var measure = function (e) {
+		var map = $(e.currentTarget).mapbender();
+
+		if (srs !== map.getSrs()){
+			button.stop();
+			return;
+		}
+
+		var pos = map.convertPixelToReal(map.getMousePosition(e));
+		updateCurrentPoint(pos);
+		
+		var previousPoint = measurePoints.length > 0 ? 
+			measurePoints[measurePoints.length - 1] : null;
+		var distance = calculateDistance(map, previousPoint, pos);
+		updateDistance(distance);
+		
+		if (isPolygon(measurePoints, pos)) {
+			updateArea(calculateArea(pos));
+		}
+		draw(map, pos);
+	};
+
+	var addPoint = function (e) {
+		var map = $(e.currentTarget).mapbender();
+
+		var pos = map.convertPixelToReal(map.getMousePosition(e));
+		updateClickedPoint(pos);
+		
+		draw(map, pos);
+
+		measurePoints.push(pos);
+	};
+
+	var addLastPoint = function (e) {
+		if ($(e.currentTarget).size() > 0) {
+			$(e.currentTarget).unbind("mousedown", addPoint)
+				.unbind("dblclick", addLastPoint)
+				.unbind("mousemove", measure);
+			$(e.currentTarget).css("cursor", "auto");
+		}			
+
+		addPoint(e);
+	};
+
+	this.activate = function () {
+		if (o.$target.size() > 0) {
+			o.$target.bind("mousedown", addPoint)
+				.bind("dblclick", addLastPoint)
+				.bind("mousemove", measure);
+			o.$target.css("cursor", "crosshair");
+		}	
+		
+		srs = o.$target.mapbender().getSrs();
+		
+		measureDialog.dialog("open");
+	};
+
+	this.deactivate = function () {
+		if (o.$target.size() > 0) {
+			o.$target.unbind("mousedown", addPoint)
+				.unbind("dblclick", addLastPoint)
+				.unbind("mousemove", measure);
+			o.$target.css("cursor", "auto");
+		}	
+	
+		srs = undefined;
+
+		for (var i in canvases) {
+			canvases[i].clear();
+		}
+		
+		measurePoints = [];
+		
+		hideMeasureData();
+
+		measureDialog.dialog("close");
+		button.stop();
+	};
+	
+	create();
+};
+
+$measure.mapbender(new MeasureApi(options));



More information about the Mapbender_commits mailing list