@@ -35,3 +35,171 @@ const double QgsClipper::MAX_Y = 16000;
35
35
const double QgsClipper::MIN_Y = -16000 ;
36
36
37
37
const double QgsClipper::SMALL_NUM = 1e-12 ;
38
+
39
+ unsigned char * QgsClipper::clippedLineWKB ( unsigned char * wkb, const QgsRectangle& clipExtent, QPolygonF& line )
40
+ {
41
+ wkb++; // jump over endian info
42
+ unsigned int wkbType = *(( int * ) wkb );
43
+ wkb += sizeof ( unsigned int );
44
+ unsigned int nPoints = *(( int * ) wkb );
45
+ wkb += sizeof ( unsigned int );
46
+
47
+ bool hasZValue = ( wkbType == QGis::WKBLineString25D );
48
+
49
+ double p0x, p0y, p1x, p1y; // original coordinates
50
+ double p1x_c, p1y_c; // clipped end coordinates
51
+ double lastClipX, lastClipY; // last successfully clipped coords
52
+
53
+ line.reserve ( nPoints + 1 );
54
+ line.clear ();
55
+
56
+ for ( unsigned int i = 0 ; i < nPoints; ++i )
57
+ {
58
+ if ( i == 0 )
59
+ {
60
+ memcpy ( &p1x, wkb, sizeof ( double ) );
61
+ wkb += sizeof ( double );
62
+ memcpy ( &p1y, wkb, sizeof ( double ) );
63
+ wkb += sizeof ( double );
64
+ if ( hasZValue ) // ignore Z value
65
+ {
66
+ wkb += sizeof ( double );
67
+ }
68
+ continue ;
69
+ }
70
+ else
71
+ {
72
+ p0x = p1x;
73
+ p0y = p1y;
74
+
75
+ memcpy ( &p1x, wkb, sizeof ( double ) );
76
+ wkb += sizeof ( double );
77
+ memcpy ( &p1y, wkb, sizeof ( double ) );
78
+ wkb += sizeof ( double );
79
+ if ( hasZValue ) // ignore Z value
80
+ {
81
+ wkb += sizeof ( double );
82
+ }
83
+
84
+ p1x_c = p1x; p1y_c = p1y;
85
+ if ( clipLineSegment ( clipExtent.xMinimum (), clipExtent.xMaximum (), clipExtent.yMinimum (), clipExtent.yMaximum (),
86
+ p0x, p0y, p1x_c, p1y_c ) )
87
+ {
88
+ bool newLine = line.size () > 0 && ( p1x_c != lastClipX || p1y_c != lastClipY );
89
+ if ( newLine )
90
+ {
91
+ // add edge points to connect old and new line
92
+ connectSeparatedLines ( lastClipX, lastClipY, p0x, p0y, clipExtent, line );
93
+ }
94
+ if ( line.size () < 1 || newLine )
95
+ {
96
+ // add first point
97
+ line << QPointF ( p0x, p0y );
98
+ }
99
+
100
+ // add second point
101
+ lastClipX = p1x_c; lastClipY = p1y_c;
102
+ line << QPointF ( p1x_c, p1y_c );
103
+ }
104
+ }
105
+ }
106
+ return wkb;
107
+ }
108
+
109
+ void QgsClipper::connectSeparatedLines ( double x0, double y0, double x1, double y1,
110
+ const QgsRectangle& clipRect, QPolygonF& pts )
111
+ {
112
+ // test the different edge combinations...
113
+ if ( doubleNear ( x0, clipRect.xMinimum () ) )
114
+ {
115
+ if ( doubleNear ( x1, clipRect.xMinimum () ) )
116
+ {
117
+ return ;
118
+ }
119
+ else if ( doubleNear ( y1, clipRect.yMaximum () ) )
120
+ {
121
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMaximum () );
122
+ return ;
123
+ }
124
+ else if ( doubleNear ( x1, clipRect.xMaximum () ) )
125
+ {
126
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMaximum () );
127
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMaximum () );
128
+ return ;
129
+ }
130
+ else if ( doubleNear ( y1, clipRect.yMinimum () ) )
131
+ {
132
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMinimum () );
133
+ return ;
134
+ }
135
+ }
136
+ else if ( doubleNear ( y0, clipRect.yMaximum () ) )
137
+ {
138
+ if ( doubleNear ( y1, clipRect.yMaximum () ) )
139
+ {
140
+ return ;
141
+ }
142
+ else if ( doubleNear ( x1, clipRect.xMaximum () ) )
143
+ {
144
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMaximum () );
145
+ return ;
146
+ }
147
+ else if ( doubleNear ( y1, clipRect.yMinimum () ) )
148
+ {
149
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMaximum () );
150
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMinimum () );
151
+ return ;
152
+ }
153
+ else if ( doubleNear ( x1, clipRect.xMinimum () ) )
154
+ {
155
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMaximum () );
156
+ return ;
157
+ }
158
+ }
159
+ else if ( doubleNear ( x0, clipRect.xMaximum () ) )
160
+ {
161
+ if ( doubleNear ( x1, clipRect.xMaximum () ) )
162
+ {
163
+ return ;
164
+ }
165
+ else if ( doubleNear ( y1, clipRect.yMinimum () ) )
166
+ {
167
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMinimum () );
168
+ return ;
169
+ }
170
+ else if ( doubleNear ( x1, clipRect.xMinimum () ) )
171
+ {
172
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMinimum () );
173
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMinimum () );
174
+ return ;
175
+ }
176
+ else if ( doubleNear ( y1, clipRect.yMaximum () ) )
177
+ {
178
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMaximum () );
179
+ return ;
180
+ }
181
+ }
182
+ else if ( doubleNear ( y0, clipRect.yMinimum () ) )
183
+ {
184
+ if ( doubleNear ( y1, clipRect.yMinimum () ) )
185
+ {
186
+ return ;
187
+ }
188
+ else if ( doubleNear ( x1, clipRect.xMinimum () ) )
189
+ {
190
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMinimum () );
191
+ return ;
192
+ }
193
+ else if ( doubleNear ( y1, clipRect.yMaximum () ) )
194
+ {
195
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMinimum () );
196
+ pts << QPointF ( clipRect.xMinimum (), clipRect.yMaximum () );
197
+ return ;
198
+ }
199
+ else if ( doubleNear ( x1, clipRect.xMaximum () ) )
200
+ {
201
+ pts << QPointF ( clipRect.xMaximum (), clipRect.yMinimum () );
202
+ return ;
203
+ }
204
+ }
205
+ }
0 commit comments