Skip to content

Exemplo de Script: Criando objetos

A script é uma ferramenta eficaz para modificação de dados, mas também pode ser usada para criar novos dados. Este exemplo mostra como importar dados seguindo um exemplo que cria um novo estado de trânsito usando dados de um arquivo externo.

Criação de Objeto

Qualquer objeto que deriva de GKObject deve ser criado (a menos que seja indicado especificamente) usando um Comando Novo. Esses comandos criam e inicializam novas referências de objetos, adicionam o objeto à sua camada ou pasta e reduzem o código a ser escrito. Por exemplo:

cmd = GKTurningNewCmd()
cmd.setTurning( origem, destino )
cmd.setUndoable( False )

Este exemplo chama o construtor, define as informações mínimas necessárias para o objeto e define undoable como falso para impedir que o comando novo seja desfeito na interface gráfica.

O novo comando precisa ser incluído no comandante do modelo para garantir a execução instantânea do comando e manter as referências de comando para fins de ação desfazer/refazer:

model.getCommander().addCommand( cmd )

Uma vez que o comando foi executado e queremos acessar o novo objeto, qualquer comando Novo retorna-o do método createdObject():

newTurn = cmd.createdObject()

Se o comando novo para o tipo GK que você está procurando não existir, há uma maneira alternativa de criar objetos que é usando a chamada GKSystem::newObject(). Esta chamada criará um novo objeto, o inicializará e o adicionará ao catálogo do modelo atual.

Criar um novo objeto que deriva de GKObject de qualquer outra maneira pode corromper o modelo atual ou fazer o sistema travar mais tarde. Portanto, para criar um novo objeto de um tipo cujo NewCmd não está disponível (GKMyType, por exemplo), o código será:

state = GKSystem.getSystem().newObject( "GKMyType", model )

e não:

state = GKMyType() # NUNCA faça isso!!!

Essa chamada instrui o sistema a criar um novo objeto de um tipo particular (um objeto GKMyType neste exemplo) no modelo fornecido. O novo objeto será sem título, portanto, é aconselhável dar-lhe um nome usando o método GKObject::setName():

state.setName( "Novo objeto do meu tipo" )

Organização de Objetos

Aimsun Next organiza objetos de duas maneiras, dependendo de seu tipo. Objetos gráficos são organizados em camadas e mostrados nas visões 2D e 3D. Objetos não gráficos são organizados em pastas e mostrados na Janela do Projeto.

Depois de criar um objeto sem usar seu comando Novo, um novo objeto deve ser adicionado a uma camada ou a uma pasta, dependendo se é gráfico ou não gráfico.

Imagine que o objeto GKMyType criado na seção anterior seja um objeto não gráfico. Como objeto não gráfico, ele deve ser adicionado a uma pasta. Vamos imaginar que queremos adicioná-lo à pasta de estados de trânsito. No entanto, essa pasta deve ser criada se ainda não existir. O código a seguir cria a pasta:

folderName = "GKModel::trafficStates"
folder = model.getCreateRootFolder().findFolder( folderName )
if folder == None:
    folder = GKSystem.getSystem().createFolder( model.getCreateRootFolder(), folderName )

Primeiro, esse código procura a pasta usando a chamada GKFolder::findFolder(). Ele busca na pasta raiz do modelo, que é o local normal. Se a pasta não estiver lá, então ela será criada. Como a pasta Estados de Trânsito é uma pasta do sistema, só precisamos passar o nome interno da pasta para o sistema criar a estrutura correta. Consulte a tabela abaixo para o nome interno das pastas do sistema.

Nomes internos das pastas do sistema

Nome Externo Nome Interno (único)
Configurações de Centróides GKModel::centroidsConf
Controle GKModel::top::control
Planos de Controle GKModel::controlPlans
Análise de Dados GKModel::top::dataAnalysis
Dados de Demanda GKModel::top::traffic
Localizações de Detectores GKModel::detectorLocations
Funções GKModel::functions
Infraestrutura GKModel::top::infrastructure
Tipos de Faixa GKModel::laneTypes
Planos de Controle Master GKModel::masterControlPlans
Matrizes OD GKCentroidConfiguration::matrices
Rotas OD GKCentroidConfiguration::routes
Transporte Público GKModel::top::publicTransport
Linhas de Transporte Público GKModel::publicLines
Planos de Transporte Público GKModel::publicPlans
Conjuntos de Dados Reais GKModel::realDataSets
Tipos de Via GKModel::roadTypes
Cenários GKModel::top::scenarios
Scripts GKModel::top::scripts
Subcaminhos GKModel::subPaths
Estrategias GKModel::strategies
Condições de Tráfego GKModel::trafficConditions
Demandas de Tráfego GKModel::trafficDemand
Gestão de Tráfego GKModel::top::trafficmanagement
Estados de Tráfego GKModel::trafficStates
Gatilhos GKModel::triggers
Veículos GKModel::vehicles
Modos de Visualização GKModel::viewModes
Estilos de Visualização GKModel::viewStyles

Finalmente, o novo objeto deve ser adicionado à pasta:

folder.append( state )

Objetos gráficos devem ser adicionados ao GeoModel. Dentro do GeoModel, os objetos devem ser atribuídos a uma camada. Na maioria dos casos, a camada ativa será utilizada. Isso é encontrado usando a chamada getActiveLayer():

(model.getGeoModel().getActiveLayer()).

Por exemplo, se o comando Novo para criar um detector não existisse (o GKSectionObjectNewCmd é o que deve ser utilizado para isso), os passos que precisaríamos seguir para escrever um script que criasse um detector no meio de uma seção seriam: Primeiro, criar o detector, em seguida, definir seus parâmetros (nome, faixas e comprimento). Adicioná-lo no topo de uma seção (um detector não pode existir por conta própria), e finalmente adicioná-lo ao GeoModel, colocando-o na mesma camada da seção. Se o script for adicionado ao menu de contexto da Seção, então a variável target é usada para se referir à seção:

detector = GKSystem.getSystem().newObject( "GKDetector", model )
detector.setName( "Um novo detector" )
detector.setLanes( 0, 1 )
detector.setLength( 4.5 )
detector.setPosition( target.length2D() / 2.0 )
target.addTopObject( detector )
model.getGeoModel().add( target.getLayer(), detector )


Adicionar script ao Menu de Contexto

Todos os passos acima para objetos não gráficos e gráficos são automaticamente gerenciados ao usar os comandos Novos.

Destruição de Objetos

Objetos são removidos do modelo em duas etapas:

  1. Obter o comando de deleção para o objeto chamando GKObject::getDelCmd()
  2. Executar o comando

Por exemplo:

myObjectToDelete = model.getCatalog().find(104) #recuperar objeto
if myObjectToDelete!=None:
    cmd = myObjectToDelete.getDelCmd()
    model.getCommander().addCommand(cmd)

Como a classe GKObjectDelCmd é derivada de GKCommand, ela fornece funcionalidade de desfazer. Portanto, para tornar a deleção permanente (não desmanchável), adicione um comando nulo:

model.getCommander().addCommand(None)

Lendo um Arquivo

Depois de criar um Estado de Tráfego, a próxima etapa é definir os fluxos de entrada lendo-os de um arquivo. Este será um arquivo ASCII com as informações organizadas em duas colunas no formato separado por vírgulas. A primeira coluna contém o identificador da seção, a segunda contém o fluxo de entrada.

Primeiro, abra o arquivo e leia-o linha por linha. Em seguida, divida cada linha, usando a vírgula como separador.

Use o catálogo para procurar a seção usando seu ID. Se, em vez de identificadores, identificadores externos ou nomes forem usados, o método pode ser alterado para se referir a esses.

Com a seção e o fluxo, definimos o fluxo no estado de tráfego:

def importState( model, state, fileName ):
for line in open( fileName, "r" ).readlines():
    # Separar a linha em colunas
    columns = line.split( "," )
    # A primeira coluna contém o id da seção
    section = model.getCatalog().find(int(columns[0]))
    # A segunda coluna contém o fluxo
    flow = float(columns[1])
    # Definir o valor se a seção for válida
    if section != None:
        state.setEntranceFlow( section, None, flow )

Tratamento de Erros

Suponha que o arquivo de entrada tenha um erro e contenha um identificador para um centróide em vez de uma seção. O catálogo retornará o objeto com aquele identificador – um centróide – e quando setEntranceFlow() for chamado usando aquele centróide. Aimsun Next relatará um erro conforme mostrado aqui:

Erro Python (exceptions.TypeError): argumento 1 de GKTrafficState.setEntranceFlow() tem um tipo inválido

Um erro de tipo inválido é dado, uma vez que a função espera uma seção, mas em vez disso recebeu um centróide. Note que o código já se protege contra objetos None; None é retornado quando nenhum objeto é encontrado.

Portanto, ao procurar um objeto no catálogo, é aconselhável verificar primeiro se ele foi encontrado e, em segundo lugar, se é do tipo correto usando o seguinte código:

if section != None and section.isA( "GKSection" ):