FEAT: Função de consulta reversa de lat e lon.

- Criada função que consulta o endereço utilizando lat e lon.

- Alterada a função que lê o CSV de upload para que ignore linhas vazias.
This commit is contained in:
Gabriel Amancio 2025-11-05 15:51:55 -03:00
parent b81c1d3f3f
commit f28ad3a716
3 changed files with 46 additions and 3 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.env
outputs/
node_modules/
.vscode/
.cache/
uploads/

24
app.js
View File

@ -9,7 +9,7 @@ const fastCsv = require("fast-csv");
const axios = require("axios");
const cors = require("cors");
const session = require("express-session"); // adiciona session
const { geocodeWithGoogle } = require("./service/geocodeService");
const { geocodeWithGoogle, addressWithGoogle } = require("./service/geocodeService");
const { fetchJson } = require("./service/fetchService");
const { BASE_BACKOFF_MS, MAX_RETRIES, REQUEST_DELAY_MS, sleep } = require("./service/retryService");
const { API_URL, HEADERS } = require("./config/apiConfig");
@ -235,7 +235,16 @@ function createApp() {
await new Promise((resolve, reject) => {
fs.createReadStream(filePath)
.pipe(csv({ separator: ";" }))
.on("data", (data) => rows.push(data))
.on("data", (data) => {
// ignora linhas totalmente vazias (todos os campos nulos/undefined/strings vazias)
const values = Object.values(data);
const allEmpty =
values.length === 0 ||
values.every(
(v) => v === null || v === undefined || String(v).trim() === ""
);
if (!allEmpty) rows.push(data);
})
.on("end", resolve)
.on("error", reject);
});
@ -280,6 +289,17 @@ function createApp() {
let builtAddress = "";
const googleGeocodeAddress = await addressWithGoogle(lat, lon);
if (googleGeocodeAddress) {
builtAddress = googleGeocodeAddress;
} else {
console.warn(
`Google Reverse Geocoding não retornou resultado para coords ${lat},${lon} (row ${i + 1})`
);
}
console.log(`Row ${i + 1}: CEP='${rawCep}' Número='${rawNumero}' Lat='${lat}' Lon='${lon}' BuiltAddress='${builtAddress}'`);
// If no coords, try ViaCEP -> Google
if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
if (rawCep) {

View File

@ -22,4 +22,21 @@ dotenv.config();
}
}
module.exports = { geocodeWithGoogle };
async function addressWithGoogle(lat, lon) {
const key = process.env.GOOGLE_API_KEY;
if (!key) return null;
try {
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${encodeURIComponent(lat)},${encodeURIComponent(lon)}&key=${encodeURIComponent(key)}`;
const r = await axios.get(url, { timeout: 10000 });
if (r && r.data && Array.isArray(r.data.results) && r.data.results.length > 0) {
console.log(`Google Reverse Geocoding result for ${lat},${lon}: ${r.data.results[0].formatted_address}`);
return r.data.results[0].formatted_address || null;
}
return null;
} catch (e) {
console.warn(`addressWithGoogle error for '${lat},${lon}': ${e.message}`);
return null;
}
}
module.exports = { geocodeWithGoogle, addressWithGoogle };