geo.js: Geolocation and Geocoding (pure) JavaScript library

Some people may know the geo-location-javascript, it supports, besides W3C Geolocation API, several other devices and platforms. I’ve used it before, but I always thought it could do better. I mean, it could be more flexible, support more alternatives, like GeoIP.

So I started to search for alternative libraries, until I found locate_me, this library doesn’t support so many platforms as geo-location-javascript, but it has support for providers, in the way that I can write my own geolocation providers. But it has some drawbracks, like not following the W3C Geolocation interface and not offering the polling functions (watchPosition and clearWatch). It also relies on Prototype, although some people don’t see this as a disadvantage.

As I could not find any other library that could fulfill my needs, I built my own. It has support for all the platforms supported by geo-location-javascript, plus geoip services, and it also support custom location providers. In addition, it support geocoding providers, so that when you receive the device’s location, you can geocode it to obtain its address.

This library has the same interface that of W3C Geolocation API, including the polling functionality. The polling functions are provided by the native device’s APIs, when enabled, and when the API has no support for it, the library uses his own implementation of watchPosition and clearWatch.

 Supported platforms

    • W3C Geolocation API
    • iOS
    • Android
    • BlackBerry OS
    • Browsers with Google Gears support
    • Nokia Web Run-Time
    • webOS Application Platform
    • Torch Mobile Iris Browser
    • Mozilla Geode

GeoIP Services

    • freegeoip.net
    • geoip.pidgets.com
    • geoplugin.com

Reverse Geocoding Service

    • Google Geocoding API
    • GeoNames
    • Nominatim OpenStreetMap

Getting Started

Include the gears_init.js, util.js and geo.js libraries in your html:


<script src="http://code.google.com/apis/gears/gears_init.js"></script>
<script src="js/util.js"></script>
<script src="js/geo.js"></script>

Now you can start the library:


Geo.init();

This is the default starter, the library will try to find the first available location provider to use. But you can give a provider to the initializer, as a string or object:


Geo.init('W3C');

//or

Geo.init(new Geo.LocationProvider.W3C());

To get the user location you just do this:


if (Geo.init()) {
Geo.getCurrentPosition(function(p) {
console.log(p);
}, function(e) {
console.log("Error " + e.code + ": " + e.message);
});
}

 

Methods

The Geo object will provide, besides the init(), the following methods:

  • getCurrentPosition(successCallback, errorCallback, options) try to get the current position of the device, passing it to the successCallback. In case of error, errorCcallback is called.
  • watchPosition(successCallback, errorCallback, options) the arguments work the same way as before. But this method will call the successCallback every time the device’s position changes. It also returns an ID corresponding to the watcher. Some APIs have this method natively implemented, in these cases this library just redirects the call, but if the API has no support, the library uses an own implementation.
  • clearWatch(watchId) stops the watcher created with the method above.

 

The options argument, is an object that can have one or more of those attributes:

  • boolean enableHighAccuracy
  • long timeout
  • long maximumAge
Other methods:
  • getIPAddress() returns the device’s IP address.
  • autoSetLocationProvider() automatically chooses the location provider.
  • setLocationProvider(p) set the location provider to be used. Can be, as in the init() a string or object instance.

Create your own Location Provider

This library has been built to enable the usage of custom location providers, the following example shows how to do that:


// This is just a dummy provider
Geo.LocationProvider.MyProvider = Geo.LocationProvider.Base.extend({
getCurrentPosition: function(successCallback, errorCallback, options) {
       successCallback(this.parseResult({
          latitude: -37,
          longitude: 11
       }));
    }
});
Geo.LocationProvider.MyProvider.available = function() {
    return true;
};

Geo.init('MyProvider');

Your location providers must be placed before the Geo.init() in order to be included in the provider auto selection. They also need to be created as an attribute of Geo.LocationProvider object to be registered.

 

Default Providers

This is the list of the default providers:

  • W3C
  • Gears
  • Bondi
  • Mojo
  • Nokia
  • FreeGeoIp
  • GeoIpPidgets
  • GeoPlugin

Reverse Geocoding

This library also support (reverse) geocoding providers. The Geo.Position object has a method for reversing geocoding his coordinates:


Geo.init();
Geo.getCurrentPosition(success_callback);

function success_callback(p) {
p.geocode(function(data) {
       console.log(p);
    });
}

When you call the geocode() method, the callback is optional, because the function will set the address retrieved by geocoding in the p object. Although there is a Geo.Address object, it is not used when doing geocoding because the Google Geocoding API can return several address components (see).

Currently there is three geocoding providers available (‘Google’, ‘GeoNames’, ‘Nominatim’). When calling the geocode() method, you can also provide to the function the geocoding provider that you would like to use:


p.geocode(function(data) {
console.log(p);
}, 'Google');

// or

p.geocode(function(data) {
console.log(p);
}, new Geo.CodingProvider.GeoNames());

In order to use the Google Geocoding API you need to include the GMaps library in your html:


<script src="http://maps.google.com/maps/api/js?sensor=false"></script>

And if you’re using the GeoNames service, you need to create an account, login into your account and enable free web services, and then inform the library what’s your username:


if (Geo.init()) {
// provide your username to use the geonames web service
    Geo.CodingProvider.GeoNames.username = 'myusername';
    Geo.getCurrentPosition(success_callback, error_callback);

function success_callback(p) {
       p.geocode(function(data) {
          console.log(data);
       }, 'GeoNames');
    }

function error_callback(p) {
       console.log(p);
    }
}

You can also write your own geocoder:


Geo.CodingProvider.MyGeocoder = Class.extend({
// this is the method called when geocode the Geo.Position object p
    geocode: function(p, callback) {
       // call the geocoding service using jsonp or through a proxy (ajax)
       // and then if there is a callback return the result
       if (callback) callback(results);

       // you need also to set the address in the Geo.Position object p
       p.address = results;
    }
});

// here you check if the service is available
Geo.CodingProvider.MyGeocoder.available = function() {
    return true;
};

Like the location providers, the geocoding providers must be placed before the Geo.init() call.

 

Download

Github

Obter a hora certa via Internet com Java

Se você precisa obter a hora atual com confiabilidade, é possível fazer isso através do protocolo NTP (Network Time Protocol). No mundo todo a hora certa é padronizada através do UTC (Coordinated Universal Time), no Brasil a definição da hora fica a cargo o Observatório Nacional, e através de um acordo entre este e o NIC.br a hora certa no Brasil é distribuída gratuitamente via Internet através do projeto NTP.br. Este projeto disponibiliza vários servidores NTP para a consulta da hora certa no Brasil.

Aqui irei mostrar um código muito simples em Java para a consulta da hora certa utilizando um dos servidores do NTP.br. Para utilizar o protocolo NTP vou fazer uso da biblioteca Apache Commons Net, disponível aqui.

A lista de servidores do NTP.br pode ser obtida neste link. No exemplo abaixo eu estou usando apenas um dos servidores, mas dependendo da necessidade de cada um seria interessante verificar se o servidor está funcionando, e em caso negativo buscar a hora em outros servidores, de preferência servidores diferentes dos do NTP.br. Você pode encontrar servidores NTP aqui e aqui.

    try {
        String ntpServer = "a.st1.ntp.br";

        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(ntpServer);
        TimeInfo timeInfo = timeClient.getTime(inetAddress);
        long returnTime = timeInfo.getReturnTime();
        Date time = new Date(returnTime);
        System.out.println("Hora para " + ntpServer + ": " + time);
    } catch (UnknownHostException ex) {
        ex.printStackTrace();
    }   catch (IOException ex) {
        ex.printStackTrace();
    }

Como eu disse antes, você pode modificar o código para procurar a hora em vários servidores. É bom tratar estas exceptions também, chamei apenas o print por ser um exemplo simples. Considero muito útil buscar a hora em um servidor confiável principalmente quando da necessidade de se obter a hora correta, algo que pode não ser obtido quando a fonte é a máquina local. Isso é interessante quando pensamos em aplicações Java desktop rodando nas máquinas de clientes.

Contornando o Cache do Hibernate

Dica rápida: quando você carrega um objeto utilizando Hibernate, modifica o mesmo e salva (utilizando update(), merge() ou saveOrUpdate()) e em outra funcionalidade de seu aplicativo obtém novamente o mesmo objeto através do Hibernate é comum que seja retornado o objeto em cache, com os valores desatualizados. Admito ter demorado mais de uma hora para encontrar uma alternativa que não fosse desabilitar o cache. Para a minha alegria, isso funcionou:

Objeto obj = (Objeto) session.get(Objeto.class, id);
session.refresh(obj);

Quando o método refresh() é chamado, ocorre a releitura do objeto no banco de dados, trazendo o último estado do objeto, ignorando o objeto em cache (ou atualizando, desconheço o funcionamento em detalhes). Testei os métodos flush() (semelhante ao commit()) e clear(), mas nenhum deles conseguiu resgatar o último estado do objeto. Ou é desconhecimento de minha parte, ou o Hibernate não atualiza o cache depois de realizada uma alteração em algum objeto da sessão. Se existe alguma forma de avisar o Hibernate sobre a alteração para que ele atualize o objeto em cache, desconheço.

StrutsTool: Desenvolvendo Aplicações em Struts sem Sofrimento

Um dos aspectos que mais chama a atenção no desenvolvimento de aplicações com Struts é a quantidade de passos necessários para criar aplicações relativamente simples. Quem já usou sabe como é custoso criar um simples CRUD.

Isso trás grande frustração para quem desenvolve aplicações web, inclusive eu. Isso se dá principalmente pois o Struts necessita de extensa configuração. Cada action que você cria precisa ser mapeada em um arquivo xml, se você usar Tiles o negócio é pior ainda, é xml para todo lado.

O pior é que isso acontece em outras frameworks Java, como o Spring. Porém esta adotou o uso de anotações ao invés de xml, mas não deixa de ser configuração. Fato é que com as anotações você não precisa criar tantos arquivos, mas ainda assim precisa escrever muitas linhas para fazer a coisa funcionar.

Com uma rápida busca na internet é possível encontrar diversas discussões sobre quando utilizar Java para web ou qual é a melhor dentre as frameworks para Java (a Wikipedia lista 35 frameworks para Java). Kelby Zorgdrager faz em um artigo uma comparação entre frameworks Java, com tabelas de pontuação para os pontos mais relevantes de uma framework. Para encurtar a história, de modo geral (não conclusivo) Struts e JSF tem as melhores notas. Entretanto, frameworks como Stripes e Tapestry tem melhores notas quando falamos em RAD, isso porque ambas se utilizam de convenção ao invés de configuração.

Nessas horas muitos diriam para trocar de linguagem, mas isso depende muito das necessidades e recursos disponíveis para o projeto. Não vou entrar nesta discussão, a internet já está cheia delas, tendo destaque as com títulos como: “linguagem A vs linguagem B”.

Continue lendo…

Melhorando a segurança dos Cookies

Estou desenvolvendo um sistema de administração básico com o Zend Framework para utilizar em meus projetos, também pretendo escrever algo sobre ele aqui, bem como disponibilizá-lo. Enfim, durante o seu desenvolvimento estava planejado a implementação da funcionalidade de lembrar-se do login no sistema.

Esta é uma funcionalidade muito utilizada e é algo muito prático para quem não aprecia digitar a senha dezenas de vezes (talvez por isso acabem as esquecendo). Apesar de ser uma mão na roda para muita gente, essa funcionalidade pode trazer consigo muitas implicações de segurança, estas citadas por Nicholas Zakas em seu blog e que eu vou resumir aqui.

Continue lendo…

JCalendar no NetBeans

Estou usando Java já faz alguns meses, e por estes dias me perguntei se havia algum datepicker disponível, deveria vir por padrão no Swing. Procurei na internet e encontrei várias soluções, algumas das melhores eram pagas, para variar. Foi então que eu encontrei o JCalendar, este me pareceu o mais bem apresentado dentre os free que encontrei.

A última versão data do início de 2009 mas, pensando bem, quantas melhorias mais um datepicker pode precisar? E o que mais me interessou foi a possibilidade de adicionar o JCalendar na paleta de componentes do Swing, até porque ficar codificando o datepicker de uma tela é perda de tempo.

Leia o resto…

Skin para jPlayer: quase tão bom quanto flash

Há alguns dias estava lendo alguns artigos sobre HTML5, então me perguntei se existia algum player mp3 que suportasse a tecnologia. Não foi difícil encontrar scripts, o problema fica na questão visual dos players, todos os que eu encontrei possuíam um visual muito simples se comparado com os desenvolvidos em flash.

Dos scripts que encontrei o que mais me agradou visualmente foi o jPlayer, escrito em javascript com jQuery. Gostei dele porque além de suportar HTML5 ele ainda dá suporte para browsers antigos através de um arquivo flash para tocar mp3. O player pode ainda ser customizado através de css e na área de downloads é possível baixar vários exemplos de utilização do player, incluindo uma demo com playlist.

Depois de ter encontrado o plugin fui em busca de skins para este, mas não encontrei. Por isso decidi pegar uma skin de um player em flash e adaptar para o jPlayer para ver o quanto fiel seria possível se manter do original. Fiz uso do jQuery para construir as funções que iriam tratar do comportamento da skin e montei uma classe para organizar o código e facilitar a utilização da skin.

A skin que eu escolhi foi esta, ela é uma das várias skins do site MixPod que permite a criação de playlists e players personalizados.  A seguir eu irei mostrar como se utiliza a classe e para quem preferir no fim do post há um link para baixar todos os arquivos com exemplos. Eu pretendia explicar também como funciona a classe, mas como ela ficou um pouco extensa preferi deixá-la bem comentada e aqui apenas abordar a sua utilização. Sei que muita gente gosta de ver e depois baixar (incluindo eu), então segue abaixo um print de como ficou a skin:

Leia o resto…

Follow

Get every new post delivered to your Inbox.