import os
from sys import platform
from ctypes import Structure, POINTER, c_void_p, c_size_t, c_double, cast, cdll
import numpy as np
import ipdb
file_path = os.path.dirname(__file__)
prefix = {'win32': ''}.get(platform, 'lib')
extension = {'darwin': '.dylib', 'win32': '.dll'}.get(platform, '.so')
lib = cdll.LoadLibrary(os.path.join(file_path, "target/release", prefix + "polylabel" + extension))
class _InnersArray(Structure):
_fields_ = [("data", c_void_p),
("len", c_size_t)]
@classmethod
def from_param(cls, seq):
return seq if isinstance(seq, cls) else cls(seq)
def __init__(self, seq, data_type = c_double):
self.arr = np.asarray([_FFIArray(s) for s in seq])
ring_array_type = _FFIArray * len(seq)
ring_array = ring_array_type()
for i, arr in enumerate(self.arr):
ring_array[i] = arr
self.data = cast(ring_array, c_void_p)
self.len = len(self.arr)
class _FFIArray(Structure):
_fields_ = [("data", c_void_p),
("len", c_size_t)]
@classmethod
def from_param(cls, seq):
return seq if isinstance(seq, cls) else cls(seq)
def __init__(self, seq, data_type = c_double):
self.data = cast(
np.array(seq, dtype=np.float64).ctypes.data_as(POINTER(data_type)),
c_void_p
)
self.len = len(seq)
class _CoordResult(Structure):
_fields_ = [("x_pos", c_double), ("y_pos", c_double)]
def _unpack_coordresult(res, _func, _args):
return res.x_pos, res.y_pos
labelpos = lib.polylabel_ffi
labelpos.argtypes = (_FFIArray, _InnersArray, c_double)
labelpos.restype = _CoordResult
labelpos.errcheck = _unpack_coordresult
if __name__ == "__main__":
res = (labelpos(
[[4.0, 1.0],
[5.0, 2.0],
[5.0, 3.0],
[4.0, 4.0],
[3.0, 4.0],
[2.0, 3.0],
[2.0, 2.0],
[3.0, 1.0],
[4.0, 1.0]],
[
[[3.5, 3.5], [4.4, 2.0], [2.6, 2.0], [3.5, 3.5]],
[[4.0, 3.0], [4.0, 3.2], [4.5, 3.2], [4.0, 3.0]]
],
0.1)
)
print(res)