Compartilhar via


Windows Mobile

Use mapas de GPS e da Web para aplicativos com reconhecimento de local

Christopher Mitchell

Código disponível para download na MSDN Code Gallery
Navegue pelo código online

Este artigo aborda:

  • MapPoint Web services
  • Tarefas de cache e mapas
  • Obtendo pontos de interesse próximos
  • Criando novas tarefas
Este artigo usa as seguintes tecnologias:
Windows Mobile 6, MapPoint

Sumário

Usando o MapPoint para localização
Tarefas e Pocket Outlook
Arquitetura de aplicativos
Obtendo pontos próximos
Adicionando tarefas
Movendo-se no futuro

Recentemente me mudei para uma nova casa e alguns amigos gentis passaram um dia todo me ajudando a embalar e desembalar caixas, providenciar instalações de utilitários e todas as outras tarefas importantes, mas chatas de se mudar. No meu caminho de volta para buscar a última caixa na casa antiga, quase esqueci de comprar o jantar para os meus amigos. Eu havia colocado um lembrete no meu celular com Windows Mobile, mas ele não conseguiu me avisar quando eu estava passando pelo restaurante mais conveniente.

A solução de que eu precisava era um celular que me informasse quando eu estivesse perto de um local no qual eu pudesse realizar determinada tarefa. Um lembrete apropriado de hora e local teria feito com que tivéssemos comprado e aproveitado a comida em casa, em vez de dirigirmos por uma vizinhança desconhecida após um longo dia de mudança de caixas.

O Windows Mobile fornece várias interfaces e recursos que podem ajudar a manter o dispositivo informado sobre seu ambiente — onde ele está, onde ele possui um sinal, a intensidade do sinal e assim por diante. Mas como esses recursos podem ser usados em seus aplicativos? O mais proeminente e comprovadamente útil desses recursos é o reconhecimento de local. Ele deve permitir que você crie aplicativos com reconhecimento de local, variando do bastante óbvio programa de navegação por satélite à lista de tarefas muito mais sofisticada que será discutida aqui.

Este artigo examinará os problemas envolvidos com o uso desse recurso e o código adicional que você precisa escrever para desenvolver aplicativos úteis. Neste artigo, discutirei os utilitários e o ambiente de desenvolvimento de aplicativos móveis e mostrarei como criar um aplicativo de lista de tarefas com reconhecimento de local que possa lembrá-lo de uma tarefa, no momento e local adequados.

Usando o MapPoint para localização

Meu aplicativo de lista de tarefas com reconhecimento de local, chamado wheretodo, precisa executar várias tarefas principais. Ele precisa obter informações sobre onde o telefone está localizado geograficamente. Ele também precisa armazenar e monitorar tarefas. Além disso, o aplicativo precisa saber que lojas e serviços estão disponíveis perto da localização atual do telefone que poderia ser usada para resolver uma tarefa atual. Finalmente, ele precisa fornecer alertas para o telefone. A interface do aplicativo é exibida na Figura 1.

fig01.gif

Figura 1 Aplicativo Wheretodo

A primeira coisa que o aplicativo requer são os dados geográficos. Para a finalidade deste artigo, optei por usar o Microsoft MapPoint Web service. Esse Web service é a tecnologia subjacente para o Live Search Maps e o Virtual Earth e fornece um serviço próximo de pesquisa para a Europa e os EUA. O código de exemplo fornecido usa configurações de dados de mapas europeus; você precisará alterar essa opção para fazê-la funcionar em outro lugar.

O MapPoint obtém a latitude e longitude de um GPS e códigos de pesquisa para tipos específicos de lojas como seus argumentos. As informações de posicionamento podem ser fornecidas pelo utilitário FakeGPS quando instalado em um emulador ou smartphone. (Consulte o quadro "FakeGPS" para obter mais informações sobre esse utilitário.)

O MapPoint fornece um Web service XML com uma API SOAP. O Web service é dividido em quatro serviços principais: um serviço comum, um serviço de localização, um serviço de processamento e um serviço de roteamento. O serviço de interesse principal para esse aplicativo é o serviço de localização, mas se você quisesse fornecer direções ao usuário ou um mapa, os outros serviços poderiam ser usados para estender a funcionalidade.

O serviço comum (CommonServiceSoap) contém classes, métodos e propriedades comuns aos serviços de localização, roteamento e processamento ou que são funções básicas do utilitário.

O serviço de localização (FindServiceSoap) pode ser usado para localizar endereços, entidades geográficas, coordenadas de latitude e longitude e POIs (pontos de interesse) a partir de dados do MapPoint Web service. Também é possível analisar endereços e retornar informações de localização para uma determinada latitude e longitude.

Você pode usar o serviço de processamento (RenderServiceSoap) para desenhar mapas de rotas e localizações, colocar tachinhas, desenhar regiões poligonais, definir o tamanho e a visualização do mapa, selecionar pontos em um mapa, obter informações de localização sobre pontos e polígonos em um mapa e aplicar as funções de panorâmica e zoom em um mapa processado.

O serviço de roteamento (RouteServiceSoap) gera rotas, informações sobre como chegar de carro e representações de rotas calculadas (usadas para processar uma rota em destaque no mapa) com base em localizações ou marcos, define preferências de segmentos e rotas e gera visualizações do mapa de segmentos e direções.

Um conjunto completo de diagramas de classe de modelo de objeto existe no MSDN. O MapPoint mantém os dados usados para os serviços de localização, roteamento e processamento em várias fontes de dados diferentes dependendo da região geográfica ou do tipo de informações necessárias. Você poderá encontrar uma ampla variedade de artigos técnicos do MapPoint sobre como usar o serviço no MSDN.

Tarefas e Pocket Outlook

O POOM (modelo de objeto do Pocket Outlook) permite que você adicione menus e funcionalidades aos aplicativos de tarefas e contatos no Windows Mobile e para manipular seus itens e dados associados. Existem três interfaces principais de interesse em um aplicativo de reconhecimento de local: IAppointment, ITask e IContact.

A IAppointment representa um compromisso na pasta Calendário. Um objeto de compromisso pode representar uma reunião, um compromisso único ou um compromisso ou reunião recorrentes.

O ITask representa uma tarefa atribuída, delegada ou atribuída automaticamente a ser executada em um intervalo de tempo específico. Os itens da tarefa estão contidos na pasta Tarefas.

O IContact representa um contato da pasta Contatos. Seus métodos podem ser usados para salvar, excluir, duplicar ou exibir um contato. A interface IPOutlookItemCollection pode ser usada para adicionar novos contatos ou recuperar contatos existentes.

O aplicativo de exemplo usará ITask. (Funcionalmente, ele poderia usar IAppointment, mas essa interface não é tão adequada às necessidades imediatas do aplicativo.) O POOM é similar ao modelo de objeto do Outlook da área de trabalho e você pode aprender mais sobre ele no MSDN no artigo "Diferenças entre o modelo de objeto do Pocket Outlook e o modelo de objeto do Outlook".

Arquitetura de aplicativos

O aplicativo com reconhecimento de local é composto de duas cadeias de funções. A primeira é o sistema que monitora os problemas e as tarefas atuais, como exibido na Figura 2. As tarefas são armazenadas em uma tabela de banco de dados do SQL Server Compact. Além disso, um conjunto de dados auxiliares é armazenado em outra tabela chamada geocache. Usar a tabela separada é um meio de limitar a quantidade de conectividade necessária, como explicarei posteriormente neste artigo.

fig02.gif

Figura 2 Monitoramento e alertas de tarefas com reconhecimento de local

As informações para os pontos próximos são fornecidas pelo Microsoft MapPoint Web service. Existem diferentes fontes de dados no MapPoint Web service para diferentes partes do mundo e algumas possuem mais recursos que outras. A fonte de dados usada pelo aplicativo de exemplo é NavTech.EU. Quando essas informações forem reunidas, alguns cálculos de distância poderão ser executados e alertas emitidos, onde aplicável.

A segunda cadeia de eventos (consulte a Figura 3) adiciona tarefas à lista de tarefas no seu dispositivo Windows Mobile pelo POOM. Essa estrutura também permite acesso ao calendário e às funções SMS.

fig03.gif

Figura 3 Fluxo do sistema para adicionar tarefas ao aplicativo Wheretodo

Tarefas e Cache representam a primeira parte da cadeia de eventos de monitoramento e alerta. O gerenciador de tarefas simplesmente obtém uma lista de tarefas do POOM. Ele também gerencia o geocache, que resolve os problemas com o uso de Web services em dispositivos de conectividade potencialmente limitados. O nível de conectividade do dispositivo pode variar de conectividade permanente a escassamente conectado ou a sem conexão alguma.

Para lidar com a ampla variedade de intensidade de conectividade, você precisa de uma diretiva de cache decente para os dados do Web service e um sistema simples que saiba como aproveitar ao máximo a conectividade. Embora cenários muito complexos possam ser facilmente imaginados, uma simples diretiva de cache de raio foi estabelecida para a finalidade deste artigo. Por exemplo, uma consulta é feita no MapPoint Web service procurando todos os restaurantes chineses que fazem entrega em um determinado raio a partir do local atual, digamos 80 quilômetros (km). Depois que você tiver percorrido 40 km em qualquer direção, uma nova pesquisa será emitida. Isso se baseia no princípio de que cada consulta ao Web service é dispendiosa.

Supõe-se também que a distância que você viaja para longe do ponto onde inseriu a tarefa provavelmente não é de mais de 40 km. Como a distância usada para controlar as ações do cache provavelmente irá variar dependendo da pessoa e do país, ela deve ser inserida pelo usuário.

Registros de onde as consultas são executadas são armazenados no banco de dados de log do geocache e são verificados antes que qualquer consulta adicional seja feita para que informações duplicadas não sejam solicitadas do Web service. Eles também proporcionam a oportunidade de o sistema ser previamente preenchido com um volume considerável de informações.

FakeGPS

sidebarfig.gif

Aplicativo FakeGPS

O SDK do Windows Mobile 6 contém um aplicativo de utilitário chamado FakeGPS que permite a você testar seu aplicativo com dados simulados de GPS. Para obter informações sobre como instalar e testar usando o FakeGPS, consulte o artigo da Biblioteca MSDN "Usando o utilitário FakeGPS."

O FakeGPS lê um conjunto pré-gravado de instruções de GPS. Os dados do GPS podem ser obtidos de um dispositivo GPS real por um gravador de dados GPS bruto. O arquivo resultante é lido por um dispositivo FakeGPS e pode ser executado novamente, simulando a mudança de dados de locais, para fins de testes. Por exemplo, eu gravei uma viagem ao redor de Londres para coletar dados para o meu aplicativo e, em seguida, executei novamente a viagem pelo FakeGPS.

Obtendo pontos próximos

O componente a seguir define como o geocache é preenchido. Quando o aplicativo precisa encontrar um local, uma função GetNearByPOI é chamada (consulte a Figura 4). O código consulta o MapPoint Web service. Observe que o código mostrado aqui foi simplificado por motivos de clareza e é ligeiramente diferente do código de download.

Figura 4 Obtendo pontos de interesse próximos

private void GetNearByPOI(
  string KeyWord, LatLong CurrentPosition) {

  FindServiceSoap findService = new FindServiceSoap();
  FindNearbySpecification findNearBySpec = new FindNearbySpecification();
  findService.Credentials = 
    new System.Net.NetworkCredential(myUserName, myPassword);
  findService.PreAuthenticate = true;

  findNearBySpec.Distance = Convert.ToDouble(inputdistance.Text);
  findNearBySpec.LatLong = new LatLong();
  findNearBySpec.LatLong.Latitude = CurrentPosition.Latitude;
  findNearBySpec.LatLong.Longitude = CurrentPosition.Longitude;

  findNearBySpec.Filter = new FindFilter();
  //findNearBySpec.Filter.EntityTypeName = KeyWord;
  findNearBySpec.Filter.EntityTypeName = "FoodType3"; // SIC CODE
  findNearBySpec.DataSourceName = "NavTech.EU";

  FindResults foundResults;
  foundResults = findService.FindNearby(findNearBySpec);

  string connectionString;
  string fileName = System.IO.Path.GetDirectoryName(
    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + 
    "\\wheretodo.sdf";
  string password = "sa";
  connectionString = string.Format("DataSource=\"{0}\"; Password='{1}'", 
    fileName, password);
  SqlCeConnection cn = new SqlCeConnection(connectionString);
  cn.Open();
  SqlCeCommand cmd;

  //Loop Round and add it to the geocache
  foreach (FindResult fr in foundResults.Results) {
    //This needs to include LongLat in geocache
    string sql = 
      "insert into geocache2 (POI_Name, POI_Address, POI_Tel, POI_Web, " +
      "POI_POST_ZIP, POI_Lat, POI_Long, POI_KeyWord) " +
      "values (@Name, @Address, @Tel, @Web, @POST_ZIP, '" + 
      fr.FoundLocation.LatLong.Latitude.ToString() + 
      "', '" + fr.FoundLocation.LatLong.Longitude.ToString() + "', '" + 
      KeyWord.ToString() + "')";
    cmd = new SqlCeCommand(sql, cn);
    cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 255, "Name").Value = 
      fr.FoundLocation.Entity.Properties[0].Value.ToString();
    cmd.Parameters.Add("@Address", SqlDbType.NVarChar, 255, "Address").Value = 
      fr.FoundLocation.Entity.Properties[1].Value.ToString() + 
      fr.FoundLocation.Entity.Properties[2].Value.ToString();
    cmd.Parameters.Add("@Tel", SqlDbType.NVarChar, 255, "Tel").Value = 
      fr.FoundLocation.Entity.Properties[9].Value.ToString();
    cmd.Parameters.Add("@Web", SqlDbType.NVarChar, 255, "Web").Value = 
      "http://m.live.com";
    cmd.Parameters.Add("@POST_ZIP", SqlDbType.NVarChar, 255, "POST_ZIP").Value = 
      fr.FoundLocation.Entity.Properties[7].Value.ToString();
    cmd.ExecuteNonQuery();

    //Update geocachelog
    sql = "insert into GeoCodeLog (Keyword, Lat, Long ) values ('" + KeyWord + 
      "', '" + fr.FoundLocation.LatLong.Latitude.ToString() + "', '" + 
      fr.FoundLocation.LatLong.Longitude.ToString() + "' )";
    cmd = new SqlCeCommand(sql, cn);
    cmd.ExecuteNonQuery();
  }
}

Dê uma olhada na seção na qual CurrentPosition.Latitude e CurrentPosition.Longitude são chamados. Isso é derivado, por fim, do GPS Intermediate Driver, uma camada de software localizada entre aplicativos e o driver do dispositivo de hardware GPS. Essa camada de abstração permite que aplicativos sejam escritos uma vez e funcionem com vários dispositivos GPS. A API do GPS Intermediate Driver é exposta por meio de uma biblioteca de códigos nativos. Você pode obter acesso a essa biblioteca a partir de códigos gerenciados usando o exemplo incluído com o SDK do Windows Mobile 6 Professional (consulte "Usando o GPS Intermediate Driver a partir de códigos gerenciados)".

Depois de possuir o local atual e POIs próximos relevantes para a tarefa, identificados aqui por códigos SIC (classificação industrial padrão) usados na fonte de dados Navtech.EU, será necessário determinar exatamente a distância desses pontos do seu local atual. Eu usei os valores de longitude e latitude retornados do Web service e do GPS (neste caso, FakeGPS); a Figura 5 mostra como converti esses valores em distância.

Figura 5 Computando a distância

private double GetLatLongTuppleDistance(
  double Lat1, double Long1, double Lat2, double Long2) {

  //Convert Degress to Radians for Calculations
  double Lat1r = ConvertDegreesToRadians(Lat1);
  double Lat2r = ConvertDegreesToRadians(Lat2);
  double Long1r = ConvertDegreesToRadians(Long1);
  double Long2r = ConvertDegreesToRadians(Long2);

  // Spherical law of cosines formula—ignores the effect of hills
  double R = 6371; // Earth's radius (km)
  double d = Math.Acos(Math.Sin(Lat1r) * Math.Sin(Lat2r) +
    Math.Cos(Lat1r) * Math.Cos(Lat2r) *
    Math.Cos(Long2r—Long1r)) * R;
  //Returns distances in km
  return d;
} 

Uma função trigonométrica esférica baseada na lei esférica de co-senos (que generaliza o teorema de Pitágoras) fornece a função que transforma pares de latitude e longitude em distâncias em km. Isso obviamente cria grandes suposições sobre as coisas que bloqueiam onde você está do local que você está tentando encontrar. Como a terra não é uma esfera perfeita, haverá erros ao usar essas fórmulas. Para obter milhas, divida os km por 1,609344 e, caso você esteja indo comprar pão de barco, para milhas náuticas, divida os km por 1,852.

A parte final dessa cadeia de eventos é emitir o alerta ao usuário se uma solução para a tarefa for encontrada a uma certa distância do seu local atual. Como essa distância é determinada pelo modo de transporte — dirigir, caminhar, andar de bicicleta e assim por diante — isso foi deixado como uma entrada para o usuário.

Adicionando tarefas

É claro que, antes que o aplicativo possa encontrar um local, o usuário precisa adicionar tarefas para o dispositivo móvel. O POOM espelha o modelo de objeto do Outlook, mas seu escopo de funcionalidade é reduzido para acomodar as restrições práticas de dispositivos móveis.

Usando o POOM, é simples modificar e exibir itens de compromissos, tarefas e contatos, bem como manipular as pastas que os contêm. Veja o código para criar um item de tarefa:

OutlookSession outlooksession = new OutlookSession();
Task NewTask = new Task();
NewTask.Body = textBox2.Text.ToString();

string MyString = dateTimePicker2.Value.ToShortDateString() + " " + dateTimePicker1.Text.ToString();
DateTime MyDateTime = new DateTime();
MyDateTime = DateTime.ParseExact(MyString, "M/d/yy h:mm:ss tt", null);
NewTask.DueDate = MyDateTime.ToUniversalTime();
NewTask.Subject = textBox1.Text.ToString();
outlooksession.Tasks.Items.Add(NewTask);

Vários parâmetros podem ser alterados para definir a data de término e o texto do corpo da tarefa e, em seguida, adicioná-los ao POOM.

Esse componente forma a última das duas cadeias de componentes usadas para fornecer a funcionalidade do aplicativo wheretodo. A interface de usuário do sistema em si é muito simples e fornece um meio de configurar todas as informações relevantes e determinar os códigos SIC que o aplicativo irá procurar. O aplicativo inteiro é simplesmente encapsulado em um loop infinito apenas para ilustrar o uso de aplicativos com reconhecimento de local. Você poderia muito facilmente adicionar isso como um serviço de plano de fundo ao seu dispositivo móvel para torná-lo uma integração mais eficiente e simples no ambiente do Windows Mobile 6 ou Windows Mobile 5.

Recursos de dados móveis

Grave código uma só vez para aplicativos móveis e de desktop

Circulando: Aplicativos adaptáveis para o Windows Mobile

Pontos de dados: Acessando dados através de um aplicativo móvel

Movendo-se no futuro

Você viu um tipo de dispositivo com reconhecimento de local e uma ferramenta que facilita o desenvolvimento desses aplicativos. Esse conceito básico de uma lista de tarefas com reconhecimento de local poderia ser facilmente estendido para RFID.

Existem melhorias que podem ser feitas nesse código e se aplicam a qualquer aplicativo de reconhecimento de local. A maior compilação delas pode ser resumida por meio de como o reconhecimento de local é vinculado a outros serviços de reconhecimento de contexto executados na maioria dos celulares. As tarefas não têm idéia do que você está tentando fazer, apenas de onde você está. Você pode destinar tarefas a uma hora e um local para que elas sejam disparadas quando você se aproximar de algo em um determinado horário (digamos, ao dirigir da sua casa ao trabalho). Ainda melhor, o lembrete de tarefa saberia que você tem uma reunião em 10 minutos e saberia também que não há tempo suficiente para comprar selos, mesmo que você esteja passando perto do correio no caminho para a reunião.

Se estiver interessado em criar um instalador personalizado para esse aplicativo ou seu próprio aplicativo com reconhecimento de local recém-atualizado, consulte meu artigo da edição de outubro de 2007 da MSDN Magazine (Ajuste o volume do seu toque de acordo com o som ambiente).

Gostaria de dedicar este artigo a Tom Passey, um querido amigo que, juntamente com sua esposa, se preocupa comigo em várias ocasiões, fornecendo grandes memórias. Desejo a vocês tudo de bom.

Christopher Mitchell concluiu seu doutorado em aprendizado de máquina e processamento de sinais de música/som, foi membro Kauffman/NCGE e atualmente está comprometido com um projeto em Cambridge, Reino Unido. Ele trabalha meio período como professor acadêmico na Anglia Ruskin University, Cambridge, Reino Unido. Você pode entrar em contato com Chris pelo endereço chris.mitchell@anglia.ac.uk.