I have a deceptively simple requirement to create a software component to record and update some mobile position information, then be able to perform simple queries concerning mobiles in a particular area. When I say 'mobile' think aircraft and ocean-going ships. When I say 'simple queries' think 'Give me a list of all the mobiles in some region' or 'Give me the list of all mobiles within X km of mobile Y'. A simple, yet basically complete API for this component in Java might look like this:

import java.util.List;
public interface MobileTracker {
/** Tell us that this mobile should be tracked. */
public void logonMobile( int mobileId );
/** Tell us that this mobile should no longer be tracked. */
public void logoffMobile( int mobileId );
/** Update the current position of the logged on mobile */
public void updatePosition( int mobileId, double lat, double lng );
/** Finds all of the mobiles in the given region (circular or polygon). */
public List<Integer> getMobilesInRegion( /* Region region */ );
/** Finds all mobiles within radiusKm km of mobileId's current location */
public List<Integer> getMobilesNear( int mobileId, double radiusKm );
}

I'm looking for a Java library that will help me implement this. Preferably one that is not GPL, and doesn't have a million dependencies for a bunch of other functions that I don't need.

I don't work in the GIS domain, so as I looked here for help, I find myself in terminology-overload. It seems to me I should be looking for a spatial-database. This data doesn't actually need to be persistent here, so I would prefer something I could embed and run in-memory only. This question looked promising, but after a bit of digging on the HatBox site, I see it uses JTS which uses 2-D math, which I don't think is accurate enough for my needs, as I'm dealing with distances of 100s or 1000s of km (maybe this should be another question).

My question comes down to:

Am I right in assuming I need a spatial-database, or are there better solutions? Can you make some suggestions?

3 Answers
3

It's a complex problem. You either have to project the data or do your distance calculations taking into account the shape of the earth. You approximate the shape of the earth with a sphere or, more accurately, with an ellipsoid. If you're dealing with whole world, sticking to geographic coordinates (expressed in decimal degrees) may be simpler.

Take a look at GeoTools, in particular org.geotools.referencing.GeodeticCalculator for your distance calculations. GeoTools also uses JTS for functions like 'contains' but I don't think there would be a problem with accuracy. Just make sure all of your data is using the same coordinate reference system.

The best solution depends on what you'll end up doing, if it is restricted purely to distance calculations and you can accept sub-meter errors in the results, you can probably get away with just implementing Vincenty's formula, as long as your data is all in a consistent datum of geographic coordinates (probably WGS84 from your description). Since you've stated your new to GIS, I'd just mention that you should always track the datum along with the coordinates, not doing so leads to the same kinds of problems that not having encoding information does if you have text.

If you're going to convert between projections, then you need a library which can handle that, and if you're going to do things like area computations, then probably the best option in the Java space is GeoTools as Sean mentioned.

If you decide for a spatial database, have you considered using SpatiaLite? Not in-memory but portable as a file (following SQLite's model). The position of the mobile can be added to a table, then spatial queries using distance expressed in SQL like at the end of this section of the tutorial.