Prezado leitor,

Neste tutorial você vai aprender, passo a passo, como enviar um shapefile diretamente para o GeoServer usando a REST API. A diferença aqui é que, em vez de o arquivo ser salvo na pasta data_dir, ele será importado automaticamente para o PostGIS, utilizando o plugin Importer do GeoServer.

Esse fluxo é extremamente útil para automatizar processos de ingestão de dados em ambientes de produção, evitando a manipulação manual da pasta data_dir.

Além disso, com a REST API, você pode integrar esse processo em scripts Python, pipelines de ETL ou até em rotinas de integração contínua (CI/CD).

Vamos ao passo a passo:

1. Criação do Store

Antes de importar o shapefile, precisamos garantir que existe um store configurado apontando para o banco PostGIS.

Isso pode ser feito pela própria REST API, com o seguinte comando:

curl  -u admin:geoserver -XPOST -H "Content-type: application/json" -d @postgis.json "http://localhost:8080/geoserver/rest/workspaces/cite/datastores.json"

O comando acima cria um novo Store no GeoServer, e as configurações ficam no arquivo postgis.json, quem contem as informações de conexão da base de dados que você deseja utilizar no GeoServer, conforme o exemplo a abaixo:

{
  "dataStore": {
    "name": "postgis",
    "type": "PostGIS",
    "workspace": {
      "name": "cite"
    },
    "connectionParameters": {
      "entry": [
        {"@key": "schema","$": "public"},
        {"@key": "database","$": "postgres"},
        {"@key": "host","$": "localhost"},
        {"@key": "port","$": "5432"},
        {"@key": "passwd","$": "postgres"},
        {"@key": "dbtype","$": "postgis"},
        {"@key": "user","$": "postgres"},
        {"@key": "Estimated extends","$": "true"},
        {"@key": "encode functions","$": "true"},
        {"@key": "Loose bbox","$": "true"},
        {"@key": "Method used to simplify geometries","$": "PRESERVETOPOLOGY"},
        {"@key": "Support on the fly geometry simplification","$": "true"},
        {"@key": "validate connections","$": "true"},
        {"@key": "Connection timeout","$": "20"},
        {"@key": "min connections","$": "1"},
        {"@key": "max connections","$": "10"},
        {"@key": "Evictor tests per run","$": "3"},
        {"@key": "Test while idle","$": "true"},
        {"@key": "Max connection idle time","$": "300"}
      ]
    },
    "_default": true
  }
}

2. Definição para importação

É importante ressaltar que para executar o comando abaixo, é necessário que o plugin Importer esteja instalado no seu GeoServer, pois é ele que fará a importação do shapefile para o banco de dados. O primeiro passo é preparar a tarefa através do seguinte comando:

curl.exe -u admin:geoserver -XPOST -H "Content-type: application/json" -d @import.json "http://localhost:8080/geoserver/rest/imports"

O arquivo import.json deve conter as informações de onde você deseja armazenar o arquivo shapefile, no caso workspace e store:

{
   "import": {
      "targetWorkspace": {
         "workspace": {
            "name": "cite"
         }
      },
      "targetStore": {
         "dataStore": {
            "name": "postgis"
         }
      }
   }
}

O comando acima irá retornar um ID (no nosso exemplo é o 0), que você irá inserir no link de resposta ao GeoServer. Após a execução do comando acima temos uma importação vazia, sem tarefas. Para adicionar uma tarefa, publique o shapefile na lista de tarefas:

curl.exe -u admin:geoserver -F name=biomas_srv.zip -F filedata=@biomas_srv.zip "http://localhost:8080/geoserver/rest/imports/0/tasks"

3. Apontar para o Store

Como enviamos um shapefile, o importador assume que o destino será um repositório de shapefiles. Para importar para o PostGIS, precisaremos redefini-lo, e faremos isso através do arquivo target.json:

{
  "dataStore": {
    "name":"postgis"
  }
}

Coloque esse arquivo na requisição abaixo:

curl.exe -u admin:geoserver -XPUT -H "Content-type: application/json" -d @target.json "http://localhost:8080/geoserver/rest/imports/0/tasks/0/target"

4. Realizar a importação

Por fim, executamos a importação enviando um POST da seguinte forma:

curl.exe -u admin:geoserver -XPOST "http://localhost:8080/geoserver/rest/imports/0"

Se tudo correr bem, o shapefile será carregado diretamente no seu banco PostGIS e publicado no GeoServer.

5. BÔNUS

Para quem deseja automatizar o processo, segue um exemplo de um Script Python usando a biblioteca requests. Veja como usar:

1. Salve o script em um arquivo, por exemplo import_shapefile.py.
2. Certifique-se de instalar a biblioteca necessária:

pip install requests

3. Ajuste os parâmetros de conexão (usuário, senha, banco, shapefile, workspace etc.) conforme seu ambiente.
4. Agora execute o script: python import_shapefile.py

# Script import_shapefile.py

import requests
import json

# Configurações
GEOSERVER_URL = "http://localhost:8080/geoserver/rest"
AUTH = ("admin", "geoserver")  # usuário e senha
WORKSPACE = "cite"
DATASTORE = "postgis"
SHAPEFILE = "biomas_srv.zip"

# 1. Criar o DataStore (caso ainda não exista)
postgis_json = {
    "dataStore": {
        "name": DATASTORE,
        "type": "PostGIS",
        "workspace": {"name": WORKSPACE},
        "connectionParameters": {
            "entry": [
                {"@key": "schema", "$": "public"},
                {"@key": "database", "$": "postgres"},
                {"@key": "host", "$": "localhost"},
                {"@key": "port", "$": "5432"},
                {"@key": "passwd", "$": "postgres"},
                {"@key": "dbtype", "$": "postgis"},
                {"@key": "user", "$": "postgres"}
            ]
        }
    }
}

resp = requests.post(
    f"{GEOSERVER_URL}/workspaces/{WORKSPACE}/datastores",
    auth=AUTH,
    headers={"Content-type": "application/json"},
    data=json.dumps(postgis_json)
)

print("Criação do DataStore:", resp.status_code)

# 2. Criar importação
import_json = {
    "import": {
        "targetWorkspace": {"workspace": {"name": WORKSPACE}},
        "targetStore": {"dataStore": {"name": DATASTORE}}
    }
}

resp = requests.post(
    f"{GEOSERVER_URL}/imports",
    auth=AUTH,
    headers={"Content-type": "application/json"},
    data=json.dumps(import_json)
)

import_id = resp.json()["import"]["id"]
print("ID da importação:", import_id)

# 3. Adicionar o shapefile à importação
with open(SHAPEFILE, "rb") as f:
    resp = requests.post(
        f"{GEOSERVER_URL}/imports/{import_id}/tasks",
        auth=AUTH,
        files={"filedata": f},
        data={"name": SHAPEFILE}
    )

print("Upload shapefile:", resp.status_code)

# 4. Ajustar destino para PostGIS
target_json = {"dataStore": {"name": DATASTORE}}

resp = requests.put(
    f"{GEOSERVER_URL}/imports/{import_id}/tasks/0/target",
    auth=AUTH,
    headers={"Content-type": "application/json"},
    data=json.dumps(target_json)
)

print("Redefinição destino:", resp.status_code)

# 5. Executar importação
resp = requests.post(
    f"{GEOSERVER_URL}/imports/{import_id}",
    auth=AUTH
)

print("Execução da importação:", resp.status_code)