Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/controllers/splinker-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ const obterModeloSPlinkerLotes = async (limit, offset, request, response) => {
const city = tombo.locais_coletum?.cidade?.nome || '\t';
const locality = tombo.locais_coletum?.descricao || '\t';
const latitude = tombo.latitude
? converteDecimalParaGrausMinutosSegundos(tombo.latitude, false, true)
? converteDecimalParaGrausMinutosSegundos(tombo.latitude, true, true)
: '\t';
const longitude = tombo.longitude
? converteDecimalParaGrausMinutosSegundos(tombo.longitude, true, true)
? converteDecimalParaGrausMinutosSegundos(tombo.longitude, false, true)
: '\t';
const elevation = tombo.altitude ? `${tombo.altitude} m` : '\t';
const identificationDate = [
Expand Down
24 changes: 12 additions & 12 deletions src/helpers/coordenadas.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ const CHAR_SEC = '\u0022';
const CHAR_SEP = '\u0020';

export const converteParaDecimal = coordenada => {
const regex = /^(\d+)\D+(\d+)\D+(\d+(?:[.,]\d+)?)\W+([NSWE])$/;
const matches = coordenada.match(regex);
if (typeof coordenada !== 'string') {
throw new Error('Coordenada inválida');
}

const regex = /^(\d+)\D+(\d+)\D+(\d+(?:[.,]\d+)?)\W+([NSWE])$/i;
const matches = coordenada.trim().match(regex);

if (matches.length < 5) {
if (!matches) {
throw new Error('Coordenada inválida');
}

const graus = parseInt(matches[1]);
const minutos = parseInt(matches[2]);
const graus = parseInt(matches[1], 10);
const minutos = parseInt(matches[2], 10);
const segundos = parseFloat(matches[3].replace(',', '.'));
const hemisferio = matches[4];
const hemisferio = matches[4].toUpperCase();

const sinal = (['S', 'W'].includes(hemisferio)) ? -1 : 1;

Expand Down Expand Up @@ -180,13 +184,9 @@ export const converteDecimalParaGrausMinutosSegundos = (gDec, ehLat, formatada)
segundos = aux;

if (ehLat) {
// Eixo X
if (graus < 0) direcao = 'W';
else direcao = 'E';
direcao = graus < 0 ? 'S' : 'N';
} else {
// Eixo Y
if (graus >= 0) direcao = 'N';
else direcao = 'S';
direcao = graus < 0 ? 'W' : 'E';
}

if (formatada) {
Expand Down
68 changes: 68 additions & 0 deletions test/unit/helpers/coordenadas.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
describe,
expect,
test
} from 'vitest'

import {
converteDecimalParaGrausMinutosSegundos,
converteParaDecimal
} from '@/helpers/coordenadas'

describe('converteParaDecimal', () => {
test('converts compact DMS latitude 48°56\'15,00"S to decimal degrees', () => {
expect(converteParaDecimal('48°56\'15,00"S')).toBe(-48.9375)
})

test('converts compact DMS longitude 48°56\'16,00"W to decimal degrees', () => {
expect(converteParaDecimal('48°56\'16,00"W')).toBeCloseTo(
-(48 + 56 / 60 + 16 / 3600),
10
)
})

test('accepts a space before the hemisphere', () => {
expect(converteParaDecimal('48°56\'15,00" S')).toBe(-48.9375)
expect(converteParaDecimal('48°56\'16,00" W')).toBeCloseTo(
-(48 + 56 / 60 + 16 / 3600),
10
)
})

test('applies a positive sign for N and E', () => {
expect(converteParaDecimal('48°56\'15,00"N')).toBe(48.9375)
expect(converteParaDecimal('48°56\'16,00"E')).toBeCloseTo(
48 + 56 / 60 + 16 / 3600,
10
)
})

test('throws when the coordinate is not DMS', () => {
expect(() => converteParaDecimal('48.9375')).toThrow('Coordenada inválida')
expect(() => converteParaDecimal('')).toThrow('Coordenada inválida')
})
})

describe('converteDecimalParaGrausMinutosSegundos', () => {
const latitudeHcf46776 = converteParaDecimal('25°18\'27,00"S')
const longitudeHcf46776 = converteParaDecimal('49°0\'49,00"W')

test('formats HCF 46776 latitude as south, not west', () => {
expect(
converteDecimalParaGrausMinutosSegundos(latitudeHcf46776, true, true)
).toBe('25°18\'27,00" S')
})

test('formats HCF 46776 longitude as west, not south', () => {
expect(
converteDecimalParaGrausMinutosSegundos(longitudeHcf46776, false, true)
).toBe('49°0\'49,00" W')
})

test('uses N/S for latitude and E/W for longitude', () => {
expect(converteDecimalParaGrausMinutosSegundos(25.3075, true, true)).toMatch(/ N$/)
expect(converteDecimalParaGrausMinutosSegundos(-25.3075, true, true)).toMatch(/ S$/)
expect(converteDecimalParaGrausMinutosSegundos(49.013611, false, true)).toMatch(/ E$/)
expect(converteDecimalParaGrausMinutosSegundos(-49.013611, false, true)).toMatch(/ W$/)
})
})
Loading