// Last edited on 2001-05-15 22:28:17 by mc726 // Implementacao da classe Planta import java.util.Vector; import java.io.IOException; import java.io.FileReader; import java.awt.Rectangle; import java.awt.Color; import LeitorDeArquivo; import Ponto; import Retangulo; import Bairro; import BairroImpl; import Esquina; import EsquinaImpl; import Trecho; import TrechoImpl; import Logradouro; import LogradouroImpl; import Servico; import ServicoImpl; import TipoDeServico; import TipoDeServicoImpl; import Escala; import EscalaImpl; import TrechoImpl; public class PlantaImpl extends Planta { // Valor default indicando invalidade do campo de identificacao private static final int ID_NULA = -1; // Caracteres e tipos de tokens especiais private static final int TT_EOL = LeitorDeArquivo.TT_EOL; private static final int TT_EOF = LeitorDeArquivo.TT_EOF; private static final int TT_NUMBER = LeitorDeArquivo.TT_NUMBER; private static final int TT_SEP = LeitorDeArquivo.TT_SEP; private static final int TT_PLUS = LeitorDeArquivo.TT_PLUS; private static final int TT_MINUS = LeitorDeArquivo.TT_MINUS; // Tabelas de componentes private Bairro[] _bairros = null; private TipoDeServico[] _tiposDeServico = null; private Trecho[] _trechos = null; private Esquina[] _esquinas = null; private Logradouro[] _logradouros = null; private Servico[] _servicos = null; public Trecho[] trechos() { return _trechos; } public Esquina[] esquinas() { return _esquinas; } public Logradouro[] logradouros() { return _logradouros; } public Bairro[] bairros() { return _bairros; } public Servico[] servicos() { return _servicos; } public TipoDeServico[] tiposDeServico() { return _tiposDeServico; } // ** CONSTRUTOR ** public PlantaImpl(String nomeBaseArquivo) throws IOException // Carrega a planta em memoria // nomeBaseArquivo é o nome base dos arquivos que descrevem a planta. // O metodo carrega() ira procurar pelos seguintes arquivos: // ./nomeBaseArquivo.trechos // ./nomeBaseArquivo.esquinas // ./nomeBaseArquivo.logradouros // ./nomeBaseArquivo.servicos // ./nomeBaseArquivo.bairros // ./nomeBaseArquivo.tiposDeServico // { // Abre arquivos e lê número de objetos em cada um: Arquivos arqs = new Arquivos(nomeBaseArquivo); //Aloca memoria, com base nos numeros de objetos de cada arquivo alocaBairros(arqs.bairros.numObjs); alocaTiposDeServico(arqs.tiposDeServico.numObjs); alocaTrechos(arqs.trechos.numObjs); alocaEsquinas(arqs.esquinas.numObjs); alocaServicos(arqs.servicos.numObjs); alocaLogradouros(arqs.logradouros.numObjs); // Le os arquivos leBairros(arqs.bairros); leTiposDeServico(arqs.tiposDeServico); leEsquinas(arqs.esquinas); leServicos(arqs.servicos); leTrechos(arqs.trechos); leLogradouros(arqs.logradouros); } public Retangulo dominio() { Retangulo r = new Retangulo(); Esquina[] e = esquinas(); for (int i = 0; i < e.length; i++) { Ponto c = e[i].centro(); r.insereXY(c.x, c.y); } Servico[] s = servicos(); for (int i = 0; i < s.length; i++) { r.inserePontos(s[i].vertices()); } r.expande(Trecho.LARGURA_NOMINAL); r.expande(Esquina.RAIO_NOMINAL); return r; } ///////////////////////////////////////////////////////////// // PRIVATE - ROTINAS PARA LEITURA DA PLANTA private final class Arquivos { public LeitorDeArquivo bairros; public LeitorDeArquivo tiposDeServico; public LeitorDeArquivo servicos; public LeitorDeArquivo logradouros; public LeitorDeArquivo esquinas; public LeitorDeArquivo trechos; public Arquivos(String nome) throws IOException { this.bairros = new LeitorDeArquivo(nome + ".bairros"); this.tiposDeServico = new LeitorDeArquivo(nome + ".tiposdeservico"); this.servicos = new LeitorDeArquivo(nome + ".servicos"); this.logradouros = new LeitorDeArquivo(nome + ".logradouros"); this.esquinas = new LeitorDeArquivo(nome + ".esquinas"); this.trechos = new LeitorDeArquivo(nome + ".trechos"); } } ///////////////////////////////////////////////////////////////////// // UTILIDADES PARA ANÁLISE LÉXICA private void verificaID(LeitorDeArquivo arq, int desejado) throws IOException // Verifica se o token corrente é o inteiro "desejado". // Se for, lê o token seguinte. Caso contrário, detona. { if (arq.toks.ttype != TT_NUMBER) { arq.erroDeFormato("falta ID"); } if (desejado != arq.proxId()) { arq.erroDeFormato("erro de seqüência - esperava " + desejado); } } ////////////////////////////////////////////////////////////////////////// // ALOCAÇÃO DOS ELEMENTOS private void alocaBairros(int n) { _bairros = new Bairro[n]; for(int i = 0; i < n; ++i) { _bairros[i] = new BairroImpl(i); } } private void alocaTiposDeServico(int n) { _tiposDeServico = new TipoDeServico[n]; for(int i = 0; i < n; ++i) { _tiposDeServico[i] = new TipoDeServicoImpl(i); } } private void alocaTrechos(int n) { _trechos = new Trecho[n]; for(int i = 0; i < n; ++i) { _trechos[i] = new TrechoImpl(i); } } private void alocaEsquinas(int n) { _esquinas = new Esquina[n]; for(int i = 0; i < n; ++i) { _esquinas[i] = new EsquinaImpl(i); } } private void alocaLogradouros(int n) { _logradouros = new Logradouro[n]; for(int i = 0; i < n; ++i) { _logradouros[i] = new LogradouroImpl(i); } } private void alocaServicos(int n) { _servicos = new Servico[n]; for(int i = 0; i < n; ++i) { _servicos[i] = new ServicoImpl(i); } } //////////////////////////////////////////////////////////////////////// // PREENCHIMENTO DOS ELEMENTOS private void leBairros(LeitorDeArquivo arq) throws IOException { try { for (int i = 0; i < _bairros.length; i++) { BairroImpl bairro = (BairroImpl) _bairros[i]; arq.bombaSeEOF(); verificaID(arq, i); arq.pulaSeparador(); String nome = arq.proxString(); bairro.inicializa(nome); arq.exigeEOL(); arq.pulaComentarios(); } } catch (IOException e) { throw e; } finally { try { arq.fr.close(); } catch (IOException e) { } } } //////////////////////////////////////////////////////////////////////// private void leTiposDeServico(LeitorDeArquivo arq) throws IOException { try { for (int i = 0; i < _tiposDeServico.length; i++) { TipoDeServicoImpl tipoDeServico = (TipoDeServicoImpl) _tiposDeServico[i]; arq.bombaSeEOF(); verificaID(arq, i); arq.pulaSeparador(); String nome = arq.proxString(); arq.pulaSeparador(); String desc = null; if (arq.toks.ttype != TT_SEP) { desc = arq.proxString(); } arq.pulaSeparador(); Color cor = new Color((int) arq.proxNumero()); System.out.println ( "tipo " + i + " cor = (" + cor.getRed() + ", " + cor.getGreen() + ", " + cor.getBlue() + ")" ); tipoDeServico.inicializa(nome, desc, cor); arq.exigeEOL(); arq.pulaComentarios(); } } catch (IOException e) { throw e; } finally { try { arq.fr.close(); } catch (IOException e) { } } } ////////////////////////////////////////////////////////////////////////////////// private void leLogradouros(LeitorDeArquivo arq) throws IOException { try { for (int i = 0; i < _logradouros.length; i++) { LogradouroImpl logr = (LogradouroImpl) _logradouros[i]; arq.bombaSeEOF(); verificaID(arq, i); arq.pulaSeparador(); String nome = arq.proxString(); arq.pulaSeparador(); Vector listaTrechos = new Vector(); while (arq.toks.ttype != TT_SEP) { int it = arq.proxId(); TrechoImpl tr = (TrechoImpl) _trechos[it]; listaTrechos.addElement(tr); } arq.pulaSeparador(); // Este campo era o tipo de logradouro - ignora int tlog = arq.proxId(); logr.inicializa(nome, listaTrechos); arq.exigeEOL(); arq.pulaComentarios(); } } catch( IOException e ) { throw e; } finally { try{ arq.fr.close(); } catch(IOException e) { } } } ///////////////////////////////////////////////////////////////////////////////// // ID : CENTRO : IDs TRECHOS CHEGAM : IDs TRECHOS SAEM : // PARES DE TRANSICOES POSSIVEIS e RESPECTIVOS CUSTOS private void leEsquinas(LeitorDeArquivo arq) throws IOException { try { for (int i = 0; i < _esquinas.length; i++) { EsquinaImpl esquina = (EsquinaImpl) _esquinas[i]; arq.bombaSeEOF(); verificaID(arq, i); arq.pulaSeparador(); // Analiza par de números. Ponto centro = new Ponto(); centro.x = arq.proxNumero(); centro.y = arq.proxNumero(); arq.pulaSeparador(); // inicio dos trechos que chegam Vector listaChg = new Vector(); while(arq.toks.ttype != TT_SEP) { int it = arq.proxId(); TrechoImpl tr = (TrechoImpl) _trechos[it]; listaChg.addElement(tr); } Vector listaSai = new Vector(); arq.pulaSeparador(); while(arq.toks.ttype != TT_SEP) { int it = arq.proxId(); TrechoImpl tr = (TrechoImpl) _trechos[it]; listaSai.addElement(tr); } Vector listaCon = new Vector(); arq.toks.nextToken(); // inicio dos pares de transicoes+custos while ((arq.toks.ttype != arq.toks.TT_EOL) && (arq.toks.ttype != arq.toks.TT_EOF)) { // Trecho que chega int itc = arq.proxId(); TrechoImpl trChg = (TrechoImpl) _trechos[itc]; // Trecho que sai int its = arq.proxId(); TrechoImpl trSai = (TrechoImpl) _trechos[its]; // Custo associado ao par de trechos double vcusto = arq.proxNumero(); listaCon.addElement(new Conexao(trChg, trSai, vcusto)); } esquina.inicializa(centro, listaChg, listaSai, listaCon); arq.exigeEOL(); arq.pulaComentarios(); } } catch( IOException e ) { throw e; } finally { try{ arq.fr.close(); } catch( IOException e ){ } } } /////////////////////////////////////////////////////////////////////////////// private void leServicos(LeitorDeArquivo arq) throws IOException { try { for (int i = 0; i < _servicos.length; i++) { ServicoImpl servico = (ServicoImpl) _servicos[i]; arq.bombaSeEOF(); verificaID(arq, i); arq.pulaSeparador(); String nome = arq.proxString(); arq.pulaSeparador(); int ig = arq.proxId(); LogradouroImpl logr = (LogradouroImpl) _logradouros[ig]; arq.pulaSeparador(); String compl = null; if (arq.toks.ttype != TT_SEP) { compl = arq.proxString(); } arq.pulaSeparador(); Ponto centro = new Ponto(); centro.x = arq.proxNumero(); centro.y = arq.proxNumero(); arq.pulaSeparador(); Vector listaVertices = new Vector(); while (arq.toks.ttype != TT_SEP) { Ponto vertice = new Ponto(); vertice.x = arq.proxNumero(); vertice.y = arq.proxNumero(); listaVertices.addElement(vertice); } arq.pulaSeparador(); Vector listaEnt = new Vector(); while (arq.toks.ttype != TT_SEP) { int it = arq.proxId(); TrechoImpl trecho = (TrechoImpl) _trechos[it]; listaEnt.addElement(trecho); } arq.pulaSeparador(); Vector listaSai = new Vector(); while (arq.toks.ttype != TT_SEP) { int it = arq.proxId(); TrechoImpl trecho = (TrechoImpl) _trechos[it]; listaSai.addElement(trecho); } arq.pulaSeparador(); // ID do tipo de servico int itp = arq.proxId(); TipoDeServicoImpl tipo = (TipoDeServicoImpl) _tiposDeServico[itp]; servico.inicializa( nome, logr, compl, centro, listaVertices, listaEnt, listaSai, tipo ); arq.exigeEOL(); arq.pulaComentarios(); } } catch( IOException e ) { throw e; } finally { try{ arq.fr.close(); } catch(IOException e){ } } } ////////////////////////////////////////////////////////////////////////////// // ID : NUM INI : NUM FIM : ID LOGR : ID ESQ //INI : ID ESQ FIM : CEP : ESTACIONA? : ID TREC OPOSTO : IDs SERVs : custo private void leTrechos(LeitorDeArquivo arq) throws IOException { try { for (int i = 0; i < _trechos.length; i++) { TrechoImpl trecho = (TrechoImpl) _trechos[i]; arq.bombaSeEOF(); verificaID(arq, i); arq.pulaSeparador(); double pcusto = arq.proxNumero(); arq.pulaSeparador(); int ig = arq.proxId(); LogradouroImpl logr = (LogradouroImpl) _logradouros[ig]; arq.pulaSeparador(); int iOrig = arq.proxId(); EsquinaImpl eOrig = (EsquinaImpl) _esquinas[iOrig]; arq.pulaSeparador(); int iDest = arq.proxId(); EsquinaImpl eDest = (EsquinaImpl) _esquinas[iDest]; arq.pulaSeparador(); int nPistas = arq.proxId(); arq.pulaSeparador(); int numIni = arq.proxId(); arq.pulaSeparador(); int numFin = arq.proxId(); arq.pulaSeparador(); String cep = arq.proxString(); arq.toks.nextToken(); // estacionamento ? boolean podeEst = ((arq.proxInt()) != 0); arq.pulaSeparador(); int ib = arq.proxId(); BairroImpl bairro = (BairroImpl) _bairros[ib]; arq.pulaSeparador(); int iOpp = arq.proxIdOrNull(ID_NULA); TrechoImpl trOpp = (iOpp == ID_NULA ? null : (TrechoImpl) _trechos[iOpp]); arq.pulaSeparador(); // inicio dos servicos // Cada Servico com acesso neste Trecho pode ser // seguido de "+" para entrada, "-" para saída, ou // nada em caso de e/s. // Vector listaDeEntradas = new Vector(); Vector listaDeSaidas = new Vector(); while ((arq.toks.ttype!=arq.toks.TT_EOL) && (arq.toks.ttype!=arq.toks.TT_EOF)) { int is = arq.proxId(); int dir = 0; ServicoImpl serv = (ServicoImpl) _servicos[is]; // proximo servico ou "+" ou "-" if ( (arq.toks.ttype == arq.toks.TT_EOL) || (arq.toks.ttype == arq.toks.TT_EOF) || (arq.toks.ttype == arq.toks.TT_NUMBER) ) { dir = 0; } else if (arq.toks.ttype == TT_PLUS) { dir = +1; arq.toks.nextToken(); // proximo servico } else if (arq.toks.ttype == TT_MINUS) { dir = -1; arq.toks.nextToken(); // proximo servico } else { arq.erroDeFormato("opcao de sentido errada = \"" + arq.toks.sval + "\""); } if (dir >= 0) { listaDeEntradas.addElement(serv); } if (dir <= 0) { listaDeSaidas.addElement(serv); } } trecho.inicializa( eOrig, eDest, trOpp, pcusto, nPistas, bairro, logr, numIni, numFin, cep, podeEst, listaDeEntradas, listaDeSaidas ); arq.exigeEOL(); arq.pulaComentarios(); } } catch( IOException e ) { throw e; } finally { try{ arq.fr.close(); } catch(IOException e){ } } } }