Indexação de dados geográficos

Propaganda
Estrutura de Dados II
2013.1 Trabalho Parte 1
Universidade Federal de Juiz de Fora
Prof. Jairo Francisco de Souza
Indexação de dados geográficos
1. Introdução e objetivo do trabalho
Aplicações que manipulam dados espaciais
necessitam implementar estruturas de dados
especiais para esse tipo de uso. É o caso de
sistemas gerenciadores de dados geográficos,
jogos e simuladores. Neste trabalho, iremos
implementar operações de inserção e busca em
uma K-d Tree de 2 dimensões para indexação de
arquivos com dados geográficos.
O objetivo desse trabalho é simular o
comportamento de busca em POIs (points of
interest), os quais são utilizados em aparelhos GPS
para marcar pontos como locais turísticos, semáforos, pontos de gasolina, etc.
2. Descrição do trabalho
Utilizaremos uma árvore de busca de dados em duas dimensões para
armazenar pontos no espaço. Para tal, usaremos uma base de pontos com locais do
Brasil.
Essa
base
pode
ser
acessada
em
http://download.geonames.org/export/dump/BR.zip.
Os registros estão dispostos no arquivo por linha, sendo que cada campo está
dividido por tabulação. Ou seja, entre cada campo existe um caractere TAB
delimitando-o. O final da linha indica fim do registro. Para entender o significado de
cada campo, o arquivo README.txt, presente no zip, explica:
The main 'geoname' table has the following fields :
--------------------------------------------------geonameid
: integer id of record in geonames database
name
: name of geographical point (utf8) varchar(200)
asciiname
: name of geographical point in plain ascii characters, varchar(200)
alternatenames
: alternatenames, comma separated varchar(5000)
latitude
: latitude in decimal degrees (wgs84)
longitude
: longitude in decimal degrees (wgs84)
feature class
: see http://www.geonames.org/export/codes.html, char(1)
feature code
: see http://www.geonames.org/export/codes.html, varchar(10)
country code
: ISO-3166 2-letter country code, 2 characters
cc2
: alternate country codes, comma separated, ISO-3166 2-letter country
code, 60 characters
admin1 code
: fipscode (subject to change to iso code), see exceptions below, see
file admin1Codes.txt for display names of this code; varchar(20)
admin2 code
: code for the second administrative division, a county in the US, see
file admin2Codes.txt; varchar(80)
admin3 code
: code for third level administrative division, varchar(20)
admin4 code
: code for fourth level administrative division, varchar(20)
population
: bigint (8 byte int)
elevation
: in meters, integer
gtopo30
: average elevation of 30'x30' (ca 900mx900m) area in meters, integer
timezone
: the timezone id (see file timeZone.txt)
modification date : date of last modification in yyyy-MM-dd format
Cada registro no arquivo indica um ponto, sendo que esse ponto pode
representar diferentes tipos de locação (cidade, rio, ilha, museu, etc). Para
identificar cada tipo de locação, é necessário entender os campos feature class e
feature
code.
A
explicação
sobre
esses
campos
está
em
http://www.geonames.org/export/codes.html.
3. Funcionalidades a serem implementadas
1. O sistema deve ler todos os registros do arquivo de pontos e inseri-los em
2.
3.
uma Kd-Tree. A árvore terá como nó uma estrutura com os campos latitude,
longitude, featureClass, featureCode, geonameid e posicaoArq .
O sistema deverá plotar todos os pontos da árvore na tela.
O usuário poderá inserir uma coordenada e o sistema disponibilizará na tela
o nome da localização correspondente a esse ponto. Caso o ponto informado
não exista na árvore, deve informar então o nome dos pontos mais próximos
(3 no máximo). Para encontrar os pontos, o sistema deverá pesquisar o nó
correspondente na árvore, recuperar a posição no arquivo em que se
encontra as informações da cidade e acessar essa posição no arquivo. Para
tal, guarde a posição do arquivo no campo posicaoArq do nó. Cuidado: não
faça busca sequencial no arquivo toda vez que for ler o arquivo! Use os
métodos ftell/fseek (ou fgetpos/fsetpos) para isso.
ATENÇÃO: Para plotar os pontos na tela, deve-se percorrer a árvore. O arquivo
texto só pode ser lido para fazer a tarefa 1 e para completar a tarefa 3!
4. Entrega
O grupo deverá ser formado por 4 alunos e as responsabilidades de cada
aluno deve ser documentada e registrada.
Deve ser entregue um relatório contendo a descrição das atividades realizadas
por cada membro do grupo. Ainda, deve ser entregue a implementação dos
algoritmos (código documentado informando o que faz e quais os autores de cada
função);
O grupo deve agendar um horário com o professor para entrega pessoal do
trabalho e apresentação oral no DCC. O sistema deverá ser instalado na máquina
do professor (sistema operacional Ubuntu 13.04 com CodeBlocks).
Atenção para a data de entrega dos trabalhos: caso você deixe para o último
dia, não espere que o professor estará disponível para te atender (outro grupo já
pode ter reservado o horário!). Se não tiver espaço vago para a sua apresentação,
será considerado entrega com atraso.
6. Pontuação
Os membros da equipe serão avaliados pelo produto final do trabalho e pelos
resultados individuais alcançados. Assim, numa mesma equipe, um membro pode
ficar com nota 90 e outro com nota 50, por exemplo. Dentre os pontos que serão
avaliados, estão:
• Execução do programa (caso o programa não funcione, a nota será zero)
• Corretude do programa (se todas as funções geram resultados esperados)
• Boa solução de programação para resolução do problema proposto.
• Código documentado e boa prática de programação (o mínimo necessário de
variáveis globais, variáveis e funções com nomes de fácil compreensão,
soluções elegantes de programação, código bem modularizado, etc)
• Pontualidade (quanto mais atrasada for a entrega do trabalho, mais pontos o
trabalho perde)
• Relatório bem redigido
Apêndice I: como criar gráficos (em C e em Java)
Para criar gráficos em C, baixe a biblioteca chamada Allegro. É necessário
compilar a biblioteca para o seu sistema operacional. As instruções de instalação
estão no site da biblioteca (pesquise no google). Para usuários do Ubuntu, pode-se
baixar a biblioteca já compilada no repositório da Canonical (digite liballegro4.2-dev
na Central de Programas do Ubuntu). Para usuários Windows, boa-sorte... :-)
Para compilar o seu projeto, será necessário setar a biblioteca liballeg-4.2.2.so
no CodeBlocks. Para tal, vá em Project → Build options → Linker settings → Add e
adicione o caminho completo da biblioteca. No Ubuntu, a biblioteca estará em
/usr/lib/liballeg-4.2.2.so .
Exemplo de código para criação gráfica de pontos em C usando o Allegro:
#include <stdio.h>
#include <stdlib.h>
#include <allegro.h>
if (allegro_init() != 0)
return 1;
install_keyboard();
/* configura o modo gráfico para resolução de 1366x768 */
if (set_gfx_mode(GFX_AUTODETECT, 1366, 768, 0, 0) != 0) {
if (set_gfx_mode(GFX_SAFE, 800, 600, 0, 0) != 0) {
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
return 1;
}
}
set_palette(desktop_palette);
clear_to_color(screen, makecol(255, 255, 255));
acquire_screen();
/** Cria um pixel na coordenada (150,150). O último parâmetro é a cor. Deve ter
um grupo de constantes para facilitar o uso. Procure na documentação **/
putpixel(screen, 150, 150, 1);
/** cria um texto na tela *//
textout_centre_ex(screen,
font,
makecol(0,0,0), -1);
“Hello
World”,
SCREEN_W/2,
SCREEN_H/2,
release_screen();
readkey();
exit(0);
return 0;
}
Exemplo de código para inserção de pontos em Java usando o AWT:
// Teste.class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JComponent;
public class Teste extends JComponent {
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
// Serve para transladar o centro do gráfico. Pode ser muito útil para
posicionar bem as coordenadas das cidades... A linha abaixo, contudo, não tem efeito
pois estamos transladando o centro em 0 pixels.
g2.translate(0, 0);
Rectangle2D rect = new Rectangle2D.Double();
g2.setColor(Color.BLUE);
// Cria um retângulo na posição (150,150) com tamanho 1 de altura e
largura.
}
}
// Frame.class
rect = new Rectangle2D.Double(150, 150, 1, 1);
g2.fill(rect);
g2.dispose();
import
import
import
import
import
java.awt.Color;
java.awt.EventQueue;
java.awt.Graphics;
java.awt.Graphics2D;
javax.swing.JFrame;
public class Frame extends JFrame {
Teste teste = new Teste();
public Frame()
{
setTitle("Teste mapa");
setSize(800,640);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void paint(Graphics g) {
//Criamos um contexto gráfico com a área de pintura restrita
//ao interior da janela.
Graphics2D clip = (Graphics2D) g.create(getInsets().left,
getInsets().top,
getWidth() - getInsets().right,
getHeight() - getInsets().bottom);
//Pintamos o fundo do frame de preto
clip.setColor(Color.WHITE);
clip.fill(clip.getClipBounds());
teste.paint(clip);
clip.dispose();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
@Override
public void run() {
new Frame().setVisible(true);
}
});
}
Download