Introdução ao GeoTools

Introdução ao GeoTools

1. Visão geral

Neste artigo, abordaremos o básico doGeoTools open source Java library – for working with geospatial data. Esta biblioteca fornece métodos compatíveis para a implementação de Sistemas de Informação Geográfica (GIS) e implementa e suporta muitos padrões do Open Geospatial Consortium (OGC).

À medida que o OGC desenvolve novos padrões, eles são implementados pelo GeoTools, o que o torna bastante útil para o trabalho geoespacial.

2. Dependências

Precisamos adicionar as dependências do GeoTools ao nosso arquivopom.xml. Como essas dependências não estão hospedadas no Maven Central, também precisamos declarar seus repositórios para que o Maven possa baixá-los:


    
        osgeo
        Open Source Geospatial Foundation Repository
        http://download.osgeo.org/webdav/geotools/
    
    
        opengeo
        OpenGeo Maven Repository
        http://repo.opengeo.org
    

Depois disso, podemos adicionar nossas dependências:


    org.geotools
    gt-shapefile
    15.2


    org.geotools
    gt-epsg-hsql
    15.2

3. GIS e Shapefiles

Para ter algum uso prático da biblioteca GeoTools, precisamos saber algumas coisas sobre sistemas de informações geográficas eshapefiles.

3.1. GIS

Se quisermos trabalhar com dados geográficos, precisaremos de um sistema de informações geográficas (GIS). Este sistema pode ser usadoto present, capture, store, manipulate, analyze, or manage geographical data.

Uma parte dos dados geográficos é espacial - ele faz referência a locais concretos na Terra. Os dados espaciais são geralmente acompanhados pelos dados do atributo. Os dados do atributo podem ser qualquer informação adicional sobre cada um dos recursos espaciais.

Um exemplo de dados geográficos seriam cidades. A localização real das cidades são os dados espaciais. Dados adicionais, como o nome da cidade e a população, constituiriam os dados do atributo.

3.2. Shapefiles

Diferentes formatos estão disponíveis para trabalhar com dados geoespaciais. Raster e vetor são os dois principais tipos de dados.

Neste artigo, veremos como trabalhar com os dados vetoriais type. Esse tipo de dados pode ser representado como pontos, linhas ou polígonos.

Para armazenar dados vetoriais em um arquivo, usaremos umshapefile. Esse formato de arquivo é usado ao trabalhar com o tipo de dados vetoriais geoespaciais. Além disso, é compatível com uma ampla gama de softwares GIS.

Podemos usar GeoTools para adicionar recursos como cidades, escolas e pontos de referência parashapefiles.

4. Criação de recursos

A documentaçãoGeoTools especifica que um elemento é qualquer coisa que pode ser desenhada em um mapa, como uma cidade ou algum ponto de referência. E, como mencionamos, uma vez criados, os recursos podem ser salvos em arquivos chamadosshapefiles.

4.1. Manter dados geoespaciais

Before creating a feature, we need to know its geospatial data or the longitude and latitude coordinates of its location on earth. Quanto aos dados do atributo, precisamos saber o nome do recurso que queremos criar.

Esta informação pode ser encontrada na web. Alguns sites comosimplemaps.com oumaxmind.com oferecem bancos de dados gratuitos com dados geoespaciais.

Quando conhecemos a longitude e latitude de uma cidade, podemos armazená-las facilmente em algum objeto. Podemos usar um objetoMap que conterá o nome da cidade e uma lista de suas coordenadas.

Vamos criar um método auxiliar para facilitar o armazenamento de dados dentro de nosso objetoMap:

private static void addToLocationMap(
  String name,
  double lat,
  double lng,
  Map> locations) {
    List coordinates = new ArrayList<>();

    coordinates.add(lat);
    coordinates.add(lng);
    locations.put(name, coordinates);
}

Agora vamos preencher nosso objetoMap:

Map> locations = new HashMap<>();

addToLocationMap("Bangkok", 13.752222, 100.493889, locations);
addToLocationMap("New York", 53.083333, -0.15, locations);
addToLocationMap("Cape Town", -33.925278, 18.423889, locations);
addToLocationMap("Sydney", -33.859972, 151.211111, locations);
addToLocationMap("Ottawa", 45.420833, -75.69, locations);
addToLocationMap("Cairo", 30.07708, 31.285909, locations);

Se fizermos o download de algum banco de dados CSV que contém esses dados, podemos facilmente criar um leitor para recuperar os dados em vez de mantê-los em um objeto como aqui.

4.2. Definindo Tipos de Característica

Então, agora temos um mapa das cidades. To be able to create features with this data, we’ll need to define their type first. GeoTools oferece duas maneiras de definir tipos de recursos.

Uma maneira é usar o métodocreateType da classeDataUtilites:

SimpleFeatureType TYPE = DataUtilities.createType(
  "Location", "location:Point:srid=4326," + "name:String");

Outra forma éuse a SimpleFeatureTypeBuilder, which provides more flexibility. Por exemplo, podemos definir o Sistema de referência de coordenadas para o tipo e definir um comprimento máximo para o campo de nome:

SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Location");
builder.setCRS(DefaultGeographicCRS.WGS84);

builder
  .add("Location", Point.class);
  .length(15)
  .add("Name", String.class);

SimpleFeatureType CITY = builder.buildFeatureType();

Both types store the same information. A localização da cidade é armazenada comoPoint, e o nome da cidade é armazenado comoString.

Você provavelmente notou que as variáveis ​​de tipoTYPE eCITY são nomeadas com todas as letras maiúsculas, como constantes. Type variables should be treated as final variables and should not be changed after they are created, então esta forma de nomear pode ser usada para indicar exatamente isso.

4.3. Criação de recursos e coleções de recursos

Depois de definirmos o tipo de recurso e termos um objeto que possui os dados necessários para criar recursos, podemos começar a criá-los com seu construtor.

Vamos instanciar umSimpleFeatureBuilder fornecendo nosso tipo de recurso:

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY);

Também precisaremos de uma coleção para armazenar todos os objetos de recurso criados:

DefaultFeatureCollection collection = new DefaultFeatureCollection();

Como declaramos em nosso tipo de recurso manter umPoint para o local, precisaremoscreate points for our cities based on their coordinates. Podemos fazer isso comGeoTools’s JTSGeometryFactoryFinder:

GeometryFactory geometryFactory
  = JTSFactoryFinder.getGeometryFactory(null);

Observe quewe can also use other Geometry classes like Line and Polygon.

Podemos criar umfunction que nos ajudará a colocar recursos na coleção:

private static Function>, SimpleFeature>
  toFeature(SimpleFeatureType CITY, GeometryFactory geometryFactory) {
    return location -> {
        Point point = geometryFactory.createPoint(
           new Coordinate(location.getValue()
             .get(0), location.getValue().get(1)));

        SimpleFeatureBuilder featureBuilder
          = new SimpleFeatureBuilder(CITY);
        featureBuilder.add(point);
        featureBuilder.add(location.getKey());
        return featureBuilder.buildFeature(null);
    };
}

Assim que tivermos o construtor e a coleção, usando ofunction criado anteriormente, podemoscreate features and store them in our collection:

locations.entrySet().stream()
  .map(toFeature(CITY, geometryFactory))
  .forEach(collection::add);

A coleção agora contém todos os recursos criados com base em nosso objetoMap que continha os dados geoespaciais.

5. Criação de um DataStore

GeoTools contém umDataStore API que é usado para representar uma fonte de dados geoespaciais. Essa fonte pode ser um arquivo, um banco de dados ou algum serviço que retorna dados. Podemos usarDataStoreFactory para criar nossoDataStore, que conterá nossos recursos.

Vamos definir o arquivo que conterá os recursos:

File shapeFile = new File(
  new File(".").getAbsolutePath() + "shapefile.shp");

Agora, vamos definir os parâmetros que vamos usar para dizer aoDataStoreFactory qual arquivo usar e indicar que precisamos armazenar um índice espacial quando criamos nossoDataStore:

Map params = new HashMap<>();
params.put("url", shapeFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);

Vamos criar oDataStoreFactory usando os parâmetros que acabamos de criar e usar essa fábrica para criar oDataStore:

ShapefileDataStoreFactory dataStoreFactory
  = new ShapefileDataStoreFactory();

ShapefileDataStore dataStore
  = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
dataStore.createSchema(CITY);

6. Escrevendo para um Shapefile

A última etapa que precisamos fazer é gravar nossos dados em umshapefile. Para fazer isso com segurança, vamos parause the Transaction interface que faz parte da APIGeoTools.

Essa interface nos dá a possibilidade deeasily commit our the changes to the file. Ele também fornece uma maneira deperform a rollback of the unsuccessful changes if some problem occurs ao gravar no arquivo:

Transaction transaction = new DefaultTransaction("create");

String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource featureSource
  = dataStore.getFeatureSource(typeName);

if (featureSource instanceof SimpleFeatureStore) {
    SimpleFeatureStore featureStore
      = (SimpleFeatureStore) featureSource;

    featureStore.setTransaction(transaction);
    try {
        featureStore.addFeatures(collection);
        transaction.commit();

    } catch (Exception problem) {
        transaction.rollback();
    } finally {
        transaction.close();
    }
}

OSimpleFeatureSource é usado para ler recursos e oSimpleFeatureStore é usado para acesso de leitura / gravação. Está especificado na documentaçãoGeoTools que usar o métodoinstanceof para verificar se podemos gravar no arquivo é a maneira correta de fazer isso.

Esteshapefile pode ser aberto posteriormente com qualquer visualizador GIS que tenha suporte parashapefile.

7. Conclusão

Neste artigo, vimos como podemos usar a bibliotecaGeoTools para fazer alguns trabalhos geoespaciais muito interessantes.

Embora o exemplo seja simples, ele pode ser estendido e usado para criarshapefiles ricos para vários fins.

Devemos ter em mente queGeoTools é uma biblioteca vibrante e este artigo serve apenas como uma introdução básica à biblioteca. Além disso,GeoTools não se limita a criar apenas tipos de dados vetoriais - também pode ser usado para criar ou trabalhar com tipos de dados raster.

Você pode encontrar o código de exemplo completo usado neste artigo em nossoGitHub project. Como é um projeto do Maven, você deve poder importá-lo e executá-lo como está.