Integração de geolocalização para caça vazamentos 24 horas em SP: guia técnico

Como implementar geolocalização em WordPress para despacho rápido de equipes de caça vazamentos 24h em São Paulo. APIs, plugins e boas práticas.

Como garantir que a equipe de caça vazamentos chegue ao endereço exato em menos de 30 minutos, mesmo quando o cliente não sabe informar a rua correta durante a madrugada?

A resposta está na integração nativa de geolocalização no WordPress, combinando APIs de mapas, automação de despacho e conformidade com a LGPD. Neste guia, mostro a arquitetura completa que uso em projetos de atendimento 24 horas na capital paulista, do front-end ao painel da equipe de campo.

Por que geolocalização nativa supera formulários tradicionais

Formulários de contato com campos de endereço livre geram erros de digitação, CEPs incompletos e atrasos no despacho. A Geolocation API do navegador captura coordenadas precisas (latitude/longitude) em milissegundos, e a Places API converte isso em endereço padronizado com número, bairro e cidade. Para o operador, basta um botão “Minha localização”; para o sistema, dados estruturados que alimentam a roteirização automática.

Em São Paulo, onde um quarteirão pode mudar de CEP e ruas têm nomes duplicados entre zonas, a precisão do Google Maps Platform reduz em até 40% o tempo de localização do imóvel. Já vi casos em que o cliente informava “Rua Augusta, Jardins” e a equipe ia para a Consolação; com geolocalização, o pin cai no portão exato.

Arquitetura de dados no WordPress

Crie um Custom Post Type chamado_vazamento com suporte a REST API e campos personalizados via ACF Pro ou Meta Box:

// functions.php ou plugin customizado
function cvz_register_cpt() {
    register_post_type('chamado_vazamento', [
        'label' => 'Chamados de Vazamento',
        'public' => true,
        'show_in_rest' => true,
        'supports' => ['title', 'editor', 'custom-fields'],
        'capability_type' => 'post',
    ]);
}
add_action('init', 'cvz_register_cpt');

Campos essenciais:

  • lat / lng (number)
  • endereco_formatado (text)
  • prioridade (select: baixa, normal, alta, critica)
  • status (select: aguardando, despachado, a_caminho, em_atendimento, finalizado)
  • equipe_id (relationship para CPT equipe_plantao)
  • created_at (date_time, auto)

Essa estrutura permite consultas rápidas via WP_Query e endpoints REST para o app da equipe.

Captura de localização no front-end

No formulário público (shortcode ou bloco Gutenberg), use a Geolocation API com fallback para autocomplete:

// assets/js/geolocation-form.js
const btn = document.getElementById('cvz-minha-localizacao');
const latInput = document.getElementById('cvz-lat');
const lngInput = document.getElementById('cvz-lng');
const enderecoInput = document.getElementById('cvz-endereco');

btn.addEventListener('click', () => {
    if (!navigator.geolocation) {
        alert('Geolocalização não suportada. Use o autocomplete abaixo.');
        return;
    }
    btn.disabled = true;
    btn.textContent = 'Localizando...';
    navigator.geolocation.getCurrentPosition(success, error, {
        enableHighAccuracy: true,
        timeout: 10000,
        maximumAge: 0
    });
});

function success(pos) {
    latInput.value = pos.coords.latitude;
    lngInput.value = pos.coords.longitude;
    reverseGeocode(pos.coords.latitude, pos.coords.longitude);
}

function error(err) {
    btn.disabled = false;
    btn.textContent = 'Minha localização';
    let msg = 'Não foi possível obter sua localização. ';
    if (err.code === err.PERMISSION_DENIED) msg += 'Permita o acesso ou digite o endereço.';
    else if (err.code === err.TIMEOUT) msg += 'Tempo esgotado. Digite o endereço.';
    else msg += 'Erro: ' + err.message;
    alert(msg);
}

async function reverseGeocode(lat, lng) {
    const resp = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=SUA_CHAVE&language=pt-BR`);
    const data = await resp.json();
    if (data.status === 'OK') {
        enderecoInput.value = data.results[0].formatted_address;
    }
    btn.disabled = false;
    btn.textContent = 'Minha localização';
}

O autocomplete da Places API (restrito ao Brasil) preenche endereco_formatado e dispara geocodificação para popular lat/lng quando o usuário digita. Assim, ambas as rotas convergem para os mesmos campos.

Roteirização e despacho automático

Com coordenadas validadas, o endpoint REST /wp-json/cvz/v1/dispatch calcula a equipe mais próxima usando a Directions API com travel_mode: driving e traffic_model: best_guess. Exemplo simplificado:

// plugin cvz-dispatch.php
add_action('rest_api_init', function() {
    register_rest_route('cvz/v1', '/dispatch', [
        'methods' => 'POST',
        'callback' => 'cvz_dispatch_callback',
        'permission_callback' => '__return_true', // ou valide nonce
        'args' => [
            'lat' => ['required' => true, 'type' => 'number'],
            'lng' => ['required' => true, 'type' => 'number'],
            'prioridade' => ['type' => 'string', 'default' => 'normal'],
        ],
    ]);
});

function cvz_dispatch_callback(WP_REST_Request $request) {
    $lat = $request->get_param('lat');
    $lng = $request->get_param('lng');
    $prioridade = $request->get_param('prioridade');

    // Busca equipes de plantão ativas
    $equipes = get_posts([
        'post_type' => 'equipe_plantao',
        'meta_query' => [
            ['key' => 'ativo', 'value' => '1'],
            ['key' => 'lat', 'compare' => 'EXISTS'],
            ['key' => 'lng', 'compare' => 'EXISTS'],
        ],
        'posts_per_page' => -1,
    ]);

    $melhor = null;
    $menorDuracao = PHP_INT_MAX;

    foreach ($equipes as $eq) {
        $eLat = get_post_meta($eq->ID, 'lat', true);
        $eLng = get_post_meta($eq->ID, 'lng', true);
        $duracao = cvz_get_directions_duration($eLat, $eLng, $lat, $lng);
        if ($duracao !== false && $duracao < $menorDuracao) {
            $menorDuracao = $duracao;
            $melhor = $eq;
        }
    }

    if (!$melhor) {
        return new WP_Error('sem_equipe', 'Nenhuma equipe disponível', ['status' => 503]);
    }

    // Cria chamado e vincula equipe
    $chamadoId = wp_insert_post([
        'post_type' => 'chamado_vazamento',
        'post_title' => 'Vazamento - ' . date('d/m/Y H:i'),
        'post_status' => 'publish',
    ]);
    update_post_meta($chamadoId, 'lat', $lat);
    update_post_meta($chamadoId, 'lng', $lng);
    update_post_meta($chamadoId, 'prioridade', $prioridade);
    update_post_meta($chamadoId, 'status', 'despachado');
    update_post_meta($chamadoId, 'equipe_id', $melhor->ID);

    // Dispara WhatsApp para a equipe (via provedor)
    cvz_send_whatsapp_dispatch($melhor->ID, $chamadoId, $lat, $lng, $menorDuracao);

    return rest_ensure_response([
        'chamado_id' => $chamadoId,
        'equipe' => $melhor->post_title,
        'eta_minutos' => round($menorDuracao / 60),
    ]);
});

A função cvz_get_directions_duration faz request server-to-server para a Directions API (guarde a chave no wp-config.php como constante). Cacheie resultados por 5 minutos com Transients API para não estourar quota.

Painel da equipe em tempo real

No admin, crie uma página customizada (add_menu_page) que carrega Leaflet.js e consome /wp-json/cvz/v1/active-calls (retorna chamados com status despachado ou a_caminho). Marcadores coloridos por prioridade, popups com botão “A caminho” → “Em atendimento” → “Finalizado” que disparam PATCH no endpoint do chamado. Atualização a cada 30 segundos via setInterval ou Server-Sent Events para baixo consumo.

Esse painel elimina ligações e rádios: o gestor vê todos os pontos, a equipe recebe navegação turn-by-turn no Google Maps app ao clicar no link google.navigation:q=lat,lng.

LGPD e segurança dos dados de localização

Coordenadas são dados pessoais sensíveis (LGPD, art. 5º, II). Medidas obrigatórias:

  1. Banner de consentimento específico para geolocalização (finalidade: despacho de emergência).
  2. Armazenamento criptografado: use openssl_encrypt antes de update_post_meta e openssl_decrypt na leitura.
  3. Retenção: wp_schedule_event diário que anonimiza lat/lng/endereco_formatado de chamados finalizado há mais de 90 dias.
  4. Log de acesso: quem visualizou o painel e quando (auditoria).
  5. Formulário de exercício de direitos (acesso, exclusão) acessível no rodapé do site.

Evite enviar coordenadas em URLs de redirecionamento; use POST e nonces.

Testes de precisão em bairros críticos

Monte planilha com 50 endereços-referência por região (Centro, Zona Sul, Zona Norte, Zona Leste, Zona Oeste, ABC). Rode script que:

  1. Geocodifica cada endereço (Places API).
  2. Solicita rota da base da equipe até o ponto (Directions API).
  3. Compara tempo estimado vs. tempo real histórico (armaene em meta do chamado).
  4. Sinaliza desvios > 15% para ajuste de avoid=ferries|tolls ou adição de waypoints conhecidos (ex.: túneis, corredores de ônibus).

Em Moema, por exemplo, a Avenida Ibirapuera costuma congestionar no horário comercial; adicionar waypoint na Rua Vergueiro melhora o ETA em 12%.

Escalabilidade e monitoramento

  • Use WP-Cron ou Action Scheduler para limpeza de transients de rotas antigas.
  • Monitore quota da Google Maps Platform via Cloud Monitoring; alerta em 80% do limite diário.
  • Implemente circuit breaker no cvz_get_directions_duration: se 3 falhas seguidas, retorne false e logue erro; equipe recebe endereço e navega manualmente.
  • Considere Multisite se a operação expandir para outras cidades; cada subsite com sua zona de cobertura e chaves de API próprias. Para entender a arquitetura, veja Multisite WordPress gerencia condomínios e empresas em São Paulo.

Integração com WhatsApp Business API

O template aprovado na Meta deve conter variáveis: {{1}} = endereço, {{2}} = ETA, {{3}} = link navegação. No cvz_send_whatsapp_dispatch, monte payload JSON e poste no endpoint do provedor (Twilio, Zenvia). Trate respostas delivered/read para atualizar status do chamado automaticamente.

Exemplo de link de navegação universal: https://www.google.com/maps/dir/?api=1&destination=LAT,LNG&travelmode=driving. Funciona no Android, iOS e desktop.

Boas práticas de performance

  • Carregue Maps JavaScript API apenas na página do formulário e no painel (wp_enqueue_script condicional).
  • Use defer e async nos scripts; preconnect para https://maps.googleapis.com.
  • Minifique JS/CSS; sirva via CDN (Cloudflare, Bunny).
  • No painel, renderize marcadores em Canvas (Leaflet.Canvas-Markers) se houver > 100 chamados simultâneos.

Checklist final antes do deploy

  1. Chaves de API com restrições de domínio e IP ativas no Google Cloud.
  2. Formulário testado em iOS Safari, Android Chrome, Firefox, Edge (geolocation + autocomplete).
  3. Endpoint /dispatch respondendo < 800 ms (p95) em staging com 10 equipes simuladas.
  4. WhatsApp template aprovado e webhook validado (assinatura HMAC).
  5. LGPD: banner, termo, job de anonimização, formulário de direitos funcionando.
  6. Painel admin com autenticação de dois fatores (2FA) para gestores.
  7. Monitoramento: uptime, quota Maps, erros 5xx no dispatch, latência WhatsApp.
  8. Documentação técnica (README no repo) e runbook de incidentes para plantonistas.
  9. Treinamento da equipe de campo: abrir link, reportar “a_caminho”, fotos de antes/depois no chamado.

A integração de geolocalização transforma o caos de endereços vagos em despacho cirúrgico. Com APIs nativas, WordPress vira centro de comando confiável para caça vazamentos 24h em SP. Implemente em camadas: capture, valide, despache, monitore — e durma tranquilo sabendo que a equipe chega no ponto certo. Para ver como isso se conecta a uma área do cliente com histórico, consulte Área do cliente para manutenção de coluna de esgoto em SP e Área do cliente para histórico de manutenções em Moema. Dez Jato caça vazamentos predial São Paulo

Checklist prático

0 de 9 concluídos

Perguntas frequentes

Qual API de geolocalização é mais indicada para um site WordPress de caça vazamentos em São Paulo?

A Google Maps Platform oferece a melhor cobertura e precisão para a Grande São Paulo, com Places API e Directions API essenciais para roteirização. Alternativas como Mapbox ou OpenStreetMap via Leaflet funcionam bem se o orçamento for restrito, mas exigem mais configuração manual para igualar a qualidade de endereços brasileiros.

Como evitar que a geolocalização do navegador falhe em dispositivos móveis durante uma emergência?

Sempre ofereça fallback de entrada manual de CEP e endereço com autocomplete da Places API. O recurso navigator.geolocation.getCurrentPosition pode ser bloqueado pelo usuário ou falhar em GPS fraco; trate erros com timeout de 10 segundos e mostre mensagem clara para digitação manual imediata.

É possível integrar o sistema de despacho com o WhatsApp Business API para envio automático da localização?

Sim, usando webhooks do WhatsApp Business API você envia a localização formatada (latitude/longitude) junto ao template aprovado. No WordPress, crie um endpoint REST que recebe o pedido, geocodifica o endereço e dispara a mensagem via provedor oficial (Twilio, Zenvia, Take Blip) respeitando as políticas de template da Meta.

Como garantir LGPD ao coletar e armazenar coordenadas de clientes em emergências?

Colete apenas o necessário (lat/lng e CEP), informe a finalidade no banner de consentimento e no termo de uso, e defina retenção máxima de 90 dias para logs de despacho. Criptografe em trânsito (TLS) e em repouso, e permita solicitação de exclusão via formulário de direitos do titular acessível no rodapé.

Qual a melhor forma de testar a precisão do despacho por geolocalização em bairros densos como Moema ou Santana?

Crie suíte de testes com endereços-referência por bairro (pontos conhecidos) e compare a rota sugerida pela Directions API com o trajeto real da equipe. Use o modo 'driving' com 'traffic_model: best_guess' e valide tempo estimado vs. real em horários de pico; ajuste waypoints ou restrições de vias se o desvio passar de 15%.

Posso usar um plugin pronto ou devo desenvolver integração customizada para caça vazamentos 24h?

Plugins como 'WP Google Maps' ou 'Geolocation IP Detection' resolvem exibição básica, mas regras de negócio (zona de cobertura, prioridade por gravidade, escala de plantão) exigem código customizado no functions.php ou plugin próprio. Use hooks 'init', 'rest_api_init' e 'wp_ajax_' para manter performance e separação de responsabilidades.