Hi,
I've made a simple lib crate to compress linestrings of georust (LineString
). It transforms float point coordinates into integers and then stores them (without leading 0s) in one vector of u8
s.
Here's a big question: how to set the precision of coordinates? E.g. for Google pseudo-Mercator 3857, only 2 decimal digits are needed, making 1cm precision. But for lon/lat one needs 7 digits for an equal precision.
Since LineStrings are CRS-agnostic, you need to pass precision as a parameter somewhere. So I came up with a trait with 2 methods, try_compact2
& try_compact7
, and two modules for Serde, which looks ugly. That's why I'm open to suggestions how to organize this parametrization.
-
To compress/decompress a linestring:
use cmpls::{ToCompLs, wktls, assert_ls_eq}; let ls = wktls!(76.9615707 43.2746200,76.9616699 43.2747688,76.9620742 43.2753715,76.9627532 43.2764091,76.9629516 43.2765502,76.9630584 43.2765998); let cmp = ls.try_compact7()?; // compress assert_ls_eq!(ls, cmp.linestring()); // decompresses with .linestring()
-
To compact LineStrings only in serde serialization:
use cmpls::{compls_p2, compls_p7}; #[derive(Serialize, Deserialize)] struct MyStruct { id: usize, #[serde(with="compls_p7")] // geometry in lat/lon need 7 digits of precision, hence compls_p7 geometry_4326: LineString, #[serde(with="compls_p2")] // geometries in metre-based CRS need just 2 digits, use compls_p2 geometry_3857: LineString }
Please, look at the code, and tell if anything needs a fix. (The test actually passes, btw.)