Guilherme Silberfarb Costa commited on
Commit
22106af
·
1 Parent(s): 5cc74bd

correcao no fluxo de exclusao/inclusao de coordenadas

Browse files
backend/app/api/elaboracao.py CHANGED
@@ -170,6 +170,12 @@ def geocodificar_reiniciar(payload: SessionPayload) -> dict[str, Any]:
170
  return elaboracao_service.reiniciar_geocodificacao(session)
171
 
172
 
 
 
 
 
 
 
173
  @router.post("/apply-selection")
174
  def apply_selection(payload: ApplySelectionPayload) -> dict[str, Any]:
175
  session = session_store.get(payload.session_id)
 
170
  return elaboracao_service.reiniciar_geocodificacao(session)
171
 
172
 
173
+ @router.post("/geocodificar-excluir-coords")
174
+ def geocodificar_excluir_coords(payload: SessionPayload) -> dict[str, Any]:
175
+ session = session_store.get(payload.session_id)
176
+ return elaboracao_service.excluir_coordenadas_para_geocodificacao(session)
177
+
178
+
179
  @router.post("/apply-selection")
180
  def apply_selection(payload: ApplySelectionPayload) -> dict[str, Any]:
181
  session = session_store.get(payload.session_id)
backend/app/services/elaboracao_service.py CHANGED
@@ -364,6 +364,25 @@ def _build_coords_payload(df: pd.DataFrame, tem_coords: bool) -> dict[str, Any]:
364
  }
365
 
366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  def _set_dataframe_base(
368
  session: SessionState,
369
  df: pd.DataFrame,
@@ -1387,6 +1406,33 @@ def reiniciar_geocodificacao(session: SessionState) -> dict[str, Any]:
1387
  }
1388
 
1389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1390
  def aplicar_correcoes_geocodificacao(
1391
  session: SessionState,
1392
  correcoes: list[dict[str, Any]],
 
364
  }
365
 
366
 
367
+ def _remover_colunas_coordenadas(df: pd.DataFrame) -> tuple[pd.DataFrame, list[str]]:
368
+ """Remove pares de colunas detectadas como coordenadas até não restar nenhum par válido."""
369
+ df_saida = df.copy()
370
+ removidas: list[str] = []
371
+ max_iter = max(1, len(df_saida.columns))
372
+
373
+ for _ in range(max_iter):
374
+ tem_coords, col_lat, col_lon = geocodificacao.verificar_coords(df_saida)
375
+ if not tem_coords or not col_lat or not col_lon:
376
+ break
377
+
378
+ for coluna in (str(col_lat), str(col_lon)):
379
+ if coluna in df_saida.columns:
380
+ removidas.append(coluna)
381
+ df_saida = df_saida.drop(columns=[col_lat, col_lon], errors="ignore")
382
+
383
+ return df_saida, list(dict.fromkeys(removidas))
384
+
385
+
386
  def _set_dataframe_base(
387
  session: SessionState,
388
  df: pd.DataFrame,
 
1406
  }
1407
 
1408
 
1409
+ def excluir_coordenadas_para_geocodificacao(session: SessionState) -> dict[str, Any]:
1410
+ if session.df_original is None:
1411
+ raise HTTPException(status_code=400, detail="Carregue dados primeiro")
1412
+
1413
+ df_sem_coords, removidas = _remover_colunas_coordenadas(session.df_original)
1414
+ if not removidas:
1415
+ raise HTTPException(status_code=400, detail="Nao ha coordenadas detectadas para excluir")
1416
+
1417
+ session.df_original = df_sem_coords.copy()
1418
+ session.df_filtrado = df_sem_coords.drop(index=session.outliers_anteriores, errors="ignore")
1419
+ session.df_geo_origem = df_sem_coords.copy()
1420
+ session.geo_falhas_df = None
1421
+ session.geo_col_cdlog = None
1422
+ session.geo_col_num = None
1423
+ session.mapa_habilitado = False
1424
+
1425
+ return {
1426
+ "status": "Coordenadas removidas. Configure a geocodificacao para gerar novas coordenadas.",
1427
+ "status_html": "",
1428
+ "falhas_html": "",
1429
+ "falhas_para_correcao": dataframe_to_payload(pd.DataFrame(), decimals=None),
1430
+ "mapa_html": _render_mapa_if_enabled(session, session.df_filtrado),
1431
+ "dados": dataframe_to_payload(session.df_filtrado, decimals=4),
1432
+ "coords": _build_coords_payload(session.df_original, False),
1433
+ }
1434
+
1435
+
1436
  def aplicar_correcoes_geocodificacao(
1437
  session: SessionState,
1438
  correcoes: list[dict[str, Any]],
frontend/src/api.js CHANGED
@@ -89,6 +89,7 @@ export const api = {
89
  geocodificar: (sessionId, colCdlog, colNum, auto200) => postJson('/api/elaboracao/geocodificar', { session_id: sessionId, col_cdlog: colCdlog, col_num: colNum, auto_200: auto200 }),
90
  geocodificarCorrecoes: (sessionId, correcoes, auto200) => postJson('/api/elaboracao/geocodificar-correcoes', { session_id: sessionId, correcoes, auto_200: auto200 }),
91
  geocodificarReiniciar: (sessionId) => postJson('/api/elaboracao/geocodificar-reiniciar', { session_id: sessionId }),
 
92
 
93
  applySelection(payload) {
94
  return postJson('/api/elaboracao/apply-selection', payload)
 
89
  geocodificar: (sessionId, colCdlog, colNum, auto200) => postJson('/api/elaboracao/geocodificar', { session_id: sessionId, col_cdlog: colCdlog, col_num: colNum, auto_200: auto200 }),
90
  geocodificarCorrecoes: (sessionId, correcoes, auto200) => postJson('/api/elaboracao/geocodificar-correcoes', { session_id: sessionId, correcoes, auto_200: auto200 }),
91
  geocodificarReiniciar: (sessionId) => postJson('/api/elaboracao/geocodificar-reiniciar', { session_id: sessionId }),
92
+ geocodificarExcluirCoords: (sessionId) => postJson('/api/elaboracao/geocodificar-excluir-coords', { session_id: sessionId }),
93
 
94
  applySelection(payload) {
95
  return postJson('/api/elaboracao/apply-selection', payload)
frontend/src/components/ElaboracaoTab.jsx CHANGED
@@ -562,6 +562,7 @@ export default function ElaboracaoTab({ sessionId }) {
562
  const [manualMapError, setManualMapError] = useState('')
563
  const [geoProcessError, setGeoProcessError] = useState('')
564
  const [coordsMode, setCoordsMode] = useState('menu')
 
565
 
566
  const [colunasNumericas, setColunasNumericas] = useState([])
567
  const [colunaY, setColunaY] = useState('')
@@ -883,6 +884,12 @@ export default function ElaboracaoTab({ sessionId }) {
883
  }
884
  }, [coordsInfo])
885
 
 
 
 
 
 
 
886
  useEffect(() => {
887
  if (marcarTodasXRef.current) {
888
  marcarTodasXRef.current.indeterminate = algumaXMarcada && !todasXMarcadas
@@ -1450,6 +1457,30 @@ export default function ElaboracaoTab({ sessionId }) {
1450
  setManualMapError('')
1451
  setGeoProcessError('')
1452
  setCoordsMode(resp.coords?.tem_coords ? 'menu' : 'geocodificar')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1453
  })
1454
  }
1455
 
@@ -2249,12 +2280,50 @@ export default function ElaboracaoTab({ sessionId }) {
2249
  </>
2250
  ) : (
2251
  <div className="subpanel coords-section-group">
2252
- <div className="section1-empty-hint">Coordenadas disponíveis ou etapa concluída.</div>
2253
- <div className="row coords-restart-row">
2254
- <button type="button" onClick={onReiniciarGeocodificacao} disabled={loading}>
2255
- Reiniciar geocodificação
2256
- </button>
2257
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2258
  </div>
2259
  )}
2260
  </div>
 
562
  const [manualMapError, setManualMapError] = useState('')
563
  const [geoProcessError, setGeoProcessError] = useState('')
564
  const [coordsMode, setCoordsMode] = useState('menu')
565
+ const [confirmarExclusaoCoords, setConfirmarExclusaoCoords] = useState(false)
566
 
567
  const [colunasNumericas, setColunasNumericas] = useState([])
568
  const [colunaY, setColunaY] = useState('')
 
884
  }
885
  }, [coordsInfo])
886
 
887
+ useEffect(() => {
888
+ if (!coordsInfo?.tem_coords || coordsMode !== 'menu') {
889
+ setConfirmarExclusaoCoords(false)
890
+ }
891
+ }, [coordsInfo, coordsMode])
892
+
893
  useEffect(() => {
894
  if (marcarTodasXRef.current) {
895
  marcarTodasXRef.current.indeterminate = algumaXMarcada && !todasXMarcadas
 
1457
  setManualMapError('')
1458
  setGeoProcessError('')
1459
  setCoordsMode(resp.coords?.tem_coords ? 'menu' : 'geocodificar')
1460
+ setConfirmarExclusaoCoords(false)
1461
+ })
1462
+ }
1463
+
1464
+ async function onExcluirCoordenadasParaGeocodificar() {
1465
+ if (!sessionId) return
1466
+ await withBusy(async () => {
1467
+ const resp = await api.geocodificarExcluirCoords(sessionId)
1468
+ setStatus(resp.status || '')
1469
+ setGeoStatusHtml(resp.status_html || '')
1470
+ setGeoFalhasHtml(resp.falhas_html || '')
1471
+ setGeoCorrecoes(parseCorrecoes(resp.falhas_para_correcao))
1472
+ setMapaHtml(resp.mapa_html || '')
1473
+ setDados(resp.dados || null)
1474
+ setCoordsInfo(resp.coords || null)
1475
+ setManualLat(resp.coords?.colunas_disponiveis?.[0] || '')
1476
+ setManualLon(resp.coords?.colunas_disponiveis?.[1] || '')
1477
+ setGeoCdlog(escolherColunaCdlogPadrao(resp.coords || null))
1478
+ setGeoNum(resp.coords?.num_auto || '')
1479
+ setGeoAuto200(true)
1480
+ setManualMapError('')
1481
+ setGeoProcessError('')
1482
+ setCoordsMode('menu')
1483
+ setConfirmarExclusaoCoords(false)
1484
  })
1485
  }
1486
 
 
2280
  </>
2281
  ) : (
2282
  <div className="subpanel coords-section-group">
2283
+ {coordsMode === 'skipped' ? (
2284
+ <>
2285
+ <div className="section1-empty-hint">Você optou por prosseguir sem mapear coordenadas nesta etapa.</div>
2286
+ <div className="row coords-restart-row">
2287
+ <button
2288
+ type="button"
2289
+ onClick={() => {
2290
+ setManualMapError('')
2291
+ setGeoProcessError('')
2292
+ setCoordsMode('menu')
2293
+ }}
2294
+ disabled={loading}
2295
+ >
2296
+ Configurar coordenadas
2297
+ </button>
2298
+ </div>
2299
+ </>
2300
+ ) : coordsInfo?.tem_coords ? (
2301
+ <>
2302
+ <div className="coords-ready-hint">Todos os dados já possuem suas coordenadas mapeadas.</div>
2303
+ <div className="row coords-restart-row">
2304
+ <button type="button" onClick={() => setConfirmarExclusaoCoords(true)} disabled={loading}>
2305
+ Excluir coordenadas e refazer geocodificação
2306
+ </button>
2307
+ </div>
2308
+ {confirmarExclusaoCoords ? (
2309
+ <div className="coords-confirm-delete">
2310
+ <div className="coords-confirm-delete-text">
2311
+ Confirma excluir as coordenadas atuais para iniciar uma nova geocodificação?
2312
+ </div>
2313
+ <div className="row compact coords-confirm-delete-actions">
2314
+ <button type="button" className="btn-confirm-delete" onClick={onExcluirCoordenadasParaGeocodificar} disabled={loading}>
2315
+ Confirmar exclusão
2316
+ </button>
2317
+ <button type="button" onClick={() => setConfirmarExclusaoCoords(false)} disabled={loading}>
2318
+ Cancelar
2319
+ </button>
2320
+ </div>
2321
+ </div>
2322
+ ) : null}
2323
+ </>
2324
+ ) : (
2325
+ <div className="section1-empty-hint">Etapa de coordenadas concluída.</div>
2326
+ )}
2327
  </div>
2328
  )}
2329
  </div>
frontend/src/styles.css CHANGED
@@ -1412,6 +1412,32 @@ button.btn-upload-select {
1412
  font-size: 0.86rem;
1413
  }
1414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1415
  .coords-choice-row {
1416
  display: flex;
1417
  flex-wrap: wrap;
@@ -2292,6 +2318,14 @@ button.btn-upload-select {
2292
  --btn-shadow-strong: rgba(255, 140, 0, 0.28);
2293
  }
2294
 
 
 
 
 
 
 
 
 
2295
  .outlier-actions-row button.btn-filtro-add {
2296
  --btn-bg-start: #2f80cf;
2297
  --btn-bg-end: #2368af;
 
1412
  font-size: 0.86rem;
1413
  }
1414
 
1415
+ .coords-ready-hint {
1416
+ color: #1f5e3a;
1417
+ font-size: 0.88rem;
1418
+ font-weight: 600;
1419
+ }
1420
+
1421
+ .coords-confirm-delete {
1422
+ margin-top: 10px;
1423
+ border: 1px solid #f0cf9f;
1424
+ background: #fffaf2;
1425
+ border-radius: 10px;
1426
+ padding: 10px 12px;
1427
+ display: grid;
1428
+ gap: 8px;
1429
+ }
1430
+
1431
+ .coords-confirm-delete-text {
1432
+ color: #7a4d00;
1433
+ font-size: 0.84rem;
1434
+ font-weight: 600;
1435
+ }
1436
+
1437
+ .coords-confirm-delete-actions {
1438
+ margin: 0;
1439
+ }
1440
+
1441
  .coords-choice-row {
1442
  display: flex;
1443
  flex-wrap: wrap;
 
2318
  --btn-shadow-strong: rgba(255, 140, 0, 0.28);
2319
  }
2320
 
2321
+ .row button.btn-confirm-delete {
2322
+ --btn-bg-start: #d92d20;
2323
+ --btn-bg-end: #b42318;
2324
+ --btn-border: #912018;
2325
+ --btn-shadow-soft: rgba(217, 45, 32, 0.2);
2326
+ --btn-shadow-strong: rgba(180, 35, 24, 0.28);
2327
+ }
2328
+
2329
  .outlier-actions-row button.btn-filtro-add {
2330
  --btn-bg-start: #2f80cf;
2331
  --btn-bg-end: #2368af;