sábado, 6 de outubro de 2012

Como definir o tipo dos dados em um CSV no QGis?

Para permitir que o Quantum GIS abra um arquivo do tipo CSV de modo que cada coluna seja formatada adequadamente, é necessário criar um outro arquivo descritor para especificar o tipo de cada uma das colunas que será importada.

Por padrão todos os dados de um CSV são adicionados como uma tabela utilizando o driver OGR que não trata as colunas por tipos diferentes, sendo todas abertas como do tipo String. A solução é criar um arquivo.csvt contendo apenas o tipo de cada coluna, por exemplo:

Para o arquivo de entrada apresentado abaixo, cujo nome é focos_mensal2010.csv


geocod,jan,fev,mar,abr,mai,jun,jul,ago,set,out,nov,dez,anual
2200202,0,0,0,0,0,0,0,0,1,3,0,0,4
3128006,0,0,0,0,0,0,0,0,5,1,0,0,6
4209805,0,0,0,0,0,0,0,0,1,0,1,0,2
4322152,0,0,0,0,0,0,0,1,5,0,0,0,6
1504208,0,0,0,0,2,0,49,385,445,75,27,0,983

tive que criar o arquivo  focos_mensal2010.csvt com o seguinte conteúdo:
"String","Integer","Integer","Integer","Integer","Integer","Integer","Integer","Integer","Integer","Integer","Integer","Integer","Integer"

Caso seja necessário é possível especificar o tamanho dos campos desta forma

"Integer(6)","Real(5.5)","String(22)"
ref:http://underdark.wordpress.com/2011/03/07/how-to-specify-data-types-of-csv-columns-for-use-in-qgis/


sexta-feira, 17 de agosto de 2012

Como criar uma tabela cruzada no Postgresql

 Uma função que ajudou bastante na construção de tabelas para serem apresentadas no site foi a "crosstab" do Postgresql, que deve ser utilizada da seguinte maneira:


create table estatisticas.br_ano_mes as (
select *
from crosstab('select extract(year from data_pas)::text , extract(month from data_pas)::text, count(gid)::text from focos_referencia
        where pais = ''Brasil''
        group by 1,2
        order by 1,2', 'select m from generate_series(1,12) m')

as ct(ano text, jan text, fev text, mar text, abr text,
mai text, jun text, jul text, ago text, set text, out text, nov text,
dez text));


e o resultado é similar a isto:

ANO Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro
1998 0 0 0 0 0 3.551 8.067 35.551 41.974 23.498 6.804 4.449
1999 1.081 1.284 667 717 1.812 3.632 8.758 39.487 36.914 27.014 8.861 4.376
2000 778 562 849 538 2.097 6.275 4.740 22.204 23.293 27.337 8.399 4.465
2001 547 1.059 1.268 1.081 2.090 8.433 6.490 31.887 39.834 31.038 15.639 6.201
2002 1.654 1.570 1.679 1.682 3.818 10.839 10.769 47.266 61.012 52.073 30.356 11.649
2003 3.603 2.353 3.181 1.902 3.871 10.549 19.391 27.666 57.249 43.058 23.010 15.061
2004 2.330 1.210 1.523 1.057 4.339 13.655 17.960 37.354 66.970 39.161 29.557 17.505
2005 4.047 1.349 1.444 1.211 3.027 4.594 13.988 52.504 63.932 48.879 25.589 5.046
2006 1.885 1.350 902 841 1.765 3.137 6.947 25.682 37.144 16.833 12.805 8.024
2007 1.513 1.179 2.289 850 2.184 4.891 7.031 64.431 94.526 32.312 13.095 4.075
2008 2.125 1.275 1.239 1.253 553 1.287 4.507 14.528 39.445 39.264 12.778 4.995
2009 2.848 1.140 1.392 1.078 2.593 2.962 6.599 17.559 29.430 24.202 23.914 9.494
2010 2.851 2.386 2.417 2.200 3.497 3.642 16.646 75.305 85.415 31.489 16.587 6.856
2011 1.416 973 937 1.152 1.985 4.578 8.524 22.477 50.302 18.691 12.222 9.830

quarta-feira, 8 de agosto de 2012

Manipulação de datas em Linux

Para fazer conversão de dia juliano (dia do ano 0-365) para o formato gregoriano (dd-mm-aaaa) deve ser utilizada a seguinte linha de comando:

yyyymmdd=$(date -d "${yyyy}-01-01 + ${ddd} days -1 day" +%Y%m%d)

onde as variáveis yyyy representam o ano de interesse e ddd representa o dia sequencial como por exemplo 221

cdsr@dallas:~/scripts$ yyyymmdd=$(date -d "2012-01-01 + 221 days -1 day" +%Y%m%d)
cdsr@dallas:~/scripts$ echo $yyyymmdd
20120808

Por outro lado converter de dia juliano para dia-mes-ano é mais simples, bastando para isto utilizar o seguinte comando:

date -d 2012-08-08 +%j

terça-feira, 29 de maio de 2012

converção de linha/coluna de uma imagem geotif para lat/long

Depois de pesquisar um pouco como fazer para extrair as coordenadas de um píxel utilizando Python  e GDAL conseguí aproveitar as dicas publicadas em:

fonte: http://stackoverflow.com/questions/2922532/obtain-latitude-and-longitude-from-a-geotiff-file

e testei da seguinte maneira:

>>> from osgeo import gdal
>>> from osgeo.gdalconst import *
>>> import numpy, sys
>>> ds = gdal.Open('/home/fmorelli/testes/b250_EV_250_Aggr1km_RefSB_b0.tif', GA_ReadOnly)
>>> print ds.GetGeoTransform()
(-65.60666969799999, 0.01, 0.0, 11.845001666000002, 0.0, -0.01)
>>> gt = ds.GetGeoTransform()
>>> linha, coluna = 0,0
>>> gt[0]+coluna*gt[4]+linha*gt[5] # valor da longitude -65.606
>>> gt[3]+coluna*gt[4]+linha*gt[5] # valor da latitude 11.845

Agora falta fazer uma função pra ficar bonito ...

quinta-feira, 19 de abril de 2012

Procedimento para detectar e corrigir feições inválidas no PostgreSQL


-->
Para atender a expecificação do padrão OGC Simple Feature um polígono deve ter sua topologia verfiricada e validada. Para isto no Postgis é possível verificar utilizando uma conjunto de comandos como por exemplo estes:

1) select st_isValid(the_geom), gid from bioma_UF ;

Neste caso estamos apenas apresentando o resultado da validação e o número do gid de cada polígono.

Agora para facilitar vamos listar apenas os gid dos polígonos não válidos.

2) select gid from bioma_UF where not st_isValid(the_geom);

Sabendo que existe erro nestas features, podemos testar uma opção para tentar corrigir o problema.

3) select st_isValid(st_buffer(the_geom,0.0)), gid from bioma_UF where not st_isValid(the_geom); 

Assim podemos atualizar os dados com o seguinte comando:

UPDATE bioma_UF set the_geom = st_buffer(the_geom, 0.0) where not st_isValid(the_geom);

Outras boas dicas sobre este assunto podem ser encontradas em:


Outra opção:

update table set geomcol = st_multi(st_collectionextract(st_makevalid(geomcol),3))
    where st_isvalid(geomcol) = false;

update dados_brutos_2020.ucstodas set geom = 
st_multi(st_simplifypreservetopology(st_buffer(geom, 0.000001), 0.0001))

quarta-feira, 18 de abril de 2012

Como adicionar um sequencial em uma consulta postgresql.

Uma solução para ter um número sequencial, a fim de ser utilizado como identificador único, por exemplo, é aproveitar a função run_number(). No exemplo:

select row_number() over(order by lin) as id , lin, col from focos_noaa limit 10;

o resultado é:
id;lin;col
1;172;1103
2;173;1383
3;173;1137
4;176;89
5;179;442
6;185;1127
7;187;76
8;192;1417
9;192;778
10;196;932

Uma explicação detalhada e muito boa eu encontrei em 01/mai/2020 em https://www.postgresqltutorial.com/postgresql-row_number/

domingo, 12 de fevereiro de 2012

Como utilizar um array de valores do POSGRESQL

Encontrei o artigo "Faster array building with array_agg" que comenta como é possível ter um array de valores distintos juntamente com uma função de agregação no banco de dados.  Um exemplo disto é quando contamos todos os pontos que estão contidos em um polígono e queremos ter como resposta o identificador do pontos que foram selecionados ou utilizados.
Neste caso temos:

select count(*), array_agg(gid) as todos_ids from focos;

Outros exemplos podem ser vistos em:
http://www.postgisonline.org/