{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module H3.Internal.FFI
( degsToRads
, radsToDegs
, getResolution
, getBaseCellNumber
, isValidCell
, isResClassIII
, isPentagon
, hsGetIcosahedronFaces
, hsPolygonToCells
, hsGetRes0Cells
, hsGetPentagons
, hsGridDisk
, hsGridDiskUnsafe
, hsGridDiskDistances
, hsGridDiskDistancesSafe
, hsGridDiskDistancesUnsafe
, hsGridRingUnsafe
, hsGridPathCells
, hsCellToChildren
, hsCompactCells
, hsUncompactCells
, isValidDirectedEdge
, hsDirectedEdgeToCells
, hsOriginToDirectedEdges
, hsCellToVertexes
, isValidVertex
) where
import Data.Int (Int64)
import Data.Word (Word32)
import System.IO.Unsafe (unsafePerformIO)
import Foreign.C.Types (CInt, CLong)
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable(peek))
import Foreign.Marshal.Alloc (alloca, free)
import Foreign.Marshal.Array (allocaArray, withArray, peekArray, callocArray, withArray, withArrayLen)
import H3.Internal.H3Api
( H3Index
, H3Error
, CGeoPolygon
, newCGeoPolygonPtr
, destroyCGeoPolygonPtr
, GeoPolygon
)
foreign import capi "h3/h3api.h degsToRads" degsToRads :: Double -> Double
foreign import capi "h3/h3api.h radsToDegs" radsToDegs :: Double -> Double
foreign import capi "h3/h3api.h getResolution" getResolution :: H3Index -> Int
foreign import capi "h3/h3api.h getBaseCellNumber" getBaseCellNumber :: H3Index -> Int
foreign import capi "h3/h3api.h isValidCell" isValidCell :: H3Index -> Int
foreign import capi "h3/h3api.h isResClassIII" isResClassIII :: H3Index -> Int
foreign import capi "h3/h3api.h isPentagon" isPentagon :: H3Index -> Int
foreign import capi "h3/h3api.h maxFaceCount" c_maxFaceCount :: H3Index -> Ptr CInt -> IO H3Error
foreign import capi "h3/h3api.h getIcosahedronFaces" c_getIcosahedronFaces :: H3Index -> Ptr CInt -> IO H3Error
hsGetIcosahedronFaces :: H3Index -> (H3Error, [Int])
hsGetIcosahedronFaces :: H3Index -> (H3Error, [Int])
hsGetIcosahedronFaces H3Index
h3index =
IO (H3Error, [Int]) -> (H3Error, [Int])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [Int]) -> (H3Error, [Int]))
-> IO (H3Error, [Int]) -> (H3Error, [Int])
forall a b. (a -> b) -> a -> b
$ (Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int]))
-> (Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int])
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
countptr -> do
h3error <- H3Index -> Ptr CInt -> IO H3Error
c_maxFaceCount H3Index
h3index Ptr CInt
countptr
if h3error == 0
then do
count <- fromIntegral <$> peek countptr
allocaArray count $ \Ptr CInt
facesptr -> do
out3error <- H3Index -> Ptr CInt -> IO H3Error
c_getIcosahedronFaces H3Index
h3index Ptr CInt
facesptr
if out3error == 0
then do
faces <- map fromIntegral <$> peekArray count facesptr
return (out3error, faces)
else return (out3error, [])
else return (h3error, [])
foreign import capi "h3/h3api.h maxPolygonToCellsSize" cMaxPolygonToCellsSize :: Ptr CGeoPolygon -> Int -> Word32 -> Ptr CLong -> IO H3Error
foreign import capi "h3/h3api.h polygonToCells" cPolygonToCells :: Ptr CGeoPolygon -> Int -> Word32 -> Ptr H3Index -> IO H3Error
hsPolygonToCellsIO :: GeoPolygon -> Int -> Word32 -> IO (H3Error, [H3Index])
hsPolygonToCellsIO :: GeoPolygon -> Int -> H3Error -> IO (H3Error, [H3Index])
hsPolygonToCellsIO GeoPolygon
poly Int
res H3Error
flags = do
cpolyPtr <- GeoPolygon -> IO (Ptr CGeoPolygon)
newCGeoPolygonPtr GeoPolygon
poly
(h3error, size) <- alloca $ \Ptr CLong
resultPtr -> do
h3error <- Ptr CGeoPolygon -> Int -> H3Error -> Ptr CLong -> IO H3Error
cMaxPolygonToCellsSize Ptr CGeoPolygon
cpolyPtr Int
res H3Error
flags Ptr CLong
resultPtr
result <- peek resultPtr
return (h3error, result)
out <- if h3error == 0
then do let sizei = CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
size
resultPtr <- callocArray sizei
h3error2 <- cPolygonToCells cpolyPtr res flags resultPtr
result <- peekArray sizei resultPtr
free resultPtr
return (h3error2, result)
else
return (h3error, [])
destroyCGeoPolygonPtr cpolyPtr
return out
hsPolygonToCells :: GeoPolygon -> Int -> Word32 -> (H3Error, [H3Index])
hsPolygonToCells :: GeoPolygon -> Int -> H3Error -> (H3Error, [H3Index])
hsPolygonToCells GeoPolygon
poly Int
res H3Error
flags = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ GeoPolygon -> Int -> H3Error -> IO (H3Error, [H3Index])
hsPolygonToCellsIO GeoPolygon
poly Int
res H3Error
flags
foreign import capi "h3/h3api.h res0CellCount" cRes0CellCount :: IO Int
foreign import capi "h3/h3api.h getRes0Cells" cGetRes0Cells :: Ptr H3Index -> IO H3Error
hsGetRes0Cells :: (H3Error, [H3Index])
hsGetRes0Cells :: (H3Error, [H3Index])
hsGetRes0Cells = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
cellCount <- IO Int
cRes0CellCount
allocaArray cellCount $ \Ptr H3Index
resultPtr -> do
h3error <- Ptr H3Index -> IO H3Error
cGetRes0Cells Ptr H3Index
resultPtr
result <- peekArray cellCount resultPtr
return (h3error, result)
foreign import capi "h3/h3api.h pentagonCount" cPentagonCount :: IO Int
foreign import capi "h3/h3api.h getPentagons" cGetPentagons :: Int -> Ptr H3Index -> IO H3Error
hsGetPentagons :: Int -> (H3Error, [H3Index])
hsGetPentagons :: Int -> (H3Error, [H3Index])
hsGetPentagons Int
res = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
cellCount <- IO Int
cPentagonCount
allocaArray cellCount $ \Ptr H3Index
resultPtr -> do
h3error <- Int -> Ptr H3Index -> IO H3Error
cGetPentagons Int
res Ptr H3Index
resultPtr
result <- peekArray cellCount resultPtr
return (h3error, result)
foreign import capi "h3/h3api.h maxGridDiskSize" cMaxGridDiskSize :: Int -> Ptr Int64 -> IO H3Error
hsMaxGridDiskSize :: Int -> IO (H3Error, Int64)
hsMaxGridDiskSize :: Int -> IO (H3Error, Int64)
hsMaxGridDiskSize Int
k = do
(Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64))
-> (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxSizePtr -> do
h3error <- Int -> Ptr Int64 -> IO H3Error
cMaxGridDiskSize Int
k Ptr Int64
maxSizePtr
if h3error == 0
then do
maxSize <- fromIntegral <$> peek maxSizePtr
return (h3error, maxSize)
else do
return (h3error, 0)
hsGridRingUnsafeSize :: Int -> IO (H3Error, Int64)
hsGridRingUnsafeSize :: Int -> IO (H3Error, Int64)
hsGridRingUnsafeSize Int
k | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> IO (H3Error, Int64)
localGridRingUnsafeSize Int
k
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
0, Int64
1)
| Bool
otherwise = (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
2, Int64
0)
where localGridRingUnsafeSize :: Int -> IO (H3Error, Int64)
localGridRingUnsafeSize Int
k0 = do
(h3error0, size0) <- Int -> IO (H3Error, Int64)
hsMaxGridDiskSize Int
k0
(h3error1, size1) <- hsMaxGridDiskSize (k0-1)
if (h3error0 == 0) && (h3error1 == 0)
then return (h3error0, size0 - size1)
else if h3error0 /= 0
then return (h3error0, 0)
else return (h3error1, 0)
hsGridDiskUsingMethod :: (H3Index -> Int -> Ptr H3Index -> IO H3Error) -> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod :: (H3Index -> Int -> Ptr H3Index -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod H3Index -> Int -> Ptr H3Index -> IO H3Error
diskMethod H3Index
h3index Int
k = do
(Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index]))
-> (Ptr Int64 -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxSizePtr -> do
sizeh3error <- Int -> Ptr Int64 -> IO H3Error
cMaxGridDiskSize Int
k Ptr Int64
maxSizePtr
if sizeh3error == 0
then do
maxSize <- fromIntegral <$> peek maxSizePtr
allocaArray maxSize $ \Ptr H3Index
resultPtr -> do
h3error <- H3Index -> Int -> Ptr H3Index -> IO H3Error
diskMethod H3Index
h3index Int
k Ptr H3Index
resultPtr
result <- peekArray maxSize resultPtr
return (h3error, result)
else do
return (sizeh3error, [])
foreign import capi "h3/h3api.h gridDisk" cGridDisk :: H3Index -> Int -> Ptr H3Index -> IO H3Error
hsGridDisk :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDisk :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDisk H3Index
origin = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> (Int -> IO (H3Error, [H3Index])) -> Int -> (H3Error, [H3Index])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod H3Index -> Int -> Ptr H3Index -> IO H3Error
cGridDisk H3Index
origin
foreign import capi "h3/h3api.h gridDiskUnsafe" cGridDiskUnsafe :: H3Index -> Int -> Ptr H3Index -> IO H3Error
hsGridDiskUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDiskUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDiskUnsafe H3Index
origin = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> (Int -> IO (H3Error, [H3Index])) -> Int -> (H3Error, [H3Index])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod H3Index -> Int -> Ptr H3Index -> IO H3Error
cGridDiskUnsafe H3Index
origin
hsGridDiskDistancesUsingMethod :: (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error) -> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod :: (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
diskDistanceMethod H3Index
h3index Int
k = do
(Ptr Int64 -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int])))
-> (Ptr Int64 -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxSizePtr -> do
sizeh3error <- Int -> Ptr Int64 -> IO H3Error
cMaxGridDiskSize Int
k Ptr Int64
maxSizePtr
if sizeh3error == 0
then do
maxSize <- fromIntegral <$> peek maxSizePtr
allocaArray maxSize $ \Ptr H3Index
indexResultPtr -> do
Int
-> (Ptr CInt -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
maxSize ((Ptr CInt -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int])))
-> (Ptr CInt -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
distanceResultPtr -> do
h3error <- H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
diskDistanceMethod H3Index
h3index Int
k Ptr H3Index
indexResultPtr Ptr CInt
distanceResultPtr
indexResult <- peekArray maxSize indexResultPtr
distanceResult <- map fromIntegral <$> peekArray maxSize distanceResultPtr
return (h3error, (indexResult, distanceResult))
else do
return (sizeh3error, ([], []))
foreign import capi "h3/h3api.h gridDiskDistances" cGridDiskDistances :: H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
hsGridDiskDistances :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistances :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistances H3Index
origin = IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int]))
forall a. IO a -> a
unsafePerformIO (IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int])))
-> (Int -> IO (H3Error, ([H3Index], [Int])))
-> Int
-> (H3Error, ([H3Index], [Int]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
cGridDiskDistances H3Index
origin
foreign import capi "h3/h3api.h gridDiskDistancesSafe" cGridDiskDistancesSafe :: H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
hsGridDiskDistancesSafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesSafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesSafe H3Index
origin = IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int]))
forall a. IO a -> a
unsafePerformIO (IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int])))
-> (Int -> IO (H3Error, ([H3Index], [Int])))
-> Int
-> (H3Error, ([H3Index], [Int]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
cGridDiskDistancesSafe H3Index
origin
foreign import capi "h3/h3api.h gridDiskDistancesUnsafe" cGridDiskDistancesUnsafe :: H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
hsGridDiskDistancesUnsafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUnsafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUnsafe H3Index
origin = IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int]))
forall a. IO a -> a
unsafePerformIO (IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int])))
-> (Int -> IO (H3Error, ([H3Index], [Int])))
-> Int
-> (H3Error, ([H3Index], [Int]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
cGridDiskDistancesUnsafe H3Index
origin
foreign import capi "h3/h3api.h gridRingUnsafe" cGridRingUnsafe :: H3Index -> Int -> Ptr H3Index -> IO H3Error
hsGridRingUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridRingUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridRingUnsafe H3Index
origin Int
k = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
(sizeh3error, maxSize64) <- Int -> IO (H3Error, Int64)
hsGridRingUnsafeSize Int
k
let maxSize = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
maxSize64
if sizeh3error == 0
then do
withArray (replicate maxSize 0) $ \Ptr H3Index
resultPtr -> do
h3error <- H3Index -> Int -> Ptr H3Index -> IO H3Error
cGridRingUnsafe H3Index
origin Int
k Ptr H3Index
resultPtr
if h3error == 0
then do
result <- peekArray maxSize resultPtr
return (h3error, result)
else return (h3error, [])
else return (sizeh3error, [])
foreign import capi "h3/h3api.h gridPathCellsSize" cGridPathCellsSize :: H3Index -> H3Index -> Ptr Int64 -> IO H3Error
foreign import capi "h3/h3api.h gridPathCells" cGridPathCells :: H3Index -> H3Index -> Ptr H3Index -> IO H3Error
hsGridPathCells :: H3Index -> H3Index -> (H3Error, [H3Index])
hsGridPathCells :: H3Index -> H3Index -> (H3Error, [H3Index])
hsGridPathCells H3Index
origin H3Index
h3 =
IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ (Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index]))
-> (Ptr Int64 -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
sizePtr -> do
sizeh3error <- H3Index -> H3Index -> Ptr Int64 -> IO H3Error
cGridPathCellsSize H3Index
origin H3Index
h3 Ptr Int64
sizePtr
if sizeh3error == 0
then do
size <- fromIntegral <$> peek sizePtr
allocaArray size $ \Ptr H3Index
resultPtr -> do
h3error <- H3Index -> H3Index -> Ptr H3Index -> IO H3Error
cGridPathCells H3Index
origin H3Index
h3 Ptr H3Index
resultPtr
result <- peekArray size resultPtr
return (h3error, result)
else do
return (sizeh3error, [])
foreign import capi "h3/h3api.h cellToChildrenSize" cCellToChildrenSize :: H3Index -> Int -> Ptr Int64 -> IO H3Error
foreign import capi "h3/h3api.h cellToChildren" cCellToChildren :: H3Index -> Int -> Ptr H3Index -> IO H3Error
hsCellToChildren :: H3Index -> Int -> (H3Error, [H3Index])
hsCellToChildren :: H3Index -> Int -> (H3Error, [H3Index])
hsCellToChildren H3Index
cell Int
childRes = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
(Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index]))
-> (Ptr Int64 -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
sizePtr -> do
sizeh3error <- H3Index -> Int -> Ptr Int64 -> IO H3Error
cCellToChildrenSize H3Index
cell Int
childRes Ptr Int64
sizePtr
if sizeh3error == 0
then do
size <- fromIntegral <$> peek sizePtr
allocaArray size $ \Ptr H3Index
resultPtr -> do
h3error <- H3Index -> Int -> Ptr H3Index -> IO H3Error
cCellToChildren H3Index
cell Int
childRes Ptr H3Index
resultPtr
if h3error == 0
then do
result <- peekArray size resultPtr
return (h3error, result)
else return (h3error, [])
else return (sizeh3error, [])
foreign import capi "h3/h3api.h compactCells" cCompactCells :: Ptr H3Index -> Ptr H3Index -> Int64 -> IO H3Error
hsCompactCells :: [H3Index] -> (H3Error, [H3Index])
hsCompactCells :: [H3Index] -> (H3Error, [H3Index])
hsCompactCells [H3Index]
cellSet = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
[H3Index]
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray [H3Index]
cellSet ((Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
cellSetPtr -> do
let size :: Int
size = [H3Index] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [H3Index]
cellSet
Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
size ((Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
compactedSetPtr -> do
h3error <- Ptr H3Index -> Ptr H3Index -> Int64 -> IO H3Error
cCompactCells Ptr H3Index
cellSetPtr Ptr H3Index
compactedSetPtr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)
if h3error == 0
then do
result <- peekArray size compactedSetPtr
return (h3error, result)
else return (h3error, [])
foreign import capi "h3/h3api.h uncompactCellsSize" cUncompactCellsSize :: Ptr H3Index -> Int64 -> Int -> Ptr Int64 -> IO H3Error
foreign import capi "h3/h3api.h uncompactCells" cUncompactCells :: Ptr H3Index -> Int64 -> Ptr H3Index -> Int64 -> Int -> IO H3Error
hsUncompactCells :: [H3Index] -> Int -> (H3Error, [H3Index])
hsUncompactCells :: [H3Index] -> Int -> (H3Error, [H3Index])
hsUncompactCells [H3Index]
compactedSet Int
res = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
[H3Index]
-> (Int -> Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
withArrayLen [H3Index]
compactedSet ((Int -> Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]))
-> (Int -> Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Int
numCells Ptr H3Index
compactedSetPtr -> do
(sizeh3error, maxCells) <- (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64))
-> (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxCellsPtr -> do
sizeh3error <- Ptr H3Index -> Int64 -> Int -> Ptr Int64 -> IO H3Error
cUncompactCellsSize Ptr H3Index
compactedSetPtr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
numCells) Int
res Ptr Int64
maxCellsPtr
if sizeh3error == 0
then do
size <- peek maxCellsPtr
return (sizeh3error, size)
else return (sizeh3error, 0)
if sizeh3error == 0
then do
let maxCellsInt = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
maxCells
allocaArray maxCellsInt $ \Ptr H3Index
cellSetPtr -> do
h3error <- Ptr H3Index -> Int64 -> Ptr H3Index -> Int64 -> Int -> IO H3Error
cUncompactCells Ptr H3Index
compactedSetPtr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
numCells) Ptr H3Index
cellSetPtr Int64
maxCells Int
res
if h3error == 0
then do
cellSet <- peekArray maxCellsInt cellSetPtr
return (h3error, cellSet)
else return (h3error, [])
else return (sizeh3error, [])
foreign import capi "h3/h3api.h isValidDirectedEdge" cIsValidDirectedEdge :: H3Index -> Int
isValidDirectedEdge :: H3Index -> Bool
isValidDirectedEdge :: H3Index -> Bool
isValidDirectedEdge = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
0) (Int -> Bool) -> (H3Index -> Int) -> H3Index -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> Int
cIsValidDirectedEdge
foreign import capi "h3/h3api.h directedEdgeToCells" cDirectedEdgeToCells :: H3Index -> Ptr H3Index -> IO H3Error
hsDirectedEdgeToCells :: H3Index -> (H3Error, [H3Index])
hsDirectedEdgeToCells :: H3Index -> (H3Error, [H3Index])
hsDirectedEdgeToCells H3Index
h3index = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
2 ((Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
originDestinationPtr -> do
h3error <- H3Index -> Ptr H3Index -> IO H3Error
cDirectedEdgeToCells H3Index
h3index Ptr H3Index
originDestinationPtr
if h3error == 0
then do
originDestination <- peekArray 2 originDestinationPtr
return (h3error, originDestination)
else return (h3error, [])
foreign import capi "h3/h3api.h originToDirectedEdges" cOriginToDirectedEdges :: H3Index -> Ptr H3Index -> IO H3Error
hsOriginToDirectedEdges :: H3Index -> (H3Error, [H3Index])
hsOriginToDirectedEdges :: H3Index -> (H3Error, [H3Index])
hsOriginToDirectedEdges H3Index
h3index = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
edgeCount ((Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
edgesPtr -> do
h3error <- H3Index -> Ptr H3Index -> IO H3Error
cOriginToDirectedEdges H3Index
h3index Ptr H3Index
edgesPtr
if h3error == 0
then do
edges <- peekArray edgeCount edgesPtr
return (h3error, edges)
else return (h3error, [])
where edgeCount :: Int
edgeCount = Int
6
foreign import capi "h3/h3api.h cellToVertexes" cCellToVertexes :: H3Index -> Ptr H3Index -> IO H3Error
hsCellToVertexes :: H3Index -> (H3Error, [H3Index])
hsCellToVertexes :: H3Index -> (H3Error, [H3Index])
hsCellToVertexes H3Index
origin = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
vertexCount ((Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
outPtr -> do
h3error <- H3Index -> Ptr H3Index -> IO H3Error
cCellToVertexes H3Index
origin Ptr H3Index
outPtr
if h3error == 0
then do
out <- peekArray vertexCount outPtr
return (h3error, out)
else return (h3error, [])
where vertexCount :: Int
vertexCount = Int
6
foreign import capi "h3/h3api.h isValidVertex" cIsValidVertex :: H3Index -> Int
isValidVertex :: H3Index -> Bool
isValidVertex :: H3Index -> Bool
isValidVertex = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
0) (Int -> Bool) -> (H3Index -> Int) -> H3Index -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> Int
cIsValidVertex