31 Classes para dados espaciais: o pacote sp

Pacotes e funções para análise de dados espaciais começaram a surgir desde o início do projeto R. Isto em parte se deve ao R fornecer um ambiente adequado para disponibilização de novas propostas de análise e formas de implementação de métodos, combinado ao fato de que a área de estatística espacial estava na época (e ainda está!) em franco desenvolvimento. As implementações procuravam tanto dotar o ambiente do R de funcionalidades usuais de estatística espacial, como implementar novas propostas metodológicas e ainda fornecer interface com outros sistemas tais como os SIG’s (Sistemas de Informação Geográfica) e bancos de dados, especialmente os estruturados espacialmente.

A característica central de dados espaciais é o fato das informações possuirem duas estruturas básicas e interrelacionadas: geometrias e atributos. Tais estruturas são distintas não somente por se referirem a elementos conceituais diferentes, localização e características da localização, mas também, e talvez principalmente, por nem sempre poderem ser representadas de forma simples, como uma única tabela de dados.

Vejamos dois exemplos. Num primeiro caso vamos imaginar que dois atributos (variáveis) sejam medidos em n pontos, sendo cada um destes identificado por um par de coordenadas. Por exemplo, poderíamos ter os atributos precipitação e temperatura máxima diária registrada em n estações meteorológicas. Neste caso, poderíamos facilmente estruturar os dados em uma matriz de dimensão n× 4, onde as quatro colunas seriam referentes ao par de coordenadas (geometria) e às duas variáveis (atributos). Num segundo caso vamos imaginar agora tais atributos medidos em cada município de um estado, onde os municípios são identificados por polígonos que definem suas fronteiras. Neste caso, diferentemente do anterior, não temos como combinar a geometria (polígonos) e os atributos (variáveis temparatura e umidade) em uma estrutura simples de dados como a matriz do exemplo anterior.

Tais exemplos reforçam a idéia que dados espaciais (e espaço-temporais) precisam ter representações que acomodem o tratamento de geometrias e atributos. A esta discussão soma-se o fato que a área de dados espaciais é tipicamente dividida em subáreas que dependem do formato específico dos dados e modelos a serem considerados, sejam de variação espacial discreta (dados de área), contínua (geoestatística) ou processos pontuais. Outras divisões e sub-divisões são ainda possíveis mas vamos nos ater nesta discussão a estas três.

Desta forma, na implementação dos pacotes de estatística espacial no R, os autores seguiram diferentes estratégias dependendo do tipo de dado contemplado pelo pacote bem como de suas preferências pessoais. Com o crescimento do número de pacotes e formas alternativas de representar os dados espaciais, em particular suas geometrias, acabou-se por criar uma verdadeira torre de Babel da representações de dados espaciais.

Neste contexto, começou-se a discutir a possibilidade de criação de uma estrutura comum e geral, que servisse para os diferentes formatos de dados espaciais. Tal idéia acabou se materializando no pacote sp de Roger Bivand e Edzer Pebesma, uma excelente, criativa e bem estruturada proposta baseada em objetos e classes do tipo S4 do R. A implementação foi inicialmente descrita em um artigo dos autores na R-NEWS (2005, vol.2, p.9-13) e também na sessão de estatística espacial do R (CRAN Spatial Task View) e, mais recentemente, no livro Analysis of Spatial Data with R que conta ainda com a co-autoria de Virgílio Gomez-Rúbio. Detalhes podem ainda ser encontrados no vignette que acompanha o pacote sp.

Embora não adotado universalmente, vários pacotes de estatística espacial agora aderem a este formato de dados e/ou possuem formas de converter as estruturas de dados de suas representações específicas para o formato definido pelo pacote sp. A tendência é que a estrutura definida pelo sp seja largamente adotada, especialmente por novos pacotes, por toda a flexibilidade que traz no tratamento e representação de dados espaciais.

Nesta sessão vamos apresentar de maneira informal e através de exemplos simples idéias introdutórias sobre a representação e estrutura de dados espaciais definidas pelo pacote sp. Entretanto, note-se que os recursos de tais classes vão muito além dos exemplos apresentados aqui. As referências mencionadas anteriormente são o guia definitivo para informações mais precisas e detalhadas sobre a potencialidade de tal representação e o texto apresentado a seguir visa somente facilitar o estudo destes materiais e não substituí-los!

O passo inicial para seguir estas notas é instalar e carregar o pacote sp. Este pacote tem dependências de vários outros e portanto, usa-se o argumento dep=TRUE que faz com que todos os demais pacotes necessários sejam também instalados.

  > install.packages("sp", dep = TRUE)
  > require(sp)

31.1 Conceitos introdutórios e classes para pontos esparsos

Vamos iniciar considerando um exemplo simples onde os dados consistem de cinco localizações nas quais foram medidos os valores de duas variáveis conforme ilustrado na Figura ??. Os dados serão inicialmente armazenados na forma de uma matriz de coordenadas e um data-frame com as variáveis, uma das estruturas básicas de dados no R, comumente utilizada para armazenar estruturas de dados na forma de linhas (indivíduos) e colunas (variáveis). Por motivos de apresentação neste material vamos considerar inicialmente as geometrias e atributos separadamente . Nesta caso poderíamos ter ainda optado por incluir as coordenadas no data-frame, adicionando então duas colunas.

  > cord <- cbind(cx = c(1, 3, 6, 2, 5), cy = c(4, 2, 5, 6, 1))
  > DF <- data.frame(var1 = c(23, 26, 18, 25, 30), var2 = c(63, 76,
  +     81, 59, 80))
  > DF

    var1 var2
  1   23   63
  2   26   76
  3   18   81
  4   25   59
  5   30   80

  > dim(DF)

  [1] 5 2

  > SPDF <- cbind(cord, DF)
  > dim(SPDF)

  [1] 5 4


PIC
Figura 78: Exemplo hipotético com dois atributos medidos em cinco localizações identificadas por pares de coordenadas. Os valores dos atributos são indicados dentro dos parêntesis.


A estrutura do data-frame, embora suficiente para anotar todas as informações, não distingue explicitamente as geometrias e atributos, cabendo ao usuário saber a que se refere cada uma das colunas. Na definição de classes do sp, este tipo de dado, com geometria dada por pontos esparsos na região, é representada por um objeto do tipo SpatialPointsDataFrame. O nome é praticamente autoexplicativo indicando que o dado é um data-frame de atributos ligados a pontos. Existem várias formas de se construir um objeto do tipo SpatialPointsDataFrame e vamos ver três delas aqui, a começar pela mais simples dada a seguir utilizando a função coordinates(). Esta função converte um data-frame em um SpatialPointsDataFrame simplesmente indicando quais os nomes das colunas em que estão armazenadas as coordenadas. Note nos comandos como fazer tal conversão e como os objetos desta classe diferem entre si. Após a conversão as coordenadas deixam de fazer parte do data-frame, que armazena agora somente as variáveis, e passam a ser somente uma informação a ele associada.

  > class(SPDF)

  [1] "data.frame"

  > dim(SPDF)

  [1] 5 4

  > coordinates(SPDF) <- c("cx", "cy")
  > class(SPDF)

  [1] "SpatialPointsDataFrame"
  attr(,"package")
  [1] "sp"

  > dim(SPDF)

  [1] 5 2

  > SPDF

    coordinates var1 var2
  1      (1, 4)   23   63
  2      (3, 2)   26   76
  3      (6, 5)   18   81
  4      (2, 6)   25   59
  5      (5, 1)   30   80

Todo objeto desta classe possui atributos específicos que são criados automaticamente podendo ainda ser modificados pelo usuário. Vamos descrevê-los por grupos cuja divisão ficará mas clara posteriormente. Os dois primeiros são as coordenadas do menor retângulo que envolve as localizações dos dados (bbox), e uma string que define a projeção dos dados (proj4string), ou seja, como o dado está georeferenciado em termos do tipo de coordenadas, podendo esta ser NA. A informação de como esta string é escrita segue um padrão definido pelo projeto proj4 e pode ser alterada usando a função CRS(). Estes dois argumentos formam um primeiro grupo devido ao fato de que todo objeto Spatial* definido pelo pacote sp possui tais atributos. Os demais atributos são específicos da classe SpatialPointsDataFrame. Como estes objetos são construídos segundo o padrão S4 da linguagem R, os atributos são usualmente chamados de slots. A listagem de slots de uma classe e a forma de extrair cada particular slot são ilustradas nos comandos a seguir.

  > class(SPDF)

  [1] "SpatialPointsDataFrame"
  attr(,"package")
  [1] "sp"

  > getSlots("SpatialPointsDataFrame")

          data   coords.nrs       coords         bbox  proj4string
  "data.frame"    "numeric"     "matrix"     "matrix"        "CRS"

  > slot(SPDF, "bbox")

     min max
  cx   1   6
  cy   1   6

  > slot(SPDF, "data")

    var1 var2
  1   23   63
  2   26   76
  3   18   81
  4   25   59
  5   30   80

Uma outra forma de criar um objeto que represente dados com geometria dada por pontos esparsos é usar a função SpatialPointsDataFrame() que recebe coordenadas e atributos separadamente em dois argumentos obrigatórios. O resultado apenas difere do retornado pela função coordinates() no slot coords.nrs, que para esta última registra as colunas do data-frame original que foram indicadas como coordenadas.

  > SPDF1 <- SpatialPointsDataFrame(coords = cord, data = DF)
  > all.equal(SPDF, SPDF1)

  [1] "Attributes: < Component 4: Numeric: lengths (2, 0) differ >"

  > slot(SPDF, "coords.nrs")

  [1] 1 2

  > slot(SPDF1, "coords.nrs")

  numeric(0)

Os demais atributos/slots do objeto são definidos automaticamente mas podem ser modificados.

  > slot(SPDF1, "bbox") <- cbind(min = c(0, 0), max = c(7, 7))
  > bbox(SPDF1)

       min max
  [1,]   0   7
  [2,]   0   7

A função possui ainda outros argumentos opcionais já comentados anteriormente, exceto por match.ID que permite que os dois objetos sejam pareados pelos nomes das suas linhas (rownames), permitindo portanto, coordenadas e atributos em ordens diferentes, desde que identificadas pelo mesmo nome da linha. No exemplo a seguir alteramos a ordem dos elementos do data-frame de atributos para ilustrar o pareamento.

  > args(SpatialPointsDataFrame)

  function (coords, data, coords.nrs = numeric(0), proj4string = CRS(as.character(NA)),
      match.ID = TRUE, bbox = NULL)
  NULL

  > DF1 <- DF[c(3, 1, 5, 2, 4), ]
  > DF1

    var1 var2
  3   18   81
  1   23   63
  5   30   80
  2   26   76
  4   25   59

  > SPDF2 <- SpatialPointsDataFrame(coords = cord, data = DF, bbox = cbind(min = c(0,
  +     0), max = c(7, 7)))
  > all.equal(SPDF1, SPDF2)

  [1] TRUE

Até aqui vimos que coordinates() e SpatialPointsDataFrame() criam diretamente objetos da referida classe. Vamos agora examinar com mais detalhe toda a concepção de classes definida no sp que tem uma estrutura hieráquica, começando por classes e construtores de objetos mais gerais que se tornam mais detalhados a cada nível e onde cada classe herda os atributos da classe superior mais geral.

A classe mais geral é Spatial e um objeto desta classe tem apenas duas informações (slots): o retângulo envolvente (bbox - bounding box) e a informação do tipo de projeção (proj4string). Este objeto então simplesmente define em que região estarão os dados e por qual sistema de coordenadas estarão referenciados, sendo que esta última pode ser um "NA" que em SIG’s corresponde a dados sem projeção (null projection). O retângulo envolvente pode ser calculado a partir das coordenadas dos dados (como feito automaticamente pelas funções já vistas), ou definido arbitrariamente pelo usuário, podendo ainda ser alterado depois de definido. Deve conter nas linhas a dimensão das coordenadas, e nas colunas os valores mínimos e máximos para cada uma. A string que informa sobre a projeção deve ser definida usando a função CRS() pois esta irá validar a definição e sintaxe. A função ainda verifica se os valores passados em bbox são compatíveis com a projeção informada, retornando erro caso sejam incompatíveis. Métodos são implementados para extrair os elementos do objeto.

  > getSlots("Spatial")

         bbox proj4string
     "matrix"       "CRS"

  > bb <- t(apply(cord, 2, range))
  > colnames(bb) <- c("min", "max")
  > S <- Spatial(bbox = bb, proj4string = CRS(projargs = as.character(NA)))
  > S

  An object of class "Spatial"
  Slot "bbox":
     min max
  cx   1   6
  cy   1   6
  
  Slot "proj4string":
  CRS arguments: NA

  > bbox(S)

     min max
  cx   1   6
  cy   1   6

  > slot(S, "bbox") <- cbind(min = c(0, 0), max = c(7, 7))
  > bbox(S)

       min max
  [1,]   0   7
  [2,]   0   7

  > proj4string(S)

  [1] NA

A classe Spatial possui três subclasses: SpatialPoints, SpatialLines e SpatialPolygons. Estas subclasses definem, como os nomes sugerem, o tipo de geometria dos dados. Seguindo nosso exemplo vamos criar um objeto da classe SpatialPoints que extende a classe Spatial adicionando um slot coords que armazena as coordenadas de um conjunto de pontos. Assim como no exemplo anterior vamos examinar os slots e tipos de objetos que estes recebem com a função getSlots() aplicada ao nome da classe. Na saída desta função fica claro que a classe SpatialPoints herda os atributos de Spatial. A função construtora tem coords como argumento obrigatório e as herdadas da classe Spatial, bbox e proj4string como opcionais. É ainda importante notar que vários métodos usuais já são definidos para este nível de classes tais como summary(), plot(), entre outros. É ainda possível fazer seleção de elementos.

  > getSlots("SpatialPoints")

       coords        bbox proj4string
     "matrix"    "matrix"       "CRS"

  > args(SpatialPoints)

  function (coords, proj4string = CRS(as.character(NA)), bbox = NULL)
  NULL

  > row.names(cord) <- 1:nrow(cord)
  > SP <- SpatialPoints(coords = cord)
  > SP <- SpatialPoints(coords = cord, bbox = bbox(S))
  > SP

  SpatialPoints:
    cx cy
  1  1  4
  2  3  2
  3  6  5
  4  2  6
  5  5  1
  Coordinate Reference System (CRS) arguments: NA

  > summary(SP)

  Object of class SpatialPoints
  Coordinates:
       min max
  [1,]   0   7
  [2,]   0   7
  Is projected: NA
  proj4string : [NA]
  Number of points: 5

  > ind <- coordinates(SP)[, 2] < 3
  > SP[ind, ]

  SpatialPoints:
    cx cy
  2  3  2
  5  5  1
  Coordinate Reference System (CRS) arguments: NA

Seguindo esta estrutura de classe e subclasses podemos revisitar a classe SpatialPointsDataFrame como sendo uma sub-sub-classe de Spatial que extende SpatialPoints acomodando uma matriz de atributos, que por default é pareada com as coordenadas pelos nomes das linhas (rownames), dai porque na criação do objeto SpatialPoints asseguramos a definição dos nomes de linhas. Já vimos acima como um objeto desta classe é criado mas note-se que ele poderia ser criado ainda a partir de um objeto SpatialPoints com a simples adição do data-frame dos atributos. Os estratores, métodos e seletores continuam válidos.

  > getSlots("SpatialPointsDataFrame")

          data   coords.nrs       coords         bbox  proj4string
  "data.frame"    "numeric"     "matrix"     "matrix"        "CRS"

  > SPDF3 <- SpatialPointsDataFrame(SP, DF)
  > all.equal(SPDF1, SPDF3)

  [1] "Attributes: < Component 3: Attributes: < Component 2: Component 1: target is NULL, current is character > >"

  > summary(SPDF3)

  Object of class SpatialPointsDataFrame
  Coordinates:
       min max
  [1,]   0   7
  [2,]   0   7
  Is projected: NA
  proj4string : [NA]
  Number of points: 5
  Data attributes:
        var1           var2
   Min.   :18.0   Min.   :59.0
   1st Qu.:23.0   1st Qu.:63.0
   Median :25.0   Median :76.0
   Mean   :24.4   Mean   :71.8
   3rd Qu.:26.0   3rd Qu.:80.0
   Max.   :30.0   Max.   :81.0

  > bbox(SPDF3)

       min max
  [1,]   0   7
  [2,]   0   7

  > SPDF3[ind, ]

    coordinates var1 var2
  2      (3, 2)   26   76
  5      (5, 1)   30   80

Neste ponto podemos revisar a estrutura das classes verificando a saída de getClass() que informa os slots de cada classe ou subclasse, qual(is) a(s) class(es) por ela extendida – se alguma, bem como quais as subclasses definidas para esta classe em vários níveis.

  > getClass("Spatial")

  Class "Spatial" [package "sp"]
  
  Slots:
  
  Name:         bbox proj4string
  Class:      matrix         CRS
  
  Known Subclasses:
  Class "SpatialPoints", directly
  Class "SpatialLines", directly
  Class "SpatialPolygons", directly
  Class "SpatialPointsDataFrame", by class "SpatialPoints", distance 2
  Class "SpatialPixels", by class "SpatialPoints", distance 2
  Class "SpatialLinesDataFrame", by class "SpatialLines", distance 2
  Class "SpatialGrid", by class "SpatialPoints", distance 3
  Class "SpatialPixelsDataFrame", by class "SpatialPoints", distance 3
  Class "SpatialGridDataFrame", by class "SpatialPoints", distance 4
  Class "SpatialPolygonsDataFrame", by class "SpatialPolygons", distance 2

  > getClass("SpatialPoints")

  Class "SpatialPoints" [package "sp"]
  
  Slots:
  
  Name:       coords        bbox proj4string
  Class:      matrix      matrix         CRS
  
  Extends: "Spatial"
  
  Known Subclasses:
  Class "SpatialPointsDataFrame", directly
  Class "SpatialPixels", directly
  Class "SpatialGrid", by class "SpatialPixels", distance 2
  Class "SpatialPixelsDataFrame", by class "SpatialPixels", distance 2
  Class "SpatialGridDataFrame", by class "SpatialGrid", distance 3

  > getClass("SpatialPointsDataFrame")

  Class "SpatialPointsDataFrame" [package "sp"]
  
  Slots:
  
  Name:         data  coords.nrs      coords        bbox proj4string
  Class:  data.frame     numeric      matrix      matrix         CRS
  
  Extends:
  Class "SpatialPoints", directly
  Class "Spatial", by class "SpatialPoints", distance 2
  
  Known Subclasses:
  Class "SpatialPixelsDataFrame", directly, with explicit coerce

31.2 Pontos em malha regular: grid e pixel

SpatialGrid e SpatialPixels são representações de pontos arranjados de forma regular numa região, tais como modelos de elevação digital, imagens (por ex. de satélite), malhas de interpolação de pontos, entre outras. Tais representações são comuns em sensoriamento remoto e representações do tipo raster em SIG’s. Todo o conjunto de pontos fica definido a partir de apenas algums informações básicas como origem e espaçamento, o que permite que os pontos de toda a malha sejam tratados de uma só vez ao invés de cada ponto individualmente. Estas classes extendem SpatialPoints de forma a registrar e utilizar as informações sobre o arranjo regular das localizações, o que é feito com GridTopology que define as células da malha de pontos. Como exemplo vamos criar uma malha retangular com espaçamento de 0, 1 × 0, 2 sobre a área do exemplo anterior. As informações necessárias são o centro da primeira célula da malha, o tamanho e número de células em cada dimensão. A combinação da classe GridTopology com os elementos de Spatial gera a subclasse SpatialGrid. A Figura 31.2 mostra a sobreposição das localizações dos dados originais e a malha de pontos que cobre a área no espaçamento especificado.

  > bbox(SPDF3)

       min max
  [1,]   0   7
  [2,]   0   7

  > espac <- c(0.1, 0.2)
  > centro1 <- bbox(SPDF3)[, 1] + espac/2
  > centro1

  [1] 0.05 0.10

  > nums <- ceiling(diff(t(bbox(SPDF3)))/espac)
  > GT <- GridTopology(cellcentre.offset = centro1, cellsize = espac,
  +     cells.dim = nums)
  > SG <- SpatialGrid(GT)
  > getClass("SpatialGrid")

  Class "SpatialGrid" [package "sp"]
  
  Slots:
  
  Name:          grid   grid.index       coords         bbox  proj4string
  Class: GridTopology      integer       matrix       matrix          CRS
  
  Extends:
  Class "SpatialPixels", directly
  Class "SpatialPoints", by class "SpatialPixels", distance 2
  Class "Spatial", by class "SpatialPixels", distance 3
  
  Known Subclasses: "SpatialGridDataFrame"

  > plot(SPDF3, pch = 19)
  > plot(SG, cex = 0.4, add = T)


PIC

Neste exemplo definimos a malha a partir da dimensão da área. Entretanto, isto não é compulsório, podendo a malha ser criada de outras formas e/ou importada de algum outro objeto ou formato e neste caso o retângulo envolvente (bounding box) é criado automaticamente. Note ainda que no exemplo continuamos usando o dado sem projeção ou qualquer tipo de sistema de coordenadas.

A extensão natural é dada pela classe SpatialGridDataFrame que associa à malha um data-frame com atributos associados a cada um dos pontos.

  > getClass("SpatialGridDataFrame")

  Class "SpatialGridDataFrame" [package "sp"]
  
  Slots:
  
  Name:          data         grid   grid.index       coords         bbox  proj4string
  Class:   data.frame GridTopology      integer       matrix       matrix          CRS
  
  Extends:
  Class "SpatialGrid", directly
  Class "SpatialPixels", by class "SpatialGrid", distance 2
  Class "SpatialPoints", by class "SpatialGrid", distance 3
  Class "Spatial", by class "SpatialGrid", distance 4

O formato de grid (raster) apresenta algumas limitações em certas circunstâncias. Por exemplo se a área tem muitos recortes e/ou várias células não possuem atributos, os valores correspondentes devem ser indicados como NA. Por exemplo, em um modelo de elevação digital de terreno poderiam haver pontos abaixo da superfície da água, ou ainda a área de estudo pode ser bem recortada, levando a um formato bastante irregular com muitas partes dentro de bbox porém fora da área. Como os grids tipicamente tem alta resolução, isto faz com que um grande volume de memória seja utilizado sem necessidade. Além disto, em certas situações pode-se desejar exportar dados para aplicativos externos em forma de coordenadas de pontos. Nestes casos pode-se usar a representação alternativa de SpatialPixels que guarda informações apenas dos pontos de interesse, assim como em SpatialPoints, porém guardando também a informação de o que se tem é um subconjunto de uma malha, como definida em SpatialGrid.

31.3 Classe para linhas e polígonos

Vimos até aqui que a subclasse SpatialPoints e as subclasses derivadas dela extendem a classe Spatial para acomodar coordenadas de uma geometria de pontos. As outras geometrias espaciais são linhas e polígonos que são tratadas pelas classes SpatialLines e SpatialPolygons, respectivamente. A representação destas geometrias no sp é feita através de uma conjunto sequencial de pontos, sendo que outras representações possíveis existem em ambientes de SIG. Estas duas geometrias são semelhantes em sua forma, sendo o polígono representado por uma linha fechada, ou seja, uma linha onde o primeiro e último pontos são iguais. Assim como em SpatialPoints, ambas subclasses são extendidas pela adição de atributos em subsubclasses SpatialLinesDataFrame e SpatialPolygonsDataFrame.

  > getClass("SpatialLines")

  Class "SpatialLines" [package "sp"]
  
  Slots:
  
  Name:        lines        bbox proj4string
  Class:        list      matrix         CRS
  
  Extends: "Spatial"
  
  Known Subclasses: "SpatialLinesDataFrame"

  > getClass("SpatialPolygons")

  Class "SpatialPolygons" [package "sp"]
  
  Slots:
  
  Name:     polygons   plotOrder        bbox proj4string
  Class:        list     integer      matrix         CRS
  
  Extends: "Spatial"
  
  Known Subclasses: "SpatialPolygonsDataFrame"

Assim como um objeto em SpatialPoints é definido por um conjunto de pontos, analogamente em SpatialLines é definido por um conjunto de linhas e em SpatialPolygons é definido por um conjunto de polígonos. Pontos são definidos simplesmente por um par de coordenadas, enquanto que linhas e polígonos são definidos por um conjunto de pontos com uma certa estrutura. Desta forma, criaram-se as funções Line e Polygon para se especificar estes elementos. A seguir vamos utilizar um exemplo envolvendo três polígonos disponíveis em um conjunto de dados do pacote geoR. Para nos concentrar apenas nos polígonos vamos extraí-los do objeto de dados original e armazená-los em uma lista onde cada elemento é uma matriz.

  > require(geoR)

  -------------------------------------------------------------
  Analysis of geostatistical data
  For an Introduction to geoR go to http://www.leg.ufpr.br/geoR
  geoR version 1.6-36 (built on 2011-05-20) is now loaded
  -------------------------------------------------------------

  > data(ca20)
  > areas <- ca20[c("reg1", "reg2", "reg3")]
  > areas

  $reg1
    east north
  1 5590  5690
  2 5340  5800
  3 5220  5700
  4 5250  5370
  5 5350  5370
  6 5450  5500
  7 5510  5600
  8 5590  5690
  
  $reg2
    east north
  1 5990  5100
  2 5590  5300
  3 5350  5370
  4 5450  5500
  5 5510  5600
  6 5590  5690
  7 5800  5690
  8 5990  5690
  
  $reg3
     east north
  1  5990  5100
  2  5590  5300
  3  5350  5370
  4  5150  5370
  5  4920  5000
  6  4920  4900
  7  5150  4920
  8  5350  4900
  9  5590  4800
  10 5780  4800

Para construir um SpatialPolygon, o primeiro passo é transformar cada matriz que define um polígono em um objeto da classe Polygon, que verifica se o polígono está bem definido, por exemplo, se a coordenada do último ponto coincide com a do primeiro. A estrutura de um objeto da classe Polygon inclui ainda o rótulo atribuído ao polígono (labpt) que é dado pelo seu centroide, a sua área, e informações sobre se ele é interno ou externo (hole e ringDir).

  > getClass("Polygon")

  Class "Polygon" [package "sp"]
  
  Slots:
  
  Name:    labpt    area    hole ringDir  coords
  Class: numeric numeric logical integer  matrix
  
  Extends: "Line"

  > Polygon(areas$reg1)

  An object of class "Polygon"
  Slot "labpt":
  [1] 5364.879 5596.530
  
  Slot "area":
  [1] 95100
  
  Slot "hole":
  [1] TRUE
  
  Slot "ringDir":
  [1] -1
  
  Slot "coords":
       east north
  [1,] 5590  5690
  [2,] 5340  5800
  [3,] 5220  5700
  [4,] 5250  5370
  [5,] 5350  5370
  [6,] 5450  5500
  [7,] 5510  5600
  [8,] 5590  5690

  > sapply(areas, function(x) identical(x[1, , drop = T], x[nrow(x),
  +     , drop = T]))

   reg1  reg2  reg3
   TRUE FALSE FALSE

  > areas <- lapply(areas, function(x) {
  +     if (identical(x[1, , drop = T], x[nrow(x), , drop = T]))
  +         x
  +     else rbind(x, x[1, ])
  + })

Normalmente, como neste exemplo, se tem mais de um polígono. Um conjunto de polígonos é agrupado na classe Polygons que contém uma lista de objetos válidos da classe Polygon. É necessário atribuir identificadores para cada polígono que poderão ser posteriormente utilizados para associá-los com atributos. Finalmente, um ou mais objetos Polygons são combinados na forma de lista para compor um objeto da classe SpatialPolygons. Neste objeto as informações dos polígonos são não apenas armazenadas mas também combinadas para gerar informações da área como um todo.

  > getClass("Polygons")

  Class "Polygons" [package "sp"]
  
  Slots:
  
  Name:   Polygons plotOrder     labpt        ID      area
  Class:      list   integer   numeric character   numeric

  > POLS <- lapply(1:length(areas), function(x) Polygons(list(Polygon(areas[[x]])),
  +     ID = paste("reg", x, sep = "")))
  > class(POLS)

  [1] "list"

  > SPol <- SpatialPolygons(POLS)
  > class(SPol)

  [1] "SpatialPolygons"
  attr(,"package")
  [1] "sp"

  > getClass("SpatialPolygons")

  Class "SpatialPolygons" [package "sp"]
  
  Slots:
  
  Name:     polygons   plotOrder        bbox proj4string
  Class:        list     integer      matrix         CRS
  
  Extends: "Spatial"
  
  Known Subclasses: "SpatialPolygonsDataFrame"

  > bbox(SPol)

     min  max
  x 4920 5990
  y 4800 5800

Métodos tais como plot, spplot, summary entre outros são implementados de forma usual como os demais objetos da família Spatial. Atributos ligados aos polígonos sau acoplados para criação de SpatialPolygonsDataFrame. O data-frame de atributos deve ter nomes de linhas que permitam o pareamento com os nomes atribuídos aos polígonos.

  > dadosPol <- data.frame(var1 = c(23, 34, 12), var2 = c("a", "b",
  +     "a"))
  > row.names(dadosPol) <- paste("reg", 1:3, sep = "")
  > SPolDF <- SpatialPolygonsDataFrame(SPol, dadosPol)