31 | | |
32 | | If this is the reason, then this problem is not so easy to fix. We can have very short arcs in our data and using same absolute stroking length means troubles. |
33 | | \\I would think more, if things could be done completely without stroking. |
34 | | \\At least I would use relative stroking compared to arc length. |
35 | | \\As a stroking method, I like most the tolerance method. Tolerance means maximum difference between original arc and stroked line. For short arcs the parametric vertices count comes more important. |
36 | | \\I created following code with Python for you to copy (and test!) freely: |
37 | | \\User can give parameters accuracy "tolerance" or number of "vertices" in resulting stroked line. |
38 | | |
39 | | {{{ |
40 | | # Radius (r), centroid (cx,cy) and angles (a1 and a3) are now |
41 | | # calculated to arc geometry (p1, p2, p3). |
42 | | # Angles a1 and a3 are specified properly when compared to sweeping angle direction. |
43 | | # Then we start stroking the geometry |
44 | | |
45 | | angleArc = a3 - a1 |
46 | | toleranceVertices = 0 |
47 | | verticesCount = 0 |
48 | | StrokingTolerance = 0.0 |
49 | | |
50 | | # If user gave the stroking tolerance, we calculate maximum angle of one stroke sector. |
51 | | # from equation: cos(angle / 2) = (radius - tolerance) / radius |
52 | | # We calculate also minimum count of vertices for whole arc that satisfies tolerance. |
53 | | |
54 | | if tolerance > 0.0: |
55 | | StrokingTolerance = tolerance |
56 | | if StrokingTolerance > 2 * r: |
57 | | StrokingTolerance = 2 * r |
58 | | angleSectorFromTolerance = 2 * math.acos((r - StrokingTolerance) / r) |
59 | | toleranceVertices = int(abs(angleArc / angleSectorFromTolerance)) |
60 | | |
61 | | # If user gave exact amount of vertices to use, |
62 | | # we use it or we use vertice count calculated from tolerance, |
63 | | # which ever is bigger so meaning more accurate. |
64 | | |
65 | | if vertices > toleranceVertices: |
66 | | verticesCount = vertices |
67 | | else: |
68 | | verticesCount = toleranceVertices |
69 | | |
70 | | # Now calculate exact angle of one stroke sector from count of vertices. |
71 | | |
72 | | angleSector = angleArc / (verticesCount + 1) |
73 | | |
74 | | # Calculate vertice points and create line from them. |
75 | | |
76 | | pointList = [(p1x, p1y)] |
77 | | |
78 | | for i in range(1, verticesCount + 1): |
79 | | currentAngle = a1 + i * angleSector |
80 | | newPointX = cx + r * math.cos(currentAngle) |
81 | | newPointY = cy + r * math.sin(currentAngle) |
82 | | pointList.append((newPointX, newPointY)) |
83 | | |
84 | | pointList.append((p3x, p3y)) |
85 | | }}} |
86 | | |
87 | | Ok, lots of text and actual error is maybe located somewhere else. |
88 | | \\I wish good luck for solving this, because function ST_Intersects is widely used in QGIS, Openlayers, etc. and this error results missing geometries and error messages in data that holds arcs. |