Mapa de atendimento para desentupimento de coluna predial em SP com WordPress

Aprenda a estruturar mapa de atendimento para desentupimento de coluna predial em SP usando WordPress, geolocalização e automação de chamados.

Como transformar a gestão de chamados de desentupimento em um sistema inteligente que despacha a equipe certa para o bairro certo em minutos?

A resposta está na integração entre geolocalização, automação e WordPress. Um mapa de atendimento bem estruturado não apenas mostra onde sua desentupidora atua — ele decide quem vai atender, calcula a rota e notifica o técnico antes que o cliente termine de preencher o formulário.

Neste artigo, você verá como construir essa arquitetura no WordPress usando custom post types, APIs de mapas e webhooks para criar um despacho automático por proximidade real.

Estrutura de dados: custom post types e taxonomias geográficas

O ponto de partida é modelar a área de cobertura como conteúdo gerenciável. Crie um Custom Post Type area_atendimento com suporte a editor de blocos, thumbnail e revisões. Registre taxonomias hierárquicas: regiao_sp (ex: Zona Norte, Zona Sul, Centro, Leste, Oeste), subprefeitura e bairro. Cada termo de bairro recebe metadados: polígono GeoJSON, CEP inicial/final, tempo médio de deslocamento (minutos) e ID da equipe plantonista.

No functions.php ou plugin próprio, use register_post_type com 'show_in_rest' => true para compatibilidade com Gutenberg. Adicione campos personalizados via ACF Pro ou register_meta para armazenar o GeoJSON do polígono e o team_id responsável. Exemplo de meta fields:

register_meta('post', 'area_geojson', [
    'type' => 'object',
    'description' => 'Polígono GeoJSON da área de cobertura',
    'single' => true,
    'show_in_rest' => true,
    'auth_callback' => function() { return current_user_can('edit_posts'); }
]);
register_meta('post', 'area_tempo_deslocamento', [
    'type' => 'integer',
    'description' => 'Tempo médio em minutos',
    'single' => true,
    'show_in_rest' => true
]);
register_meta('post', 'area_equipe_id', [
    'type' => 'integer',
    'description' => 'ID da equipe plantonista',
    'single' => true,
    'show_in_rest' => true
]);

Essa estrutura permite que o gestor cadastre, edite e versionamento áreas diretamente no admin, sem tocar em código.

Validação de CEP e geocodificação reversa no front-end

Quando o cliente acessa o formulário de emergência, o primeiro passo é confirmar que o endereço está dentro da cobertura. Use a API ViaCEP (gratuita, sem chave) para autocompletar endereço a partir do CEP. Em seguida, envie as coordenadas (lat/lng) para um endpoint REST customizado que verifica interseção com os polígonos cadastrados.

Crie o endpoint em functions.php:

add_action('rest_api_init', function() {
    register_rest_route('desentupidora/v1', '/verificar-cobertura/', [
        'methods' => 'POST',
        'callback' => 'verificar_cobertura_callback',
        'permission_callback' => '__return_true',
        'args' => [
            'lat' => ['required' => true, 'type' => 'number'],
            'lng' => ['required' => true, 'type' => 'number'],
        ],
    ]);
});

function verificar_cobertura_callback(WP_REST_Request $request) {
    $lat = $request->get_param('lat');
    $lng = $request->get_param('lng');
    $point = "POINT($lng $lat)";
    
    $areas = get_posts([
        'post_type' => 'area_atendimento',
        'posts_per_page' => -1,
        'meta_key' => 'area_geojson',
        'meta_compare' => 'EXISTS',
    ]);
    
    foreach ($areas as $area) {
        $geojson = get_post_meta($area->ID, 'area_geojson', true);
        if ($geojson && isset($geojson->coordinates)) {
            // Simplificação: use biblioteca PHP como php-geojson ou PostGIS se disponível
            // Aqui, verificação básica via point-in-polygon
            if (point_in_polygon($lat, $lng, $geojson->coordinates[0])) {
                return new WP_REST_Response([
                    'coberto' => true,
                    'area_id' => $area->ID,
                    'area_nome' => $area->post_title,
                    'tempo_estimado' => get_post_meta($area->ID, 'area_tempo_deslocamento', true),
                    'equipe_id' => get_post_meta($area->ID, 'area_equipe_id', true),
                ], 200);
            }
        }
    }
    
    return new WP_REST_Response([
        'coberto' => false,
        'mensagem' => 'Endereço fora da área de cobertura padrão. Entre em contato via WhatsApp para verificação especial.'
    ], 200);
}

No front-end, chame esse endpoint via fetch ao perder foco no campo CEP. Se coberto: true, libere o calendário de agendamento; se false, exiba a mensagem e o botão de WhatsApp.

Despacho automático: webhook do formulário para equipe de campo

O formulário de emergência (Gravity Forms, Contact Form 7 ou formulário customizado via REST) deve disparar um webhook assim que validado. O payload inclui: dados do cliente, endereço completo, lat/lng, area_id e equipe_id retornados pela verificação de cobertura.

Configure o webhook no functions.php usando gform_after_submission (Gravity Forms) ou wpcf7_mail_sent (CF7). Exemplo com Gravity Forms:

add_action('gform_after_submission_1', function($entry, $form) {
    $payload = [
        'chamado_id' => $entry['id'],
        'cliente' => [
            'nome' => rgar($entry, '1.3'),
            'telefone' => rgar($entry, '2'),
            'email' => rgar($entry, '3'),
        ],
        'endereco' => [
            'cep' => rgar($entry, '4'),
            'logradouro' => rgar($entry, '5'),
            'numero' => rgar($entry, '6'),
            'bairro' => rgar($entry, '7'),
            'lat' => rgar($entry, 'lat'),
            'lng' => rgar($entry, 'lng'),
        ],
        'area_id' => rgar($entry, 'area_id'),
        'equipe_id' => rgar($entry, 'equipe_id'),
        'timestamp' => current_time('mysql'),
    ];
    
    // Envia para sistema de gestão de campo ou webhook interno
    wp_remote_post('https://seu-sistema-campo.com/api/webhook/novo-chamado', [
        'body' => wp_json_encode($payload),
        'headers' => ['Content-Type' => 'application/json'],
        'timeout' => 10,
    ]);
    
    // Notifica técnico via WhatsApp API (ex: Zenvia, Twilio, Evolution API)
    $tecnico = get_user_by('id', $payload['equipe_id']);
    if ($tecnico && $tecnico->user_meta['whatsapp']) {
        $msg = "Novo chamado: {$payload['cliente']['nome']} - {$payload['endereco']['logradouro']}, {$payload['endereco']['numero']} - {$payload['endereco']['bairro']}. Tempo estimado: {$payload['tempo_estimado']} min. Rota: https://maps.google.com/?daddr={$payload['endereco']['lat']},{$payload['endereco']['lng']}";
        wp_remote_post('https://api.whatsapp.com/send', [
            'body' => ['phone' => $tecnico->user_meta['whatsapp'], 'message' => $msg],
        ]);
    }
}, 10, 2);

Esse fluxo elimina a central de atendimento manual: o chamado cai direto no celular do técnico mais próximo com rota pronta.

Painel administrativo com editor visual de áreas no mapa

Para manter a cobertura atualizada, crie uma página de opções ou submenu em Áreas de Atendimento com um mapa Leaflet editável. Use a biblioteca Leaflet.draw para permitir desenhar, editar e excluir polígonos. Ao salvar, o JavaScript envia o GeoJSON para admin-ajax.php ou endpoint REST que atualiza o post_meta do area_atendimento correspondente.

Exemplo de enqueue no admin:

add_action('admin_enqueue_scripts', function($hook) {
    if ($hook !== 'toplevel_page_areas-atendimento') return;
    wp_enqueue_script('leaflet', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js', [], '1.9.4', true);
    wp_enqueue_script('leaflet-draw', 'https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.js', ['leaflet'], '1.0.4', true);
    wp_enqueue_style('leaflet', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css');
    wp_enqueue_style('leaflet-draw', 'https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.css');
    wp_enqueue_script('areas-mapa-admin', get_template_directory_uri() . '/js/areas-mapa-admin.js', ['leaflet', 'leaflet-draw'], '1.0', true);
    wp_localize_script('areas-mapa-admin', 'areasMapaData', [
        'nonce' => wp_create_nonce('areas_mapa_nonce'),
        'ajaxurl' => admin_url('admin-ajax.php'),
        'areas' => get_areas_geojson(), // função que retorna array de áreas com GeoJSON
    ]);
});

No areas-mapa-admin.js, inicialize o mapa, carregue as áreas existentes como layers editáveis, e no evento draw:created / draw:edited / draw:deleted, envie o GeoJSON atualizado via fetch para wp_ajax_salvar_area_geojson. Registre o handler AJAX para validar nonce, sanitizar e salvar no post_meta.

Log de auditoria e versionamento de alterações

Toda alteração nas áreas de cobertura deve ser rastreável. Crie uma tabela customizada wp_areas_auditoria ou use Custom Post Type auditoria_area (não público) com campos: area_id, usuario_id, acao (criado, editado, excluido), geojson_anterior, geojson_novo, timestamp. No handler AJAX de salvamento, antes de atualizar, recupere o GeoJSON atual, compare e registre a entrada de auditoria.

function registrar_auditoria_area($area_id, $acao, $geojson_anterior, $geojson_novo) {
    $auditoria = [
        'post_type' => 'auditoria_area',
        'post_title' => "Auditoria: {$acao} - Area ID {$area_id}",
        'post_status' => 'publish',
        'meta_input' => [
            'auditoria_area_id' => $area_id,
            'auditoria_usuario_id' => get_current_user_id(),
            'auditoria_acao' => $acao,
            'auditoria_geojson_anterior' => wp_json_encode($geojson_anterior),
            'auditoria_geojson_novo' => wp_json_encode($geojson_novo),
            'auditoria_timestamp' => current_time('mysql'),
        ],
    ];
    wp_insert_post($auditoria);
}

Isso garante rastreabilidade total e permite rollback se uma edição quebrar a cobertura.

Integração com aplicativo móvel da equipe de campo

O técnico precisa receber o chamado, visualizar a rota e atualizar status (a caminho, no local, finalizado). Se sua desentupidora usa app próprio (React Native, Flutter) ou ferramenta como Zoho Field Service, FieldControl, ou até Google Forms + Planilhas, a integração ocorre via webhook bidirecional.

No WordPress, crie endpoint para o app consultar chamados pendentes da equipe:

register_rest_route('desentupidora/v1', '/chamados-equipe/(?P<equipe_id>\d+)', [
    'methods' => 'GET',
    'callback' => 'get_chamados_equipe',
    'permission_callback' => function($request) {
        // Valide token JWT ou API Key no header
        return validar_api_key($request->get_header('Authorization'));
    },
]);

function get_chamados_equipe(WP_REST_Request $request) {
    $equipe_id = $request->get_param('equipe_id');
    $chamados = get_posts([
        'post_type' => 'chamado_emergencia',
        'meta_query' => [
            ['key' => 'chamado_equipe_id', 'value' => $equipe_id],
            ['key' => 'chamado_status', 'value' => ['pendente', 'a_caminho'], 'compare' => 'IN'],
        ],
        'orderby' => 'meta_value',
        'meta_key' => 'chamado_timestamp',
        'order' => 'ASC',
    ]);
    
    return rest_ensure_response(array_map(function($c) {
        return [
            'id' => $c->ID,
            'cliente' => get_post_meta($c->ID, 'chamado_cliente_nome', true),
            'endereco' => get_post_meta($c->ID, 'chamado_endereco_completo', true),
            'lat' => get_post_meta($c->ID, 'chamado_lat', true),
            'lng' => get_post_meta($c->ID, 'chamado_lng', true),
            'status' => get_post_meta($c->ID, 'chamado_status', true),
            'prioridade' => get_post_meta($c->ID, 'chamado_prioridade', true),
        ];
    }, $chamados));
}

O app consome esse endpoint a cada 30s (ou via push FCM/OneSignal) e exibe lista priorizada. Ao tocar em “A caminho”, o app envia PATCH para endpoint de atualização de status, que dispara notificação ao cliente: “Técnico João a caminho, previsão 15 min”.

Métricas e otimização contínua da cobertura

Com o sistema rodando, colete dados para expandir ou ajustar áreas: tempo real de deslocamento vs. estimado, chamados fora de cobertura (oportunidades), bairros com alta demanda e baixa cobertura. Crie dashboard no admin usando WP_Query + Chart.js ou integre com Metabase/Grafana lendo a tabela de chamados.

Exemplo de query para tempo médio real por bairro:

function get_tempo_medio_real_por_bairro() {
    global $wpdb;
    return $wpdb->get_results(
        "SELECT 
            pm_bairro.meta_value as bairro,
            AVG(TIMESTAMPDIFF(MINUTE, pm_chegada.meta_value, pm_chamado.meta_value)) as tempo_medio_real,
            COUNT(*) as total_chamados
        FROM {$wpdb->postmeta} pm_chamado
        JOIN {$wpdb->postmeta} pm_chegada ON pm_chamado.post_id = pm_chegada.post_id
        JOIN {$wpdb->postmeta} pm_bairro ON pm_chamado.post_id = pm_bairro.post_id
        WHERE pm_chamado.meta_key = 'chamado_timestamp'
        AND pm_chegada.meta_key = 'chamado_chegada_timestamp'
        AND pm_bairro.meta_key = 'chamado_bairro'
        AND pm_chamado.post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = 'chamado_emergencia' AND post_status = 'publish')
        GROUP BY pm_bairro.meta_value
        HAVING total_chamados >= 10
        ORDER BY tempo_medio_real DESC"
    );
}

// Use no dashboard admin para identificar bairros onde tempo real > estimado + 20%

Com esses dados, o gestor ajusta polígonos, redistribui equipes ou negocia expansão de frota.

Conclusão prática

Um mapa de atendimento no WordPress deixa de ser um desenho estático quando vira motor de despacho automático: valida CEP, escolhe equipe, envia rota e registra tudo para auditoria. Comece modelando áreas como custom posts com GeoJSON, integre verificação de cobertura no formulário, automatize o webhook para o técnico e dê ao gestor um editor visual no admin. O resultado é menos tempo no telefone, mais chamados atendidos no prazo e dados reais para crescer a cobertura com inteligência.

Para ver esse fluxo em operação real, confira o desentupimento de coluna predial em toda a cidade de São Paulo e como a geolocalização acelera o atendimento. Se precisa estruturar a área do cliente para histórico de manutenções, veja nosso guia sobre área do cliente para manutenção de coluna de esgoto em SP. Para formulários de orçamento acessíveis no centro, leia sobre acessibilidade WCAG em formulários de orçamento no centro de São Paulo.

Checklist prático

0 de 9 concluídos

Perguntas frequentes

Como integrar mapa de atendimento ao WordPress para desentupidora?

Utilize plugins de geolocalização como GeoDirectory ou WP Store Locator combinados com custom post types para áreas de cobertura. A API do Google Maps ou Mapbox permite renderizar polígonos de atendimento por bairros de São Paulo. Configure campos personalizados para tempo estimado de chegada e equipe responsável por região.

Qual a melhor forma de exibir área de cobertura por bairros em SP?

Crie taxonomias hierárquicas para regiões, subprefeituras e bairros. Use GeoJSON para desenhar polígonos no mapa front-end via Leaflet ou Mapbox GL JS. No painel admin, cadastre cada área com CEP inicial/final, tempo de deslocamento e plantonista responsável, facilitando o despacho automático.

Como automatizar o despacho de técnicos pelo mapa de atendimento?

Integre o formulário de emergência com webhook para sistema de gestão de campo (Field Service). Ao receber chamado, o sistema identifica o bairro via geocodificação reversa, consulta a equipe mais próxima no mapa e envia notificação push via WhatsApp API ou OneSignal. O técnico recebe rota otimizada no app mobile.

É possível restringir agendamento apenas às áreas cobertas pelo mapa?

Sim. No front-end, valide o CEP digitado contra a base de polígonos cadastrados antes de liberar o calendário. Use a API ViaCEP para preencher endereço e verifique interseção com GeoJSON das áreas. Se fora de cobertura, exiba mensagem personalizada com opção de contato via WhatsApp para negociação especial.

Como manter o mapa de atendimento atualizado com expansão de cobertura?

Crie interface administrativa com editor visual de polígonos (Leaflet.draw ou Mapbox Draw). Permita ao gestor adicionar/remover bairros, ajustar tempo de deslocamento e redefinir equipes. Registre alterações em log de auditoria e versionamento de GeoJSON. Publique alterações via webhook para apps móveis dos técnicos em tempo real.