Usando Python e o geoprocessing framework #2
Boa tarde pessoal!
Continuando naquele nosso projetinho, hoje vamos falar sobre a classe em Python que atualiza nossos dados em um determinado banco de dados. Temos algumas particularidades quando trabalhamos com ArcSDE, (registro de camadas como versionadas/não versionadas), portanto mostrarei como trabalhar com um Geodatabase local. A alteração para ArcSDE não é tão grande, e com um cadinho de pesquisa vocês conseguem fazer.
Lembre-se das outras classes que precisamos, mostradas no post anterior.
Construiremos duas classes, uma chamada GeoprocessorWrapper, um "embrulho" do objeto geoprocessor da ESRI. Isto não necessário, mas facilita, já que facilitamos algumas operações através deste "embrulho". A outra será uma tarefa, que juntará todos os dados e resultados das classes anteriores para atualizar nosso banco de dados.
Vamos começar com a mais simples, geoprocessorWrapper:
import arcgisscripting, logHandler
__toolboxAliases = [
"analysis",
"management",
"3d",
"cartography",
"arc",
"interop",
"geocoding",
"ga",
"lr",
"md",
"na",
"samples",
"sa",
"stats"]
class geoprocessorWrapperClass():
def __init__(self,workspace,toolboxList,overwriteOutput=False):
self.logs = logHandler.logHandlerClass()
# Startup logging object
self.gp = arcgisscripting.create(9.3)
# Startup ESRI geoprocessing object
self.gp.Workspace = workspace
self.gp.OverwriteOutput = overwriteOutput
# Define overwrite output. Default is to FALSE.
#lista de toolboxes disponiveis
self.toolboxList = []
self.toolboxList += toolboxList
self.buildGeoprocessorOptions(toolboxList)
def buildGeoprocessorOptions(self):
for x in self.toolboxList:
try:
if x in __toolboxAliases:
self.gp.AddToolbox(x)
except:
self.logs.newLogMessage(self, "Error in adding " + x + " toolbox to geoprocessor object. Are you sure this toolbox exists?" + self.gp.GetMessages(), "Geoprocessing Error")
# adds all toolboxes to current geoprocessing object.
def changeWorkspace(self,workspace):
self.gp.Workspace = workspace;
# changes the current workspace in geoprocessing object
def removeToolboxes(self,toolboxList):
for x in self.toolboxList:
try:
self.gp.RemoveToolbox(x)
self.toolboxList.remove(x)
self.logs.newLogMessage(self,"Removed " + x + "toolbox from geoprocessing object.","Information")
except:
self.logs.newLogMessage(self,self.gp.GetMessages(),"Geoprocessing Error")
# removes unneeded toolboxes from current geoprocessing object
Vamos começar com alguns detalhes desta classe:
Em primeiro lugar, temos os tradicionais import x. Eles são responsáveis por disponibilizar outras bibliotecas ao nosso código. Note que importamos o módulo arcgisscripting.
Logo depois, temos uma lista dos aliases que cada toolbox possui no Python. É necessário adicionar uma toolbox ao objeto geoprocessing para que se tenha acesso às ferramentas da mesma - o que pode ser feito de dois jeitos, pelo caminho da toolbox (C:\Program Files\...\ArcGis\Toolbox.tbx) ou pelo seu apelido. A primeira maneira é útil para adicionar toolboxes customizadas, que não tem apelido. A segunda maneira é mais prática para adicionar as toolboxes tradicionais.
O construtor da classe toma dois parâmetros obrigatórios e um opcional para inicializar a classe. O workspace é a pasta onde iremos trabalhar - ele poderia ser também um geodatabase, mas neste caso, uma pasta. toolboxList é uma lista com os apelidos das toolboxes que queremos adicionar ao nosso objeto de geoprocessing. O parâmetro adicional é se você deseja que os resultados do objeto geoprocessing sejam escritos por cima dos anteriores (caso tenham o mesmo nome) e é por default, falso.
O construtor é bastante simples. Ele cria um objeto geoprocessing, utilizando a versão 9.3 como opção (ajuste para sua versão caso necessário - mas não garanto que funcione na 9.2 - já que vários métodos como ListDatasets, têm uma resposta diferente do que
na versão 9.3), define qual é o workspace inicial e adiciona as toolboxes relevantes.
A forma de uso é a seguinte:
g = geoprocessorWrapper.geoprocessorWrapperClass(r"C:\",["analysis","management","lr"])
#ou
g = geoprocessorWrapper.geoprocessorWrapperClass(r"C:\",["analysis","management","lr"],true)
# para acessar o geoprocessor do nosso wrapper, use:
listaDeFeatureClasses = g.gp.ListFeatureClasses()
for x in listaDeFeatureClasses:
print x.FeatureType
Bem simples né? Temos um método também para mudar de workspace, sem necessitar de criarmos uma nova ferramenta. O outro método disponível é para remover toolboxes que não precisamos. Um método aqui poderia ser facilmente criado para adicionar novas toolboxes ao objeto. Alguém se arrisca?
Com esta classe podemos fazer quaisquer operações, mas utilizaremos uma outra classe para realizar todo o trabalho sujo. Lembra-se do código do post passado? Temos disponível em nossa máquina um arquivo .zip extraído em uma pasta qualquer, correto?
Vamos à classe geodatabaseUpdateTask.
import os, sys
class geodatabaseOperationClass():
def __init__(self,geoprocessor,inputShapefile,outputGeodatabase,outputFeatureDataset,outputFeatureClass):
self.geoprocessorWrapperClass = geoprocessor
self.inputShapefile = inputShapefile
self.outputGeodatabase = outputGeodatabase
self.outputFeatureDataset = outputFeatureDataset
self.outputFeatureClass = outputFeatureClass
self.processStage = 0
self.stages = ["Testes de conformidade",
"Deleçãoo de Feature Class",
"Cópia de Shapefile",
"Atualização Completa"]
def getProcessStage(self):
return self.stages[self.processStage]
def testGeodatabase(self):
#workspace definido pelo geoprocessor
return self.outputGeodatabase in self.geoprocessorWrapperClass.gp.ListWorkspaces(self.outputGeodatabase,"ALL")
def testFeatureDataset(self):
#adaptando workspace
self.geoprocessorWrapperClass.gp.Workspace += "\\" + self.outputGeodatabase
return self.outputFeatureDataset in self.geoprocessorWrapperClass.gp.ListDatasets(self.outputFeatureDataset,"ALL")
def testFeatureClass(self):
#adaptando workpace
self.geoprocessorWrapperClass.gp.Workspace += "\\" + self.outputFeatureDataset
return self.outputFeatureClass.gp.Workspace in self.geoprocessorWrapperClass.gp.ListFeatureClasses(self.outputFeatureClass,"ALL")
def testAllObjetcs(self):
if self.testGeodatabase() and self.testFeatureDataset() and self.testFeatureClass():
self.processStage = 1
return True
else:
self.processStage = 0
return False
def deleteFeatureClass(self,featureClass):
try:
self.geoprocessorWrapperClass.gp.Delete_management(featureClass)
except:
print self.geoprocessorWrapperClass.gp.getmessages()
def copyFeatures(self,inputShapefile,outputFeatureClass):
try:
self.geoprocessorWrapperClass.gp.CopyFeatures_management(inputShapefile,outputFeatureClass)
except:
print self.geoprocessorWrapperClass.gp.getmessages()
def updateFeatureClass(self):
try:
if self.testAllObjects:
self.processStage += 1
print self.getProcessStage()
self.deleteFeatureClass(self.outputFeatureClass)
self.processStage += 1
print self.getProcessStage()
self.copyFeatures(self.inputShapefile,self.outputFeatureClass)
self.processStage += 1
print self.getProcessStage()
except:
print self.geoprocessorWrapperClass.gp.getmessages()
Temos os tradicionais import no cabeçalho de nosso arquivo e logo depois o construtor da classe.
Nosso construtor tem os seguintes parâmetros: geoprocessor (um objeto do tipo geoprocessorWrapper), o caminho para o shapefile à ser carregado no banco de dados, o geodatabase de destino, o featureDataset de destino e a FeatureClass de destino.
Você pode ver que construí uma lista de estágios que temos de passar antes de atualizar a FeatureClass. O estágio testes de conformidade vão garantir que os objetos existam no geodatabase e não ocorram erros. Esta etapa pode ser customizada, caso a FeatureClass não exista, crie a mesma, somente importando os dados - também deixo isto para o usuário interessado! Lembre-se que temos de passar um objeto geoprocessorWrapper com um workspace, uma pasta. Neste caso em específico, deve-se passar apenas pastas, pois definimos o geodatabase em outras áreas.
Os testes cuidam da mudança de workspace e asseguram que a featureClass exista. Perceba que todo o trabalho é realizado dentro desta classe, nas funções:
- deleteFeatureClass()
- copyFeatureClass()
Uma função resume todo o processo: updateFeatureClass(). Veja que ela não tem parâmetros, pois usa os parâmetros setados no construtor. À medida que a mesma progride, atualiza o status do processo e informa ao usuário.
Forma de uso:
gp = geoprocessorWrapper.geoprocessorWrapperClass(r"C:\",['management']) geoOperation = geodatabaseOperation.geodatabaseOperationClass(gp,r"C:\shapefile.shp","teste.mdb","dnpm","dnpm_brasil") geoOperation.updateFeatureClass()
Lembrem-se que o restante do código (buscar o arquivo na net, dezipar, etc) está no post anterior. Como prometi, aqui vai a classe LogHandler.
E ae pessoal? Dúvidas?
Podem ver que o Python dá muito poder ao framework de geoprocessing do ArcGIS e é muito simples.
Um abraço
George
Funções PostGIS #3
Boa tarde pessoal!
Vamos falar um pouco hoje das funções de análise espacial e medições. Antes disso, o blog alcançou +50 postagens essa semana. Parabéns para nós!
ST_Area()
Esta função é bastante simples. Ela retorna a área de um polígono ou multipolígono.
-- assinatura
-- SELECT ST_Area(geometria)
SELECT ST_Area(
ST_GeomFromText(('POLYGON((0 0, 1 0,1 1,0 1,0 0))')))
ST_Perimeter()
Outra função bastante simples, de um único argumento. O argumento deve ser uma geometria do tipo polígono. Se você passar uma LINESTRING, o PostGIS irá retornar 0. Veja ST_Length() para LINESTRINGs.
-- assinatura
-- SELECT ST_Area(geometria)
SELECT ST_Perimeter(
ST_GeomFromText(('POLYGON((0 0, 1 0,1 1,0 1,0 0))')));
-- só funciona com polígonos. user ST_Length()
SELECT ST_Perimeter(
ST_GeomFromText('LINESTRING(0 0, 1 0, 2 1, 2 2, 3 2)'));
ST_Perimeter2D()
Calcula o perímetro considerando apenas as coordenadas X e Y de um polígono.
-- assinatura
-- SELECT ST_Perimeter2D(geometria)
-- note que nosso polígono é 3D, possui Z.
SELECT ST_Perimeter2D(
ST_GeomFromText(('POLYGON((0 0 1, 1 0 1,1 1 2,0 1 3,0 0 1))')));
ST_Perimeter3D()
Calcula o perímetro de um polígono levando em conta as coordenadas Z. Veja que nosso polígono anterior, com a coordenada Z, ST_Perimeter3D() nos dá um retorno diferente.
-- assinatura
-- SELECT ST_Perimeter3D(geometria)
-- note que o polígono é 3D, possui Z.
SELECT ST_Perimeter3d(
ST_GeomFromText(('POLYGON((0 0 1, 1 0 1,1 1 2,0 1 3,0 0 1))')));
ST_Length()
Calcula o comprimento de uma LINESTRING. Simples e direto
. Esta função calcula o comprimento de uma linha em duas dimensões.
-- assinatura
-- SELECT ST_Length(geometria)
SELECT ST_Length(
ST_GeomFromText('LINESTRING(0 0, 1 0, 2 1, 3 3)'));
ST_Length2D()
Exatamente igual à função acima. É apenas um apelido para ST_Length().
ST_Length3D()
Esta função funciona exatamente como ST_Perimeter3D. Mas para LINESTRINGs. Esta função leva em conta as coordenadas no eixo Z de uma geometria.
-- assinatura
-- SELECT ST_Length3D(geometria)
SELECT ST_Length3D(
ST_GeomFromText('LINESTRING(0 0 1, 0 0 0, 1 0 2, 2 3 1)'));
ST_Centroid()
Esta função calcula o centro de massa de uma geometria. Para pontos é apenas uma média aritmética de seus conjuntos de coordenadas. Para LINESTRINGS, é o resultado de uma média ponderada do comprimento de seus segmentos e para polígonos o centro de massa do mesmo.
É possível aplicar esta função em qualquer tipo de geometria e em coleções genéricas (GEOMETRY_COLLECTIONs - conjuntos de geometrias de diversos tipos), sendo o resultado equivalente ao centróide do conjunto de geometrias de maior dimensionalidade (pontos são 0-dimensionais, linhas unidimensionais, polígonos bidimensionais). Ou seja, se temos um conjunto de pontos, linhas e polígonos, o centróide será igual ao centróide do conjunto de polígonos.
Esta função é importante. Diversas vezes a maneira mais prática e fácil de se transformar dados é através do centróide e preparar dados para estatísticas espaciais.
-- assinatura
-- SELECT ST_Centroid(geometria)
SELECT ST_AsText(
ST_CENTROID(
ST_GeomFromText('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))')));
SELECT ST_AsText(
ST_CENTROID(
ST_GeomFromText('LINESTRING(0 0, 1 0, 1 1)')));
SELECT ST_AsText(
ST_CENTROID(
ST_GeomFromText('MULTIPOINT((0 0),(5 8),(10 1))')));
Aqui estão os resultados das chamadas acima.
ST_Intersects()
Outra função importante. Esta função simplesmente teste se geometria A interseciona geometria B. Esta função não retorna a real interseção das duas partes, mas somente se elas se intersecionam ou não, true ou false. ST_Intersects pode ser utilizado com qualquer par de geometrias.
-- assinatura
-- SELECT ST_Intersercts(geometria_A,geometria_B);
-- retorna true
SELECT ST_Intersects(
ST_GeomFromText('POLYGON((0 0, 1 1, 1 0, 0 1, 0 0))'),ST_GeomFromText('LINESTRING(0 0, 2 2, 1 1)'));
-- retorna false
SELECT ST_Intersects(
ST_GeomFromText('POLYGON((0 0, 1 1, 1 0, 0 1, 0 0))'),ST_GeomFromText('LINESTRING(10 10, 20 10)'));
ST_Intersection()
Esta função é parecida com a ST_Intersects, mas esta retorna de fato a interseção entre as duas geometrias. Ambas as funções são computacionalmente intensivas, portanto cuidado ao utilizá-la em um sistema em produção, em views e outras coisas deste tipo. Esta função tem uma particularidade: podemos usar como parametro qualquer tipo de geometria, mas o resultado sempre virá no formato de geometria com menor dimensionalidade.
Exemplo: se computarmos a interseção entre dois polígonos, teremos como resultado um polígono (ou nulo). Se computarmos a interseção entre um polígono e diversas linhas, o resultado será uma LINESTRING obrigatoriamente. Porque? É matemático, a interseção de um polígono com um ponto sempre terá como resultado um ponto. Os resultados estão em verde.
Veja:
Podemos ter como resultado da interseção entre duas LINESTRINGs um conjunto de pontos ou uma LINESTRING (quando dois segmentos são coincidentes).
Vamos à assinatura da função:
-- assinatura
-- SELECT ST_Intersection(geometria_A,geometria_B);
-- POLYGON e LINESTRING
SELECT ST_AsText(ST_Intersection(
ST_GeomFromText('POLYGON((0 0,1 0, 1 1,0 1,0 0))'),
ST_GeomFromText('LINESTRING(0 0,.5 .5,2 2,3 3)')));
-- POLYGON E PONTO
SELECT ST_AsText(ST_Intersection(
ST_GeomFromText('POLYGON((0 0,1 0, 1 1,0 1,0 0))'),
ST_GeomFromText('POINT(.2 .2)')))
-- POLYGON e POLYGON
SELECT ST_AsText(ST_Intersection(
ST_GeomFromText('POLYGON((0 0,1 0, 1 1,0 1,0 0))'),
ST_GeomFromText('POLYGON((.5 .5,1.5 .5,1.5 1.5,.5 1.5,.5 .5))')))
-- LINESTRING e LINESTRING
SELECT ST_AsText(ST_Intersection(
ST_GeomFromText('LINESTRING(0 0,1 1,3 2,6 6)'),
ST_GeomFromText('LINESTRING(-1 -1,.5 .5,3 4,5 6)')))
Os resultados em formato texto são os seguintes:
Uma nota importante: pontos não se intersecionam. Ou eles são coincidentes ou não.
ST_Overlaps
Esta função é parecida em funcionamento com a ST_Intersects. Na verdade ela realiza a mesma operação que ST_Intersects, mas leva em consideração se um objeto não está contido plenamente dentro do outro. Esta função opera com qualquer tipo de geometria, mas presta atenção na dimensionalidade de cada uma: uma geometria de menor dimensionalidade está sempre contida na geometria de maior dimensionalidade, portanto, não sobrepõe a de maior dimensionalidade.
Exemplo: geometria_a é um ponto e geometria_b é um polígono. Se perguntado se ST_Overlaps(geometria_a,geometria_b), o PostGIS vai retornar falso, pois não são da mesma dimensionalidade. Se geometria_a é um polígono e geometria_b também, a operação pode retornar verdadeiro, caso a sobreposição ocorra.
-- assinatura
-- SELECT ST_Overlaps(geometria_a,geometria_b)
-- [1]
-- mesma dimensionalidade: estas geometrias podem se sobrepor.
SELECT ST_Overlaps(
ST_GeomFromText('LINESTRING(0 0,1 1,3 2,6 6)'),
ST_GeomFromText('LINESTRING(-1 -1,.5 .5,3 4,5 6)'))
-- [2]
-- mesma dimensionalidade: estas geometrias podem se sobrepor.
SELECT ST_Overlaps(
ST_GeomFromText('POLYGON((0 0,1 0,1 1,0 1,0 0))'),
ST_GeomFromText('POLYGON((.5 .5,1.5 .5,1.5 1.5,.5 1.5,.5 .5))'))
-- [3]
-- dimensionalidade diferente: estas geometrias não podem se sobrepor (mesmo que se intersecionem)
SELECT ST_Overlaps(
ST_GeomFromText('LINESTRING(0 0,1 1,3 2,6 6)'),
ST_GeomFromText('POINT(0 0)'));
-- [4]
-- dimensionalidade diferente: estas geometrias não podem se sobrepor (mesmo que se intersecionem)
SELECT ST_Overlaps(
ST_GeomFromText('POLYGON((0 0,1 0,1 1,0 1,0 0))'),
ST_GeomFromText('POINT(0 0)'));
ST_Covers()
Esta função retorna verdadeiro caso nenhum ponto da geometria_b se encontre fora da geometria_a.
-- assinatura
-- SELECT ST_Covers(geometria_a,geomtria_b);
-- geometria_a cobre geometria_b? verdadeiro
SELECT ST_Covers(
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'),
ST_GeomFromText('POLYGON((.5 .5,1.5 .5,1.5 1.5,.5 1.5,.5 .5))'));
-- geometria_a cobre geometria_b? verdadeiro, todos os pontos de geometria_b estão contidos em a
SELECT ST_Covers(
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'),
ST_GeomFromText('POINT(1 1)'));
-- geometria_a cobre geometria_b? falso. geometria_a é menor que geometria_a.
SELECT ST_Covers(
ST_GeomFromText('POLYGON((.5 .5,1.5 .5,1.5 1.5,.5 1.5,.5 .5))'),
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'));
-- geometria_a cobre geometria_b? falso. geometria_a cobre geometria_b parcialmente (note o segundo ponto, em 100 100)
SELECT ST_Covers(
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'),
ST_GeomFromText('MULTIPOINT((1 1),(100 100))'));
ST_Within()
Esta função é similar em funcionamento à ST_Covers(). A diferença aqui é que esta retorna positivo se estiver completamente dentro de B.
-- assinatura
-- SELECT ST_Within(geometria_a,geometria_b)
-- [1]
-- geometria_a está completamente dentro de geometria_b? verdadeiro
SELECT ST_Within(
ST_GeomFromText('POINT(5 5)'),
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'));
-- [2]
-- geometria_a está completamente dentro de geometria_b? verdadeiro
SELECT ST_Within(
ST_GeomFromText('LINESTRING(5 5, 2 3, 1 0)'),
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'));
-- [3]
-- geometria_a está completamente dentro de geometria_b? verdadeiro
SELECT ST_Within(
ST_GeomFromText('POLYGON((1 1,2 1,2 2,1 2,1 1))'),
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'));
-- [4]
-- geometria_a está completamente dentro de geometria_b? falso. geometrias de dimensionalidade menor não contém geometrias de maior
-- dimensionalidade
SELECT ST_Within(
ST_GeomFromText('POLYGON((1 1,2 1,2 2,1 2,1 1))'),
ST_GeomFromText('MULTIPOINT((0 0),(10 0),(10 10),(0 10),(0 0))'));
-- [5]
-- geometria_a está completamente dentro de geometria_b? falso. A não está inteiramente dentro de B
SELECT ST_Within(
ST_GeomFromText('MULTIPOINT((5 5),(100 100))'),
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'));
Por agora é só pessoal. No próximo post vou tentar explicar melhor sobre a dimensionalidade de cada tipo de geometria e os porquês estas funções se comportam desta maneira.
Espero que tenham gostado.
Abraços
George R. C. Silva
Funções PostGIS #2
Boa tarde senhores e senhoras,
Continuando nossa peregrinação pelas funções do PostGIS, irei começar explicar a que usamos no post anterior e não expliquei.
ST_AsText()
Esta função retorna o valor WKT (Well Known Text - especificação OGC) da geometria. Esta função é útil pois lhe mostra algo um pouco mais inteligível do que o WKB (Well Known Byte).
Ela tem como retorno o WKT sem o código SRID da geometria especificada. Se utilizada em um comando SELECT, ela irá realizar esta conversão em todos os objetos válidos da coluna especificada. Ela é uma função de output.
-- assinatura -- SELECT ST_AsText(the_geom) SELECT nm_equipamento_urbano, ST_AsText(the_geom);
Vamos falar um pouco das funções construtoras de geometria. Por que elas são importantes? É uma maneira de se converter dados de coordenadas, em objetos geográficos, representados no banco de dados por uma string com o valor WKB. Vamos começar pela mais simples: ST_Point()
ST_Point()
Esta é a mais simples das funções construtoras. Ela tem como entrada apenas um X e Y. Esta função esta de acordo com a norma OGC. Na verdade, o que ela faz é chamar a função ST_MakePoint() passando como entrada apenas os eixos X e Y.
-- assinatura -- SELECT ST_Point(coordenada_x, coordenada_y); SELECT ST_Point(-42.5,-19.2);
O resultado é retornado em WKB. Veja:
ST_MakePoint()
A função MakePoint é mais completa que a ST_Point, pois permite a utilização de até quatro eixos de coordenadas, X, Y, Z e M. Esta função não está de acordo com a norma OGC mas é uma forma de se trabalhar no PostGIS. O problema do uso da mesma é no momento de integração com outros softwares OGC compliant. Fique atento!
-- assinaturas -- SELECT ST_MakePoint(x,y); -- SELECT ST_MakePoint(x,y,z); -- SELECT ST_MakePoint(x,y,z,m); SELECT ST_MakePoint(-10,-1,300,1);
O resultado desta função também é trazido em WKB.
Existem funções deste tipo para todos os tipos de geometria. Vamos mostrar as outras:
ST_MakeLine()
Vamos complicar um pouquinho. Da mesma maneira que podemos construir pontos, podemos construir linhas. Existem três maneiras de se utilizar esta função: uma é com o resultado agregado de uma consulta, um array de pontos, ou dois pontos. Vou mostrar as três maneiras.
-- assinatura -- SELECT ST_MakeLine(geometry_set); -- SELECT ST_MakeLine(ponto1,ponto2); -- SELECT ST_MakeLine(array_pontos); -- resultado agregado de consulta SELECT l.setor, ST_AsText(ST_MakeLine(l.the_geom)) FROM (SELECT codsetor as "setor", the_geom FROM equipamento_urbano) as l GROUP BY l.setor; -- dois pontos SELECT ST_AsText(ST_MakeLine(ST_MakePoint(-1,-1),ST_MakePoint(-2,-2))) -- array de pontos SELECT ST_AsText(ST_MakeLine(ARRAY[ST_MakePoint(-10,-1),ST_MakePoint(-5,0),ST_MakePoint(-10,2),ST_MakePoint(-19,-20),ST_MakePoint(-1,0)])); -- note que a abertura do array se faz com os colchetes!
Vejamos os resultados, respectivamente: agregado, dois pontos e array de pontos. Uma nota: utilizei ST_AsText nas funções para facilitar a visualização do resultado. Todos os resultados podem ser facilmente testados, com exceção do agregado. Caso alguém tenha interesse, posso lhe enviar a tabela em formato .sql para conferência
Vamos complicar mais um pouquinho?
ST_MakePolygon()
Esta função constrói polígonos. Para um polígono ser um polígono ele deve ter uma clara distinção de seu interior com seu exterior. A única maneira de delimitarmos isto é tenho uma LINESTRING fechada, ou seja, o último vértico deve ser igual ao primeiro. Um polígono também pode ter holes ou seja, buracos. Eles também podem ser construídos aqui. Veja só:
-- assinatura -- SELECT ST_MakePolygon(linestring_fechada); -- SELECT ST_MakePolygon(linestring_fechada,array_poligonos_interiores); SELECT ST_AsText(ST_MakePolygon( ST_MakeLine(ARRAY[ ST_MakePoint(0,0), ST_MakePoint(1,0), ST_MakePoint(1,1), ST_MakePoint(0,1), ST_MakePoint(0,0)])))
Veja o resultado:
Todas estas funções são extremamente úteis, permitindo o usuário à manipular as geometrias de diversas tabelas para construir objetos temporários ou views para visualização em softwares de SIG. Lembrem-se que você não precisa utilizar ST_MakePoint() para construir polígonos ou linhas. Você pode utilizar a agregados e resultados de consultas como parâmetros de entrada para estas funções.
ST_GeomFromText
Esta é a rainha das funções construtoras de geometria. Com ela é possível construir qualquer geometria, desde que você tenha o WKT das mesmas. Mão na roda. A segunda assinatura lhe permite especificar um SRID.
-- assinatura
-- SELECT ST_GeomFromText('wkt');
-- SELECT ST_GeomFromText('wkt',srid);
SELECT ST_AsText(ST_GeomFromText('LINESTRING(0 0, 1 0, 2 1, 2 2, 3 1, 3 3, 0 1, 0 0)'))
SELECT ST_AsText(ST_GeomFromText('POLYGON((0 0, 1 0,1 1,0 1,0 0))'));
Agora vem a pergunta: porque utilizamos dois pares de parênteses quando construímos um polígono e apenas um quando construímos uma linestring? Lembra quando construímos um polígono, temos a opção de passar uma array de polígonos internos, os famosos holes? Então, o segundo set de parênteses corresponde à possibilidade de inserir este array de polígonos. Não se esqueça, para polígonos e geometrias multi*, dois sets de parênteses são necessários.
Hoje vimos um pouco sobre as funções construtoras de geometrias no PostGIS. O que acharam?
Abraços
George R. C. Silva
Agricultura Familiar e Geoprocessamento
Olá Pessoal!
Hoje gostaria de comentar com vocês sobre um trabalho elaborado pela também Tecnóloga em Geoprocessamento, Julie Eugênio.
Há algum tempo ela preparou um projeto de gerenciamento de atividades de agricultura familiar fazendo uso de técnicas de Geoprocessamento.
O objetivo principal da pesquisa dela foi o desenvolvimento de uma aplicação, com base em técnicas de Geoprocessamento, para apoiar as atividades de um projeto voltado à agricultura familiar sustentável denominado “Cinturão Verde”, inserido no programa de microcrédito “Empreender-JP”, no município de João Pessoa, capital do Estado da Paraíba.
O mapa abaixo mostra a localização da área de estudo.
Durante a construção da aplicação SIG integrada a um Banco de Dados Geográficos deu-se ênfase ao uso de tecnologias livres, com destaque para o Quantum Gis (QGis) e PostgreSQL/PostGis.
Na parte escrita do trabalho desenvolvido foi detalhada toda a metodologia empregada. A qual está resumida na figura abaixo.
O trabalho foi extremamente elogiado pelos responsáveis técnicos da prefeitura de João Pessoa. Você pode fazer o download do trabalho completo a partir do link abaixo, que traz o tema da monografia escrita com base nesse projeto.
Espero que tirem proveito de mais essa demonstração da potencialidade do uso de tecnologias livres para Geoprocessamento.
Abraços.
--
Anderson Medeiros
Tecnólogo em Geoprocessamento
Padrões Open Geospatial Consortium – Parte 2
Hoje vamos dar sequência à postagem sobre padrões da OGC. Na primeira postagem dessa série vimos o que é o OGC e alguns comentários sobre as especificações WMS, WFS e WCS.
Agora vamos tecer algumas considerações sobre os padrões GML, KML e SLD.
Geographic Markup Language (GML)
O objetivo da GML é oferecer um conjunto de regras com as quais um usuário pode definir sua própria linguagem para descrever seus dados, assim utilização do padrão GML permite a interoperabilidade entre dados geográficos. Definindo como será o armazenamento e transporte de informações geográficas, incluindo propriedades espaciais e não espaciais das entidades geográficas.
O GML é usado também em serviços WFS para trocar feições entre clientes e servidores, servindo, portanto como suporte ao serviço WFS.
Keyhole Markup Language (KML)
A linguagem XML (eXtensible Markup Language), como o próprio nome já diz, pode ser extendida ou ampliada. O próprio padrão KML da OGC é uma extensão de um XML utilizado pelo Google para tornar possível a visualização de dados geográficos nos seus famosos programas: Google Earth e Google Maps.
A estrutura do KML é baseado em tags como ocorre com arquivos HTML e XML comuns. Estas tags do KML tem os nomes e atributos usados para objetivos de exibição específicas. Em termos simples, notamos que o Google Earth e e o Google Maps funcionam pra os arquivos KML como como navegadores.
O KML depende de outros padrões para gerar a visualização de dados geográficos, pois na sintaxe do KML proveniente de um serviço de internet existe uma requisição WMS.
Hoje, o OGC e o Google trabalham em conjunto para aprimorar a implementação do KML, além de manter a comunidade informada das atualizações e avanços em seu projeto.
Styled Layer Descriptor (SLD)
A especificação SLD se refere à um arquivo XML que representa graficamente entidades geográficas (textos, pontos, objetos lineares ou polígonos.). Na linguagem SLD podem ser definidas regras que agrupam objetos em diferentes categorias e definindo para cada grupo um estilo diferente, por exemplo a simbologia de um WMS (estabelecer cores e rótulos) a partir de regras a serem definidas.
Programas de SIG, como o Udig, geram arquivos SLD de forma automática. Para executar este processo, basta adicionar uma camada WFS à uma visualização do Udig, fazer uma requisição ao servidor através de uma URL adequada e depois criar temas e rótulos de acordo com as necessidades da aplicação.
Enfim, esta foi uma breve consideração sobre alguns dos principais padrões da OGC (WMS, WFS, WCS, GML, KML e SLD). Espero que tenham gostado. Qualquer dúvida, entre em contato deixando um comentário.
Um Abraço e até a próxima postagem
--
Anderson Medeiros
Tecnólogo em Geoprocessamento
Consultor em Geotecnologias Livres
Criação de Templates para PostGIS
Olá a todos, muito bom está por aqui novamente.
Hoje vou falar para vocês de um assunto que na minha graduação o Prof. Marcello Benigno[1] sempre "enchia o saco" repetindo e repetindo e repetindo... a criação de templates para o banco de dados (no nosso caso, PostgreSQL[2]). Templates nada mais são que modelos pré-definidos de banco de dados, que aumentam a produtividade na criação de novos bancos. Neles nós colocamos características comuns aos bancos de dados que serão criados e só associamos os novos bancos a eles.
Como exemplo, hoje a tarde precisei recriar um template_postgis para que pudesse sincronizar uma aplicação geodjango a ele (A aplicação poderá ser vista em breve na edição número 1 da revista Geo.NET), então fiz da seguinte forma:
Como root chamei o postgres:
# su postgres
Após entrar no root postgres, mandei criar um novo banco de dados chamado template_postgis:
$ createdb -U postgres template_postgis
A opção "-U" do comando createdb se refere ao usuário que será dono do banco, ou do template, como é nosso caso (Para maiores informações sobre outras opções do comando createdb digite $ man createdb). Para esta versão, o root postgres é por default o dono das tabelas, bancos e templates criados, por tanto, não faz necessário informá-lo como usuário.
Para que seja possível rodar as funções da extensão espacial postgis, é necessário a criação da linguagem procedural plpgsql. Por meio desta, é possível rodar as funções contidas nos arquivos lwpostgis.sql e ref_spatial_sys.sql, arquivos estes que contem funções que resolvem referência espacial, tipos de geometrias, sistemas de coordenadas e etc. Para criar a linguagem, basta usar o comando:
$ createlang -d template_postgis -U postgres plpgsql
A opção "-d" informa para qual banco de dados, ou template será criada a nova linguagem procedural (Para maiores informações, consulte $ man createlang).
Depois de ter criado a linguagem, basta importar os arquivos lwpostgis.sql, lwpostgis_upgrade.sql e spatial_ref_sys.sql. Para isso usaremos o terminal interativo do pgsql através do comando:
$ psql -d template_postgis -f lwpostgis.sql
$ psql -d template_postgis -f lwpostgis_upgrde.sql
$ psql -d template_postgis -f spatial_ref_sys.sql
Neste ponto é importante tomar nota de que, se o usuário não estiver no path onde estão os arquivos acima, lhe será retornado um erro. Para evitar tal erro, consulte a documentação para a sua distribuição.
Para confirmar se tudo correu bem, entre no template e faça uma consulta às tabelas da seguinte forma:
$ psql -d template_postgis
template_postgis=# \dt Lista de relações Esquema | Nome | Tipo | Dono ---------+------------------+--------+---------- public | geometry_columns | tabela | postgres public | spatial_ref_sys | tabela | postgres (2 registros)
Observe que dentro do template_postgis foram criadas as tabelas espaciais, e que por default o dono das mesmas é o root postgres. Agora ficou simples, pois sempre que for preciso criar um db com extensão espacial, basta rodar o comando:
$ psql -T template_postgis <nome_novo_db>
Este novo db será criado, e dentro dele já estarão inseridas as tabelas espaciais.
Fácil não é?
Abraço a todos.
Referencias:
[1] Prof. Marcello
[2] PostgreSQL
Vicente Martins.
Padrões Open Geospatial Consortium – Parte 1
Olá Pessoal!
Hoje vou abordar um tema de extremo interesse para quem trabalha com Geotecnologias, livres ou não: Os padrões do Open Geospatial Consortium (OGC). Nesta primeira parte da série vamos entender o que é o OGC e os padrões WMS, WFS e WCS.
O Open Geospatial Consortium (OGC)
Desde seus primórdios em 1994 a instituição, que se chamava OpenGis Consortium, tem o com o objetivo de criar especificações de interfaces e padrões de intercâmbio de dados geoespaciais.
O OGC é hoje uma entidade internacional com mais de 350 companhias, agências governamentais e universidades, que tem o intuito de promover o desenvolvimento de tecnologias que facilitem a interoperabilidade entre diferentes sistemas que trabalhem com informação e localização espacial.
Asim, o OGC define especificações, ou padrões (como o WMS, WFS, WCS, etc) aos quais produtos e serviços precisam se adequar para que a interação entre diversas fontes de dados e informações espaciais seja facilitada, independente de fatores como a plataforma utilizada. A partir de agora vamos começar a compreender três das especificações do OGC.
Web Map Service (WMS)
O padrão WMS define um serviço para a produção de mapas que serão apenas uma representação visual dos dados espaciais e não os dados em si. Estas representações serão geradas no formato de imagem, como JPEG, PNG e GIF ou em formato vetorial, como o Scalable Vector Graphics (SVG).
Este padrão especifica como o cliente deve requisitar as informações para o servidor e como este deve responder ao cliente. As operações WMS podem ser realizadas a partir de um navegador comum que fará a submissão das requisições sob a forma de uma URL.
É importante destacarmos que o conteúdo da URL dependerá da operação solicitada. Em outras palavras, através da URL, indica-se qual a informação que deve ser exibida (região geográfica e dado de interesse), bem como o sistema de referência espacial, além das características da imagem de saída (altura e largura).
Web Feature Service (WFS) e Web Coverage Service (WCS)
A especificação de serviço WFS define um serviço para que clientes possam recuperar feições especiais em formato GML (você terá mais detalhes sobre GML na segunda parte desta série sobre o OGC). O WFS pode ser implementado pelo servidor em duas versões:
- Básica - Neste caso, basicamente funções de consulta ficam disponíveis, ou
- Transacional - Implementa o serviço completo, incluindo operações de inserção, deleção, edição e, claro, consulta à objetos espaciais.
Assim, podemos afirmar que o WFS apresenta maior interatividade que o WMS, pois este primeiro possibilita não apenas a visualização das feições geográficas, mas também sua manipulação.
Já o padrão WCS define o acesso aos dados que representam fenômenos com variação contínua no espaço. Este serviço é especificado para
tratamento de dados modelados como geocampos.
Breves Comparações entre WMS, WFS e WCS
Uma diferença marcante entre o WMS e o WCS é que este último retorna ao usuário dados sobre a semântica original dos fenômenos representados, ao invés de imagens. Em outras palavras, o WCS fornece os dados disponíveis de imagens, juntamente com detalhes descritivos sobre as mesmas, como a grade.
Já em uma comparação entre o WFS e o WCS notamos que o primeiro retorna os chamados geo-objetos, já no caso do WCS retorna geocampos, conforme mencionado anteriormente.
Assim, chegamos a conclusão de que o serviço WCS pode ser utilizada para enquadrar aplicações do Sensoriamento Remoto (pois em geral o SR está relacionado com geocampos) no contexto da interoperabilidade.
Conclusão e o que vem por ai
Dessa nossa breve análise sobre estes três dos diversos padrões do OGC podemos notar que cada um terá sua aplicabilidade, sendo interpretado e explorado de maneira diferente dependendo dos objetivos de seu projeto.
Programas como o gvSIG e o Udig permitem interações com webservices que sigam as especificações WMS, WFS e WCS.
Na segunda parte desse post veremos mais sobre as padrões da OGC, com ênfase nas especificações GML, SLD e KML.
Fiquem na expectativa...
--
Anderson Maciel Lima de Medeiros
Tecnólogo em Geoprocessamento
shp2pgsql: Você conhece esta fantástica ferramenta?
Olá pessoal, boa noite.
É tempo de retomar a implementação de antigos projetos no trabalho (isso soa estranho né?), para poder mostrar que existem ferramentas livres, super-poderosas e que trazem respostas a várias perguntas de "onde" estão os problemas.
Neste trabalho que estou reiniciando na Companhia, estamos implementando um DB (Data Base) que guardará um monte de informações que estavam soltas nas mãos de todos os seus "donos".
Com estas informações, será possível fazer várias análises, inclusive espaciais, e diponibilizá-las em um ambiente interno [intranet] a partir de uma aplicação WebGIS, o que facilitará o acesso a informação de interesse comum, bem como facilitará o planejamento das decisões a serem tomadas. É sim um projeto extravagante, uma vez que um "novato" vai mexer com o lugar e "poder" de muita gente lá dentro, mas em contra-partida, tenho certeza que isso trará melhorias para a Companhia, o que é na verdade o objetivo do mesmo.
Para vocês hoje, trago uma ferramenta que a muito tempo não utilizava, mas que é extremamente importante quando falamos de PostGIS: shp2pgsql. O Anderson a um tempo atrás disponibilizou um mini-tutorial no ClickGeo[1], que inclusive serviu de fonte de pesquisa para mim, e que recomendo para quem quer utilizar shp2pgsql. Algumas outras pesquisas na documentação oficial da extensão[2], mais algumas conversas com o próprio Anderson e outros amigos da área, me vi "obrigado" a compartilhar mais um pouco de conhecimento.
A shp2pgsql, como o prórpio nome sugere, é um aplicativo que transforma arquivos shapefile da ESRI em sql, em que os antigos dados em formato shapefile são inseridos dentro das tabelas de um Data Base em PostgeSQL/PostGIS da maneira correta.
Para tanto, é necessário conhecer alguns parametros que precisamos informar ao aplicativo. De maneira geral, a utilização do shp2pgsql se dá da seguinte forma:
# shp2pgsql /path/do/shape/dado.shp nome_tabela > nome_arquivo.sql
# psql -d nome_DB -f nome_arquivo.sql
Convenções:
- "#" você precisa estar logado como super-usuário para utilizar esta ferramenta;
- "/path/do/shape/dado.shp" é o caminho onde está guardado o dado em shapefile;
- "psql -d" define o Data Base utilizado;
- "psql - f" executa o arquivo .sql indicado. Talvez seja necessário informar o caminho total do arquivo ".sql", caso não se esteja dentro do path indicado.
Porém, é possível informar alguns parametros para o aplicativo shp2pgsql que facilita a inserção dos dados desejados. Dentre os principais (ao menos para mim, foram os mais utilizados) cito:
-s: Este parametro define o SRID (Spatial Reference System Identifier)que será utilizado.
# shp2pgsql -s <SRID> dado.shp nome_tabela > nome_arquivo.sql
-W: Este parametro informa a codificação em que está o seu Data Base, inserindo os dados na mesma codificação.
# shp2pgsql -s <SRID> -W <encoding> dado.shp nome_tabela > nome_arquivo.sql
Bem, fora estes, o carregador de dados shp2pgsql traz outros parametros de inserção de dados que vale a pena ser consultado. De qualquer forma, é interessante consultar a documentação.
Vou ficando por aqui.
Abraço a todos.
Vicente Martins.
Referências:
[1] ClickGeo - Importando Arquivos Shapefile para PostGIS 8.1 via prompt do DOS
Monografias Geoprocessamento – IFPB
Olá pessoal!
Depois de disponibilizarmos aqui duas monografias dos autores do blog, estou passando pra vocês o endereço da página do Curso Superior de Tecnologias em Geoprocessamento do Instituto Federal de Educação, Ciência e Tecnologia da Paraíba - IFPB.
Como informa o próprio site o curso "forma tecnólogos instrumentalizados com os recursos da Geomática, atuando como agentes de desenvolvimento sustentável do ambiente urbano, a partir de uma visão científico-tecnológica, abrangente e atualizada."
O curso, que oferece cinquenta vagas anuais, é reconhecido pelo MEC desde 2008. A carga horária total é de 2068 horas.
Na seção de "publicações" você tem acesso e permissão de download gratuito, no formato PDF de diversas monografias, que abordam desde assuntos que vão do desenvolvimento de plugins para softwares, passando pelo uso de aplicações SIG e Banco de Dados Geográficos até o Webmapping.
Os trabalhos são de alta qualidade. Conheço pessoalmente a maioria dos autores (afinal, fizemos o mesmo curso). Veja alguns dos temas que você encontrará no site:
Gerenciamento de Atividades de Agricultura Familiar Sustentável com Base em Técnicas de Geoprocessamento, no Município de João Pessoa/PB.
Utilização de Técnicas de Geoprocessamento na Identificação de Locais Críticos de Acidentes de Trânsito.
Geoprocessamento Aplicado ao Planejamento dos Transportes Urbanos.
Geoprocessamento como Suporte à Administração do Agronegócio.
Ortorretificação de Fotografias Áereas de Pequeno Formato Obtidas com Câmara
Digital Convencional.
Proposta para Compartilhamento de Dados Geográficos entre Setores da Prefeitura Municipal de João Pessoa Através do Serviço WMS.
Desenvolvimento de uma Aplicação SIG-WEB Voltada ao Turismo.
E ai? Deu pra sentir o gostinho do que você vai achar lá no site do curso? Não perca tempo, acesse já!
Espero que tenham gostado da dica de hoje.
Um Abraço e até a próxima.
--
Anderson Medeiros
Monografia
Boa noite pessoal,
Muita gente já me pediu e estava sem tempo de colocar online, mas agora vai.
A Construção de um Sistema Geocodificado de Acidentes de Trânsito
Defendi a monografia ano passado e fica como referência para quem tiver interesse.
Tenho certeza que não é perfeita, portanto, se tiverem algumas dúvidas ou enxergarem alguns erros, por favor, entre em contato
Abraços
George



























