Skip to content

Commit

Permalink
fix(Manual GPS): Determine whether the user is using UTM zone letters…
Browse files Browse the repository at this point in the history
… for latitude bands or hemisphere
  • Loading branch information
gmaclennan committed Jun 14, 2019
1 parent dd3c6bd commit 9bac3e1
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions src/frontend/screens/ManualGpsScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,57 @@ class ManualGpsScreen extends React.Component<Props, State> {

toLatLon() {
const { zoneNum, zoneLetter, easting, northing } = this.state;
const parsedNorthing = parseNumber(northing);
let northern;
// There are two conventions for UTM. One uses a letter to refer to latitude
// bands from C to X, excluding "I" and "O". The other uses "N" or "S" to
// refer to the northern or southern hemisphere. If the user enters "N" or
// "S" we do not know which convention they are using, so we guess. We try
// to use the latitude band if we can, since it is better for catching
// errors in coordinate entry.
if (zoneLetter === "S") {
// "S" could refer to grid zone "S" (in the northern hemisphere) or it
// could mean "Southern" - conventions differ in different places
const startOfZoneS = 3544369.909548157;
const startOfZoneT = 4432069.057005376;
if (
parsedNorthing !== undefined &&
parsedNorthing >= startOfZoneS &&
parsedNorthing < startOfZoneT
) {
// Indeterminate, this could be latitude band S, or it could mean
// southern hemisphere. The only place in the southern hemisphere that
// matches these coordinates is the very southern tip of Chile and
// Argentina, so assume that in this case zoneLetter "S" refers to
// latitude band "S", in the northern hemisphere.
// TODO: Check with the user what they mean, or use last known location
} else {
// The northing is not within the range of grid zone "S", so we assume
// the user meant "Southern" with the letter "S"
northern = false;
}
} else if (zoneLetter === "N") {
const startOfZoneN = 0;
const startOfZoneP = 885503.7592863895;
if (
parsedNorthing &&
parsedNorthing >= startOfZoneN &&
parsedNorthing < startOfZoneP
) {
// Definitely in latitude band N, just use the band letter
} else {
// Outside latitude band "N", so the user probably means "Northern"
northern = true;
}
}
try {
return toLatLon(
parseNumber(easting),
parseNumber(northing),
parseNumber(zoneNum),
zoneLetter
// If northern defined, then don't use the zoneLetter.
northern !== undefined ? undefined : zoneLetter,
northern
);
} catch (err) {
ToastAndroid.showWithGravity(
Expand Down Expand Up @@ -127,7 +172,7 @@ class ManualGpsScreen extends React.Component<Props, State> {
placeholderTextColor="silver"
underlineColorAndroid="transparent"
onChangeText={zoneLetter =>
this.setState({ zoneLetter: zoneLetter.trim() })
this.setState({ zoneLetter: zoneLetter.trim().toUpperCase() })
}
maxLength={1}
autoCapitalize="characters"
Expand Down

0 comments on commit 9bac3e1

Please sign in to comment.