1#[macro_export]
2macro_rules! multipoint {
3 (
4 $( {x: $x_value:expr, y: $y_value:expr} ),* $(,)?
5 ) => {
6 shapefile::Multipoint::new(
7 vec![
8 $(
9 shapefile::Point {x: $x_value, y: $y_value }
10 ),+
11 ]
12 )
13 };
14 (
15 $( {x: $x_value:expr, y: $y_value:expr, m: $m_value:expr}),* $(,)?
16 ) => {
17 shapefile::MultipointM::new(
18 vec![
19 $(
20 shapefile::PointM {x: $x_value, y: $y_value, m: $m_value }
21 ),+
22 ]
23 )
24 };
25 (
26 $( {x: $x_value:expr, y: $y_value:expr, z: $z_value:expr, m: $m_value:expr} ),* $(,)?
27 ) => {
28 shapefile::MultipointZ::new(
29 vec![
30 $(
31 shapefile::PointZ {x: $x_value, y: $y_value, z: $z_value, m: $m_value }
32 ),+
33 ]
34 )
35 };
36 (
37 $( ($x_value:expr, $y_value:expr) ),* $(,)?
38 ) => {
39 shapefile::Multipoint::new(
40 vec![
41 $(
42 shapefile::Point::new($x_value, $y_value)
43 ),+
44 ]
45 )
46 };
47 (
48 $( ($x_value:expr, $y_value:expr, $m_value:expr) ),* $(,)?
49 ) => {
50 shapefile::MultipointM::new(
51 vec![
52 $(
53 shapefile::PointM::new($x_value, $y_value, $m_value)
54 ),+
55 ]
56 )
57 };
58 (
59 $( ($x_value:expr, $y_value:expr, $z_value:expr, $m_value:expr) ),* $(,)?
60 ) => {
61 shapefile::MultipointZ::new(
62 vec![
63 $(
64 shapefile::PointZ::new($x_value, $y_value, $z_value, $m_value)
65 ),+
66 ]
67 )
68 };
69}
70
71#[macro_export]
72macro_rules! multipatch {
73 (
74 $(
75 $patch_type:ident( $({x: $x_value:expr, y: $y_value:expr, z: $z_value:expr, m: $m_value:expr}),* $(,)? $(,)? )
76 ),*
77 ) => {
78 shapefile::Multipatch::with_parts(
79 vec! [
80 $(
81 shapefile::Patch::$patch_type(
82 vec![
83 $(shapefile::PointZ {x: $x_value, y: $y_value, z: $z_value, m: $m_value}),*
84 ]
85 )
86 ),*
87 ]
88 )
89 };
90 (
91 $(
92 $patch_type:ident( $(($x_value:expr, $y_value:expr, $z_value:expr, $m_value:expr)),* $(,)? $(,)? )
93 ),*
94 ) => {
95 shapefile::Multipatch::with_parts(
96 vec! [
97 $(
98 shapefile::Patch::$patch_type(
99 vec![
100 $(shapefile::PointZ::new($x_value, $y_value, $z_value, $m_value)),*
101 ]
102 )
103 ),*
104 ]
105 )
106 };
107}
108
109#[macro_export]
110macro_rules! polygon {
111 (
113 $(
114 $ring_type:ident( $({x: $x_value:expr, y: $y_value:expr}),* $(,)? ) $(,)?
115 ),*
116 ) => {
117 shapefile::Polygon::with_rings(
118 vec! [
119 $(
120 shapefile::PolygonRing::$ring_type(
121 vec![
122 $(shapefile::Point {x: $x_value, y: $y_value}),*
123 ]
124 )
125 ),*
126 ]
127 )
128 };
129 (
130 $(
131 $ring_type:ident( $(($x_value:expr, $y_value:expr)),* $(,)? ) $(,)?
132 ),*
133 ) => {
134 polygon!{
135 $(
136 $ring_type( $({x: $x_value, y: $y_value}),* )
137 ),+
138 }
139 };
140 (
142 $(
143 $ring_type:ident( $({x: $x_value:expr, y: $y_value:expr, m: $m_value:expr}),* $(,)? ) $(,)?
144 ),*
145 ) => {
146 shapefile::PolygonM::with_rings(
147 vec! [
148 $(
149 shapefile::PolygonRing::$ring_type(
150 vec![
151 $(shapefile::PointM {x: $x_value, y: $y_value, m: $m_value}),*
152 ]
153 )
154 ),*
155 ]
156 )
157 };
158 (
159 $(
160 $ring_type:ident( $(($x_value:expr, $y_value:expr, $m_value:expr)),* $(,)? ) $(,)?
161 ),*
162 ) => {
163 polygon!{
164 $(
165 $ring_type( $({x: $x_value, y: $y_value, m: $m_value}),* )
166 ),+
167 }
168 };
169 (
171 $(
172 $ring_type:ident( $({x: $x_value:expr, y: $y_value:expr, z: $z_value:expr, m: $m_value:expr}),* $(,)? ) $(,)?
173 ),*
174 ) => {
175 shapefile::PolygonZ::with_rings(
176 vec! [
177 $(
178 shapefile::PolygonRing::$ring_type(
179 vec![
180 $(shapefile::PointZ {x: $x_value, y: $y_value, z: $z_value, m: $m_value}),*
181 ]
182 )
183 ),*
184 ]
185 )
186 };
187 (
188 $(
189 $ring_type:ident( $(($x_value:expr, $y_value:expr, $z_value:expr, $m_value:expr)),* $(,)? ) $(,)?
190 ),*
191 ) => {
192 polygon!{
193 $(
194 $ring_type( $({x: $x_value, y: $y_value, z: $z_value, m: $m_value}),* )
195 ),+
196 }
197 };
198}
199
200#[macro_export]
201macro_rules! polyline {
202 (
204 $(
205 [ $({x: $x_value:expr, y: $y_value:expr}),* $(,)? ]
206 ),* $(,)?
207 ) => {
208 shapefile::Polyline::with_parts(
209 vec! [
210 $(
211 vec![
212 $(shapefile::Point {x: $x_value, y: $y_value}),*
213 ]
214 ),*
215 ]
216 )
217 };
218 (
219 $(
220 [ $(($x_value:expr, $y_value:expr)),* $(,)? ]
221 ),* $(,)?
222 ) => {
223 polyline!{
224 $(
225 [$({x: $x_value, y: $y_value}),*]
226 ),+
227 }
228 };
229 (
231 $(
232 [ $({x: $x_value:expr, y: $y_value:expr, m: $m_value:expr}),* $(,)? ]
233 ),* $(,)?
234 ) => {
235 shapefile::PolylineM::with_parts(
236 vec! [
237 $(
238 vec![
239 $(shapefile::PointM {x: $x_value, y: $y_value, m: $m_value}),*
240 ]
241 ),*
242 ]
243 )
244 };
245 (
246 $(
247 [ $(($x_value:expr, $y_value:expr, $m_value:expr)),* $(,)? ]
248 ),* $(,)?
249 ) => {
250 polyline!{
251 $(
252 [$({x: $x_value, y: $y_value, m: $m_value}),*]
253 ),+
254 }
255 };
256 (
258 $(
259 [ $({x: $x_value:expr, y: $y_value:expr, z: $z_value:expr, m: $m_value:expr}),* $(,)? ]
260 ),* $(,)?
261 ) => {
262 shapefile::PolylineZ::with_parts(
263 vec! [
264 $(
265 vec![
266 $(shapefile::PointZ {x: $x_value, y: $y_value, z: $z_value, m: $m_value}),*
267 ]
268 ),*
269 ]
270 )
271 };
272 (
273 $(
274 [ $(($x_value:expr, $y_value:expr, $z_value:expr, $m_value:expr)),* $(,)? ]
275 ),* $(,)?
276 ) => {
277 polyline!{
278 $(
279 [ $({x: $x_value, y: $y_value, z: $z_value, m: $m_value}),* ]
280 ),+
281 }
282 };
283}
284
285#[cfg(test)]
286mod test {
287 use crate as shapefile;
289 use crate::record::{Point, PointM, PointZ, PolygonRing, Polyline, PolylineM, PolylineZ};
290 use crate::Patch;
291
292 #[test]
293 fn test_multipatch() {
294 let multipatch = multipatch!(
295 TriangleStrip(
296 {x: 1.0, y: 1.0, z: 1.0, m: 1.0}
297 )
298 );
299 let multipatch_2 = multipatch!(TriangleStrip((1.0, 1.0, 1.0, 1.0)));
300 let expected_multipatch =
301 shapefile::Multipatch::new(Patch::TriangleStrip(vec![shapefile::PointZ::new(
302 1.0, 1.0, 1.0, 1.0,
303 )]));
304
305 assert_eq!(multipatch, expected_multipatch);
306 assert_eq!(multipatch_2, expected_multipatch);
307 }
308
309 #[test]
310 fn test_multipoint_macro() {
311 let multipoint = multipoint![
312 {x: 1.0, y: 1.0},
313 {x: 2.0, y: 2.0},
314 ];
315 let multipoint_2 = multipoint![(1.0, 1.0), (2.0, 2.0)];
316 let expected_multipoint = shapefile::Multipoint::new(vec![
317 shapefile::Point::new(1.0, 1.0),
318 shapefile::Point::new(2.0, 2.0),
319 ]);
320
321 assert_eq!(multipoint, expected_multipoint);
322 assert_eq!(multipoint, multipoint_2);
323 }
324
325 #[test]
326 fn test_multipoint_m_macro() {
327 let multipoint = multipoint![
328 {x: 1.0, y: 1.0, m: 42.1337},
329 {x: 2.0, y: 2.0, m: 1337.42}
330 ];
331
332 let expected_multipoint = shapefile::MultipointM::new(vec![
333 shapefile::PointM::new(1.0, 1.0, 42.1337),
334 shapefile::PointM::new(2.0, 2.0, 1337.42),
335 ]);
336 assert_eq!(multipoint, expected_multipoint);
337 }
338
339 #[test]
340 fn test_multipoint_z_macro() {
341 let multipoint = multipoint![
342 {x: 1.0, y: 1.0, z: 17.5, m: 42.1337},
343 {x: 2.0, y: 2.0, z: 14.021, m: 1337.42}
344 ];
345 let expected_multipoint = shapefile::MultipointZ::new(vec![
346 shapefile::PointZ::new(1.0, 1.0, 17.5, 42.1337),
347 shapefile::PointZ::new(2.0, 2.0, 14.021, 1337.42),
348 ]);
349 assert_eq!(multipoint, expected_multipoint);
350 }
351
352 #[test]
353 fn test_polyline_macro() {
354 let poly_1 = polyline!(
355 [
356 {x: 1.0, y: 1.0},
357 {x: 2.0, y: 2.0}
358 ],
359 [
360 {x: 3.0, y: 3.0},
361 {x: 4.0, y: 4.0}
362 ]
363 );
364
365 let poly_2 = polyline!([(1.0, 1.0), (2.0, 2.0)], [(3.0, 3.0), (4.0, 4.0)]);
366
367 let poly_3 = Polyline::with_parts(vec![
368 vec![Point::new(1.0, 1.0), Point::new(2.0, 2.0)],
369 vec![Point::new(3.0, 3.0), Point::new(4.0, 4.0)],
370 ]);
371 assert_eq!(poly_1, poly_3);
372 assert_eq!(poly_2, poly_3);
373 }
374
375 #[test]
376 fn test_polyline_m_macro() {
377 let poly_1 = polyline!(
378 [
379 {x: 1.0, y: 1.0, m: 5.0},
380 {x: 2.0, y: 2.0, m: 42.1337}
381 ],
382 [
383 {x: 3.0, y: 3.0, m: 17.65},
384 {x: 4.0, y: 4.0, m: 454.4598}
385 ]
386 );
387
388 let poly_2 = polyline!(
389 [(1.0, 1.0, 5.0), (2.0, 2.0, 42.1337)],
390 [(3.0, 3.0, 17.65), (4.0, 4.0, 454.4598),]
391 );
392
393 let poly_3 = PolylineM::with_parts(vec![
394 vec![PointM::new(1.0, 1.0, 5.0), PointM::new(2.0, 2.0, 42.1337)],
395 vec![
396 PointM::new(3.0, 3.0, 17.65),
397 PointM::new(4.0, 4.0, 454.4598),
398 ],
399 ]);
400
401 assert_eq!(poly_1, poly_3);
402 assert_eq!(poly_2, poly_3);
403 }
404
405 #[test]
406 fn test_polyline_z_macro() {
407 let poly_1 = polyline!(
408 [
409 {x: 1.0, y: 1.0, z: 17.56, m: 5.0},
410 {x: 2.0, y: 2.0, z: 18.17, m: 42.1337}
411 ],
412 [
413 {x: 3.0, y: 3.0, z: 54.9, m: 17.65},
414 {x: 4.0, y: 4.0, z: 7.0, m: 454.4598}
415 ]
416 );
417
418 let poly_2 = polyline!(
419 [(1.0, 1.0, 17.56, 5.0), (2.0, 2.0, 18.17, 42.1337)],
420 [(3.0, 3.0, 54.9, 17.65), (4.0, 4.0, 7.0, 454.4598),]
421 );
422
423 let poly_3 = PolylineZ::with_parts(vec![
424 vec![
425 PointZ::new(1.0, 1.0, 17.56, 5.0),
426 PointZ::new(2.0, 2.0, 18.17, 42.1337),
427 ],
428 vec![
429 PointZ::new(3.0, 3.0, 54.9, 17.65),
430 PointZ::new(4.0, 4.0, 7.0, 454.4598),
431 ],
432 ]);
433 assert_eq!(poly_1, poly_3);
434 assert_eq!(poly_2, poly_3);
435 }
436
437 #[test]
438 fn test_polygon_macro() {
439 let polygon_1 = polygon!(
440 Outer(
441 {x: 1.0, y: 1.0},
442 {x: 2.0, y: 2.0},
443 {x: 1.0, y: 1.0},
444 {x: 1.0, y: 0.0},
445 {x: 1.0, y: 1.0}
446 ),
447 Inner(
448 {x: 1.0, y: 1.0},
449 {x: 1.0, y: 0.0},
450 {x: 1.0, y: 1.0},
451 {x: 2.0, y: 2.0},
452 {x: 1.0, y: 1.0},
453 )
454 );
455
456 let polygon_2 = polygon!(
457 Outer((1.0, 1.0), (2.0, 2.0), (1.0, 1.0), (1.0, 0.0), (1.0, 1.0),),
458 Inner((1.0, 1.0), (1.0, 0.0), (1.0, 1.0), (2.0, 2.0), (1.0, 1.0),)
459 );
460
461 let polygon_3 = shapefile::Polygon::with_rings(vec![
462 PolygonRing::Outer(vec![
463 shapefile::Point::new(1.0, 1.0),
464 shapefile::Point::new(2.0, 2.0),
465 shapefile::Point::new(1.0, 1.0),
466 shapefile::Point::new(1.0, 0.0),
467 shapefile::Point::new(1.0, 1.0),
468 ]),
469 PolygonRing::Inner(vec![
470 shapefile::Point::new(1.0, 1.0),
471 shapefile::Point::new(1.0, 0.0),
472 shapefile::Point::new(1.0, 1.0),
473 shapefile::Point::new(2.0, 2.0),
474 shapefile::Point::new(1.0, 1.0),
475 ]),
476 ]);
477 assert_eq!(polygon_1, polygon_3);
478 assert_eq!(polygon_1, polygon_2);
479 }
480
481 #[test]
482 fn test_polygon_m_macro() {
483 let polygon_1 = polygon!(
484 Outer(
485 {x: 1.0, y: 1.0, m: 5.0},
486 {x: 2.0, y: 2.0, m: 42.1337},
487 {x: 1.0, y: 1.0, m: 5.0},
488 {x: 1.0, y: 0.0, m: 2.2},
489 {x: 1.0, y: 1.0, m: 5.0}
490 ),
491 Inner(
492 {x: 1.0, y: 1.0, m: 1.0},
493 {x: 1.0, y: 0.0, m: 2.0},
494 {x: 1.0, y: 1.0, m: 1.1},
495 {x: 2.0, y: 2.0, m: 2.2},
496 {x: 1.0, y: 1.0, m: 1.0},
497 )
498 );
499
500 let polygon_2 = polygon!(
501 Outer(
502 (1.0, 1.0, 5.0),
503 (2.0, 2.0, 42.1337),
504 (1.0, 1.0, 5.0),
505 (1.0, 0.0, 2.2),
506 (1.0, 1.0, 5.0)
507 ),
508 Inner(
509 (1.0, 1.0, 1.0),
510 (1.0, 0.0, 2.0),
511 (1.0, 1.0, 1.1),
512 (2.0, 2.0, 2.2),
513 (1.0, 1.0, 1.0),
514 )
515 );
516
517 let polygon_3 = shapefile::PolygonM::with_rings(vec![
518 PolygonRing::Outer(vec![
519 shapefile::PointM::new(1.0, 1.0, 5.0),
520 shapefile::PointM::new(2.0, 2.0, 42.1337),
521 shapefile::PointM::new(1.0, 1.0, 5.0),
522 shapefile::PointM::new(1.0, 0.0, 2.2),
523 shapefile::PointM::new(1.0, 1.0, 5.0),
524 ]),
525 PolygonRing::Inner(vec![
526 shapefile::PointM::new(1.0, 1.0, 1.0),
527 shapefile::PointM::new(1.0, 0.0, 2.0),
528 shapefile::PointM::new(1.0, 1.0, 1.1),
529 shapefile::PointM::new(2.0, 2.0, 2.2),
530 shapefile::PointM::new(1.0, 1.0, 1.0),
531 ]),
532 ]);
533
534 assert_eq!(polygon_1, polygon_3);
535 assert_eq!(polygon_2, polygon_3);
536 }
537
538 #[test]
539 fn test_polygon_z_macro() {
540 let polygon_1 = polygon!(
541 Outer(
542 {x: 1.0, y: 1.0, z: 5.0, m: 5.0},
543 {x: 2.0, y: 2.0, z: 6.0, m: 42.1337},
544 {x: 1.0, y: 1.0, z: 7.0, m: 5.0},
545 {x: 1.0, y: 0.0, z: 8.0, m: 2.2},
546 {x: 1.0, y: 1.0, z: 5.0, m: 5.0}
547 ),
548 Inner(
549 {x: 1.0, y: 1.0, z: 6.0, m: 1.0},
550 {x: 1.0, y: 0.0, z: 7.0,m: 2.0},
551 {x: 1.0, y: 1.0, z: 8.0, m: 1.1},
552 {x: 2.0, y: 2.0, z: 9.9, m: 2.2},
553 {x: 1.0, y: 1.0, z: 6.0, m: 1.0},
554 )
555 );
556
557 let polygon_2 = polygon!(
558 Outer(
559 (1.0, 1.0, 5.0, 5.0),
560 (2.0, 2.0, 6.0, 42.1337),
561 (1.0, 1.0, 7.0, 5.0),
562 (1.0, 0.0, 8.0, 2.2),
563 (1.0, 1.0, 5.0, 5.0)
564 ),
565 Inner(
566 (1.0, 1.0, 6.0, 1.0),
567 (1.0, 0.0, 7.0, 2.0),
568 (1.0, 1.0, 8.0, 1.1),
569 (2.0, 2.0, 9.9, 2.2),
570 (1.0, 1.0, 6.0, 1.0),
571 )
572 );
573
574 let polygon_3 = shapefile::PolygonZ::with_rings(vec![
575 PolygonRing::Outer(vec![
576 shapefile::PointZ::new(1.0, 1.0, 5.0, 5.0),
577 shapefile::PointZ::new(2.0, 2.0, 6.0, 42.1337),
578 shapefile::PointZ::new(1.0, 1.0, 7.0, 5.0),
579 shapefile::PointZ::new(1.0, 0.0, 8.0, 2.2),
580 shapefile::PointZ::new(1.0, 1.0, 5.0, 5.0),
581 ]),
582 PolygonRing::Inner(vec![
583 shapefile::PointZ::new(1.0, 1.0, 6.0, 1.0),
584 shapefile::PointZ::new(1.0, 0.0, 7.0, 2.0),
585 shapefile::PointZ::new(1.0, 1.0, 8.0, 1.1),
586 shapefile::PointZ::new(2.0, 2.0, 9.9, 2.2),
587 shapefile::PointZ::new(1.0, 1.0, 6.0, 1.0),
588 ]),
589 ]);
590
591 assert_eq!(polygon_1, polygon_3);
592 assert_eq!(polygon_2, polygon_3);
593 }
594}