<\/HEAD>
A família de produtos dos ArcGIS Runtime SDKs<\/A> é compatível com uso offline desde a versão 10.2. Nesse contexto, mapas base e dados vetoriais podem ser exportados de serviços, e no caso dos dados vetoriais, também sincronizados. Para ilustrar essas funcionalidades, a Esri Alemanha desenvolveu um aplicativo de demonstração que reproduz a funcionalidade offline do Collector for ArcGIS<\/A> usando o ArcGIS Runtime SDK para .NET<\/A> e Java<\/A>. Essa demo se chama Collector Light e está publicada no GitHub<\/A>. Além disso, já foi publicado um blog<\/A> sobre o tema.<\/SPAN><\/P>Neste artigo, agora, usando como exemplo a demo em Java, será analisado mais detalhadamente o processo de exportação e sincronização de dados vetoriais.<\/SPAN><\/P>
<\/H2>Agora finalmente começa a programação<\/SPAN><\/H2>Não precisamos implementar diretamente essas interfaces REST. Elas já são encapsuladas pelo ArcGIS Runtime SDK for Java, de modo que temos classes e métodos Java disponíveis para isso. O uso para exportar dados vetoriais pode ser encontrado na demo na classe action.CreateOfflineProject. Mais precisamente no método createGeodatabaseFromService. <\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/><\/>.
Após uma pequena preparação dos dados devido ao uso de uma WebMap, começa a parte interessante na linha 330 com a criação dos GenerateGeodatabaseParameters.
//set up the parameters
GenerateGeodatabaseParameters params = new GenerateGeodatabaseParameters(
ArrayUtils.toPrimitive(layerIds.toArray(new Integer[layerIds.size()])),
extent,
map.getSpatialReference(),
false,
SyncModel.GEODATABASE,
map.getSpatialReference());
Aqui fica claro que é possível restringir os dados a serem exportados. Por um lado existe a possibilidade de selecionar camadas individuais do serviço. Por outro lado pode-se fornecer uma extensão (extent), limitando assim a área. Também anexos podem ser carregados, mas não necessariamente precisam ser. Além disso é importante fornecer um sistema de coordenadas desejado como parâmetro para que os dados possam ser exibidos corretamente em nosso mapa posteriormente. Em seguida são necessárias duas classes Callback. Uma é usada para receber informações de status durante o tempo de execução. A outra é chamada quando a tarefa termina e finalmente recebe o resultado. Agora entra em cena a classe GeodatabaseSyncTask , que faz a chamada real generateGeodatabase.
// ------------------------------------------------------------------------
// Generate the geodatabase from the service and download
// ------------------------------------------------------------------------
GeodatabaseSyncTask gdbTask = new GeodatabaseSyncTask(featureServiceUrl, PortalConnector.getUser(true));
gdbTask.generateGeodatabase(params, pathToGdb, false, statusCallback, gdbResponseCallback);
Para criar essa classe só é necessário o URL do FeatureService. Caso seja um serviço protegido, deve-se também passar as credenciais conforme neste exemplo. Detalhes sobre autorização e autenticação estão em um blog separado.
Onde estão meus dados agora?
No gdbResponseCallback deste exemplo apenas informa-se ao ProjectManager que novos dados estão disponíveis. Portanto surge a pergunta: onde estão meus dados? Eles estão no caminho e nome que foram passados como parâmetro (pathToGdb) na chamada. Ao nome ainda é anexada a extensão .geodatabase. Os dados estão em uma estrutura de banco de dados, mais precisamente em formato SQLite e podem ser visualizados com qualquer ferramenta SQLite comum.
Como os dados entram no meu mapa?
Mas queremos visualizar os dados em nosso mapa e não em alguma outra ferramenta. Para isso o ArcGIS Runtime SDK for Java oferece a classe FeatureLayer. Ela pode ser criada com base em várias fontes de dados diferentes. Essa é a vantagem dessa classe. Independentemente da fonte de dados o manuseio é sempre o mesmo. Uma dessas fontes de dados é a GeodatabaseFeatureTable. Acessamos essas tabelas usando nosso SQLite Inicializar o banco de dados com a ajuda da classe Geodatabse. Para cada camada individual, uma GeodatabseFeatureTable é criada.<\/SPAN><\/P><\/P>Geodatabase localGeodatabase = new Geodatabase("PathToGeodatabase");
for (GeodatabaseFeatureTable table : localGeodatabase.getGeodatabaseTables()) {
FeatureLayer featureLayer = new FeatureLayer(table);
featureLayer.initializeAsync();
} <\/PRE><\/P>Eu quero ligar para casa novamente<\/SPAN><\/H2>Então, agora os dados estão offline. Podemos nos mover livremente, longe da civilização digital, e coletar, alterar ou excluir dados. Mas em algum momento chegará a hora em que queremos compartilhar nossas alterações com nossos colegas. Além disso, talvez eu queira saber o que eles fizeram na minha ausência. Portanto, precisamos entrar em contato com a nave-mãe (o FeatureService). Na demonstração, isso acontece na classe action.SyncProject. O método syncGeodatabase na já conhecida classe GeodatabaseSyncTask nos ajuda com isso.<\/SPAN><\/P><\/P>gdbTask.syncGeodatabase(syncParams, gdb, statusCallback, syncResponseCallback);<\/PRE><\/P>Novamente vemos os dois callbacks para mensagens de status e para o resultado. Como outros parâmetros, precisamos do Geodatabase (gdb) e de parâmetros especiais SyncGeodatabaseParameters. Já criamos o Geodatabase no passo anterior para visualizar os dados. E também não precisamos nos preocupar com os SyncParameters, pois eles são gerados pelo Geodatabase.<\/SPAN><\/P><\/P>final SyncGeodatabaseParameters syncParams = gdb.getSyncParameters();<\/PRE><\/P>Isso tem a vantagem de que não precisamos conhecer a estrutura complexa do banco de dados para extrair nossas alterações. Porque sempre é transmitido apenas o delta, não o banco de dados completo. Durante a sincronização, todas as alterações no serviço também são transferidas para meu banco de dados local, para que eu possa continuar trabalhando com os dados mais atualizados. Aqui também é transmitido apenas o delta. Isso também pode ser visto no gráfico a seguir, que representa schematicamente todo o fluxo de trabalho.<\/SPAN><\/P><\/P>
<\/P>Se vários colegas fizeram alterações em um registro, sempre prevalece a última alteração. Considerando que o carimbo de data/hora da sincronização conta e não o carimbo de data/hora da alteração. No futuro, também haverá outras opções para resolver conflitos que poderão ser configuradas por serviço. Atualmente isso ainda não é possível.<\/SPAN><\/P><\/H2>Vamos acabar com a vida de eremita<\/SPAN><\/H2>Em algum momento esperamos voltar ao escritório e não precisar mais da cópia local dos dados. Então é importante não simplesmente excluí-los, mas primeiro fazer um Unregister no serviço. Claro que aqui temos novamente a classe GeodatabaseSyncTask disponível para isso, desta vez com o método unregisterGeodatabase.<\/SPAN><\/P><\/P>gdbTask.unregisterGeodatabase(gdb, unregisterCallback);<\/SPAN><\/PRE><\/P>Na demonstração este chamado está na classe action.DeleteProject. Mas por que essa chamada é tão importante? O FeatureService cria uma chamada Replica para cada cópia. Nela estão armazenadas informações sobre a cópia como por exemplo o momento da última sincronização. Esses dados são necessários para realizar o mecanismo de sincronização. No Unregister essa Replica é excluída porque o serviço então sabe que a cópia local não é mais necessária. As Replicas de um serviço também podem ser vistas no seu Service Directory.<\/SPAN><\/P><\/P>
<\/P><\/BODY><\/HTML>