module Data.Internal.Wkb.Geometry ( GeometryType (..) , CoordinateType (..) , WkbGeometryType (..) , geometryTypeWithCoords ) where import qualified Control.Monad as Monad import qualified Data.Binary.Get as BinaryGet import qualified Data.Word as Word import qualified Data.Internal.Wkb.Endian as Endian data GeometryType = Geometry | Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon | GeometryCollection deriving (Show, Eq) data CoordinateType = TwoD | Z | M | ZM deriving (Show, Eq) data WkbGeometryType = WkbGeom GeometryType CoordinateType deriving (Show, Eq) geometryTypeWithCoords :: Endian.EndianType -> BinaryGet.Get WkbGeometryType geometryTypeWithCoords endianType = do fullGeometryType <- Endian.fourBytes endianType let geomType = intToGeometryType $ fullGeometryType `rem` 1000 coordType = intToCoordinateType $ fullGeometryType `div` 1000 case (geomType, coordType) of (Just g, Just c) -> pure $ WkbGeom g c _ -> Monad.fail $ "Invalid WkbGeometryType: " ++ show fullGeometryType intToGeometryType :: Word.Word32 -> Maybe GeometryType intToGeometryType int = case int of 0 -> Just Geometry 1 -> Just Point 2 -> Just LineString 3 -> Just Polygon 4 -> Just MultiPoint 5 -> Just MultiLineString 6 -> Just MultiPolygon 7 -> Just GeometryCollection _ -> Nothing intToCoordinateType :: Word.Word32 -> Maybe CoordinateType intToCoordinateType int = case int of 0 -> Just TwoD 1 -> Just Z 2 -> Just M 3 -> Just ZM _ -> Nothing