This commit is contained in:
Luiz Silva 2026-06-06 12:12:24 -03:00
parent 9b2651d5c7
commit 05f5f950cb
31 changed files with 4997 additions and 4176 deletions

View file

@ -0,0 +1,62 @@
import type { zCoordenadas } from "p-comuns"
import type z from "zod"
export type TipoCoordenadas = z.infer<typeof zCoordenadas>
/** Centro padrão do Brasil (Brasília) */
export const COORDENADAS_PADRAO: TipoCoordenadas = {
formato: "decimal",
datum: "EPSG:4326",
latitude: -15.7801,
longitude: -47.9292,
}
/** Zoom padrão do mapa */
export const ZOOM_PADRAO = 4
/** Altura padrão do mapa em pixels */
export const ALTURA_MAPA_PADRAO = 300
/** Limites válidos para latitude (-90 a 90) e longitude (-180 a 180) */
export function coordenadaValida(lat: number, lng: number): boolean {
return lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180
}
/** Formata número de coordenada para exibição com vírgula (padrão BR) */
export function formatarCoordenada(valor: number): string {
return valor.toFixed(6).replace(".", ",")
}
/** Converte texto digitado (aceita vírgula ou ponto) em número. Retorna null se inválido. */
export function parseCoordenada(v: string | number): number | null {
if (typeof v === "number") return Number.isNaN(v) ? null : v
const normalizado = v.replace(",", ".")
const n = Number.parseFloat(normalizado)
return Number.isNaN(n) ? null : n
}
/** Tenta geolocalização do navegador; se falhar, usa GeoIP como fallback */
export async function obterLocalizacao(): Promise<{ latitude: number; longitude: number }> {
try {
return await obterViaBrowser()
} catch {
return await obterViaGeoIp()
}
}
function obterViaBrowser(): Promise<{ latitude: number; longitude: number }> {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) return reject(new Error("Geolocation indisponível"))
navigator.geolocation.getCurrentPosition(
(pos) => resolve({ latitude: pos.coords.latitude, longitude: pos.coords.longitude }),
(err) => reject(err),
{ enableHighAccuracy: true, timeout: 10000 },
)
})
}
async function obterViaGeoIp(): Promise<{ latitude: number; longitude: number }> {
const resp = await fetch("http://ip-api.com/json/?fields=lat,lon")
const dados: { lat: number; lon: number } = await resp.json()
return { latitude: dados.lat, longitude: dados.lon }
}