[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²";
+ var area = data.area;
+ if (area > 10000000){
+ area /= 1000000;
+ areaUnit = "km²";
+ }
+ 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