Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Setting to choose coordinate display format #526

Merged
merged 23 commits into from
Apr 19, 2021

Conversation

luandro
Copy link
Contributor

@luandro luandro commented Mar 16, 2021

This adds the ability to change the coordinate system, saving to AsyncStorage the selected option.

  • Add coordinate system page to settings with ability to change between LatLon, UTM, DMS, DD
  • Change coords on observation screens based on setting
  • Change coords on GPS screen based on setting

@luandro luandro marked this pull request as ready for review March 17, 2021 12:11
@hackergrrl
Copy link
Contributor

I don't feel super qualified to review this, but it looks good to me! If it all seems to be working in your manual tests, I think it's ok to merge now.

cc @gmaclennan to take a look over when he's back.

@gmaclennan
Copy link
Member

Hi! I'm back! Great work on this @luandro! I haven't installed this or checked the code yet, but based purely on the screenshots a couple of comments:

  • "Latitude and Longitude" and "Decimal Degrees" are the same thing. DMS is also Latitude and Longitude. Basically DMS and Decimal Degrees are two ways or writing lat & lon.
  • I think we should round decimal degrees to 6 decimal places (see https://wiki.openstreetmap.org/wiki/Precision_of_coordinates). That is about 10cm precision at the equator, which is way more than our GPS precision anyway.
  • Just to make sure that we show decimals on DMS coordinates, e.g. 0°00′00.004″. We should show 3 decimal places here to match the same precision as DD.
  • There are lots of ways to format / write DMS (see https://github.com/gmaclennan/parse-dms/blob/master/test/index.js) but I think DD°MM′SS.sss″ N DD°MM′SS.sss″ W makes the most sense. Latitude is first when writing DMS (most of the time!)
  • There is controversy about whether to write decimal degrees as lon/lat or lat/lon. The "traditionalists" say lat/lon, which is "y-axis" first, but most computer code expects Longitude first (e.g. x-axis first). I would lean towards lon first. Not sure what the best way is to format this so that it is clear to the user, could you do some research into ways of formatting / writing decimal degrees?

@gmaclennan
Copy link
Member

Also we should put this data (selected coordinate system) in React Context, and the hook should read from there. I can talk through the reasons for this and how to do this on our next check-in.

@luandro
Copy link
Contributor Author

luandro commented Mar 24, 2021

"Latitude and Longitude" and "Decimal Degrees" are the same thing. DMS is also Latitude and Longitude. Basically DMS and Decimal Degrees are two ways or writing lat & lon.

lol thanks, was really confused that both looked exactly the same.

I think we should round decimal degrees to 6 decimal places

Makes a lot of sense.

Just to make sure that we show decimals on DMS coordinates, e.g. 0°00′00.004″. We should show 3 decimal places here to match the same precision as DD.

👍

could you do some research into ways of formatting / writing decimal degrees?

In relation to what comes first (lat or long):

My interpratation:

Lat/Long is commonly used because Latitute was discovered first, as has been used first since.

Long/Lat is also commonly used because of conventional math (ie, f(x ,y, z)).

I think lat/long will make more sense for the user, while long/lat will make more sense for a machine. Thoughts @gmaclennan, as you have more experience? @rudokemper might also have some thought on this.

@rudokemper
Copy link
Member

In my experience, latitude is generally always written out first, conforming to your observations on user expectations @luandro. But that might be specific to the contexts where I have done GIS work (Suriname, Brazil, Colombia, and now Kenya). But even experienced GIS specialists get lat & long confused all the time, and have to look up which is which, haha..

@luandro
Copy link
Contributor Author

luandro commented Mar 25, 2021

Todo:

  • Add settings context, and have the coordinate config live there
  • Rename LatLog to Decimal Degrees
  • Pass lat lon as object to coordinate format functions

Forgetting anything @gmaclennan?

@luandro
Copy link
Contributor Author

luandro commented Apr 1, 2021

Had a bit of a hard time updating my knowledge on React hooks, but all worked out. Ready for another review @gmaclennan.

@luandro luandro requested a review from gmaclennan April 1, 2021 13:19
Copy link
Member

@gmaclennan gmaclennan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding my feedback here that I shared over Slack, so there's a record of it. I've fixed this up myself and I'm just testing locally before pushing.

Comment on lines 15 to 59
const defaultContext = [initialState, () => {}];
const SettingsContext = React.createContext(defaultContext);

function reducer(state: State, action: Action): State {
switch (action.type) {
case "set": {
return action.value;
}
case "set_coordinate_system": {
try {
return { ...state, coordinateSystem: action.value };
} catch {
return state;
}
}
default:
return state;
}
}

const getData = async dispatch => {
try {
// AsyncStorage.clear()
const state = await AsyncStorage.getItem(STORE_KEY);
if (state) {
const parsedState = JSON.parse(state);
dispatch({ type: "set", value: parsedState });
return parsedState;
} else return initialState;
} catch (e) {
console.log("Failed to fetch the data from storage");
return initialState;
}
};

const saveData = async value => {
try {
const stringified = JSON.stringify(value);
await AsyncStorage.setItem(STORE_KEY, stringified);
return value;
} catch (e) {
console.log("Failed to save the data to the storage");
}
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a usePersistedState hook, so best use that rather than have two different implementations of this.

}, [contextValue]);
return (
<SettingsContext.Provider
value={{ settings: contextValue[0], dispatch: contextValue[1] }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creates a new object on every render

Comment on lines 132 to 134
const formattedSeconds = Number(
Math.round(seconds + "e" + decimals) + "e-" + decimals
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not seconds.toFixed(3)?

@@ -55,6 +58,7 @@ const LocationField = ({ children }: Props) => {
return children({
longitude: value.lon,
latitude: value.lat,
system: coordinateSystem,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't really belong here, because this component has nothing to do with the display of coordinates. To separate concerns, I think it's better to keep this in the <LocationView> component

@gmaclennan gmaclennan changed the title Custom coordinate system feat: Allow user to choose the format coordinates are displayed in Apr 16, 2021
@gmaclennan gmaclennan changed the title feat: Allow user to choose the format coordinates are displayed in feat: Choose the format coordinates are displayed in Apr 16, 2021
@gmaclennan gmaclennan changed the title feat: Choose the format coordinates are displayed in feat: Setting to choose coordinate display format Apr 16, 2021
@gmaclennan gmaclennan merged commit 567fcce into develop Apr 19, 2021
@gmaclennan gmaclennan deleted the custom-coord-system branch April 19, 2021 18:03
gmaclennan added a commit that referenced this pull request Apr 20, 2021
* develop:
  feat: Setting to choose coordinate display format (#526)
  chore: Re-apply c267a99 with correct npm@6 version and lockfile v1
  Revert "feat: Updated translations for default configuration (vi, srn)"
  feat: Updated translations for default configuration (vi, srn)
  fix: Update Thai, Khmer & Vietnamese translations
  feat: Add Dutch translations
  feat: Add Sranan Tongo translations
  feat: Add French translations
  fix: Fix cutoff of text on OnePlus6T phone #502 (#511)
  fix: Write preset tags to observations (#514)
  chore: Fix Github CI builds by removing NDK r22 (#516)
  fix: Fix import config button crash (#512)
  feat: Updated translations (vi, es, po) (#498)

# Conflicts:
#	src/backend/package-lock.json
#	src/backend/package.json
#	src/frontend/screens/Settings/Settings.js
@achou11 achou11 mentioned this pull request Sep 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants