Spaces:
Running
Running
Guilherme Silberfarb Costa commited on
Commit ·
e56a352
1
Parent(s): 9c95fcc
Improve avaliando location lookup by CDLOG
Browse files
backend/app/services/pesquisa_service.py
CHANGED
|
@@ -172,6 +172,40 @@ CRITERIO_ESPACIAL_MEDIA_DISTANCIA = "media_distancia"
|
|
| 172 |
CRITERIO_ESPACIAL_MAIOR_DISTANCIA = "maior_distancia"
|
| 173 |
CRITERIO_ESPACIAL_PADRAO = CRITERIO_ESPACIAL_MAIOR_DISTANCIA
|
| 174 |
VERSAO_MODELO_RE = re.compile(r"^(?P<base>.*?)(?P<sufixo>[A-Za-z])$")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
|
| 176 |
|
| 177 |
@dataclass(frozen=True)
|
|
@@ -1158,10 +1192,12 @@ def _marker_payloads_avaliandos(avaliandos_geo: list[dict[str, Any]]) -> list[di
|
|
| 1158 |
tooltip = f"{tooltip} • {endereco}{f', {numero_usado}' if numero_usado else ''}"
|
| 1159 |
marker_html = (
|
| 1160 |
"<div style='display:flex;align-items:center;justify-content:center;"
|
| 1161 |
-
"width:
|
| 1162 |
-
"
|
| 1163 |
-
"
|
| 1164 |
-
|
|
|
|
|
|
|
| 1165 |
"</div>"
|
| 1166 |
)
|
| 1167 |
payloads.append(
|
|
@@ -1170,8 +1206,8 @@ def _marker_payloads_avaliandos(avaliandos_geo: list[dict[str, Any]]) -> list[di
|
|
| 1170 |
"lon": float(lon_item),
|
| 1171 |
"tooltip_html": escape(tooltip),
|
| 1172 |
"marker_html": marker_html,
|
| 1173 |
-
"icon_size": [
|
| 1174 |
-
"icon_anchor": [
|
| 1175 |
"class_name": "mesa-avaliando-marker",
|
| 1176 |
}
|
| 1177 |
)
|
|
@@ -2865,7 +2901,7 @@ def _carregar_catalogo_vias() -> list[dict[str, Any]]:
|
|
| 2865 |
try:
|
| 2866 |
registros = load_attribute_records(
|
| 2867 |
resolve_core_path("dados", "EixosLogradouros.shp"),
|
| 2868 |
-
property_fields=("CDLOG", "NMIDELOG", "NMIDEPRE", "NMIDEABR"),
|
| 2869 |
)
|
| 2870 |
append_runtime_log(f"[mesa] pesquisa: catalogo leve de logradouros carregado com {len(registros)} registros")
|
| 2871 |
except Exception as exc:
|
|
@@ -2882,8 +2918,8 @@ def _carregar_catalogo_vias() -> list[dict[str, Any]]:
|
|
| 2882 |
nome = str(row.get("NMIDELOG") or "").strip()
|
| 2883 |
prefixo = str(row.get("NMIDEPRE") or "").strip()
|
| 2884 |
abreviado = str(row.get("NMIDEABR") or "").strip()
|
| 2885 |
-
|
| 2886 |
-
aliases =
|
| 2887 |
catalogo_local.append(
|
| 2888 |
{
|
| 2889 |
"cdlog": cdlog,
|
|
@@ -2909,6 +2945,7 @@ def _carregar_catalogo_vias() -> list[dict[str, Any]]:
|
|
| 2909 |
nome_col = cols.get("NMIDELOG")
|
| 2910 |
prefixo_col = cols.get("NMIDEPRE")
|
| 2911 |
abreviado_col = cols.get("NMIDEABR")
|
|
|
|
| 2912 |
if cdlog_col is None or nome_col is None:
|
| 2913 |
append_runtime_log("[mesa] pesquisa: colunas obrigatorias dos eixos nao foram encontradas")
|
| 2914 |
raise HTTPException(status_code=500, detail="Base de eixos sem colunas necessarias para localizar o avaliando")
|
|
@@ -2923,8 +2960,8 @@ def _carregar_catalogo_vias() -> list[dict[str, Any]]:
|
|
| 2923 |
nome = str(row.get(nome_col) or "").strip()
|
| 2924 |
prefixo = str(row.get(prefixo_col) or "").strip() if prefixo_col else ""
|
| 2925 |
abreviado = str(row.get(abreviado_col) or "").strip() if abreviado_col else ""
|
| 2926 |
-
|
| 2927 |
-
aliases =
|
| 2928 |
catalogo.append(
|
| 2929 |
{
|
| 2930 |
"cdlog": cdlog,
|
|
@@ -2959,6 +2996,35 @@ def _score_logradouro(consulta: str, item: dict[str, Any]) -> int:
|
|
| 2959 |
return melhor
|
| 2960 |
|
| 2961 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2962 |
def _to_int_or_none(value: Any) -> int | None:
|
| 2963 |
if _is_empty(value):
|
| 2964 |
return None
|
|
|
|
| 172 |
CRITERIO_ESPACIAL_MAIOR_DISTANCIA = "maior_distancia"
|
| 173 |
CRITERIO_ESPACIAL_PADRAO = CRITERIO_ESPACIAL_MAIOR_DISTANCIA
|
| 174 |
VERSAO_MODELO_RE = re.compile(r"^(?P<base>.*?)(?P<sufixo>[A-Za-z])$")
|
| 175 |
+
TIPO_LOGRADOURO_ABREV = {
|
| 176 |
+
"AC": "AC",
|
| 177 |
+
"AL": "AL",
|
| 178 |
+
"AV": "AV",
|
| 179 |
+
"BCO": "BCO",
|
| 180 |
+
"ESC": "ESC",
|
| 181 |
+
"EST": "EST",
|
| 182 |
+
"LGO": "LGO",
|
| 183 |
+
"PASS": "PASS",
|
| 184 |
+
"PCA": "PCA",
|
| 185 |
+
"PC": "PCA",
|
| 186 |
+
"R": "R",
|
| 187 |
+
"ROD": "ROD",
|
| 188 |
+
"TRAV": "TRAV",
|
| 189 |
+
"TV": "TV",
|
| 190 |
+
"VL": "VL",
|
| 191 |
+
}
|
| 192 |
+
TIPO_LOGRADOURO_EXPANDIDO = {
|
| 193 |
+
"AC": "ACESSO",
|
| 194 |
+
"AL": "ALAMEDA",
|
| 195 |
+
"AV": "AVENIDA",
|
| 196 |
+
"BCO": "BECO",
|
| 197 |
+
"ESC": "ESCADARIA",
|
| 198 |
+
"EST": "ESTRADA",
|
| 199 |
+
"LGO": "LARGO",
|
| 200 |
+
"PASS": "PASSAGEM",
|
| 201 |
+
"PCA": "PRACA",
|
| 202 |
+
"PC": "PRACA",
|
| 203 |
+
"R": "RUA",
|
| 204 |
+
"ROD": "RODOVIA",
|
| 205 |
+
"TRAV": "TRAVESSA",
|
| 206 |
+
"TV": "TRAVESSA",
|
| 207 |
+
"VL": "VILA",
|
| 208 |
+
}
|
| 209 |
|
| 210 |
|
| 211 |
@dataclass(frozen=True)
|
|
|
|
| 1192 |
tooltip = f"{tooltip} • {endereco}{f', {numero_usado}' if numero_usado else ''}"
|
| 1193 |
marker_html = (
|
| 1194 |
"<div style='display:flex;align-items:center;justify-content:center;"
|
| 1195 |
+
"width:30px;height:30px;filter:drop-shadow(0 2px 6px rgba(0,0,0,0.22));'>"
|
| 1196 |
+
"<svg viewBox='0 0 24 24' width='28' height='28' aria-hidden='true'>"
|
| 1197 |
+
"<path d='M12 3.2L3.9 10v10.1h5.4v-5.3h5.4v5.3h5.4V10L12 3.2Z' "
|
| 1198 |
+
"fill='#c62828' stroke='rgba(255,255,255,0.96)' stroke-width='1.5' stroke-linejoin='round'/>"
|
| 1199 |
+
"<rect x='10.1' y='15.2' width='3.8' height='4.9' rx='0.5' fill='rgba(255,255,255,0.96)'/>"
|
| 1200 |
+
"</svg>"
|
| 1201 |
"</div>"
|
| 1202 |
)
|
| 1203 |
payloads.append(
|
|
|
|
| 1206 |
"lon": float(lon_item),
|
| 1207 |
"tooltip_html": escape(tooltip),
|
| 1208 |
"marker_html": marker_html,
|
| 1209 |
+
"icon_size": [30, 30],
|
| 1210 |
+
"icon_anchor": [15, 15],
|
| 1211 |
"class_name": "mesa-avaliando-marker",
|
| 1212 |
}
|
| 1213 |
)
|
|
|
|
| 2901 |
try:
|
| 2902 |
registros = load_attribute_records(
|
| 2903 |
resolve_core_path("dados", "EixosLogradouros.shp"),
|
| 2904 |
+
property_fields=("CDLOG", "NMIDELOG", "NMIDEPRE", "NMIDEABR", "CDIDECAT"),
|
| 2905 |
)
|
| 2906 |
append_runtime_log(f"[mesa] pesquisa: catalogo leve de logradouros carregado com {len(registros)} registros")
|
| 2907 |
except Exception as exc:
|
|
|
|
| 2918 |
nome = str(row.get("NMIDELOG") or "").strip()
|
| 2919 |
prefixo = str(row.get("NMIDEPRE") or "").strip()
|
| 2920 |
abreviado = str(row.get("NMIDEABR") or "").strip()
|
| 2921 |
+
categoria = str(row.get("CDIDECAT") or "").strip()
|
| 2922 |
+
logradouro, aliases = _montar_logradouro_catalogo(nome, prefixo, abreviado, categoria)
|
| 2923 |
catalogo_local.append(
|
| 2924 |
{
|
| 2925 |
"cdlog": cdlog,
|
|
|
|
| 2945 |
nome_col = cols.get("NMIDELOG")
|
| 2946 |
prefixo_col = cols.get("NMIDEPRE")
|
| 2947 |
abreviado_col = cols.get("NMIDEABR")
|
| 2948 |
+
categoria_col = cols.get("CDIDECAT")
|
| 2949 |
if cdlog_col is None or nome_col is None:
|
| 2950 |
append_runtime_log("[mesa] pesquisa: colunas obrigatorias dos eixos nao foram encontradas")
|
| 2951 |
raise HTTPException(status_code=500, detail="Base de eixos sem colunas necessarias para localizar o avaliando")
|
|
|
|
| 2960 |
nome = str(row.get(nome_col) or "").strip()
|
| 2961 |
prefixo = str(row.get(prefixo_col) or "").strip() if prefixo_col else ""
|
| 2962 |
abreviado = str(row.get(abreviado_col) or "").strip() if abreviado_col else ""
|
| 2963 |
+
categoria = str(row.get(categoria_col) or "").strip() if categoria_col else ""
|
| 2964 |
+
logradouro, aliases = _montar_logradouro_catalogo(nome, prefixo, abreviado, categoria)
|
| 2965 |
catalogo.append(
|
| 2966 |
{
|
| 2967 |
"cdlog": cdlog,
|
|
|
|
| 2996 |
return melhor
|
| 2997 |
|
| 2998 |
|
| 2999 |
+
def _montar_logradouro_catalogo(
|
| 3000 |
+
nome: str,
|
| 3001 |
+
prefixo: str,
|
| 3002 |
+
abreviado: str,
|
| 3003 |
+
categoria: str,
|
| 3004 |
+
) -> tuple[str, list[str]]:
|
| 3005 |
+
nome_limpo = str(nome or "").strip()
|
| 3006 |
+
prefixo_limpo = str(prefixo or "").strip()
|
| 3007 |
+
abreviado_limpo = re.sub(r"\s+", " ", str(abreviado or "").strip())
|
| 3008 |
+
categoria_limpa = str(categoria or "").strip().upper()
|
| 3009 |
+
|
| 3010 |
+
tipo_abrev = TIPO_LOGRADOURO_ABREV.get(categoria_limpa, categoria_limpa)
|
| 3011 |
+
tipo_expandido = TIPO_LOGRADOURO_EXPANDIDO.get(categoria_limpa, categoria_limpa)
|
| 3012 |
+
|
| 3013 |
+
partes_base = [item for item in [tipo_abrev, prefixo_limpo, nome_limpo] if item]
|
| 3014 |
+
partes_extenso = [item for item in [tipo_expandido, prefixo_limpo, nome_limpo] if item]
|
| 3015 |
+
logradouro = " ".join(partes_base).strip() or abreviado_limpo or nome_limpo
|
| 3016 |
+
|
| 3017 |
+
aliases = _dedupe_strings(
|
| 3018 |
+
[
|
| 3019 |
+
logradouro,
|
| 3020 |
+
" ".join(partes_extenso).strip(),
|
| 3021 |
+
nome_limpo,
|
| 3022 |
+
abreviado_limpo,
|
| 3023 |
+
]
|
| 3024 |
+
)
|
| 3025 |
+
return logradouro, aliases
|
| 3026 |
+
|
| 3027 |
+
|
| 3028 |
def _to_int_or_none(value: Any) -> int | None:
|
| 3029 |
if _is_empty(value):
|
| 3030 |
return None
|
frontend/src/components/AvaliacaoTab.jsx
CHANGED
|
@@ -934,8 +934,15 @@ export default function AvaliacaoTab({ sessionId, quickLoadRequest = null, onRou
|
|
| 934 |
return
|
| 935 |
}
|
| 936 |
} else {
|
| 937 |
-
|
| 938 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 939 |
return
|
| 940 |
}
|
| 941 |
const numero = Number(avaliandoLocalizacaoInputs.numero)
|
|
|
|
| 934 |
return
|
| 935 |
}
|
| 936 |
} else {
|
| 937 |
+
const logradouro = String(avaliandoLocalizacaoInputs.logradouro || '').trim()
|
| 938 |
+
const cdlogTexto = String(avaliandoLocalizacaoInputs.cdlog || '').trim()
|
| 939 |
+
const cdlog = cdlogTexto ? Number(cdlogTexto) : null
|
| 940 |
+
if (!logradouro && !(Number.isFinite(cdlog) && cdlog > 0)) {
|
| 941 |
+
setAvaliandoLocalizacaoError('Informe o logradouro ou um CDLOG válido para localizar o avaliando.')
|
| 942 |
+
return
|
| 943 |
+
}
|
| 944 |
+
if (cdlogTexto && !(Number.isFinite(cdlog) && cdlog > 0)) {
|
| 945 |
+
setAvaliandoLocalizacaoError('Informe um CDLOG válido para localizar o avaliando.')
|
| 946 |
return
|
| 947 |
}
|
| 948 |
const numero = Number(avaliandoLocalizacaoInputs.numero)
|
frontend/src/components/PesquisaTab.jsx
CHANGED
|
@@ -1720,8 +1720,15 @@ export default function PesquisaTab({
|
|
| 1720 |
return
|
| 1721 |
}
|
| 1722 |
} else {
|
| 1723 |
-
|
| 1724 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1725 |
return
|
| 1726 |
}
|
| 1727 |
const numero = Number(localizacaoInputs.numero)
|
|
|
|
| 1720 |
return
|
| 1721 |
}
|
| 1722 |
} else {
|
| 1723 |
+
const logradouro = String(localizacaoInputs.logradouro || '').trim()
|
| 1724 |
+
const cdlogTexto = String(localizacaoInputs.cdlog || '').trim()
|
| 1725 |
+
const cdlog = cdlogTexto ? Number(cdlogTexto) : null
|
| 1726 |
+
if (!logradouro && !(Number.isFinite(cdlog) && cdlog > 0)) {
|
| 1727 |
+
setLocalizacaoError('Informe o logradouro ou um CDLOG válido para localizar o avaliando.')
|
| 1728 |
+
return
|
| 1729 |
+
}
|
| 1730 |
+
if (cdlogTexto && !(Number.isFinite(cdlog) && cdlog > 0)) {
|
| 1731 |
+
setLocalizacaoError('Informe um CDLOG válido para localizar o avaliando.')
|
| 1732 |
return
|
| 1733 |
}
|
| 1734 |
const numero = Number(localizacaoInputs.numero)
|