# LocationPicker

> Escolha de coordenada geográfica num mapa com GPS, devolvendo latitude e longitude ao chamador.

Source: https://crossfly.dev/pt/docs/ui/widgets/locationpicker — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# LocationPicker

`LocationPicker` escolhe uma **coordenada geográfica** num mapa, com rastreamento de GPS e pino arrastável. Segue o padrão dos pickers (ver [`Picker`](/docs/ui/widgets/picker)) e devolve um `LatLon`.

> 🔴 · **Pacote:** `dev.crossfly.ui.picker` · **Estende:** `Picker` · **Hardware:** GPS + mapa

## Quando usar
- Coletar uma localização (endereço de entrega, ponto de interesse) num mapa.

## Aparência
Barra superior com botões circulares (tipo de mapa Normal/Satélite, voltar, confirmar), o mapa (FILL) ocupando o corpo, um pino arrastável com círculo de precisão (verde/vermelho conforme o PDOP) e um rótulo de status na base.

## Exemplo completo (copiar, colar e rodar)
`LocationPicker` abre um mapa em tela cheia — dispare-o a partir de um `Button`. O exemplo reutiliza o uso básico e mostra a coordenada confirmada num `Label`. `LatLon` vem de `dev.crossfly.map`.

```java
package com.exemplo;

import dev.crossfly.map.LatLon;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label saida = new Label("Nenhuma coordenada");
      add(LAY_AUTO, saida);

      Button escolher = new Button("Escolher local no mapa")
         .onAction(c ->
         {
            LocationPicker lp = new LocationPicker(
               coord -> {},   // onCapture do construtor (opcional; pode ser null)
               10.0,          // minPdop
               true,          // pode arrastar o pino
               true,          // alta precisão
               false);        // sem street view

            lp.show(answer ->
            {
               LatLon ll = (LatLon) answer;
               if (ll != null)
                  saida.setText("Local: " + ll.lat + ", " + ll.lon);
            });
         });
      add(LAY_AUTO, escolher);
   }
}
```

> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Uso básico
```java
LocationPicker lp = new LocationPicker(
   coord -> Debug.log("Capturado: " + coord.lat + "," + coord.lon),
   10.0,   // minPdop
   true,   // pode arrastar o pino
   true,   // alta precisão
   false); // sem street view

lp.show(answer ->
{
   LatLon ll = (LatLon) answer;
   salvarLocal(ll.lat, ll.lon);
});
```

## Construtores
| Construtor | Descrição |
|---|---|
| `LocationPicker(RunnableWith<LatLon> onCapture, double minPdop, boolean canDragPin, boolean highPrecision, boolean streetview)` | Ver parâmetros abaixo. |

| Parâmetro | Tipo | O que faz |
|---|---|---|
| `onCapture` | `RunnableWith<LatLon>` | Callback com o `LatLon` ao confirmar (pode ser `null`). |
| `minPdop` | `double` | PDOP máximo aceitável; o confirmar fica oculto até ser atingido. |
| `canDragPin` | `boolean` | Permite arrastar o pino para um local manual. |
| `highPrecision` | `boolean` | Liga o GPS de alta precisão. |
| `streetview` | `boolean` | Habilita street view no mapa. |

## Callbacks e eventos
| Callback | Quando dispara |
|---|---|
| `onCapture` (construtor) | ao confirmar, com o `LatLon` (se `!= null`). |
| `show(onAnswer)` | ao fechar, entrega o `LatLon` confirmado. |

`getAnswer()` retorna o `LatLon` confirmado, ou `null` se cancelado. **Há dois caminhos para o resultado** (o `onCapture` do construtor e o `onAnswer` do `show`) — ambos só disparam quando `answer != null`.

## Estados
- Arrastar o pino desliga o GPS (`canUpdateGPS = false`), marca "Custom Location" e revela o confirmar.
- O botão confirmar só aparece quando a precisão é aceitável (ou em desktop, ou após arraste manual).
- Recursos (thread GPS, `Location`, mapa) são liberados uma única vez ao fechar.

## Boas práticas
- Escolha um `minPdop` realista; em mobile o confirmar fica oculto até o GPS atingi-lo.
- Não reaproveite a instância após `hide()` — os recursos de GPS/mapa são liberados.

## Erros comuns
- **Confirmar nunca aparecer** — GPS não atingiu `minPdop` e o usuário não arrastou o pino (em desktop aparece de imediato).
- **Esperar `onAnswer` no cancelamento** — não dispara (`answer = null`).

## Veja também
- Guia da área: [`ui/`](/docs/ui) · Receitas: [`cookbook/`](/docs/cookbook)
- Base do padrão: [`Picker`](/docs/ui/widgets/picker)
