woensdag 18 juni 2008

Het is me in de (aard)bol geslagen


“In mathematics, you don't understand things, you get used to them.” von Neumann

En met dat in gedachte zal ik toch proberen om een verhelderend stuk te schrijven over dit favoriete vak van menig programmeur. Waar heb ik dat aan te danken, hoor ik je denken en ergens heb je gelijk. Waarom zou ik je lastig vallen met een onderwerp waar je vroeger al slecht in was en wat je sinds het behalen van je diploma waarschijnlijk achteraan in je hersenen hebt geduwd (nog achter die genante herinneringen van toen je veertien was en je je geluk waagde bij het mooiste meisje van de klas). Hiervoor verwijs ik je naar Google in Mountain View, Californië. Die bedachten enkele jaren geleden dat het grappig zou zijn om een virtuele aarde te maken met aaneengeregen foto’s. Google Earth is in een korte tijd uitgegroeid tot een begrip en steeds vaker word je geconfronteerd met opdrachten waarbij locatiegegevens en kaarten een rol spelen. Het is een kwestie van tijd voordat je oog in oog komt te staan met de opgave om de afstand tussen twee coördinaten te berekenen en erachter komt dat deze coördinaten (uitgedrukt in lengtegraden en breedtegraden) niet altijd even ver van elkaar af staan. Met alleen de stelling van Pythagoras, die je ooit uit je hoofd hebt geknald omdat je wiskunde docent je wist te vertellen dat je hiermee alles kon uitrekenen, kom je letterlijk en figuurlijk nergens. Wat jij nodig hebt is een stevige dosis haversinus.

De haversinus formule kun je gebruiken om de afstand tussen twee coördinaten te berekenen en wel op de volgende manier:


  • Je neemt de radius van de aarde (R), 6371 km

  • Je neemt het verschil tussen de twee breedtegraden (∆b = b1 – b2)

  • Je neemt het verschil tussen de twee lengtegraden (∆l = l1 – l2)

  • En dan gooi je die in de onderstaande formule:

    afstand = R * (2 * atan2(√(sin2(∆b/2) + cos (b1) * cos(b2) * sin2(∆l/2) ), √(1-a)))


Ho ho ho, even een stapje terug, wat was die laatste? Laat me het uitdrukken in Java code, dat begrijp je vast beter.


public double calculateDistance(double long1, double long2, double lat1, double lat2) {
Integer r = new Integer(6371);
Double deltaLong = Math.toRadians(long1 - long2);
Double deltaLat = Math.toRadians(lat1 - lat2);
Double x = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(deltaLong/2) * Math.sin(deltaLong/2);
Double y = 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1-x));
Double z = r * y;
return z;
}

Ok, laten we het er maar op houden dat je in wiskunde niks begrijpt, maar er aan went.

dinsdag 17 juni 2008

Mozilla 3 Merge conflict


Mozilla heeft met Firefox 3 een behoorlijke verbetering geleverd op de vorige versie, minder geheugengebruik en snellere opstarttijden lossen het grootste probleem van de browser op. Maar dat neemt niet weg dat we niet nog een schop onder de gordel kunnen geven in de richting van Mozilla. Neem een kijkje naar de afbeelding, dit is de site zoals die live stond op de releasedag van Mozilla FireFox 3. Het ziet er naar uit dat er een SVN/CSV merge conflict door het net is geglipt.

maandag 9 juni 2008

Een webservice in 5 minuten


EJB 3.0 en webservice annotations maken het mogelijk om webservices te maken, zonder alle details te kennen van WSDL of binding of wat dan ook. Sterker nog, je kunt in enkele minuten een webservice maken. Het enige dat je nodig hebt is een interface klasse, een implementatie klasse en een paar annotations. Laten we dit eens van dichtbij bekijken met het aloude “Hello World” voorbeeld. Maak een EJB 3.0 project en maak daarin allereerst de interface klasse.

package nl.isaac.ejb.service;

import java.rmi.Remote;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style = Style.DOCUMENT)
public interface HelloWorld extends Remote {
String hello(String name);
}

Hierin zie je twee annotations staan. De eerste “@WebService” geeft simpelweg aan dat het om een webservice gaat. De tweede geeft aan welk soort SOAP binding je gebruikt, hierin heb je twee smaken “RPC” en “Document”. In het voorbeeld gebruik ik “Document”, maar in dit geval maakt het niet uit om hier “RPC” van te maken (Het verschil tussen document en RPC is grofweg gezegd dat RPC maar een enkel element als resultaat geeft en document een uitgebreid XML document terug kan geven). In de interface klasse staat verder alleen onze methode gedefinieerd. Let er wel op dat de interface jave.rmi.Remote extend. Nu kunnen we onze implementatie klasse maken.

package nl.isaac.ejb.service;

import javax.ejb.Stateless;
import javax.jws.WebService;

@Stateless
@WebService(endpointInterface = "nl.isaac.ejb.service.HelloWorld")
public class HelloWorldImpl {
public String hello(String name) {
return "Hello " + name;
}
}

Let erop dat, ondanks dat dit de implementatie klasse van een interface is, je deze niet implementeert met de code “implements HelloWorld”. Dit gebeurt in de annotation @WebService, die in deze methode zijn endpoint interface instelt. Deze verwijst naar de interface klasse die we zojuist gemaakt hebben. Onze methode wordt geïmplementeerd en voilá, een webservice is geboren. Deploy je project in JBoss en controleer voordat je een client maakt of je service draait door de WSDL file aan te roepen. Dit kun je doen door de URL van je project in IE in te voeren met daarachter “/HelloWorldImpl?wsdl”, dit zou je een XML document moeten tonen met alle details over de webservice.