shapefile_gbk/record/
macros.rs

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    // Polygon rules
112    (
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    // Polygon M rules
141    (
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    //Polygon Z rules
170    (
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    // Polyline rules
203    (
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    // Polyline M rules
230    (
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    //Polyline Z rules
257    (
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    // the macros expect the shapefile namespace to be in scope
288    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}