[Mapbender-commits] r2582 - in branches/testbaudson_dev:
http/javascripts lib
svn_mapbender at osgeo.org
svn_mapbender at osgeo.org
Fri Jul 4 04:08:06 EDT 2008
Author: christoph
Date: 2008-07-04 04:08:05 -0400 (Fri, 04 Jul 2008)
New Revision: 2582
Added:
branches/testbaudson_dev/lib/geometry1.1.js
Removed:
branches/testbaudson_dev/http/javascripts/geometry1.1.js
Log:
moved to lib
Deleted: branches/testbaudson_dev/http/javascripts/geometry1.1.js
===================================================================
--- branches/testbaudson_dev/http/javascripts/geometry1.1.js 2008-07-02 15:34:21 UTC (rev 2581)
+++ branches/testbaudson_dev/http/javascripts/geometry1.1.js 2008-07-04 08:08:05 UTC (rev 2582)
@@ -1,1125 +0,0 @@
-/*
-* $Id$
-* COPYRIGHT: (C) 2001 by ccgis. This program is free software under the GNU General Public
-* License (>=v2). Read the file gpl.txt that comes with Mapbender for details.
-*/
-var Geometry = {
- /**
- * A static class representing geometry types.
- */
- Type : {
- /**
- * excludes Linear ring as it is no valid geometry itself
- */
- isValid : function (aGeometry) {
- try {
- if (aGeometry.getType() == this.point ||
- aGeometry.getType() == this.line ||
- aGeometry.getType() == this.polygon ||
- aGeometry.getType() == this.multigeometry)
- {
- return true;
- }
- }
- catch (e) {
- var exc = new Mb_exception ("Geometry.Type.isValid: invalid geometry type for geometry: " + aGeometry + "; " + e);
- }
- return false;
- },
-
- isPoint : function (aGeometry) {
- try {
- if (aGeometry.getType() == this.point) {
- return true;
- }
- }
- catch (e) {
- var exc = new Mb_exception ("Geometry.Type.isPoint: not a point: geometry: " + aGeometry + "; " + e);
- }
- return false;
- },
-
- isLine : function (aGeometry) {
- try {
- if (aGeometry.getType() == this.line) {
- return true;
- }
- }
- catch (e) {
- var exc = new Mb_exception ("Geometry.Type.isLine: not a line: geometry: " + aGeometry + "; " + e);
- }
- return false;
- },
-
- isPolygon : function (aGeometry) {
- try {
- if (aGeometry.getType() == this.polygon) {
- return true;
- }
- }
- catch (e) {
- var exc = new Mb_exception ("Geometry.Type.isPolygon: not a polygon: geometry: " + aGeometry + "; " + e);
- }
- return false;
- },
-
- isLinearRing : function (aGeometry) {
- try {
- if (aGeometry.getType() == this.linearring) {
- return true;
- }
- }
- catch (e) {
- var exc = new Mb_exception ("Geometry.Type.isLinearRing: not a linear ring: geometry: " + aGeometry + "; " + e);
- }
- return false;
- },
-
- point : "point",
- line : "line",
- linearring : "linearring",
- polygon : "polygon",
- multigeometry : "multigeometry"
- },
-
- /**
- * A class representing MultiGeometries. A MultiGeometry is a List containing
- * Point objects, Line objects, Polygon objects and MultiGeometry objects.
- */
- MultiGeometry : function () {
-
- this.getType = function () {
- return Geometry.Type.multipolygon;
- };
-
- this.push = function (aGeometry) {
- if (Geometry.Type.isValid(aGeometry)) {
- this.add(aGeometry);
- this.get(-1).onEmpty.register(function () {
- that.isEmpty();
- });
- return true;
- }
- return false;
- };
-
- this.pop = function () {
- return this.remove(-1);
- };
-
- this.remove = function (index) {
- // TODO: parameter might be a geometry
- if (this.del(index)) {
- this.isEmpty();
- return true;
- }
- return false;
- };
-
- /**
- * Checks if the multi geometry is empty. If yes, the event onEmpty is triggered.
- */
- this.isEmpty = function () {
- if (this.count() === 0) {
- this.onEmpty.trigger();
- return true;
- }
- return false;
- };
-
- this.onEmpty = new MapbenderEvent();
-
- // this class extends List
- this.list = [];
- },
-
- /**
- * A class representing lines. A line is a List of Point objects
- */
- Line : function () {
-
- this.getType = function () {
- return Geometry.Type.line;
- };
-
- this.push = function (aPoint) {
- if (Geometry.Type.isPoint(aPoint)) {
- this.add(aPoint);
- this.get(-1).onEmpty.register(function () {
- that.rearrangeList();
- });
- return true;
- }
- return false;
- };
-
- this.remove = function (index) {
- // TODO: parameter might be a point
- if (this.del(index)) {
- return this.isEmpty();
- }
- return false;
- };
-
- /**
- * remove all invalid points
- */
- this.rearrangeList = function () {
- var listLength = this.count();
- for (var i = 0; i < listLength; i++) {
- if (!this.get(i).isSet()) {
- this.remove(i);
- i -= 1;
- listLength -= 1;
- }
- }
- };
-
- this.isEmpty = function () {
- if (this.count === 0) {
- this.onEmpty.trigger();
- return true;
- }
- return false;
- };
-
- this.onEmpty = new MapbenderEvent();
-
- // this class extends List
- this.list = [];
- },
-
- /**
- * A class representing a Polygon. A Polygon consists of an outer boundary (LinearRing)
- * and 0..n inner boundaries (InnerBoundaryArray).
- */
- Polygon : function () {
-
- this.getType = function () {
- return Geometry.Type.polygon;
- };
-
- this.setOuterBoundary = function (aLinearRing) {
- if (Geometry.Type.isLinearRing(aLinearRing)) {
- outerBoundary = aLinearRing;
- outerBoundary.onEmpty.register(function () {
- that.isEmpty();
- });
- return true;
- }
- return false;
- };
-
- this.removeOuterBoundary = function () {
- outerBoundary = null;
- innerBoundaryArray = null;
- return this.onEmpty.trigger();
- };
-
- this.appendInnerBoundary = function (aLinearRing) {
- innerBoundaryArray.push(aLinearRing);
- };
-
- this.removeInnerBoundary = function (index) {
- return innerBoundaryArray.remove(index);
- };
-
- this.isEmpty = function () {
- if (!Geometry.Type.isLinearRing(outerBoundary)) {
- return this.onEmpty.trigger();
- }
- return false;
- };
-
- var outerBoundary;
- var innerBoundaryArray = new Geometry.InnerBoundaryArray();
- },
-
- /**
- * An InnerBoundaryArray is a List of LinearRing objects.
- */
- InnerBoundaryArray : function () {
-
- this.push = function (aLinearRing) {
- if (Geometry.Type.isLinearRing(aLinearRing)) {
- return this.add(aLinearRing);
- }
- return false;
- };
-
- this.remove = function (index) {
- return this.del(index);
- };
-
- this.onEmpty = new MapbenderEvent();
-
- this.list = [];
- },
-
- /**
- * A Linear Ring is a List of Point objects. The last Point and the first Point must be identical.
- */
- LinearRing : function () {
- this.getType = function () {
- return Geometry.Type.linearring;
- };
-
- this.push = function (aPoint) {
- if (Geometry.Type.isPoint(aPoint)) {
- if (!this.isClosed()) {
- this.add(aPoint);
- // linear ring with at least 4 points (triangle!)
- // AND
- // last point equals first point
- if (this.count() > 3 && this.get(0).equals(this.get(-1))) {
- this.close();
- }
- this.get(-1).onEmpty.register(function () {
- that.rearrangeList();
- });
- return true;
- }
- else {
- var e = new Mb_warning("Geometry.LinearRing: push: Cannot add point; linear ring is already closed!");
- }
- }
- return false;
- };
-
- this.remove = function (index) {
- var i = this.getIndex(index);
- if (i !== false) {
- // if the first or last point is being deleted,
- // re-set the first or last point so that the
- // ring remains closed
- if (i === 0 || i === this.getIndex(-1)) {
- // remove the first point (list is automatically shifted)
- this.del(0);
-
- // check if there are still points remaining
- if (!this.isEmpty()) {
- // add the new first point as the last point
- this.list[this.count()-1] = this.list[0];
- }
- return true;
- }
- // if it is a point in the middle, just delete it (list is automatically shifted)
- else {
- return this.del(i);
- }
- }
- return false;
- };
-
- /**
- * Checks if the outer boundary is empty. If yes, the event onEmpty is triggered.
- */
- this.isEmpty = function () {
- if (this.count() === 0) {
- this.onEmpty.trigger();
- return true;
- }
- return false;
- };
-
- /**
- * remove all invalid points
- */
- this.rearrangeList = function () {
- var listLength = this.count();
- for (var i = 0; i < listLength; i++) {
- if (!this.get(i).isSet()) {
- this.remove(i);
- i -= 1;
- listLength -= 1;
- }
- }
- };
-
- this.close = function () {
- // linear ring with at least 4 points (triangle!)
- // AND
- // last point equals first point
- if (this.count() > 3 && this.get(0).equals(this.get(-1))) {
- closed = true;
- return closed;
- }
- // linear with at least 3 points (triangle!)
- // AND
- // last point DOESNT equal first point
- else if (this.count() > 2 && !this.get(0).equals(this.get(-1))) {
- var newPoint = new Geometry.Point(this.get(0).x, this.get(0).y);
- // push will return to close to set closed to true
- this.push(newPoint);
- }
- else {
- var e = new Mb_warning("Geometry.LinearRing: close: cannot close linear ring, must have at least 3 points (triangle)");
- }
- return false;
- };
-
- this.isClosed = function () {
- return closed;
- };
-
- this.onEmpty = new MapbenderEvent();
-
- /**
- * if the first point and the last point match, and the ring has at least 4 points (triangle!)
- * closed is set to true via close
- */
- var closed = false;
-
- this.list = [];
- },
-
- /**
- * A Point consists of an x- and a y-coordinate.
- */
- Point : function () {
- this.getType = function () {
- return Geometry.Type.point;
- };
-
- this.remove = function () {
- onEmpty.trigger();
- this.x = null;
- this.y = null;
- this.onEmpty = null;
- };
-
- /**
- * x value of the {@link Point}
- *
- * @type Float
- */
- this.x = parseFloat(x);
-
- /**
- * y value of the {@link Point}
- *
- * @type Float
- */
- this.y = parseFloat(y);
-
- this.isSet = function () {
- return (this.x !== null && this.y !== null);
- };
-
- this.onEmpty = new MapbenderEvent();
- }
-};
-
-Geometry.GeometryArray.prototype = new List();
-Geometry.MultiGeometry.prototype = new List();
-Geometry.InnerBoundary.prototype = new List();
-Geometry.LinearRing.prototype = new List();
-Geometry.Line.prototype = new List();
-
-/**
- * computes the distance between a {@link Point} p and this {@link Point}
- *
- * @param {Point} p the distance between this {@link Point} and the {@link Point} p is computed.
- * @return {Float} the distance between the two {@link Point} objects.
- */
-Geometry.Point.prototype.dist = function(p){
- return Math.sqrt(Math.pow(this.y-p.y,2) + Math.pow(this.x-p.x,2)) ;
-};
-/**
- * checks if the coordinates of this {@link Point} match the coordinates of a {@link Point} p
- *
- * @param {Point} p
- * @return {Boolean} true if the two points are equal; elso false
- */
-Geometry.Point.prototype.equals = function(p){
- if (this.x == p.x && this.y == p.y) {return true;}
- return false;
-};
-/**
- * subtracts a {@link Point} p from this {@link Point}
- *
- * @param {Point} p
- * @return a new {@link Point} with the difference of the two points
- */
-Geometry.Point.prototype.minus = function(p){
- return new Point(this.x-p.x, this.y-p.y);
-};
-/**
- * adds this {@link Point} to a {@link Point} p
- *
- * @param {Point} p
- * @return a new {@link Point} with the sum of the two points
- */
-Geometry.Point.prototype.plus = function(p){
- return new Point(this.x+p.x, this.y+p.y);
-};
-/**
- * divides this {@link Point} by a scalar c
- *
- * @param {Float} c divisor
- * @return a new {@link Point} divided by c
- */
-Geometry.Point.prototype.dividedBy = function(c){
- if (c !== 0) {
- return new Point(this.x/c, this.y/c);
- }
- var e = new Mb_exception("Point.dividedBy: Division by zero");
- return false;
-};
-/**
- * multiplies this {@link Point} by a scalar c
- *
- * @param {Float} c factor
- * @return a new {@link Point} multiplied by c
- */
-Geometry.Point.prototype.times = function(c){
- return new Point(this.x*c, this.y*c);
-};
-/**
- * rounds the coordinates to numOfDigits digits
- *
- * @param numOfDigits the coordinate will be rounded to numOfDigits digits
- * @return a new {@link Point} rounded to numOfDigits digits
- * @type Point
- */
-Geometry.Point.prototype.round = function(numOfDigits){
- return new Point(roundToDigits(this.x, numOfDigits), roundToDigits(this.y, numOfDigits));
-};
-/**
- * @returns a {String} representation of this Point
- * @type String
- */
-Geometry.Point.prototype.toString = function(){
- return "(" + this.x + ", " + this.y + ")";
-};
-
-
-
-/**
- * @class an array of elements, each consisting of a name/value pair
- *
- * @ constructor
- */
-function Wfs_element(){
-
- /**
- * returns the number of elements of this {@link Wfs_element} object.
- *
- * @return the number of elements
- * @type Integer
- */
- this.count = function(){
- return name.length;
- };
-
- /**
- * returns the name of the element at index i.
- *
- * @param {Integer} i index
- * @return the name
- * @type String
- */
- this.getName = function(i){
- if (isValidElementIndex(i)) {return name[i];}
- return false;
- };
-
- /**
- * returns the value of the element at index i.
- *
- * @param {Integer} i index
- * @return the value
- */
- this.getValue = function(i){
- if (isValidElementIndex(i)) {return value[i];}
- return false;
- };
-
- /**
- * appends a new element with a given name. If an element with this name exists, it is overwritten.
- *
- * @param {String} aName the name of the new element
- * @param {String} aValue the value of the new element
- */
- this.setElement = function(aName, aValue){
- var i = this.getElementIndexByName(aName);
- if (i === false) {i = this.count();}
- name[i] = aName;
- value[i] = aValue;
- };
-
- /**
- * checks if an index is valid
- *
- * @private
- * @param {Integer} i an index
- * @return true if the index is valid; otherwise false
- * @type Boolean
- */
- var isValidElementIndex = function(i){
- if (i>=0 && i<name.length) {return true;}
- var e = new Mb_exception("class Wfs_element: function isValidElementIndex: illegal element index");
- return false;
- };
-
- var name = [];
- var value = [];
-}
-
-/**
- * gets the index of the element with a given name.
- *
- * @param {String} elementName a name
- * @return the index of the element; if no element with this name exists, false
- * @type Integer, Boolean
- */
-Wfs_element.prototype.getElementIndexByName = function(elementName){
- for (var j = 0 ; j < this.count() ; j++){
- if (this.getName(j) == elementName) {return j;}
- }
- return false;
-};
-
-/**
- * gets the value of the element with a given name.
- *
- * @param {String} elementName a name
- * @return the value of the element; if no element with this name exists, false
- * @type String, Boolean
- */
-Wfs_element.prototype.getElementValueByName = function(elementName){
- var i = this.getElementIndexByName(elementName);
- if (i === false) {return false;}
- return this.getValue(i);
-};
-
-
-/**
- * @class a {@link Canvas} contains a {@link DivTag} that holds graphics rendered by {@link jsGraphics}
- *
- * @constructor
- * @requires DivTag
- * @requires jsGraphics
- * @requires GeometryArray
- * @requires MultiGeometry
- * @requires Geometry
- * @param {String} aMapFrame name of the target mapframe
- * @param {String} aTagName name of the target div tag
- * @param {String} aStyle style of the div tag
- * @param {Integer} aLineWidth the line width of the jsGraphics output
- */
-function Canvas(aMapframe, aTagName, aStyle, aLineWidth) {
-
- /**
- * draws the geometry of the canvas
- *
- * @param {String} t geometry type (@see GeomType)
- * @param {MultiGeometry} g a MultiGeometry object
- * @param {String} col a color
- * @private
- */
- this.drawGeometry = function(t,g,col){
- var mapObjInd = getMapObjIndexByName(mapframe);
- width = mb_mapObj[mapObjInd].width;
- height = mb_mapObj[mapObjInd].height;
- for(var i=0; i < g.count(); i++){
- if(t==geomType.point) {
- var p = realToMap(mapframe,g.get(i).get(0));
- if (p.x + diameter < mb_mapObj[mapObjInd].width && p.x - diameter > 0 &&
- p.y + diameter < mb_mapObj[mapObjInd].height && p.y - diameter > 0) {
- drawCircle(p.x-1, p.y-1, diameter,col);
- }
- }
- else if(t==geomType.line || t==geomType.polygon) {
- for (var j=0; j<g.get(i).count()-1; j++) {
- var pq = calculateVisibleDash(realToMap(mapframe,g.get(i).get(j)), realToMap(mapframe,g.get(i).get(j+1)), width, height);
- if (pq) {
- drawLine([pq[0].x-1, pq[1].x-1], [pq[0].y-1, pq[1].y-1], col);
- }
- }
- }
- else {
- var e = new Mb_exception("class Canvas: function drawGeometry: unknown geomType " + t);
- }
- }
- };
-
- /**
- * checks if the MultiGeometry's bounding box width and height is smaller than minWidth
- *
- * @private
- * @param {MultiGeometry} g a MultiGeometry object
- */
- this.isTooSmall = function(g){
- var tmp = g.getBBox();
- var min = realToMap(mapframe,tmp[0]);
- var max = realToMap(mapframe,tmp[1]);
- if((Math.abs(max.x - min.x) < minWidth) && (Math.abs(max.y - min.y) < minWidth)) {
- return true;
- }
- return false;
- };
-
- /**
- * gets the jsGraphics.
- *
- * @private
- * @return the jsGraphics
- * @type jsGraphics
- */
- this.getCanvas = function(){
- return canvas;
- };
-
- /**
- * draws a circle with {@link jsGraphics}.
- *
- * @private
- * @param {Float} x x value of the center
- * @param {Float} y y value of the center
- * @param {Float} diameter diameter of the circle
- * @param {String} color the color of the circle in hex format
- */
- var drawCircle = function(x, y, diameter, color) {
- canvas.setColor(color);
- canvas.drawEllipse(x-diameter/2,y-diameter/2,diameter,diameter);
- };
-
- /**
- * draws a polyline with {@link jsGraphics}.
- *
- * @private
- * @param {Array} x_array array of x values
- * @param {Array} y_array array of y values
- * @param {String} color the color of the polyline in hex format
- */
- var drawLine = function(x_array, y_array, color) {
- canvas.setColor(color);
- canvas.drawPolyline(x_array, y_array);
- };
-
- /**
- * This is the {@link DivTag} that contains the output by {@link jsGraphics}.
- *
- * @type DivTag
- */
- this.canvasDivTag = new DivTag(aTagName, aMapframe, aStyle);
-
- var that = this;
-
- var diameter = 8;
- var minWidth = 8;
- var lineWidth = aLineWidth;
- var mapframe = aMapframe;
- var style = aStyle;
- var canvas = new jsGraphics(aTagName, window.frames[mapframe]);
- canvas.setStroke(lineWidth);
- mb_registerPanSubElement(aTagName);
-}
-
-/**
- * cleans the canvas by emptying the canvas {@link DivTag}.
- */
-Canvas.prototype.clean = function () {
- this.canvasDivTag.clean();
-};
-
-/**
- * paints all geometries.
- *
- * @param {GeometryArray} gA the geometries that will be drawn
- */
-Canvas.prototype.paint = function(gA) {
- for (var q = 0; q < gA.count(); q++) {
- var m = gA.get(q);
- var t = m.geomType;
- var col = m.color;
- if (t == geomType.point) {
- this.drawGeometry(t,m,col);
- }
- else {
- if (this.isTooSmall(m)){
- var newMember = new MultiGeometry(geomType.point);
- newMember.addGeometry();
- newMember.get(-1).addPoint(m.getCenter());
- this.drawGeometry(geomType.point,newMember,col);
- }
- else{
- if(t == geomType.line) {this.drawGeometry(t,m, col);}
- else if(t == geomType.polygon) {this.drawGeometry(t,m,col);}
- else {
- var e = new Mb_exception("class Canvas: function paint: unknown geomType" + t);
- }
- }
- }
- }
- this.getCanvas().paint();
-};
-
-/**
- * @class a {@link Highlight} object is {@link jsGraphics} rendering of a {@link GeometryArray} in various mapframes.
- *
- * @constructor
- * @requires Canvas
- * @requires GeometryArray
- * @param {Array} aTargetArray an array of Strings referring to mapframes
- * @param {String} aTagName the name of the div tags
- * @param {Object} aStyle the style of the div tags
- * @param {Integer} the line width of the jsGraphics lines
- */
-function Highlight(aTargetArray, aTagName, aStyle, aLineWidth) {
- /**
- * removes a {@link MultiGeometry} object from the geometry Array
- *
- * @param {MultiGeometry} m a MultiGeometry
- * @param {String} color a color
- */
- this.del = function(m, color) {
- var a = gA.findMultiGeometry(m);
- var del = false;
- for (var i=0; i<a.length && del === false; i++) {
- if (gA.get(a[i]).color == color) {
- gA.del(a[i]);
- del = true;
- }
- }
- this.paint();
- };
-
- /**
- * adds a {@link MultiGeometry} object to the geometry Array
- *
- * @param {MultiGeometry} m a MultiGeometry
- * @param {String} color the color of the highlight
- */
- this.add = function(m, color) {
- gA.addCopy(m);
- if (typeof(color) != 'undefined') {gA.get(-1).color = color;}
- else {gA.get(-1).color = lineColor;}
- this.paint();
- };
-
- /**
- * removes all MultiGeometries.
- *
- */
- this.clean = function() {
- if (gA.count() > 0) {
- gA = new GeometryArray();
- this.paint();
- }
- };
-
- /**
- * displays the highlight
- *
- */
- this.paint = function() {
- for (var i=0; i < canvas.length; i++) {
- if (typeof(canvas[i]) == "object") {canvas[i].clean();}
- }
- for (var i=0; i<targets.length; i++){
- if (typeof(canvas[i]) == 'undefined') {
- canvas[i] = new Canvas(targets[i], tagname, style, lineWidth);
- }
- canvas[i].paint(gA);
- }
- };
-
- var lineWidth = aLineWidth;
- var tagname = 'mod_gaz_draw'+aTagName;
- var style = aStyle;
- var targets = aTargetArray;
- var canvas = [];
- var gA = new GeometryArray();
- var lineColor = "#ff0000";
- this.paint();
-}
-
-// ----------------------------------------------------------------------------------------------------
-// Snapping
-// ----------------------------------------------------------------------------------------------------
-/**
- * @class a {@link Snapping} object stores is {@link jsGraphics} rendering of a {@link GeometryArray} in various mapframes.
- *
- * @constructor
- * @requires GeometryArray
- * @requires Highlight
- * @param {String} aTarget name of the mapframe where snapping occurs
- * @param {String} aTolerance Snapping is activated if the mouse is
- * within aTolerance pixel distance to the reference point.
- * @param {String} aColor apparently deprecated?
- * @param {Integer} aZIndex the z-Index of the {@link jsGraphics} generated by {@link Highlight}.
- */
-function Snapping(aTarget, aTolerance, aColor, aZIndex){
-
- /**
- * draws a circle to highlight the snapped point.
- *
- * @param {Point} center the snapped point.
- * @param {Integer} radius radius of the circular highlight.
- */
- this.draw = function(center,radius){
- mG = new MultiGeometry(geomType.point);
- mG.addGeometry();
- mG.get(-1).addPoint(center);
- highlight.add(mG);
- };
- this.getTolerance = function() {
- return tolerance;
- };
- this.getTarget = function() {
- return target;
- };
- this.cleanHighlight = function() {
- return highlight.clean();
- };
- this.addPoint = function(aPoint) {
- coord.push(aPoint);
- };
- this.getPointCount = function() {
- return coord.length;
- };
- this.getPoint = function(i) {
- return coord[i];
- };
- this.resetPoints = function() {
- coord = [];
- };
- this.getNearestNeighbour = function(){
- if (min_i != -1) {return this.getPoint(min_i);}
- return false;
- };
- this.setIndexOfNearestNeighbour = function(i){
- min_i = i;
- };
- this.resetIndexOfNearestNeighbour = function(){
- min_i = -1;
- };
-
- /**
- * @private
- */
- var tolerance = (typeof(aTolerance) == 'undefined') ? 10 : aTolerance;
-
- /**
- * @private
- */
- var zIndex = (typeof(aZIndex) == 'undefined') ? 50 : aZIndex;
-
- /**
- * @private
- */
- var coord = [];
-
- /**
- * @private
- */
- var min_i = -1;
-
- /**
- * @private
- */
- var target = aTarget;
-
- /**
- * @private
- */
- var lineWidth = 2;
-
- /**
- * @private
- */
- var style = {"position":"absolute", "top":"0px", "left":"0px", "z-index":zIndex};
-
- /**
- * @private
- */
- var highlight = new Highlight([target], "snapping"+Math.round(Math.random()*Math.pow(10,10)), style, lineWidth);
-}
-
-Snapping.prototype.check = function(currPoint){
- var minDist = false;
-
- for (var i = 0 ; i < this.getPointCount() ; i++) {
-
- var currDist = currPoint.dist(realToMap(this.getTarget(), this.getPoint(i)));
- if (minDist === false || currDist < minDist) {
- minDist = currDist;
- if (minDist < this.getTolerance()) {this.setIndexOfNearestNeighbour(i);}
- }
- }
- if (this.getPointCount() > 0 && minDist > this.getTolerance()) {
- this.resetIndexOfNearestNeighbour();
- }
- this.cleanHighlight();
- if (this.isSnapped()) {
- this.draw(this.getNearestNeighbour(), this.getTolerance());
- }
-};
-
-/**
- * Stores the points which will have the snapping property.
- *
- * @param {GeometryArray} geom all points of geom will be stored. May also be a
- * {@link MultiGeometry} or {@link Geometry}.
- * @param {Point} point this point is excluded. Useful when moving a point of a
- * geometry; you don't want to snap against the point you
- * move. Optional.
- */
-Snapping.prototype.store = function(geom, point){
- this.resetPoints();
- this.resetIndexOfNearestNeighbour();
-
- for (var i = 0 ; i < geom.count(); i++){
- if (geom.name == nameGeometryArray || geom.name == nameMultiGeometry){
- for (var j = 0 ; j < geom.get(i).count() ; j++){
- if (geom.get(i).name == nameMultiGeometry){
- for (var k = 0 ; k < geom.get(i).get(j).count() ; k++){
- if ((geom.get(i).get(j).isComplete() === true && typeof(point) == 'undefined') || (typeof(point) != 'undefined' && !geom.get(i).get(j).get(k).equals(point))){
- this.add(geom.getPoint(i, j, k));
- }
- }
- }
- else {
- if ((geom.get(i).isComplete() === true && typeof(point) == 'undefined') || (typeof(point) != 'undefined' && !geom.get(i).get(j).get(k).equals(point))){
- this.add(geom.getPoint(i, j));
- }
- }
- }
- }
- else {
- if (typeof(point) != 'undefined' && !geom.get(i).get(j).get(k).equals(point)){
- this.add(geom.get(i));
- }
- }
- }
-};
-
-/**
- * Determines whether a point is within snapping distance to the mouse cursor
- *
- * @return true if a point is within snapping distance; else false
- * @type Boolean
- */
-Snapping.prototype.isSnapped = function(){
- if (this.getNearestNeighbour() !== false) {return true;}
- return false;
-};
-
-/**
- * Returns the point that is within snapping distance and closest to the mouse cursor.
- *
- * @return the point (if there is any); else false
- * @type Point
- */
-Snapping.prototype.getSnappedPoint = function(){
- return this.getNearestNeighbour();
-};
-
-/**
- * Adds the point to the stored points with snapping property.
- *
- * @param {Point} point which receives snapping property.
- */
-Snapping.prototype.add = function(aPoint){
- this.addPoint(aPoint);
-};
-
-/**
- * Removes the highlight.
- */
-Snapping.prototype.clean = function(){
- this.cleanHighlight();
-};
-
-
-
-// ----------------------------------------------------------------------------------------------------
-// misc. functions
-// ----------------------------------------------------------------------------------------------------
-
-/**
- * @ignore
- */
-function calculateVisibleDash (p0, p1, width, height) {
- if (p0.x > p1.x) {var p_temp = p0; p0 = p1; p1 = p_temp; p_temp = null;}
- var p = p0; var q = p1; var m; var ix; var iy;
- if (p1.x != p0.x) {
- m = -(p1.y-p0.y)/(p1.x-p0.x);
- if (p0.x < width && p1.x > 0 && !(p0.y < 0 && p1.y < 0) && !(p0.y > height && p1.y > height) ) {
- if (p0.x < 0) {
- iy = p0.y - m*(0-p0.x);
- if (iy > 0 && iy < height) {p = new Point(0, iy);}
- else if (iy > height) {
- ix = p0.x+((p0.y - height)/m);
- if (ix > 0 && ix < width) {p = new Point(ix, height);} else {return false;}
- }
- else if (iy < 0) {
- ix = p0.x+(p0.y/m);
- if (ix > 0 && ix < width) {p = new Point(ix, 0);} else {return false;}
- }
- else {return false;}
- }
- else if (p0.y >= 0 && p0.y <= height) {p = p0;}
- else if (p0.y < 0) {
- ix = p0.x+(p0.y/m);
- if (ix > 0 && ix < width) {p = new Point(ix, 0);} else {return false;}
- }
- else if (p0.y > height && m > 0) {
- ix = p0.x+((p0.y - height)/m);
- if (ix > 0 && ix < width) {p = new Point(ix, height);} else {return false;}
- }
- else {return false;}
- if (p1.x > width) {
- iy = p1.y - m*(width-p1.x);
- if (iy > 0 && iy < height) {q = new Point(width, iy);}
- else if (iy < 0) {
- ix = p0.x+(p0.y/m);
- if (ix > 0 && ix < width) {q = new Point(ix, 0);} else {return false;}
- }
- else if (iy > height) {
- ix = p0.x+((p0.y - height)/m);
- if (ix > 0 && ix < width) {q = new Point(ix, height);} else {return false;}
- }
- else {return false;}
- }
- else if (p1.y >= 0 && p1.y <= height) {q = p1;}
- else if (p1.y < 0) {
- ix = p1.x+(p1.y/m);
- if (ix > 0 && ix < width) {q = new Point(ix, 0);} else {return false;}
- }
- else if (p1.y > height) {
- ix = p1.x+((p1.y- height)/m);
- if (ix > 0 && ix < width) {q = new Point(ix, height);} else {return false;}
- }
- }
- else {return false;}
- }
- else {
- if (!(p0.y < 0 && p1.y < 0) && !(p0.y > height && p1.y > height)) {
- if (p0.y < 0) {p = new Point(p0.x, 0);}
- else if (p0.y > height) {p = new Point(p0.x, height);}
- else {p = p0;}
- if (p1.y < 0) {q = new Point(p0.x, 0);}
- else if (p1.y > height) {q = new Point(p0.x, height);}
- else {q = p1;}
- }
- else {return false;}
- }
- return [new Point(Math.round(q.x), Math.round(q.y)), new Point(Math.round(p.x), Math.round(p.y))];
-}
-
-/**
- * @ignore
- */
-function objString (a){
- var z = "";
-
- for (attr in a) {
- var b = a[attr];
- if (typeof(b) == "object") {z += objString(b);}
- else {z += attr + " " + b + "\n";alert(attr + " " + b);}
- }
- return z;
-}
Copied: branches/testbaudson_dev/lib/geometry1.1.js (from rev 2575, branches/testbaudson_dev/http/javascripts/geometry1.1.js)
===================================================================
--- branches/testbaudson_dev/lib/geometry1.1.js (rev 0)
+++ branches/testbaudson_dev/lib/geometry1.1.js 2008-07-04 08:08:05 UTC (rev 2582)
@@ -0,0 +1,1125 @@
+/*
+* $Id$
+* COPYRIGHT: (C) 2001 by ccgis. This program is free software under the GNU General Public
+* License (>=v2). Read the file gpl.txt that comes with Mapbender for details.
+*/
+var Geometry = {
+ /**
+ * A static class representing geometry types.
+ */
+ Type : {
+ /**
+ * excludes Linear ring as it is no valid geometry itself
+ */
+ isValid : function (aGeometry) {
+ try {
+ if (aGeometry.getType() == this.point ||
+ aGeometry.getType() == this.line ||
+ aGeometry.getType() == this.polygon ||
+ aGeometry.getType() == this.multigeometry)
+ {
+ return true;
+ }
+ }
+ catch (e) {
+ var exc = new Mb_exception ("Geometry.Type.isValid: invalid geometry type for geometry: " + aGeometry + "; " + e);
+ }
+ return false;
+ },
+
+ isPoint : function (aGeometry) {
+ try {
+ if (aGeometry.getType() == this.point) {
+ return true;
+ }
+ }
+ catch (e) {
+ var exc = new Mb_exception ("Geometry.Type.isPoint: not a point: geometry: " + aGeometry + "; " + e);
+ }
+ return false;
+ },
+
+ isLine : function (aGeometry) {
+ try {
+ if (aGeometry.getType() == this.line) {
+ return true;
+ }
+ }
+ catch (e) {
+ var exc = new Mb_exception ("Geometry.Type.isLine: not a line: geometry: " + aGeometry + "; " + e);
+ }
+ return false;
+ },
+
+ isPolygon : function (aGeometry) {
+ try {
+ if (aGeometry.getType() == this.polygon) {
+ return true;
+ }
+ }
+ catch (e) {
+ var exc = new Mb_exception ("Geometry.Type.isPolygon: not a polygon: geometry: " + aGeometry + "; " + e);
+ }
+ return false;
+ },
+
+ isLinearRing : function (aGeometry) {
+ try {
+ if (aGeometry.getType() == this.linearring) {
+ return true;
+ }
+ }
+ catch (e) {
+ var exc = new Mb_exception ("Geometry.Type.isLinearRing: not a linear ring: geometry: " + aGeometry + "; " + e);
+ }
+ return false;
+ },
+
+ point : "point",
+ line : "line",
+ linearring : "linearring",
+ polygon : "polygon",
+ multigeometry : "multigeometry"
+ },
+
+ /**
+ * A class representing MultiGeometries. A MultiGeometry is a List containing
+ * Point objects, Line objects, Polygon objects and MultiGeometry objects.
+ */
+ MultiGeometry : function () {
+
+ this.getType = function () {
+ return Geometry.Type.multipolygon;
+ };
+
+ this.push = function (aGeometry) {
+ if (Geometry.Type.isValid(aGeometry)) {
+ this.add(aGeometry);
+ this.get(-1).onEmpty.register(function () {
+ that.isEmpty();
+ });
+ return true;
+ }
+ return false;
+ };
+
+ this.pop = function () {
+ return this.remove(-1);
+ };
+
+ this.remove = function (index) {
+ // TODO: parameter might be a geometry
+ if (this.del(index)) {
+ this.isEmpty();
+ return true;
+ }
+ return false;
+ };
+
+ /**
+ * Checks if the multi geometry is empty. If yes, the event onEmpty is triggered.
+ */
+ this.isEmpty = function () {
+ if (this.count() === 0) {
+ this.onEmpty.trigger();
+ return true;
+ }
+ return false;
+ };
+
+ this.onEmpty = new MapbenderEvent();
+
+ // this class extends List
+ this.list = [];
+ },
+
+ /**
+ * A class representing lines. A line is a List of Point objects
+ */
+ Line : function () {
+
+ this.getType = function () {
+ return Geometry.Type.line;
+ };
+
+ this.push = function (aPoint) {
+ if (Geometry.Type.isPoint(aPoint)) {
+ this.add(aPoint);
+ this.get(-1).onEmpty.register(function () {
+ that.rearrangeList();
+ });
+ return true;
+ }
+ return false;
+ };
+
+ this.remove = function (index) {
+ // TODO: parameter might be a point
+ if (this.del(index)) {
+ return this.isEmpty();
+ }
+ return false;
+ };
+
+ /**
+ * remove all invalid points
+ */
+ this.rearrangeList = function () {
+ var listLength = this.count();
+ for (var i = 0; i < listLength; i++) {
+ if (!this.get(i).isSet()) {
+ this.remove(i);
+ i -= 1;
+ listLength -= 1;
+ }
+ }
+ };
+
+ this.isEmpty = function () {
+ if (this.count === 0) {
+ this.onEmpty.trigger();
+ return true;
+ }
+ return false;
+ };
+
+ this.onEmpty = new MapbenderEvent();
+
+ // this class extends List
+ this.list = [];
+ },
+
+ /**
+ * A class representing a Polygon. A Polygon consists of an outer boundary (LinearRing)
+ * and 0..n inner boundaries (InnerBoundaryArray).
+ */
+ Polygon : function () {
+
+ this.getType = function () {
+ return Geometry.Type.polygon;
+ };
+
+ this.setOuterBoundary = function (aLinearRing) {
+ if (Geometry.Type.isLinearRing(aLinearRing)) {
+ outerBoundary = aLinearRing;
+ outerBoundary.onEmpty.register(function () {
+ that.isEmpty();
+ });
+ return true;
+ }
+ return false;
+ };
+
+ this.removeOuterBoundary = function () {
+ outerBoundary = null;
+ innerBoundaryArray = null;
+ return this.onEmpty.trigger();
+ };
+
+ this.appendInnerBoundary = function (aLinearRing) {
+ innerBoundaryArray.push(aLinearRing);
+ };
+
+ this.removeInnerBoundary = function (index) {
+ return innerBoundaryArray.remove(index);
+ };
+
+ this.isEmpty = function () {
+ if (!Geometry.Type.isLinearRing(outerBoundary)) {
+ return this.onEmpty.trigger();
+ }
+ return false;
+ };
+
+ var outerBoundary;
+ var innerBoundaryArray = new Geometry.InnerBoundaryArray();
+ },
+
+ /**
+ * An InnerBoundaryArray is a List of LinearRing objects.
+ */
+ InnerBoundaryArray : function () {
+
+ this.push = function (aLinearRing) {
+ if (Geometry.Type.isLinearRing(aLinearRing)) {
+ return this.add(aLinearRing);
+ }
+ return false;
+ };
+
+ this.remove = function (index) {
+ return this.del(index);
+ };
+
+ this.onEmpty = new MapbenderEvent();
+
+ this.list = [];
+ },
+
+ /**
+ * A Linear Ring is a List of Point objects. The last Point and the first Point must be identical.
+ */
+ LinearRing : function () {
+ this.getType = function () {
+ return Geometry.Type.linearring;
+ };
+
+ this.push = function (aPoint) {
+ if (Geometry.Type.isPoint(aPoint)) {
+ if (!this.isClosed()) {
+ this.add(aPoint);
+ // linear ring with at least 4 points (triangle!)
+ // AND
+ // last point equals first point
+ if (this.count() > 3 && this.get(0).equals(this.get(-1))) {
+ this.close();
+ }
+ this.get(-1).onEmpty.register(function () {
+ that.rearrangeList();
+ });
+ return true;
+ }
+ else {
+ var e = new Mb_warning("Geometry.LinearRing: push: Cannot add point; linear ring is already closed!");
+ }
+ }
+ return false;
+ };
+
+ this.remove = function (index) {
+ var i = this.getIndex(index);
+ if (i !== false) {
+ // if the first or last point is being deleted,
+ // re-set the first or last point so that the
+ // ring remains closed
+ if (i === 0 || i === this.getIndex(-1)) {
+ // remove the first point (list is automatically shifted)
+ this.del(0);
+
+ // check if there are still points remaining
+ if (!this.isEmpty()) {
+ // add the new first point as the last point
+ this.list[this.count()-1] = this.list[0];
+ }
+ return true;
+ }
+ // if it is a point in the middle, just delete it (list is automatically shifted)
+ else {
+ return this.del(i);
+ }
+ }
+ return false;
+ };
+
+ /**
+ * Checks if the outer boundary is empty. If yes, the event onEmpty is triggered.
+ */
+ this.isEmpty = function () {
+ if (this.count() === 0) {
+ this.onEmpty.trigger();
+ return true;
+ }
+ return false;
+ };
+
+ /**
+ * remove all invalid points
+ */
+ this.rearrangeList = function () {
+ var listLength = this.count();
+ for (var i = 0; i < listLength; i++) {
+ if (!this.get(i).isSet()) {
+ this.remove(i);
+ i -= 1;
+ listLength -= 1;
+ }
+ }
+ };
+
+ this.close = function () {
+ // linear ring with at least 4 points (triangle!)
+ // AND
+ // last point equals first point
+ if (this.count() > 3 && this.get(0).equals(this.get(-1))) {
+ closed = true;
+ return closed;
+ }
+ // linear with at least 3 points (triangle!)
+ // AND
+ // last point DOESNT equal first point
+ else if (this.count() > 2 && !this.get(0).equals(this.get(-1))) {
+ var newPoint = new Geometry.Point(this.get(0).x, this.get(0).y);
+ // push will return to close to set closed to true
+ this.push(newPoint);
+ }
+ else {
+ var e = new Mb_warning("Geometry.LinearRing: close: cannot close linear ring, must have at least 3 points (triangle)");
+ }
+ return false;
+ };
+
+ this.isClosed = function () {
+ return closed;
+ };
+
+ this.onEmpty = new MapbenderEvent();
+
+ /**
+ * if the first point and the last point match, and the ring has at least 4 points (triangle!)
+ * closed is set to true via close
+ */
+ var closed = false;
+
+ this.list = [];
+ },
+
+ /**
+ * A Point consists of an x- and a y-coordinate.
+ */
+ Point : function () {
+ this.getType = function () {
+ return Geometry.Type.point;
+ };
+
+ this.remove = function () {
+ onEmpty.trigger();
+ this.x = null;
+ this.y = null;
+ this.onEmpty = null;
+ };
+
+ /**
+ * x value of the {@link Point}
+ *
+ * @type Float
+ */
+ this.x = parseFloat(x);
+
+ /**
+ * y value of the {@link Point}
+ *
+ * @type Float
+ */
+ this.y = parseFloat(y);
+
+ this.isSet = function () {
+ return (this.x !== null && this.y !== null);
+ };
+
+ this.onEmpty = new MapbenderEvent();
+ }
+};
+
+Geometry.GeometryArray.prototype = new List();
+Geometry.MultiGeometry.prototype = new List();
+Geometry.InnerBoundary.prototype = new List();
+Geometry.LinearRing.prototype = new List();
+Geometry.Line.prototype = new List();
+
+/**
+ * computes the distance between a {@link Point} p and this {@link Point}
+ *
+ * @param {Point} p the distance between this {@link Point} and the {@link Point} p is computed.
+ * @return {Float} the distance between the two {@link Point} objects.
+ */
+Geometry.Point.prototype.dist = function(p){
+ return Math.sqrt(Math.pow(this.y-p.y,2) + Math.pow(this.x-p.x,2)) ;
+};
+/**
+ * checks if the coordinates of this {@link Point} match the coordinates of a {@link Point} p
+ *
+ * @param {Point} p
+ * @return {Boolean} true if the two points are equal; elso false
+ */
+Geometry.Point.prototype.equals = function(p){
+ if (this.x == p.x && this.y == p.y) {return true;}
+ return false;
+};
+/**
+ * subtracts a {@link Point} p from this {@link Point}
+ *
+ * @param {Point} p
+ * @return a new {@link Point} with the difference of the two points
+ */
+Geometry.Point.prototype.minus = function(p){
+ return new Point(this.x-p.x, this.y-p.y);
+};
+/**
+ * adds this {@link Point} to a {@link Point} p
+ *
+ * @param {Point} p
+ * @return a new {@link Point} with the sum of the two points
+ */
+Geometry.Point.prototype.plus = function(p){
+ return new Point(this.x+p.x, this.y+p.y);
+};
+/**
+ * divides this {@link Point} by a scalar c
+ *
+ * @param {Float} c divisor
+ * @return a new {@link Point} divided by c
+ */
+Geometry.Point.prototype.dividedBy = function(c){
+ if (c !== 0) {
+ return new Point(this.x/c, this.y/c);
+ }
+ var e = new Mb_exception("Point.dividedBy: Division by zero");
+ return false;
+};
+/**
+ * multiplies this {@link Point} by a scalar c
+ *
+ * @param {Float} c factor
+ * @return a new {@link Point} multiplied by c
+ */
+Geometry.Point.prototype.times = function(c){
+ return new Point(this.x*c, this.y*c);
+};
+/**
+ * rounds the coordinates to numOfDigits digits
+ *
+ * @param numOfDigits the coordinate will be rounded to numOfDigits digits
+ * @return a new {@link Point} rounded to numOfDigits digits
+ * @type Point
+ */
+Geometry.Point.prototype.round = function(numOfDigits){
+ return new Point(roundToDigits(this.x, numOfDigits), roundToDigits(this.y, numOfDigits));
+};
+/**
+ * @returns a {String} representation of this Point
+ * @type String
+ */
+Geometry.Point.prototype.toString = function(){
+ return "(" + this.x + ", " + this.y + ")";
+};
+
+
+
+/**
+ * @class an array of elements, each consisting of a name/value pair
+ *
+ * @ constructor
+ */
+function Wfs_element(){
+
+ /**
+ * returns the number of elements of this {@link Wfs_element} object.
+ *
+ * @return the number of elements
+ * @type Integer
+ */
+ this.count = function(){
+ return name.length;
+ };
+
+ /**
+ * returns the name of the element at index i.
+ *
+ * @param {Integer} i index
+ * @return the name
+ * @type String
+ */
+ this.getName = function(i){
+ if (isValidElementIndex(i)) {return name[i];}
+ return false;
+ };
+
+ /**
+ * returns the value of the element at index i.
+ *
+ * @param {Integer} i index
+ * @return the value
+ */
+ this.getValue = function(i){
+ if (isValidElementIndex(i)) {return value[i];}
+ return false;
+ };
+
+ /**
+ * appends a new element with a given name. If an element with this name exists, it is overwritten.
+ *
+ * @param {String} aName the name of the new element
+ * @param {String} aValue the value of the new element
+ */
+ this.setElement = function(aName, aValue){
+ var i = this.getElementIndexByName(aName);
+ if (i === false) {i = this.count();}
+ name[i] = aName;
+ value[i] = aValue;
+ };
+
+ /**
+ * checks if an index is valid
+ *
+ * @private
+ * @param {Integer} i an index
+ * @return true if the index is valid; otherwise false
+ * @type Boolean
+ */
+ var isValidElementIndex = function(i){
+ if (i>=0 && i<name.length) {return true;}
+ var e = new Mb_exception("class Wfs_element: function isValidElementIndex: illegal element index");
+ return false;
+ };
+
+ var name = [];
+ var value = [];
+}
+
+/**
+ * gets the index of the element with a given name.
+ *
+ * @param {String} elementName a name
+ * @return the index of the element; if no element with this name exists, false
+ * @type Integer, Boolean
+ */
+Wfs_element.prototype.getElementIndexByName = function(elementName){
+ for (var j = 0 ; j < this.count() ; j++){
+ if (this.getName(j) == elementName) {return j;}
+ }
+ return false;
+};
+
+/**
+ * gets the value of the element with a given name.
+ *
+ * @param {String} elementName a name
+ * @return the value of the element; if no element with this name exists, false
+ * @type String, Boolean
+ */
+Wfs_element.prototype.getElementValueByName = function(elementName){
+ var i = this.getElementIndexByName(elementName);
+ if (i === false) {return false;}
+ return this.getValue(i);
+};
+
+
+/**
+ * @class a {@link Canvas} contains a {@link DivTag} that holds graphics rendered by {@link jsGraphics}
+ *
+ * @constructor
+ * @requires DivTag
+ * @requires jsGraphics
+ * @requires GeometryArray
+ * @requires MultiGeometry
+ * @requires Geometry
+ * @param {String} aMapFrame name of the target mapframe
+ * @param {String} aTagName name of the target div tag
+ * @param {String} aStyle style of the div tag
+ * @param {Integer} aLineWidth the line width of the jsGraphics output
+ */
+function Canvas(aMapframe, aTagName, aStyle, aLineWidth) {
+
+ /**
+ * draws the geometry of the canvas
+ *
+ * @param {String} t geometry type (@see GeomType)
+ * @param {MultiGeometry} g a MultiGeometry object
+ * @param {String} col a color
+ * @private
+ */
+ this.drawGeometry = function(t,g,col){
+ var mapObjInd = getMapObjIndexByName(mapframe);
+ width = mb_mapObj[mapObjInd].width;
+ height = mb_mapObj[mapObjInd].height;
+ for(var i=0; i < g.count(); i++){
+ if(t==geomType.point) {
+ var p = realToMap(mapframe,g.get(i).get(0));
+ if (p.x + diameter < mb_mapObj[mapObjInd].width && p.x - diameter > 0 &&
+ p.y + diameter < mb_mapObj[mapObjInd].height && p.y - diameter > 0) {
+ drawCircle(p.x-1, p.y-1, diameter,col);
+ }
+ }
+ else if(t==geomType.line || t==geomType.polygon) {
+ for (var j=0; j<g.get(i).count()-1; j++) {
+ var pq = calculateVisibleDash(realToMap(mapframe,g.get(i).get(j)), realToMap(mapframe,g.get(i).get(j+1)), width, height);
+ if (pq) {
+ drawLine([pq[0].x-1, pq[1].x-1], [pq[0].y-1, pq[1].y-1], col);
+ }
+ }
+ }
+ else {
+ var e = new Mb_exception("class Canvas: function drawGeometry: unknown geomType " + t);
+ }
+ }
+ };
+
+ /**
+ * checks if the MultiGeometry's bounding box width and height is smaller than minWidth
+ *
+ * @private
+ * @param {MultiGeometry} g a MultiGeometry object
+ */
+ this.isTooSmall = function(g){
+ var tmp = g.getBBox();
+ var min = realToMap(mapframe,tmp[0]);
+ var max = realToMap(mapframe,tmp[1]);
+ if((Math.abs(max.x - min.x) < minWidth) && (Math.abs(max.y - min.y) < minWidth)) {
+ return true;
+ }
+ return false;
+ };
+
+ /**
+ * gets the jsGraphics.
+ *
+ * @private
+ * @return the jsGraphics
+ * @type jsGraphics
+ */
+ this.getCanvas = function(){
+ return canvas;
+ };
+
+ /**
+ * draws a circle with {@link jsGraphics}.
+ *
+ * @private
+ * @param {Float} x x value of the center
+ * @param {Float} y y value of the center
+ * @param {Float} diameter diameter of the circle
+ * @param {String} color the color of the circle in hex format
+ */
+ var drawCircle = function(x, y, diameter, color) {
+ canvas.setColor(color);
+ canvas.drawEllipse(x-diameter/2,y-diameter/2,diameter,diameter);
+ };
+
+ /**
+ * draws a polyline with {@link jsGraphics}.
+ *
+ * @private
+ * @param {Array} x_array array of x values
+ * @param {Array} y_array array of y values
+ * @param {String} color the color of the polyline in hex format
+ */
+ var drawLine = function(x_array, y_array, color) {
+ canvas.setColor(color);
+ canvas.drawPolyline(x_array, y_array);
+ };
+
+ /**
+ * This is the {@link DivTag} that contains the output by {@link jsGraphics}.
+ *
+ * @type DivTag
+ */
+ this.canvasDivTag = new DivTag(aTagName, aMapframe, aStyle);
+
+ var that = this;
+
+ var diameter = 8;
+ var minWidth = 8;
+ var lineWidth = aLineWidth;
+ var mapframe = aMapframe;
+ var style = aStyle;
+ var canvas = new jsGraphics(aTagName, window.frames[mapframe]);
+ canvas.setStroke(lineWidth);
+ mb_registerPanSubElement(aTagName);
+}
+
+/**
+ * cleans the canvas by emptying the canvas {@link DivTag}.
+ */
+Canvas.prototype.clean = function () {
+ this.canvasDivTag.clean();
+};
+
+/**
+ * paints all geometries.
+ *
+ * @param {GeometryArray} gA the geometries that will be drawn
+ */
+Canvas.prototype.paint = function(gA) {
+ for (var q = 0; q < gA.count(); q++) {
+ var m = gA.get(q);
+ var t = m.geomType;
+ var col = m.color;
+ if (t == geomType.point) {
+ this.drawGeometry(t,m,col);
+ }
+ else {
+ if (this.isTooSmall(m)){
+ var newMember = new MultiGeometry(geomType.point);
+ newMember.addGeometry();
+ newMember.get(-1).addPoint(m.getCenter());
+ this.drawGeometry(geomType.point,newMember,col);
+ }
+ else{
+ if(t == geomType.line) {this.drawGeometry(t,m, col);}
+ else if(t == geomType.polygon) {this.drawGeometry(t,m,col);}
+ else {
+ var e = new Mb_exception("class Canvas: function paint: unknown geomType" + t);
+ }
+ }
+ }
+ }
+ this.getCanvas().paint();
+};
+
+/**
+ * @class a {@link Highlight} object is {@link jsGraphics} rendering of a {@link GeometryArray} in various mapframes.
+ *
+ * @constructor
+ * @requires Canvas
+ * @requires GeometryArray
+ * @param {Array} aTargetArray an array of Strings referring to mapframes
+ * @param {String} aTagName the name of the div tags
+ * @param {Object} aStyle the style of the div tags
+ * @param {Integer} the line width of the jsGraphics lines
+ */
+function Highlight(aTargetArray, aTagName, aStyle, aLineWidth) {
+ /**
+ * removes a {@link MultiGeometry} object from the geometry Array
+ *
+ * @param {MultiGeometry} m a MultiGeometry
+ * @param {String} color a color
+ */
+ this.del = function(m, color) {
+ var a = gA.findMultiGeometry(m);
+ var del = false;
+ for (var i=0; i<a.length && del === false; i++) {
+ if (gA.get(a[i]).color == color) {
+ gA.del(a[i]);
+ del = true;
+ }
+ }
+ this.paint();
+ };
+
+ /**
+ * adds a {@link MultiGeometry} object to the geometry Array
+ *
+ * @param {MultiGeometry} m a MultiGeometry
+ * @param {String} color the color of the highlight
+ */
+ this.add = function(m, color) {
+ gA.addCopy(m);
+ if (typeof(color) != 'undefined') {gA.get(-1).color = color;}
+ else {gA.get(-1).color = lineColor;}
+ this.paint();
+ };
+
+ /**
+ * removes all MultiGeometries.
+ *
+ */
+ this.clean = function() {
+ if (gA.count() > 0) {
+ gA = new GeometryArray();
+ this.paint();
+ }
+ };
+
+ /**
+ * displays the highlight
+ *
+ */
+ this.paint = function() {
+ for (var i=0; i < canvas.length; i++) {
+ if (typeof(canvas[i]) == "object") {canvas[i].clean();}
+ }
+ for (var i=0; i<targets.length; i++){
+ if (typeof(canvas[i]) == 'undefined') {
+ canvas[i] = new Canvas(targets[i], tagname, style, lineWidth);
+ }
+ canvas[i].paint(gA);
+ }
+ };
+
+ var lineWidth = aLineWidth;
+ var tagname = 'mod_gaz_draw'+aTagName;
+ var style = aStyle;
+ var targets = aTargetArray;
+ var canvas = [];
+ var gA = new GeometryArray();
+ var lineColor = "#ff0000";
+ this.paint();
+}
+
+// ----------------------------------------------------------------------------------------------------
+// Snapping
+// ----------------------------------------------------------------------------------------------------
+/**
+ * @class a {@link Snapping} object stores is {@link jsGraphics} rendering of a {@link GeometryArray} in various mapframes.
+ *
+ * @constructor
+ * @requires GeometryArray
+ * @requires Highlight
+ * @param {String} aTarget name of the mapframe where snapping occurs
+ * @param {String} aTolerance Snapping is activated if the mouse is
+ * within aTolerance pixel distance to the reference point.
+ * @param {String} aColor apparently deprecated?
+ * @param {Integer} aZIndex the z-Index of the {@link jsGraphics} generated by {@link Highlight}.
+ */
+function Snapping(aTarget, aTolerance, aColor, aZIndex){
+
+ /**
+ * draws a circle to highlight the snapped point.
+ *
+ * @param {Point} center the snapped point.
+ * @param {Integer} radius radius of the circular highlight.
+ */
+ this.draw = function(center,radius){
+ mG = new MultiGeometry(geomType.point);
+ mG.addGeometry();
+ mG.get(-1).addPoint(center);
+ highlight.add(mG);
+ };
+ this.getTolerance = function() {
+ return tolerance;
+ };
+ this.getTarget = function() {
+ return target;
+ };
+ this.cleanHighlight = function() {
+ return highlight.clean();
+ };
+ this.addPoint = function(aPoint) {
+ coord.push(aPoint);
+ };
+ this.getPointCount = function() {
+ return coord.length;
+ };
+ this.getPoint = function(i) {
+ return coord[i];
+ };
+ this.resetPoints = function() {
+ coord = [];
+ };
+ this.getNearestNeighbour = function(){
+ if (min_i != -1) {return this.getPoint(min_i);}
+ return false;
+ };
+ this.setIndexOfNearestNeighbour = function(i){
+ min_i = i;
+ };
+ this.resetIndexOfNearestNeighbour = function(){
+ min_i = -1;
+ };
+
+ /**
+ * @private
+ */
+ var tolerance = (typeof(aTolerance) == 'undefined') ? 10 : aTolerance;
+
+ /**
+ * @private
+ */
+ var zIndex = (typeof(aZIndex) == 'undefined') ? 50 : aZIndex;
+
+ /**
+ * @private
+ */
+ var coord = [];
+
+ /**
+ * @private
+ */
+ var min_i = -1;
+
+ /**
+ * @private
+ */
+ var target = aTarget;
+
+ /**
+ * @private
+ */
+ var lineWidth = 2;
+
+ /**
+ * @private
+ */
+ var style = {"position":"absolute", "top":"0px", "left":"0px", "z-index":zIndex};
+
+ /**
+ * @private
+ */
+ var highlight = new Highlight([target], "snapping"+Math.round(Math.random()*Math.pow(10,10)), style, lineWidth);
+}
+
+Snapping.prototype.check = function(currPoint){
+ var minDist = false;
+
+ for (var i = 0 ; i < this.getPointCount() ; i++) {
+
+ var currDist = currPoint.dist(realToMap(this.getTarget(), this.getPoint(i)));
+ if (minDist === false || currDist < minDist) {
+ minDist = currDist;
+ if (minDist < this.getTolerance()) {this.setIndexOfNearestNeighbour(i);}
+ }
+ }
+ if (this.getPointCount() > 0 && minDist > this.getTolerance()) {
+ this.resetIndexOfNearestNeighbour();
+ }
+ this.cleanHighlight();
+ if (this.isSnapped()) {
+ this.draw(this.getNearestNeighbour(), this.getTolerance());
+ }
+};
+
+/**
+ * Stores the points which will have the snapping property.
+ *
+ * @param {GeometryArray} geom all points of geom will be stored. May also be a
+ * {@link MultiGeometry} or {@link Geometry}.
+ * @param {Point} point this point is excluded. Useful when moving a point of a
+ * geometry; you don't want to snap against the point you
+ * move. Optional.
+ */
+Snapping.prototype.store = function(geom, point){
+ this.resetPoints();
+ this.resetIndexOfNearestNeighbour();
+
+ for (var i = 0 ; i < geom.count(); i++){
+ if (geom.name == nameGeometryArray || geom.name == nameMultiGeometry){
+ for (var j = 0 ; j < geom.get(i).count() ; j++){
+ if (geom.get(i).name == nameMultiGeometry){
+ for (var k = 0 ; k < geom.get(i).get(j).count() ; k++){
+ if ((geom.get(i).get(j).isComplete() === true && typeof(point) == 'undefined') || (typeof(point) != 'undefined' && !geom.get(i).get(j).get(k).equals(point))){
+ this.add(geom.getPoint(i, j, k));
+ }
+ }
+ }
+ else {
+ if ((geom.get(i).isComplete() === true && typeof(point) == 'undefined') || (typeof(point) != 'undefined' && !geom.get(i).get(j).get(k).equals(point))){
+ this.add(geom.getPoint(i, j));
+ }
+ }
+ }
+ }
+ else {
+ if (typeof(point) != 'undefined' && !geom.get(i).get(j).get(k).equals(point)){
+ this.add(geom.get(i));
+ }
+ }
+ }
+};
+
+/**
+ * Determines whether a point is within snapping distance to the mouse cursor
+ *
+ * @return true if a point is within snapping distance; else false
+ * @type Boolean
+ */
+Snapping.prototype.isSnapped = function(){
+ if (this.getNearestNeighbour() !== false) {return true;}
+ return false;
+};
+
+/**
+ * Returns the point that is within snapping distance and closest to the mouse cursor.
+ *
+ * @return the point (if there is any); else false
+ * @type Point
+ */
+Snapping.prototype.getSnappedPoint = function(){
+ return this.getNearestNeighbour();
+};
+
+/**
+ * Adds the point to the stored points with snapping property.
+ *
+ * @param {Point} point which receives snapping property.
+ */
+Snapping.prototype.add = function(aPoint){
+ this.addPoint(aPoint);
+};
+
+/**
+ * Removes the highlight.
+ */
+Snapping.prototype.clean = function(){
+ this.cleanHighlight();
+};
+
+
+
+// ----------------------------------------------------------------------------------------------------
+// misc. functions
+// ----------------------------------------------------------------------------------------------------
+
+/**
+ * @ignore
+ */
+function calculateVisibleDash (p0, p1, width, height) {
+ if (p0.x > p1.x) {var p_temp = p0; p0 = p1; p1 = p_temp; p_temp = null;}
+ var p = p0; var q = p1; var m; var ix; var iy;
+ if (p1.x != p0.x) {
+ m = -(p1.y-p0.y)/(p1.x-p0.x);
+ if (p0.x < width && p1.x > 0 && !(p0.y < 0 && p1.y < 0) && !(p0.y > height && p1.y > height) ) {
+ if (p0.x < 0) {
+ iy = p0.y - m*(0-p0.x);
+ if (iy > 0 && iy < height) {p = new Point(0, iy);}
+ else if (iy > height) {
+ ix = p0.x+((p0.y - height)/m);
+ if (ix > 0 && ix < width) {p = new Point(ix, height);} else {return false;}
+ }
+ else if (iy < 0) {
+ ix = p0.x+(p0.y/m);
+ if (ix > 0 && ix < width) {p = new Point(ix, 0);} else {return false;}
+ }
+ else {return false;}
+ }
+ else if (p0.y >= 0 && p0.y <= height) {p = p0;}
+ else if (p0.y < 0) {
+ ix = p0.x+(p0.y/m);
+ if (ix > 0 && ix < width) {p = new Point(ix, 0);} else {return false;}
+ }
+ else if (p0.y > height && m > 0) {
+ ix = p0.x+((p0.y - height)/m);
+ if (ix > 0 && ix < width) {p = new Point(ix, height);} else {return false;}
+ }
+ else {return false;}
+ if (p1.x > width) {
+ iy = p1.y - m*(width-p1.x);
+ if (iy > 0 && iy < height) {q = new Point(width, iy);}
+ else if (iy < 0) {
+ ix = p0.x+(p0.y/m);
+ if (ix > 0 && ix < width) {q = new Point(ix, 0);} else {return false;}
+ }
+ else if (iy > height) {
+ ix = p0.x+((p0.y - height)/m);
+ if (ix > 0 && ix < width) {q = new Point(ix, height);} else {return false;}
+ }
+ else {return false;}
+ }
+ else if (p1.y >= 0 && p1.y <= height) {q = p1;}
+ else if (p1.y < 0) {
+ ix = p1.x+(p1.y/m);
+ if (ix > 0 && ix < width) {q = new Point(ix, 0);} else {return false;}
+ }
+ else if (p1.y > height) {
+ ix = p1.x+((p1.y- height)/m);
+ if (ix > 0 && ix < width) {q = new Point(ix, height);} else {return false;}
+ }
+ }
+ else {return false;}
+ }
+ else {
+ if (!(p0.y < 0 && p1.y < 0) && !(p0.y > height && p1.y > height)) {
+ if (p0.y < 0) {p = new Point(p0.x, 0);}
+ else if (p0.y > height) {p = new Point(p0.x, height);}
+ else {p = p0;}
+ if (p1.y < 0) {q = new Point(p0.x, 0);}
+ else if (p1.y > height) {q = new Point(p0.x, height);}
+ else {q = p1;}
+ }
+ else {return false;}
+ }
+ return [new Point(Math.round(q.x), Math.round(q.y)), new Point(Math.round(p.x), Math.round(p.y))];
+}
+
+/**
+ * @ignore
+ */
+function objString (a){
+ var z = "";
+
+ for (attr in a) {
+ var b = a[attr];
+ if (typeof(b) == "object") {z += objString(b);}
+ else {z += attr + " " + b + "\n";alert(attr + " " + b);}
+ }
+ return z;
+}
More information about the Mapbender_commits
mailing list