Conexão SDE x Conexão ArcGis Server, Java e ESRI

Primerio post teorico irei tratar de um assunto que vivenciamos a pouco tempo aqui na empresa. Trabalhamos com plataforma ESRI e a forma de conexão sempre foi o passo incial para um projeto, mas mudar essa forma de conexão depois que o projeto já estava sólido também foi uma decisão difícil de se tomar.

Nós tinhamos um projeto, webservice – wsdl em Java, focado apenas ao público interno da empresa. Incialmente tudo funcionava perfeitamente, não tinhamos problemas com performance nem acessos concorrentes ao programa, porém o projeto virou um produto interessante e a empresa resolveu vender esse acesso e disponibilizar o webservice para seus clientes, o escopo então mudou, já não eram poucos acessos e então vieram os problemas de performance, estouro de memória da JVM, concorrência de dados entre outros problemas que diversas pessoas já devem ter passado ao se migrar de uma aplicação de pequeno porte para uma de grande porte. Estava realmente na hora de migrar nossa aplicação ArcGis Desktop para o ArcGis Server, que como o nome diz é destinado para esse tipo de serviço.

Irei mostrar dois exemplos práticos de como se obter cada tipo de conexão, cabe a você decidir qual o escopo do seu projeto e qual tipo implementar. Os exemplos utilizam API ArcObjects e para se utilizada você precisa ter instalado o ArcGis destop na sua máquina para obter a licença para uso.

Acesso ao ArcGis Desktop:

Connector.java

//Classe de controle de acesso as conexões do SDE
public class Connector{

    //Classe criada para obter as informações de conexão, setadas previamente por um framework de DI ou manuamente passada via get/set
    private Proriedades propriedades;

    //Classes setadas previamente via framework DI ou passadas via get/set
    private IWorkspaceFactory workspaceFactory;
    private IFeatureWorkspace featureWorkspace;
    private IPropertySet propertySet;

    //Contrutor da classe, faz a validação da licença disponível na máquina
    public SDEConnector(){
        try {
        	EngineInitializer.initializeEngine();
            com.esri.arcgis.system.AoInitialize ao = new com.esri.arcgis.system.AoInitialize();
            if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeEngine) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
                ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeEngine);
            } else if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
                ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView);
            } else if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcEditor) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
                ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcEditor);
            } else if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcInfo) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
                ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //Abre uma conexão com o SDE
    public void open() throws AutomationException, IOException{
        propertySet.setProperty("server", this.propriedades.getServer());
        propertySet.setProperty("instance", this.propriedades.getInstance());
        propertySet.setProperty("user", this.propriedades.getUser());
        propertySet.setProperty("password", this.propriedades.getPassword());
        propertySet.setProperty("version", this.propriedades.getVersion());
        this.featureWorkspace = (IFeatureWorkspace) workspaceFactory.open(propertySet, 0);
    }

    //Fecha a conexão
    public void close(){
    	Cleaner.release(this.featureWorkspace);
    }
    //Retorna o acesso a uma FeatureClass
    public IFeatureClass getFeature(String featureName) throws AutomationException, IOException{
    	return this.getFeatureWorkspace().openFeatureClass(featureName);
    }

Com essa classe podemos obter uma conexão com o SDE e fecha-la quando desejarmos, podemos também ter acesso a uma IFeatureClass para editar, visualizar e listar as Features da tabela além de outras ferramentas úteis para controle dos dados geocoreferenciados.

Acesso ao ArcGis Server:

Connector.java

public class Connector {

    private static Log LOG = LogFactory.getLog(Connector.class);
    private IServerContext context;
    private Properties propriedades;

    public Connector() {
	try {
	    EngineInitializer.initializeEngine();
	    AoInitialize ao = new AoInitialize();
	    if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeEngine) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
		ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeEngine);
	    } else if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
		ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcView);
	    } else if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcEditor) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
		ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcEditor);
	    } else if (ao.isProductCodeAvailable(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcInfo) == com.esri.arcgis.system.esriLicenseStatus.esriLicenseAvailable) {
		ao.initialize(com.esri.arcgis.system.esriLicenseProductCode.esriLicenseProductCodeArcInfo);
	    }
	} catch (Exception e) {
	    Connector.LOG.error(e.getMessage(), e);
	}
    }

    public IServerContext getServerContext(){
	return this.context;
    }

    public IFeatureClass getFeatureClass(int layer) {
	MapServer mapServer = (MapServer) context.getServerObject();
	IMap map = mapServer.getMap(mapServer.getDefaultMapName());
	IFeatureLayer fLayer = (IFeatureLayer) map.getLayer(layer);
	return fLayer.getFeatureClass();
    }

    public void open() {
	try {
	    ServerInitializer serverInit = new ServerInitializer();
	    serverInit.initializeServer(propriedades.domain, propriedades.user, propriedades.psw);
	    ServerConnection connection = new ServerConnection();
	    connection.connect(propriedades.server);
	    IServerObjectManager som = connection.getServerObjectManager();
	    this.context = som.createServerContext(propriedades.service, propriedades.serviceType);
	} catch (AutomationException e) {
	    Connector.LOG.error("Problema ArcObjects");
	    Connector.LOG.error(e.getMessage());
	    this.close();
	} catch (IOException e) {
	    Connector.LOG.error("Problema com Release!");
	    Connector.LOG.error(e.getMessage());
	}
    }

    public void close() {
	try {
	    this.context.releaseContext();
	    Connector.LOG.debug("Conexao finalizada com sucesso!");
	} catch (AutomationException e) {
	    Connector.LOG.error("Problema com release!");
	    Connector.LOG.error(e.getMessage());
	    try {
		this.context.removeAll();
	    } catch (AutomationException e1) {
		e1.printStackTrace();
	    } catch (IOException e1) {
		e1.printStackTrace();
	    }
	} catch (IOException e) {
	    Connector.LOG.error("Problema com Release!");
	    Connector.LOG.error(e.getMessage(), e);
	}
    }
}

Desta forma também podemos ter acesso total a IFeatureClass e também controle para abrir e fechar conexões. Porém cada uma tem suas vantágens e desevantágens e como foi dito você precisa saber em qual escopo você está trabalhando para poder tirar proveito de cada uma.

Bom, é isso. Para um primeiro post acho que o conteudo está legal, ainda é preciso abordar algumas partes do código e irei aproveitar esse tema para continuar com o assunto em posts seguintes, irei aprofundar em exemplos de códigos para plataforma ESRI e como utilizar frameworks de DI(que eu utilizo também dentro dos meus projetos). Não espero muitos comentário nem muitas visualizações, mas realmente não é isso que preciso, quero apenas conseguir passar a informação para quem precisar e aos poucos aprender um pouco e conhecer pessoas da área. Estou focando mais no assunto relacionado a GIS pois encontro poucos exemplos/textos em português, então acredito que isso pode ajudar o pessoal a começar a desenvolver nessa plataforma.


Chegando agora

Desde que te trabalho com desenvolvimento de software quero ter um blog pra conseguir postar minhas conquistas e tentar aprender um pouco mais com as coisas que escrevo, e quem sabe passar a informação a diante. Aqui você vai encontrar posts relacionados com verramentas GIS plataforma ESRI, Java, C#, Python, Groovy, entre outras ferramentas que utilizei nesse pouco tempo de expêriencia que tenho. Tentarei postar pequenos tutoriais que vão direto ao assunto com links uteis e meu email sempre vai estar disponível para dúvidas, sugestões, elogios,críticas e um convite pra tomar um bom chopp. Bom, é isso ae.


Seguir

Obtenha todo post novo entregue na sua caixa de entrada.