A Base Cartográfica Contínua serve como referência cartográfica para as ações de planejamento, monitoramento e gestão territorial do país, e está modelada conforme as Especificações Técnicas para Estruturação de Dados Geoespaciais Vetoriais na versão 2.1 (ET-EDGV v2.1) (IBGE).
A BC250 foi disponibilizada pelo IBGE em dois formatos:
- Em um formato de banco de dados proprietário (*.mdb), usado pelo ArcMap;
- E em PostGIS;
Os arquivos compactados com zip são no formado mdb, que nesse caso, lido pelo Access da Microsoft, e pode ser importada ou migrada para outras bases.
O que vai interessar aqui é o dump da base do PostGIS. Para tanto, vou colocar aqui os primeiros passos para instalação do postgres, principalmente no MacOS, que foi onde instalei, mas os passos são os mesmos, seja linux, ou windows. o que vai mudar, é claro, são alguns comandos ou procedimentos referentes, principalmente, à instalação do postgres, mas os links valem para todos os SO's.
Instalação do Postgres com PostGIS
O PostGIS, PostgreSQL + PostGIs podem ser encontrados nesse link http://postgis.net/install , recomendo baixar a versão binária, seja para Windows, Mac ou Linux.
Para instalar no seu SO, basta seguir as informações no link acima, normalmente, a instalação é bem automatizada.
No MacOs não vem por padrão com uma IDE de acesso ao Postgres, para tanto podem ser baixadas em http://postgresapp.com/documentation/gui-tools.html, pessoalmente recomendo mesmo a PgAdmin. No Windows, ela já vem com o pacote de instalação, se não me engano. No linux também tem que ser instalada a parte.
O PostGIS já vem instalado com o Postgres, mas não vem habilitado. Para habilitá-lo deve-se em cada base de dados criada, executar os comandos abaixo:
-- Enable PostGIS (includes raster) CREATE EXTENSION postgis; -- Enable Topology CREATE EXTENSION postgis_topology; -- fuzzy matching needed for Tiger CREATE EXTENSION fuzzystrmatch; -- Enable US Tiger Geocoder CREATE EXTENSION postgis_tiger_geocoder;
Após executar esses comandos no banco de dados recém criado, o PostGIS estará habilitado para ser usado. Lembrando novamente, para cada nova base de dados, deve-se executar os comandos acima.
Exemplo básico de uso do SQL Spartial, mais informações podem ser encontradas em http://postgis.net/documentation ou http://postgis.net/docs/manual-2.1/
-- Create table with spatial column CREATE TABLE mytable ( id SERIAL PRIMARY KEY, geom GEOMETRY(Point, 26910), name VARCHAR(128) ); -- Add a spatial index CREATE INDEX mytable_gix ON mytable USING GIST (geom); -- Add a point INSERT INTO mytable (geom) VALUES ( ST_GeomFromText('POINT(0 0)', 26910) ); -- Query for nearby points SELECT id, name FROM mytable WHERE ST_DWithin( geom, ST_GeomFromText('POINT(0 0)', 26910), 1000 );
Bom, instalado o PostGIS e habilitado em uma nova base, vamos agora fazer o download do dump da base do IBGE, a BC250.
Obtendo os Dados
Os arquivos de dados do IBGE podem ser baixados no endereço abaixo,
Acima uma prévia do deve ser encontrado no ftp do IBGE. O arquivo que vai interessar é o bc250_pgis20_dump.zip. No caso ele possui cerca de 1.1Gb compactado.
Façam o download e descompactem.
Restaurando a base de dados do IBGE - BC250
A restauração da base não é simplesmente executar o pg_dump. Precisamos configurar algumas coisas antes, vamos lá:
1. Os dados podem ser restaurados para qualquer base de dados, sendo assim, deve-se criar uma base de dados nova no PostGIS. Não esqueçam de habilitar o PostGIS, como descrito no início desse artigo, que no meu caso chamei de gisibge.
2. Obrigatoriamente, deve-se criar um schema nessa base de dados nova, chamada de bc250. Deve-se também criar um usuário chamado ccar. Abaixo os comandos, lembrando de trocar o nome da base de gisibge para o nome do seu database :
1
2
3
4
5
6
7
8
9
| --Logando como superusuário sudo su su postgres --Logando à base de dados psql gisibge -- Criando o shema CREATE SCHEMA bc250; --Criando o usuário CREATE USER ccar;
|
3. Editar o arquivo restore.sql que foi descompactado e substituir a variável “$$PATH$$” para o caminho onde os arquivos foram descompactados. Nesse caso recomendo o localizar e substituir. Esse passo é necessário pois os dados de cada tabela estão em arquivos separados, ou seja os insert's.
Outra coisa que foi necessária alterar no arquivo restore.sql foi o tamanho dos campos que são varchar(3) pois dava erro na importação, sendo assim, fiz uma substituição de character varying(3) para character varying(30), e com isso não deu mais erro.
Outra coisa que foi necessária alterar no arquivo restore.sql foi o tamanho dos campos que são varchar(3) pois dava erro na importação, sendo assim, fiz uma substituição de character varying(3) para character varying(30), e com isso não deu mais erro.
4. Executar o comando de importar os dados para o Postgres.
1
| psql -d gisibge -f restore.sql |
A restore vai demorar um pouco devido ao tamanho e quantidade de informações existentes.
No FTP existe um arquivo, pdf que possui as informações e detalhes da organização do Base do IBGE.
Criando novas tabelas e importando dados
O objetivo de ter estudado o PostGIS e importado a base do IBGE é para o Mestrado que estou fazendo, em uma disciplina. Para tanto, abaixo vou colocar o que foi feito para o trabalho, como forma de exemplificar o seu uso, e entender o que pode ser feito a título de exemplos de seu uso.
Foram criadas novas tabelas tblcidades, tblestados, tblrios, tblcidade_localizacao.
A diferença entre tblcidades e tblcidade_localização é que a primeira possui a geometria da cidade, e a segunda somente a coordenada de localização e a informação se a cidade é capital, e foi utilizada de forma temporária somente.
CREATE TABLE public.tblcidade_localizacao
(
intcidadeid integer,
bolcapital integer,
strcidade character varying(80),
gislocalizacao geometry
)
WITH (
OIDS=FALSE
);
CREATE TABLE public.tblcidades
(
intcidadeid integer NOT NULL,
bolcapital integer NOT NULL DEFAULT 0,
strcidade character varying(80),
gislocalizacao geometry NOT NULL,
CONSTRAINT tblcidades_pkey PRIMARY KEY (intcidadeid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.tblcidades
OWNER TO thiago;
-- Index: public.idx_cidades_001
-- DROP INDEX public.idx_cidades_001;
CREATE INDEX idx_cidades_001
ON public.tblcidades
USING gist
(gislocalizacao);
-- Index: public.idx_cidades_002
-- DROP INDEX public.idx_cidades_002;
CREATE INDEX idx_cidades_002
ON public.tblcidades
USING btree
(strcidade COLLATE pg_catalog."default");
-- Index: public.idx_cidades_003
-- DROP INDEX public.idx_cidades_003;
CREATE INDEX idx_cidades_003
ON public.tblcidades
USING btree
(bolcapital);
CREATE TABLE public.tblestados
(
intestadoid integer NOT NULL,
strestado character varying(80),
strsigla character(2),
intgeocodigoid integer,
gislocalizacao geometry NOT NULL,
CONSTRAINT tblestados_pkey PRIMARY KEY (intestadoid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.tblestados
OWNER TO thiago;
-- Index: public.idx_estados_001
-- DROP INDEX public.idx_estados_001;
CREATE INDEX idx_estados_001
ON public.tblestados
USING btree
(strestado COLLATE pg_catalog."default");
-- Index: public.idx_estados_002
-- DROP INDEX public.idx_estados_002;
CREATE INDEX idx_estados_002
ON public.tblestados
USING gist
(gislocalizacao);
-- Index: public.idx_estados_003
-- DROP INDEX public.idx_estados_003;
CREATE INDEX idx_estados_003
ON public.tblestados
USING btree
(strsigla COLLATE pg_catalog."default");
-- Index: public.idx_estados_004
-- DROP INDEX public.idx_estados_004;
CREATE INDEX idx_estados_004
ON public.tblestados
USING btree
(intgeocodigoid);
CREATE TABLE public.tblrios
(
intrioid integer NOT NULL,
strrio character varying(80),
strsalinidade character varying(30),
strregime character varying(30),
strtipotrechomassa character varying(30),
gislocalizacao geometry NOT NULL,
CONSTRAINT tblrios_pkey PRIMARY KEY (intrioid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.tblrios
OWNER TO thiago;
-- Index: public.idx_rios_001
-- DROP INDEX public.idx_rios_001;
CREATE INDEX idx_rios_001
ON public.tblrios
USING btree
(strrio COLLATE pg_catalog."default");
-- Index: public.idx_rios_002
-- DROP INDEX public.idx_rios_002;
CREATE INDEX idx_rios_002
ON public.tblrios
USING gist
(gislocalizacao);
-- Index: public.idx_rios_003
-- DROP INDEX public.idx_rios_003;
CREATE INDEX idx_rios_003
ON public.tblrios
USING btree
(strsalinidade COLLATE pg_catalog."default");
-- Index: public.idx_rios_004
-- DROP INDEX public.idx_rios_004;
CREATE INDEX idx_rios_004
ON public.tblrios
USING btree
(strregime COLLATE pg_catalog."default");
-- Index: public.idx_rios_005
-- DROP INDEX public.idx_rios_005;
CREATE INDEX idx_rios_005
ON public.tblrios
USING btree
(strtipotrechomassa COLLATE pg_catalog."default");
CREATE TABLE public.tblcidade_localizacao
(
intcidadeid integer,
bolcapital integer,
strcidade character varying(80),
gislocalizacao geometry
)
WITH (
OIDS=FALSE
);
CREATE TABLE public.tblcidades
(
intcidadeid integer NOT NULL,
bolcapital integer NOT NULL DEFAULT 0,
strcidade character varying(80),
gislocalizacao geometry NOT NULL,
CONSTRAINT tblcidades_pkey PRIMARY KEY (intcidadeid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.tblcidades
OWNER TO thiago;
-- Index: public.idx_cidades_001
-- DROP INDEX public.idx_cidades_001;
CREATE INDEX idx_cidades_001
ON public.tblcidades
USING gist
(gislocalizacao);
-- Index: public.idx_cidades_002
-- DROP INDEX public.idx_cidades_002;
CREATE INDEX idx_cidades_002
ON public.tblcidades
USING btree
(strcidade COLLATE pg_catalog."default");
-- Index: public.idx_cidades_003
-- DROP INDEX public.idx_cidades_003;
CREATE INDEX idx_cidades_003
ON public.tblcidades
USING btree
(bolcapital);
CREATE TABLE public.tblestados
(
intestadoid integer NOT NULL,
strestado character varying(80),
strsigla character(2),
intgeocodigoid integer,
gislocalizacao geometry NOT NULL,
CONSTRAINT tblestados_pkey PRIMARY KEY (intestadoid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.tblestados
OWNER TO thiago;
-- Index: public.idx_estados_001
-- DROP INDEX public.idx_estados_001;
CREATE INDEX idx_estados_001
ON public.tblestados
USING btree
(strestado COLLATE pg_catalog."default");
-- Index: public.idx_estados_002
-- DROP INDEX public.idx_estados_002;
CREATE INDEX idx_estados_002
ON public.tblestados
USING gist
(gislocalizacao);
-- Index: public.idx_estados_003
-- DROP INDEX public.idx_estados_003;
CREATE INDEX idx_estados_003
ON public.tblestados
USING btree
(strsigla COLLATE pg_catalog."default");
-- Index: public.idx_estados_004
-- DROP INDEX public.idx_estados_004;
CREATE INDEX idx_estados_004
ON public.tblestados
USING btree
(intgeocodigoid);
CREATE TABLE public.tblrios
(
intrioid integer NOT NULL,
strrio character varying(80),
strsalinidade character varying(30),
strregime character varying(30),
strtipotrechomassa character varying(30),
gislocalizacao geometry NOT NULL,
CONSTRAINT tblrios_pkey PRIMARY KEY (intrioid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.tblrios
OWNER TO thiago;
-- Index: public.idx_rios_001
-- DROP INDEX public.idx_rios_001;
CREATE INDEX idx_rios_001
ON public.tblrios
USING btree
(strrio COLLATE pg_catalog."default");
-- Index: public.idx_rios_002
-- DROP INDEX public.idx_rios_002;
CREATE INDEX idx_rios_002
ON public.tblrios
USING gist
(gislocalizacao);
-- Index: public.idx_rios_003
-- DROP INDEX public.idx_rios_003;
CREATE INDEX idx_rios_003
ON public.tblrios
USING btree
(strsalinidade COLLATE pg_catalog."default");
-- Index: public.idx_rios_004
-- DROP INDEX public.idx_rios_004;
CREATE INDEX idx_rios_004
ON public.tblrios
USING btree
(strregime COLLATE pg_catalog."default");
-- Index: public.idx_rios_005
-- DROP INDEX public.idx_rios_005;
CREATE INDEX idx_rios_005
ON public.tblrios
USING btree
(strtipotrechomassa COLLATE pg_catalog."default");
Após a criação das tabelas, foi feita a importação dos dados diretamente da base do IBGE importada.
insert into tblcidade_localizacao (intcidadeid, strcidade, gislocalizacao, bolcapital)
select id_objeto, nome, geom, 1 as bolcapital from bc250.loc_capital_p
union
select id_objeto, nome, geom, 0 as bolcapital from bc250.loc_cidade_p;
insert into tblcidades (intcidadeid, strcidade, gislocalizacao, bolcapital)
select id_objeto, nome, geom, 0 as bolcapital from bc250.lim_municipio_a ;
insert into tblestados (intestadoid, strestado, strsigla, intgeocodigoid, gislocalizacao)
select id_objeto, nome, sigla, geocodigo::int, geom from bc250.lim_unidade_federacao_a ;
insert into tblrios(intrioid, strrio, strsalinidade, strtipotrechomassa, strregime, gislocalizacao)
select id_objeto, nome, salinidade, tipotrechomassa, regime, geom from bc250.hid_trecho_massa_dagua_a ;
update tblcidades set bolcapital = 1
where
ST_Contains(tblcidades.gislocalizacao, (select gislocalizacao from tblcidade_localizacao where bolcapital =1
and replace(strcidade, '''', '') = tblcidades.strcidade) );
select id_objeto, nome, geom, 1 as bolcapital from bc250.loc_capital_p
union
select id_objeto, nome, geom, 0 as bolcapital from bc250.loc_cidade_p;
insert into tblcidades (intcidadeid, strcidade, gislocalizacao, bolcapital)
select id_objeto, nome, geom, 0 as bolcapital from bc250.lim_municipio_a ;
insert into tblestados (intestadoid, strestado, strsigla, intgeocodigoid, gislocalizacao)
select id_objeto, nome, sigla, geocodigo::int, geom from bc250.lim_unidade_federacao_a ;
insert into tblrios(intrioid, strrio, strsalinidade, strtipotrechomassa, strregime, gislocalizacao)
select id_objeto, nome, salinidade, tipotrechomassa, regime, geom from bc250.hid_trecho_massa_dagua_a ;
Foi feito um update para atualizar o campo bolcapital
update tblcidades set bolcapital = 1
where
ST_Contains(tblcidades.gislocalizacao, (select gislocalizacao from tblcidade_localizacao where bolcapital =1
and replace(strcidade, '''', '') = tblcidades.strcidade) );
Nesse caso foi utilizada a função ST_Contains para pegar qual a capital que pertente, está contida, ao estado. Aqui foi onde foi utilizada a tabela tblcidade_localizacao.
Foram criadas as seguintes estruturas: 1 view e 2 funções como forma de explorar um pouco as funcionalidades do postgres.
Abaixo os códigos das mesmas:
CREATE OR REPLACE VIEW public.viewcidades AS
SELECT tblcidades.intcidadeid,
tblcidades.bolcapital,
tblcidades.strcidade,
tblcidades.gislocalizacao,
tblestados.intestadoid,
tblestados.strestado,
tblestados.strsigla,
tblestados.gislocalizacao AS gisestado,
tblcapitais.strcidade AS strcapital,
tblcapitais.gislocalizacao AS giscapital,
st_distance_sphere(st_centroid(tblcapitais.gislocalizacao), st_centroid(tblcidades.gislocalizacao)) / 1000::double precision AS numdistanciacapital,
st_astext(st_centroid(tblcidades.gislocalizacao)) AS numcoordenadas,
st_astext(st_centroid(tblcapitais.gislocalizacao)) AS numcoordenadascapital,
st_astext(st_centroid(tblestados.gislocalizacao)) AS numcoordenadas_estado,
st_area(tblcidades.gislocalizacao) AS numareacidade,
st_area(tblcapitais.gislocalizacao) AS numareacapital,
st_area(tblestados.gislocalizacao) AS numareaestado
FROM tblcidades
JOIN tblestados ON st_within(tblcidades.gislocalizacao, tblestados.gislocalizacao)
JOIN tblcidades tblcapitais ON st_within(tblcapitais.gislocalizacao, tblestados.gislocalizacao) AND tblcapitais.bolcapital = 1;
Nesse caso, foram usadas as funções ST_Within para pegar quais cidades pertencem ao estado e qual capital pertence ao estado. Além dessas as seguintes:
st_distance_sphere: Calcular a distância, nesse caso, da cidade até a capital do estado.
st_centroid: Utilizar o centro das cidades para calcular a distância.
st_astext: Converter a geometria salva, em formato binário, para formato texto e assim, identificar qual o tipo de geometria: Ponto, Poligono e etc. É bom ver a documentação no link mais acima.
st_area: Calcular a área da cidade, capital e do estado.
A função abaixo, fn_estadosvizinhos, serve para mostrar quais são os estados vizinhos ao desejado, e para isso foi utilizada a função st_Intersects.
Sua chamada é da seguinte forma:
select * from fn_estadosvizinhos('MA')
CREATE OR REPLACE FUNCTION public.fn_estadosvizinhos(sigla character)
RETURNS SETOF tblestados AS
$BODY$
BEGIN
RETURN QUERY select tbloutros.* from tblestados
inner join tblestados tbloutros on st_Intersects(tblestados.gislocalizacao, tbloutros.gislocalizacao) and
tbloutros.intestadoid <> tblestados.intestadoid
where
tblestados.strsigla = $1;
RETURN ;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
A função abaixo, fn_quaisrios, serve para mostrar quais são os rios que passam por uma cidade ou por um estado, e para isso foi utilizada a função st_Intersects.
Sua chamada é da seguinte forma:
select * from fn_quaisrios('MA') -- para o estado
select * from fn_quaisrios('Rosário') -- para uma cidade
CREATE OR REPLACE FUNCTION public.fn_quaisrios(local character varying)
RETURNS SETOF tblrios AS
$BODY$
BEGIN
RETURN QUERY select tblrios.* from tblrios
inner join tblestados on ST_Intersects(tblestados.gislocalizacao, tblrios.gislocalizacao)
where
strsigla = local
and
strrio is not null
union
select tblrios.* from tblrios
inner join tblcidades on ST_Intersects(tblcidades.gislocalizacao, tblrios.gislocalizacao)
where
strcidade = local
and
strrio is not null
order by
strrio;
RETURN ;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
um outro select interessante é calcular a área do rio que passa em uma cidade, por exemplo.
select tblrios.intrioid, strrio, strsalinidade, strregime, st_area(ST_Intersection(tblrios.gislocalizacao, tblcidades.gislocalizacao)) as arearionacidade from tblrios
inner join tblcidades on ST_Intersects(tblcidades.gislocalizacao, tblrios.gislocalizacao)
where
strcidade = 'Rosário'
and
strrio is not null
Quem quiser fazer o download do esquema completo das tabelas criadas, views, funções e dados importados, faça aqui.
Somente a estrutura das tabelas, views e funções.
Somente os dados das tabelas.
Dump realizado pelo pgadmin com estrutura e dados.
Somente os dados das tabelas.
Dump realizado pelo pgadmin com estrutura e dados.
Nenhum comentário:
Postar um comentário