A Rust implementation of the Polylabel algorithm
The orange dot is the polygon centroid. The teal dot is the ideal label position. Red boxes show the search space.

You can generate this visualisation yourself by cloning this repo, switching to the visualise branch, and opening the visualise.ipynb Jupyter notebook, then stepping through the cells. You can also easily visualise a Polygon of your own using the notebook.
extern crate polylabel;
use polylabel::polylabel;
extern crate geo;
use geo::{Point, LineString, Polygon};
let coords = vec![
(0.0, 0.0),
(4.0, 0.0),
(4.0, 1.0),
(1.0, 1.0),
(1.0, 4.0),
(0.0, 4.0),
(0.0, 0.0)
];
let poly = Polygon::new(coords.into(), vec![]);
let label_pos = polylabel(&poly, &0.10);
// Point(0.5625, 0.5625)https://docs.rs/polylabel
Call polylabel_ffi with the following three mandatory arguments:
Array(a struct with two fields):data: a void pointer to an array of two-elementc_doublearrays, each of which represents a point on the exterior Polygon shell)len: the length of thedataarray, asize_t
WrapperArray(a struct with two fields):data: a void pointer to an array ofArrays, each entry representing an interior Polygon ring. Empty if there are no rings.len: the length of thedataarray, asize_t. 0 if it's empty.
tolerance, ac_double
The function returns a struct with two c_double fields:
x_posy_pos
A Python example is available in ffi.py
Finding a label position on a ~9k-vertex polygon using a tolerance of 10.0 takes around 4 ms on a 1.8 GHz Core i7 processor. Higher tolerances will significantly increase this time; finding a position on the same polygon using a tolerance of 5.0 takes around 10 ms, and finally, using 1.0 takes around 60 ms, though in general this level of precision isn't required.
Binary libs for:
x86_64*nix (built usingmanylinux1, thus easy to include in Python 2.7 / 3.5 / 3.6 wheels) and OS Xi686andx86_64Windows
are available in releases.