4 ms·
Having a nice modern language helps. I'm maintaining a small library with some geospatial algorithms and geojson support for Kotlin called geogeometry. One nic
by jillesvangurp 5y ago
Having a nice modern language helps. I'm maintaining a small library with some geospatial algorithms and geojson support for Kotlin called geogeometry.
One nice feature with Kotlin is using extension functions and extension properties on type aliases. I use this a lot in my library. So, I can represent points using a DoubleArray, which is a specialized primitive array type.
I defined a typealias PointCoordinates = DoubleArray, and then have extension properties defined on like:
val PointCoordinates.latitude: Double
get() = this[1]
The compiler inlines all of that of course so it's all simple array manipulation. But it looks like an object. And I get to avoid the longitude/latitude confusion. Another nice language feature that I use a lot is named parameters on functions. Nothing worse than somebody calling f(lat,lon) when they should have called f(lon,lat). Much less confusing if you call f(latitude: lat, longitude: lon).
- wereHamster 5y agoThe issue really exists only at I/O boundaries, where if there is a format mismatch you have to convert, which incurs some costs (CPU mostly, and memory bandwidth). Most languages can inline the data such that there isn't much overhead in accessing the raw bytes. Arrays with aliases for indexes (like you did, or in JS maybe I'd do something like `const LAT = 0, LON = 1; point[LAT]`, C-family languages can pack the bytes into tight structs where field names act as aliases to the memory location, Haskell has the UNPACK pragma etc. Btw, give that you have a PointCoordinates type, why not f(p: PointCoordinates)?
- jillesvangurp 5y agoThe issue is code readability while dealing with memory efficient arrays of DoubleArrays, which are used by geojson to represent geometries. You are right about the function call :-). Actually you can also do fun PointCoordinates.f() {...}. The reason I have function calls with latitude and longitude in there as equivalents for their point coordinate variants is just convenience. If you have some other library using its own point representation, having to first convert to my representation before you can use my functions is a bit verbose. And of course, people into OO programming usually get a bit carried away reinventing their own Point classes. It's one of the reasons I stayed away from using object hierarchies in this library. The geojson classes are an exception to this and were actually bolted on fairly recently so I can support geojson compatible serialization/deserialization.