diff --git a/web/client/components/mapcontrols/annotations/CoordinateEntry.jsx b/web/client/components/mapcontrols/annotations/CoordinateEntry.jsx
index 23c9ab7685..db7d7b24d4 100644
--- a/web/client/components/mapcontrols/annotations/CoordinateEntry.jsx
+++ b/web/client/components/mapcontrols/annotations/CoordinateEntry.jsx
@@ -4,6 +4,7 @@ const PropTypes = require('prop-types');
const DecimalCoordinateEditor = require('./editors/DecimalCoordinateEditor');
const AeronauticalCoordinateEditor = require('./editors/AeronauticalCoordinateEditor');
const {isNil} = require('lodash');
+const no90Lat = require('./enhancers/no90Lat');
/**
This component can render an input field in two different formats: 'decimal' or 'aeronautical'
@@ -28,4 +29,4 @@ class CoordinateEntry extends React.Component {
}
}
-module.exports = CoordinateEntry;
+module.exports = no90Lat(CoordinateEntry); // TODO: remove no90Lat this when issue with coordinate 90 is fixed in annotations
diff --git a/web/client/components/mapcontrols/annotations/editors/AeronauticalCoordinateEditor.jsx b/web/client/components/mapcontrols/annotations/editors/AeronauticalCoordinateEditor.jsx
index 9804107a00..161574e40a 100644
--- a/web/client/components/mapcontrols/annotations/editors/AeronauticalCoordinateEditor.jsx
+++ b/web/client/components/mapcontrols/annotations/editors/AeronauticalCoordinateEditor.jsx
@@ -10,7 +10,7 @@ const {isNil} = require('lodash');
const decimalToAeronautical = require('../enhancers/decimalToAeronautical');
const coordinateTypePreset = require('../enhancers/coordinateTypePreset');
-const tempAreonauticalValue = require('../enhancers/tempAreonauticalValue');
+const tempAeronauticalValue = require('../enhancers/tempAeronauticalValue');
class CoordinateEntry extends React.Component {
@@ -42,7 +42,7 @@ class CoordinateEntry extends React.Component {
minutes: this.props.minutes,
seconds: this.props.seconds,
direction: this.props.direction,
- [part]: newValue
+ [part]: part === "degrees" ? Math.min(newValue, this.props.maxDegrees) : newValue
};
let seconds = newValues.seconds;
let minutes = newValues.minutes + this.getSexagesimalStep(seconds);
@@ -160,7 +160,7 @@ class CoordinateEntry extends React.Component {
}
module.exports = compose(
+ coordinateTypePreset,
decimalToAeronautical,
- tempAreonauticalValue,
- coordinateTypePreset
+ tempAeronauticalValue
)(CoordinateEntry);
diff --git a/web/client/components/mapcontrols/annotations/editors/__tests__/AeronauticalCoordinateEditor-test.jsx b/web/client/components/mapcontrols/annotations/editors/__tests__/AeronauticalCoordinateEditor-test.jsx
new file mode 100644
index 0000000000..dfdd84c9c2
--- /dev/null
+++ b/web/client/components/mapcontrols/annotations/editors/__tests__/AeronauticalCoordinateEditor-test.jsx
@@ -0,0 +1,49 @@
+const React = require('react');
+const ReactDOM = require('react-dom');
+const ReactTestUtils = require('react-dom/test-utils');
+const expect = require('expect');
+const AeronauticalCoordinateEditor = require('../AeronauticalCoordinateEditor');
+
+describe('AeronauticalCoordinateEditor enhancer', () => {
+ beforeEach((done) => {
+ document.body.innerHTML = '
';
+ setTimeout(done);
+ });
+ afterEach((done) => {
+ ReactDOM.unmountComponentAtNode(document.getElementById("container"));
+ document.body.innerHTML = '';
+ setTimeout(done);
+ });
+ it('AeronauticalCoordinateEditor rendering with defaults', () => {
+ ReactDOM.render(, document.getElementById("container"));
+ const container = document.getElementById('container');
+ const elements = container.querySelectorAll('input');
+ expect(elements.length).toBe(3);
+ });
+ it('AeronauticalCoordinateEditor rendering with 13.3333333333', () => {
+ ReactDOM.render(, document.getElementById("container"));
+ const container = document.getElementById('container');
+ const elements = container.querySelectorAll('input');
+ expect(elements.length).toBe(3);
+ expect(elements[0].value).toBe('13');
+ expect(elements[1].value).toBe('20');
+ expect(elements[2].value).toBe('0');
+ });
+ it('Test AeronauticalCoordinateEditor onChange', () => {
+ const actions = {
+ onChange: () => {}
+ };
+ const spyonChange = expect.spyOn(actions, 'onChange');
+ ReactDOM.render(, document.getElementById("container"));
+ const container = document.getElementById('container');
+
+ const elements = container.querySelectorAll('input');
+ expect(elements.length).toBe(3);
+ expect(elements[0].value).toBe('19');
+ expect(elements[1].value).toBe('0');
+ expect(elements[2].value).toBe('0');
+ ReactTestUtils.Simulate.change(elements[0], { target: { value: "20" } });
+ expect(spyonChange).toHaveBeenCalled();
+ expect(parseFloat(spyonChange.calls[0].arguments[0])).toBe(20);
+ });
+});
diff --git a/web/client/components/mapcontrols/annotations/enhancers/__tests__/decimalToAeronautical-test.js b/web/client/components/mapcontrols/annotations/enhancers/__tests__/decimalToAeronautical-test.js
index c2547c12f6..f3941a94ed 100644
--- a/web/client/components/mapcontrols/annotations/enhancers/__tests__/decimalToAeronautical-test.js
+++ b/web/client/components/mapcontrols/annotations/enhancers/__tests__/decimalToAeronautical-test.js
@@ -38,6 +38,20 @@ describe("test the Annotations enahncers", () => {
coordinate="lon"
/>), document.getElementById("container"));
});
+ it('decimalToAeronautical conversion correctly step on minutes and seconds', (done) => {
+ // 13.3333333333 should be 13 degrees, 20 minutes
+ const Sink = decimalToAeronautical(createSink(props => {
+ expect(props).toExist();
+ expect(props.degrees).toBe(13);
+ expect(props.minutes).toBe(20);
+ expect(props.seconds).toBe(0);
+ done();
+ }));
+ ReactDOM.render((), document.getElementById("container"));
+ });
it('convert from/to preserve precision', (done) => {
const enhancer = compose(
withState('value', 'onChange', 1.5),
diff --git a/web/client/components/mapcontrols/annotations/enhancers/__tests__/no90Lat-test.js b/web/client/components/mapcontrols/annotations/enhancers/__tests__/no90Lat-test.js
new file mode 100644
index 0000000000..22d441aad1
--- /dev/null
+++ b/web/client/components/mapcontrols/annotations/enhancers/__tests__/no90Lat-test.js
@@ -0,0 +1,50 @@
+const React = require('react');
+const ReactDOM = require('react-dom');
+const {createSink} = require('recompose');
+const expect = require('expect');
+const no90Lat = require('../no90Lat');
+
+describe('no90Lat enhancer', () => {
+ beforeEach((done) => {
+ document.body.innerHTML = '';
+ setTimeout(done);
+ });
+ afterEach((done) => {
+ ReactDOM.unmountComponentAtNode(document.getElementById("container"));
+ document.body.innerHTML = '';
+ setTimeout(done);
+ });
+ it('no90Lat rendering with defaults', (done) => {
+ const onChange = (v) => {
+ expect(parseFloat(v)).toBeLessThan(90);
+ };
+ const Sink = no90Lat(createSink( props => {
+ expect(props).toExist();
+ props.onChange("90");
+ done();
+ }));
+ ReactDOM.render(, document.getElementById("container"));
+ });
+ it('no90Lat rendering with negative value', (done) => {
+ const onChange = (v) => {
+ expect(parseFloat(v)).toBeMoreThan(-90);
+ };
+ const Sink = no90Lat(createSink(props => {
+ expect(props).toExist();
+ props.onChange("-90");
+ done();
+ }));
+ ReactDOM.render(, document.getElementById("container"));
+ });
+ it('no90Lat rendering with lon', (done) => {
+ const onChange = (v) => {
+ expect(parseFloat(v)).toBe(90);
+ };
+ const Sink = no90Lat(createSink(props => {
+ expect(props).toExist();
+ props.onChange("90");
+ done();
+ }));
+ ReactDOM.render(, document.getElementById("container"));
+ });
+});
diff --git a/web/client/components/mapcontrols/annotations/enhancers/decimalToAeronautical.js b/web/client/components/mapcontrols/annotations/enhancers/decimalToAeronautical.js
index 8ed106b831..89728d4de1 100644
--- a/web/client/components/mapcontrols/annotations/enhancers/decimalToAeronautical.js
+++ b/web/client/components/mapcontrols/annotations/enhancers/decimalToAeronautical.js
@@ -2,11 +2,27 @@
const {compose, withHandlers, withProps} = require('recompose');
const convertDDToDMS = (D, lng) => {
+ let d = parseInt(D, 10);
+ let minFloat = Math.abs((D - d) * 60);
+ let m = Math.floor(minFloat);
+ let secFloat = (minFloat - m) * 60;
+ let s = Math.round(secFloat);
+ d = Math.abs(d);
+
+ if (s === 60) {
+ m++;
+ s = 0;
+ }
+ if (m === 60) {
+ d++;
+ m = 0;
+ }
+
return {
- degrees: Math.abs(0 | D),
+ degrees: d,
direction: D < 0 ? lng ? 'W' : 'S' : lng ? 'E' : 'N',
- minutes: Math.floor(Math.abs(0 | D % 1 * 60)),
- seconds: Math.round(Math.abs((0 | D * 60 % 1 * 6000) / 100))
+ minutes: m,
+ seconds: s
};
};
diff --git a/web/client/components/mapcontrols/annotations/enhancers/no90Lat.js b/web/client/components/mapcontrols/annotations/enhancers/no90Lat.js
new file mode 100644
index 0000000000..ac7b843eb2
--- /dev/null
+++ b/web/client/components/mapcontrols/annotations/enhancers/no90Lat.js
@@ -0,0 +1,17 @@
+const {compose, withHandlers} = require('recompose');
+
+/**
+ * This workaround issues with annotations at 90 degrees lat.
+ * This avoid wrong input from user breaks the draw support
+ * // TODO: remove this in favor of some more general enhancer or some check inside draw support
+ */
+module.exports = compose(
+ withHandlers({
+ onChange: ({ onChange = () => { }, maxLatitude = 89.9997222222, coordinate}) => v =>
+ onChange(
+ Math.abs(parseFloat(v)) > maxLatitude && coordinate === "lat"
+ ? Math.sign(v) * maxLatitude
+ : v
+ )
+ })
+);
diff --git a/web/client/components/mapcontrols/annotations/enhancers/tempAreonauticalValue.js b/web/client/components/mapcontrols/annotations/enhancers/tempAeronauticalValue.js
similarity index 100%
rename from web/client/components/mapcontrols/annotations/enhancers/tempAreonauticalValue.js
rename to web/client/components/mapcontrols/annotations/enhancers/tempAeronauticalValue.js