我是靠谱客的博主 畅快柜子,这篇文章主要介绍 百度地图判断多边形区域是否重复,现在分享给大家,希望可以做个参考。

原文来自 taoeer.top

前端时间遇到个问题,就是判断百度地图里的多个任意多边形区域是否重复,在网上看了很多的文章都没有找到解决方案,功夫不负有心人,在网上找到个可以判断是否重复的,但是在包含的情况下就不能判断,后来自己加入根据点判断点是否在多边形内来判断重复,问题已解决,在此把代码贴出来,供大家参考


复制代码
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
//#region 验证两个面是否相交的算法 (此函数摘抄自网络) function intersectsPolygonAndPolygon (polygon1LinearRings, polygon2LinearRings) { // polygon1LinearRings : array[LinearRing,...] function intersectsByPolygon (polygon1LinearRings, polygon2LinearRings) { var intersect = false; intersect = intersectsByLinearRings(polygon1LinearRings, polygon2LinearRings); if(!intersect) { // check if this poly contains points of the ring/linestring for(i=0, len=polygon2LinearRings.length; i<len; ++i) { var point = polygon2LinearRings[i]; intersect = containsPointByLinearRing(point, polygon1LinearRings); if(intersect) { break; } } } return intersect; } // LinearRings function containsPointByPolygon (point, LinearRings) { var numRings = LinearRings.length; var contained = false; if(numRings > 0) { contained = containsPointByLinearRing(point, LinearRings[0]); if( numRings > 1) { // check interior rings var hole; for(var i=1; i<numRings; ++i) { hole = containsPointByLinearRing(point, LinearRings[i]); if(hole) { if(hole === 1) { // on edge contained = 1; } else { // in hole contained = false; } break; } } } } return contained; } // LinearRing : array[pt] // point : {x:1,y:2} function containsPointByLinearRing (point, LinearRing) { //limitSigDigs function approx(num, sig) { var fig = 0; if (sig > 0) { fig = parseFloat(num.toPrecision(sig)); } return fig; } var digs = 14; var px = approx(point.x, digs); var py = approx(point.y, digs); function getX(y, x1, y1, x2, y2) { return (y - y2) * ((x2 - x1) / (y2 - y1)) + x2; } var numSeg = LinearRing.length - 1; var start, end, x1, y1, x2, y2, cx, cy; var crosses = 0; for(var i=0; i<numSeg; ++i) { start = LinearRing[i]; x1 = approx(start.x, digs); y1 = approx(start.y, digs); end = LinearRing[i + 1]; x2 = approx(end.x, digs); y2 = approx(end.y, digs); if(y1 == y2) { // horizontal edge if(py == y1) { // point on horizontal line if(x1 <= x2 && (px >= x1 && px <= x2) || // right or vert x1 >= x2 && (px <= x1 && px >= x2)) { // left or vert // point on edge crosses = -1; break; } } // ignore other horizontal edges continue; } cx = approx(getX(py, x1, y1, x2, y2), digs); if(cx == px) { // point on line if(y1 < y2 && (py >= y1 && py <= y2) || // upward y1 > y2 && (py <= y1 && py >= y2)) { // downward // point on edge crosses = -1; break; } } if(cx <= px) { // no crossing to the right continue; } if(x1 != x2 && (cx < Math.min(x1, x2) || cx > Math.max(x1, x2))) { // no crossing continue; } if(y1 < y2 && (py >= y1 && py < y2) || // upward y1 > y2 && (py < y1 && py >= y2)) { // downward ++crosses; } } var contained = (crosses == -1) ? // on edge 1 : // even (out) or odd (in) !!(crosses & 1); return contained; } function intersectsByLinearRings (LinearRing1, LinearRings2) { var intersect = false; var segs1 = getSortedSegments(LinearRing1); var segs2 = getSortedSegments(LinearRings2); var seg1, seg1x1, seg1x2, seg1y1, seg1y2, seg2, seg2y1, seg2y2; // sweep right outer: for(var i=0, len=segs1.length; i<len; ++i) { seg1 = segs1[i]; seg1x1 = seg1.x1; seg1x2 = seg1.x2; seg1y1 = seg1.y1; seg1y2 = seg1.y2; inner: for(var j=0, jlen=segs2.length; j<jlen; ++j) { seg2 = segs2[j]; if(seg2.x1 > seg1x2) { // seg1 still left of seg2 break; } if(seg2.x2 < seg1x1) { // seg2 still left of seg1 continue; } seg2y1 = seg2.y1; seg2y2 = seg2.y2; if(Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2)) { // seg2 above seg1 continue; } if(Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2)) { // seg2 below seg1 continue; } if(segmentsIntersect(seg1, seg2)) { intersect = true; break outer; } } } return intersect; } function getSortedSegments(points) { var numSeg = points.length - 1; var segments = new Array(numSeg), point1, point2; for(var i=0; i<numSeg; ++i) { point1 = points[i]; point2 = points[i + 1]; if(point1.x < point2.x) { segments[i] = { x1: point1.x, y1: point1.y, x2: point2.x, y2: point2.y }; } else { segments[i] = { x1: point2.x, y1: point2.y, x2: point1.x, y2: point1.y }; } } // more efficient to define this somewhere static function byX1(seg1, seg2) { return seg1.x1 - seg2.x1; } return segments.sort(byX1); } function segmentsIntersect(seg1, seg2, options) { var point = options && options.point; var tolerance = options && options.tolerance; 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 = { 'x':x, 'y':y }; } } } if(tolerance) { var dist; if(intersection) { if(point) { var segs = [seg1, seg2]; var seg, x, y; // check segment endpoints for proximity to intersection // set intersection to first endpoint within the tolerance outer: for(var i=0; i<2; ++i) { seg = segs[i]; for(var j=1; j<3; ++j) { x = seg["x" + j]; y = seg["y" + j]; dist = Math.sqrt( Math.pow(x - intersection.x, 2) + Math.pow(y - intersection.y, 2) ); if(dist < tolerance) { intersection.x = x; intersection.y = y; break outer; } } } } } else { // no calculated intersection, but segments could be within // the tolerance of one another var segs = [seg1, seg2]; var source, target, x, y, p, result; // check segment endpoints for proximity to intersection // set intersection to first endpoint within the tolerance outer: for(var i=0; i<2; ++i) { source = segs[i]; target = segs[(i+1)%2]; for(var j=1; j<3; ++j) { p = {x: source["x"+j], y: source["y"+j]}; result = distanceToSegment(p, target); if(result.distance < tolerance) { if(point) { intersection = { 'x':p.x, 'y':p.y }; } else { intersection = true; } break outer; } } } } } return intersection; }; function distanceToSegment(point, segment) { var result = distanceSquaredToSegment(point, segment); result.distance = Math.sqrt(result.distance); return result; }; function distanceSquaredToSegment(point, segment) { var x0 = point.x; var y0 = point.y; var x1 = segment.x1; var y1 = segment.y1; var x2 = segment.x2; var y2 = segment.y2; var dx = x2 - x1; var dy = y2 - y1; var along = ((dx * (x0 - x1)) + (dy * (y0 - y1))) / (Math.pow(dx, 2) + Math.pow(dy, 2)); var x, y; if(along <= 0.0) { x = x1; y = y1; } else if(along >= 1.0) { x = x2; y = y2; } else { x = x1 + along * dx; y = y1 + along * dy; } return { distance: Math.pow(x - x0, 2) + Math.pow(y - y0, 2), x: x, y: y, along: along }; } return intersectsByPolygon(polygon1LinearRings, polygon2LinearRings); } //#endregion function railsIsOverlap (rails) { var i, j, k, v, l, n; if (rails.length < 2) { return false; } for (i = 0, j = rails.length - 1; i < j; i++) { var rail = rails[i]; var railPath = rail.getPath(); for (k = i + 1, v = rails.length; k < v; k++) { var railed = rails[k]; var railedPath = railed.getPath(); for (l = 0 , n = railPath.length; l < n; l ++) { if (BMapLib.GeoUtils.isPointInPolygon(new BMap.Point(railPath[l].lng, railPath[l].lat), railed)) { layer.alert("片区不能重复"); return true; } } for (l = 0, n = railedPath.length; l < n; l ++) { if (BMapLib.GeoUtils.isPointInPolygon(new BMap.Point(railedPath[l].lng, railedPath[l].lat), rail)) { // console.log(53) layer.alert("片区不能重复"); return true; } } } } var lines = []; for ( i = 0 ; i < rails.length; i ++) { var line = rails[i].getPath(); lines.push([]); for (j = 0 ;j < line.length ; j ++) { var p = { x: line[j].lng, y: line[j].lat }; lines[i].push(p); } lines[i].push(lines[i][0]) } for (i = 0; i < lines.length - 1; i ++) { var p1 = lines[i]; for (j = i + 1; j < lines.length; j ++) { var p2 = lines[j]; if (intersectsPolygonAndPolygon(p1,p2)) { layer.alert("片区不能重复!"); return true; } } } return false; }

使用时直接调用railsIsOverlap函数就行,参数是多边形数组

最后

以上就是畅快柜子最近收集整理的关于 百度地图判断多边形区域是否重复的全部内容,更多相关内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部