diff --git a/service/csvService.js b/service/csvService.js index 28e15ac..6017e34 100644 --- a/service/csvService.js +++ b/service/csvService.js @@ -132,8 +132,9 @@ function hasAddressOrNumberHeader(headers) { } function hasGeoHeaders(headers) { - return hasHeaderAlias(headers, ['latitude', 'lat']) - && hasHeaderAlias(headers, ['longitude', 'long', 'lng', 'lon']); + const norm = headers.map(normalizeHeader); + return norm.some(h => /\blat(itude)?\b/.test(h)) + && norm.some(h => /\blo?n[g]?(itude)?\b/.test(h)); } function findHeaderRowIndex(rows) { @@ -152,8 +153,10 @@ function resolveColumnIndexes(headers) { idxCep: findFirstHeaderIndex(headers, header => /\bcep\b/.test(header) || header === 'codigo postal'), idxNumero: exactIndex(['numero', 'número', 'num', 'nº', 'n°']), idxEndereco: findFirstHeaderIndex(headers, header => header.includes('endereco') || header.includes('logradouro')), - idxLatitude: exactIndex(['latitude', 'lat']), - idxLongitude: exactIndex(['longitude', 'long', 'lng', 'lon']) + // Antes: exactIndex(['latitude', 'lat']) + idxLatitude: findFirstHeaderIndex(headers, header => /\blat(itude)?\b/.test(header)), + // Antes: exactIndex(['longitude', 'long', 'lng', 'lon']) + idxLongitude: findFirstHeaderIndex(headers, header => /\blo?n[g]?(itude)?\b/.test(header)), }; } @@ -187,7 +190,20 @@ function buildCepPayload(cols, indexes) { } function parseCoordinate(value) { - const parsed = parseFloat(String(value ?? '').trim().replace(',', '.')); + const str = String(value ?? '') + .replace(/[\u00A0\u202F\u2000-\u200B\u3000]/g, '') // Bug 2: remove non-breaking spaces + .trim() + .replace(',', '.'); + + // Bug 3: converte DMS "17 38 18.80 S" → -17.638556 + const dms = str.match(/^(\d+)[°\s]+(\d+)['\s]+(\d+(?:\.\d+)?)["\s]*([NSEW])?$/i); + if (dms) { + const decimal = parseFloat(dms[1]) + parseFloat(dms[2]) / 60 + parseFloat(dms[3]) / 3600; + const negative = /[SW]/i.test(dms[4] ?? ''); + return negative ? -decimal : decimal; + } + + const parsed = parseFloat(str); return Number.isFinite(parsed) ? parsed : NaN; } diff --git a/service/viabilidadeService.js b/service/viabilidadeService.js index 8a14fe8..560b99b 100644 --- a/service/viabilidadeService.js +++ b/service/viabilidadeService.js @@ -105,8 +105,8 @@ function hasAddressOrNumberHeader(headers) { } function hasGeoHeaders(headers) { - return hasHeader(headers, ['latitude', 'lat']) - && hasHeader(headers, ['longitude', 'long', 'lng', 'lon']); + return headers.some(h => /\blat(itude)?\b/.test(h)) + && headers.some(h => /\blo?n[g]?(itude)?\b/.test(h)); } async function consultarViabilidade(data) {