turf_dart icon indicating copy to clipboard operation
turf_dart copied to clipboard

Decide if all functions should always return normalized coordinates (within ±90deg/±180deg range)

Open lukas-h opened this issue 3 years ago • 7 comments

Relating to the new vector functions #23 – which don't have a "wraparound" conversion built-in. But may also be important more broadly:

I'm not sure if [coordinate normalization] belongs here or not, it sort of depends on the use cases. Is there a use case for getting positions that are technically out of bounds or should the value we return from any function always be normalized to within the ±90deg/±180deg range?

Originally posted by @baparham in https://github.com/dartclub/turf_dart/pull/43#discussion_r769008563

lukas-h avatar Dec 14 '21 21:12 lukas-h

Right now, the coordinate types Position(lng, lat, alt) and BBox have a toSigned method to do the normalization.

But you have to explicitly call it. Nowhere in the library is this done automatically.

lukas-h avatar Dec 14 '21 21:12 lukas-h

I found some older discussions, where this is mentioned: https://github.com/dartclub/turf_dart/pull/4#issuecomment-723502151

lukas-h avatar Dec 14 '21 21:12 lukas-h

After giving this a small amount of thought, I would presume that most use cases center on real world geographical data, in which case, extending beyond the bounds of the standard ±90deg/±180deg range aren't much use.

There is probably a small use case to be argued for allowing non-normalized coordinates, particularly with abstract geo-manipulation, but I would posit that is the exception, not the rule.

With that said, my vote would be to make coordinates always normalized to within the standard range, and potentially provide a way to keep calculations and positions unsigned, i.e. non-normalized. How that is achieved, I don't really know, since normalization is "lossy" in effect, and you can never return to the pre-normalized state, UNLESS you keep that data around as part of the position and bbox objects for some future use, but I think it's better to wait for someone in the community to actually raise that as a valid use case before building it into the implementation.

baparham avatar Dec 15 '21 19:12 baparham

100% agree

Maybe this could be done in the constructors of the coordinate types. Similarly to this approach maybe: https://github.com/flutter-mapbox-gl/maps/blob/01a038d93560bebcf2170dabf32e44b3cdffafcc/mapbox_gl_platform_interface/lib/src/location.dart#L16

lukas-h avatar Dec 15 '21 22:12 lukas-h

There is probably a small use case to be argued for allowing non-normalized coordinates, particularly with abstract geo-manipulation, but I would posit that is the exception, not the rule.

We could add a constructor Position.unsigned/Position.unbounded or similarly named. This should flip a boolean flag for “this position is not normalized and should remain so”. With that we could re-implement the vector operations somehow like this:

Position operator +(Position other) => 
shouldRemainUnsigned
? Position.unsigned(lng + other.lng, lat + other.lat)
: Position(lng + other.lng, lat + other.lat);

lukas-h avatar Dec 15 '21 22:12 lukas-h

I will start with an implementation attempt soon

lukas-h avatar Dec 19 '21 15:12 lukas-h

The decision was, to keep Position unsigned by default, but it can be converted to a signed coordinate easily!

The imagined behaviour with signed/unsigned is similar to DateTime, which can be local or UTC. The DateTime has conversion functions toLocal() and toUTC(), that return a new object. Internally it uses a boolean to save the state (local = true/false).

CC @baparham @tobrun

lukas-h avatar Mar 02 '22 22:03 lukas-h