### ----------------------------------------------------
### -- Geo::Geometry
### -- Licenses: Artistic-2.0
### -- Authors: Kevin Pye (kjfez@pye.id.au)
### -- File: lib/Geo/Geometry.rakumod
### ----------------------------------------------------
### -- Chunk 2 of 2
, wkbMultiPointM, $endian);
        $b.write-uint32(5, $!num-points,   $endian);
        $b ~ [~] @!points.map({.wkb($byteorder)})
    }
}
    
class MultiPointZM does Geometry {
    has $!type = wkbMultiPointZM;
    has $.num-points;
    has PointZM @.points is required is built;

    method type { $!type; }
    method TWEAK { $!num-points = +@!points; }
    method Str() { @!points.map({'(' ~ .Str ~ ')'}).join(',') };
    method wkt() { "MultiPointZM({self.Str})"; }
    method wkb(:$byteorder = wkbXDR) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-uint32(1, wkbMultiPointZM, $endian);
        $b.write-uint32(5, $!num-points,    $endian);
        $b ~ [~] @!points.map({.wkb($byteorder)})
    }
}

class MultiLineString does Geometry {
    has $!type = wkbMultiLineString;
    has $.num-linestrings;
    has LineString @.linestrings is required is built;

    method type { $!type; }
    method TWEAK { $!num-linestrings = +@!linestrings; }
    method Str { '(' ~ @!linestrings.map({.Str}).join('),(') ~ ')'; }
    method wkt { 'MultiLineString(' ~ self.Str ~ ')'; }
    method tobuf($endian) {
        my $b = Buf.new(0);
        $b.write-uint32(0, $!num-linestrings, $endian);
        $b ~ [~] @!linestrings.map({.tobuf($endian)});
    }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiLineString, $endian);
        $b.write-int32(5, $!num-linestrings,  $endian);
        $b ~ self.tobuf($endian);
    }
}

class MultiLineStringZ does Geometry {
    has $!type = wkbMultiLineStringZ;
    has $.num-linestrings;
    has LineStringZ @.linestrings is required is built;

    method type { $!type; }
    method TWEAK { $!num-linestrings = +@!linestrings; }
    method Str { '(' ~ @!linestrings.map({.Str}).join('),(') ~ ')'; }
    method wkt { 'MultiLineStringZ(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiLineStringZ, $endian);
        $b.write-int32(5, $!num-linestrings,   $endian);
        $b ~ [~] @!linestrings.map({.wkb($byteorder)})
    }
}

class MultiLineStringM does Geometry {
    has $!type = wkbMultiLineStringM;
    has $.num-linestrings;
    has LineStringM @.linestrings is required is built;

    method type { $!type; }
    method TWEAK { $!num-linestrings = +@!linestrings; }
    method Str { '(' ~ @!linestrings.map({.Str}).join('),(') ~ ')'; }
    method wkt { 'MultiLineStringM(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiLineStringM, $endian);
        $b.write-int32(5, $!num-linestrings,   $endian);
        $b ~ [~] @!linestrings.map({.wkb($byteorder)})
    }
}

class MultiLineStringZM does Geometry {
    has $!type = wkbMultiLineStringZM;
    has $.num-linestrings;
    has LineStringZM @.linestrings is required is built;

    method type { $!type; }
    method TWEAK { $!num-linestrings = +@!linestrings; }
    method Str { '(' ~ @!linestrings.map({.Str}).join('),(') ~ ')'; }
    method wkt { 'MultiLineStringZM(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiLineStringZM, $endian);
        $b.write-int32(5, $!num-linestrings,   $endian);
        $b ~ [~] @!linestrings.map({.wkb($byteorder)})
    }
}

class MultiPolygon does Geometry {
    has $!type = wkbMultiPolygon;
    has $.num-polygons;
    has Polygon @.polygons is required is built;

    method type { $!type; }
    method TWEAK { $!num-polygons = +@!polygons; }
    method Str   { '(' ~ @!polygons.map({.Str}).join('),(') ~ ')'; }
    method wkt   { 'MultiPolygon(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiPolygon, $endian);
        $b.write-int32(5, $!num-polygons,  $endian);
        $b ~ [~] @!polygons.map({.wkb($byteorder)})
    }
}

class MultiPolygonZ does Geometry {
    has $!type = wkbMultiPolygonZ;
    has $.num-polygons;
    has PolygonZ @.polygons is required is built;

    method type { $!type; }
    method TWEAK { $!num-polygons = +@!polygons; }
    method Str   { '(' ~ @!polygons.map({.Str}).join('),(') ~ ')'; }
    method wkt   { 'MultiPolygonZ(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiPolygonZ, $endian);
        $b.write-int32(5, $!num-polygons,  $endian);
        $b ~ [~] @!polygons.map({.wkb($byteorder)})
    }
}

class MultiPolygonM does Geometry {
    has $!type = wkbMultiPolygonM;
    has $.num-polygons;
    has PolygonM @.polygons is required is built;

    method type { $!type; }
    method TWEAK { $!num-polygons = +@!polygons; }
    method Str   { '(' ~ @!polygons.map({.Str}).join('),(') ~ ')'; }
    method wkt   { 'MultiPolygonM(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiPolygonM, $endian);
        $b.write-int32(5, $!num-polygons,  $endian);
        $b ~ [~] @!polygons.map({.wkb($byteorder)})
    }
}

class MultiPolygonZM does Geometry {
    has $!type = wkbMultiPolygonZM;
    has $.num-polygons;
    has PolygonZM @.polygons is required is built;

    method type { $!type; }
    method TWEAK { $!num-polygons = +@!polygons; }
    method Str   { '(' ~ @!polygons.map({.Str}).join('),(') ~ ')'; }
    method wkt   { 'MultiPolygonZM(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbMultiPolygonZM, $endian);
        $b.write-int32(5, $!num-polygons,  $endian);
        $b ~ [~] @!polygons.map({.wkb($byteorder)})
    }
}

class GeometryCollection does Geometry {
    has $.num-geometries;
    has Geometry @.geometries is required is built;

    method TWEAK { $!num-geometries = +@!geometries; }
    method Str { @!geometries.map({.wkt}).join(','); }
    method wkt { 'GeometryCollection(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbGeometryCollection, $endian);
        $b.write-int32(5, $!num-geometries,  $endian);
        $b ~ [~] @!geometries.map({.wkb($byteorder)})
    }
}

class GeometryCollectionZ does Geometry {
    has $.num-geometries;
    has Geometry @.geometries is required is built;

    method TWEAK { $!num-geometries = +@!geometries; }
    method Str { @!geometries.map({.wkt}).join(','); }
    method wkt { 'GeometryCollectionZ(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbGeometryCollectionZ, $endian);
        $b.write-int32(5, $!num-geometries,  $endian);
        $b ~ [~] @!geometries.map({.wkb($byteorder)})
    }
}

class GeometryCollectionM does Geometry {
    has $.num-geometries;
    has Geometry @.geometries is required is built;

    method TWEAK { $!num-geometries = +@!geometries; }
    method Str { @!geometries.map({.wkt}).join(','); }
    method wkt { 'GeometryCollectionM(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbGeometryCollectionM, $endian);
        $b.write-int32(5, $!num-geometries,  $endian);
        $b ~ [~] @!geometries.map({.wkb($byteorder)})
    }
}

class GeometryCollectionZM does Geometry {
    has $.num-geometries;
    has Geometry @.geometries is required is built;

    method TWEAK { $!num-geometries = +@!geometries; }
    method Str { @!geometries.map({.wkt}).join(','); }
    method wkt { 'GeometryCollectionZM(' ~ self.Str ~ ')'; }
    method wkb($byteorder) {
        my $b = Buf.new($byteorder);
        my $endian = $byteorder == wkbXDR ?? BigEndian !! LittleEndian;
        $b.write-int32(1, wkbGeometryCollectionZM, $endian);
        $b.write-int32(5, $!num-geometries,  $endian);
        $b ~ [~] @!geometries.map({.wkb($byteorder)})
    }
}


