Geometry.js
7.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Format/WKT.js
* @requires OpenLayers/Feature/Vector.js
*/
/**
* Class: OpenLayers.Geometry
* A Geometry is a description of a geographic object. Create an instance of
* this class with the <OpenLayers.Geometry> constructor. This is a base class,
* typical geometry types are described by subclasses of this class.
*/
OpenLayers.Geometry = OpenLayers.Class({
/**
* Property: id
* {String} A unique identifier for this geometry.
*/
id: null,
/**
* Property: parent
* {<OpenLayers.Geometry>}This is set when a Geometry is added as component
* of another geometry
*/
parent: null,
/**
* Property: bounds
* {<OpenLayers.Bounds>} The bounds of this geometry
*/
bounds: null,
/**
* Constructor: OpenLayers.Geometry
* Creates a geometry object.
*/
initialize: function() {
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ "_");
},
/**
* Method: destroy
* Destroy this geometry.
*/
destroy: function() {
this.id = null;
this.bounds = null;
},
/**
* APIMethod: clone
* Create a clone of this geometry. Does not set any non-standard
* properties of the cloned geometry.
*
* Returns:
* {<OpenLayers.Geometry>} An exact clone of this geometry.
*/
clone: function() {
return new OpenLayers.Geometry();
},
/**
* Set the bounds for this Geometry.
*
* Parameters:
* object - {<OpenLayers.Bounds>}
*/
setBounds: function(bounds) {
if (bounds) {
this.bounds = bounds.clone();
}
},
/**
* Method: clearBounds
* Nullify this components bounds and that of its parent as well.
*/
clearBounds: function() {
this.bounds = null;
if (this.parent) {
this.parent.clearBounds();
}
},
/**
* Method: extendBounds
* Extend the existing bounds to include the new bounds.
* If geometry's bounds is not yet set, then set a new Bounds.
*
* Parameters:
* newBounds - {<OpenLayers.Bounds>}
*/
extendBounds: function(newBounds){
var bounds = this.getBounds();
if (!bounds) {
this.setBounds(newBounds);
} else {
this.bounds.extend(newBounds);
}
},
/**
* APIMethod: getBounds
* Get the bounds for this Geometry. If bounds is not set, it
* is calculated again, this makes queries faster.
*
* Returns:
* {<OpenLayers.Bounds>}
*/
getBounds: function() {
if (this.bounds == null) {
this.calculateBounds();
}
return this.bounds;
},
/**
* APIMethod: calculateBounds
* Recalculate the bounds for the geometry.
*/
calculateBounds: function() {
//
// This should be overridden by subclasses.
//
},
/**
* Method: atPoint
* Note - This is only an approximation based on the bounds of the
* geometry.
*
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
* toleranceLon - {float} Optional tolerance in Geometric Coords
* toleranceLat - {float} Optional tolerance in Geographic Coords
*
* Returns:
* {Boolean} Whether or not the geometry is at the specified location
*/
atPoint: function(lonlat, toleranceLon, toleranceLat) {
var atPoint = false;
var bounds = this.getBounds();
if ((bounds != null) && (lonlat != null)) {
var dX = (toleranceLon != null) ? toleranceLon : 0;
var dY = (toleranceLat != null) ? toleranceLat : 0;
var toleranceBounds =
new OpenLayers.Bounds(this.bounds.left - dX,
this.bounds.bottom - dY,
this.bounds.right + dX,
this.bounds.top + dY);
atPoint = toleranceBounds.containsLonLat(lonlat);
}
return atPoint;
},
/**
* Method: getLength
* Calculate the length of this geometry. This method is defined in
* subclasses.
*
* Returns:
* {Float} The length of the collection by summing its parts
*/
getLength: function() {
//to be overridden by geometries that actually have a length
//
return 0.0;
},
/**
* Method: getArea
* Calculate the area of this geometry. This method is defined in subclasses.
*
* Returns:
* {Float} The area of the collection by summing its parts
*/
getArea: function() {
//to be overridden by geometries that actually have an area
//
return 0.0;
},
/**
* Method: toString
* Returns the Well-Known Text representation of a geometry
*
* Returns:
* {String} Well-Known Text
*/
toString: function() {
return OpenLayers.Format.WKT.prototype.write(
new OpenLayers.Feature.Vector(this)
);
},
CLASS_NAME: "OpenLayers.Geometry"
});
/**
* Method: OpenLayers.Geometry.segmentsIntersect
* Determine whether two line segments intersect. Optionally calculates
* and returns the intersection point. This function is optimized for
* cases where seg1.x2 >= seg2.x1 || seg2.x2 >= seg1.x1. In those
* obvious cases where there is no intersection, the function should
* not be called.
*
* Parameters:
* seg1 - {Object} Object representing a segment with properties x1, y1, x2,
* and y2. The start point is represented by x1 and y1. The end point
* is represented by x2 and y2. Start and end are ordered so that x1 < x2.
* seg2 - {Object} Object representing a segment with properties x1, y1, x2,
* and y2. The start point is represented by x1 and y1. The end point
* is represented by x2 and y2. Start and end are ordered so that x1 < x2.
* point - {Boolean} Return the intersection point. If false, the actual
* intersection point will not be calculated. If true and the segments
* intersect, the intersection point will be returned. If true and
* the segments do not intersect, false will be returned. If true and
* the segments are coincident, true will be returned.
*
* Returns:
* {Boolean | <OpenLayers.Geometry.Point>} The two segments intersect.
* If the point argument is true, the return will be the intersection
* point or false if none exists. If point is true and the segments
* are coincident, return will be true (and the instersection is equal
* to the shorter segment).
*/
OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, point) {
var intersection = false;
var x11_21 = seg1.x1 - seg2.x1;
var y11_21 = seg1.y1 - seg2.y1;
var x12_11 = seg1.x2 - seg1.x1;
var y12_11 = seg1.y2 - seg1.y1;
var y22_21 = seg2.y2 - seg2.y1;
var x22_21 = seg2.x2 - seg2.x1;
var d = (y22_21 * x12_11) - (x22_21 * y12_11);
var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);
var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);
if(d == 0) {
// parallel
if(n1 == 0 && n2 == 0) {
// coincident
intersection = true;
}
} else {
var along1 = n1 / d;
var along2 = n2 / d;
if(along1 >= 0 && along1 <= 1 && along2 >=0 && along2 <= 1) {
// intersect
if(!point) {
intersection = true;
} else {
// calculate the intersection point
var x = seg1.x1 + (along1 * x12_11);
var y = seg1.y1 + (along1 * y12_11);
intersection = new OpenLayers.Geometry.Point(x, y);
}
}
}
return intersection;
};