Writing Geospatial Queries for MongoDB in Java


MongoDB supports 2-dimensional geospatial indexes. This presentation will help you understand it at a basic level.

In this article, I will help you quickly write Geospatial queries described in above presentation using Java programming language. Source code for this article is available at this Github project.

A repository of Gegraphical Places

Below Java class is a simple repository of all major cities in California, US.


public class Places
{
 public static final String[] cities = new String[]

{ "Palos Verdes Estates", "Los Altos Hills", "Hillsborough", "Monte Sereno", "Villa Park", "Palo Alto",
 "Belvedere", "Los Altos", "Rolling Hills", "Montecito", "Piedmont", "Foster City", "Yorba Linda",
 "Mission Canyon", "Saratoga", "Orinda", "Manhattan Beach", "Pleasanton", "Imperial", "Goleta", "Tiburon",
 "Tustin Foothills", "Rancho Palos Verdes", "Mountain View", "La Habra Heights", "Newport Beach",
 "Toro Canyon", "Agoura Hills", "Redondo Beach", "Menlo Park", "Mill Valley", "Indian Wells", "Moraga",
 "Ross", "La Palma", "Kensington", "Hermosa Beach", "Thousand Oaks", "Belmont", "Rolling Hills Estates",
 "Loyola", "Summerland", "Santa Monica", "Rossmoor", "Irvine", "Lafayette", "Laguna Niguel", "Torrance",
 "Fairbanks Ranch", "Cupertino", "Santa Barbara", "Portola Valley", "Woodside", "San Ramon", "Santa Ynez",
 "Emerald Lake Hills", "Angwin", "El Segundo", "Orange", "West Menlo Park", "West Bishop", "Ladera Heights",
 "Huntington Beach", "Atherton", "Coronado", "Danville", "Diamond Bar", "Rancho Santa Fe", "Chino Hills",
 "Clayton", "Walnut", "San Anselmo", "Solvang", "Cerritos", "Blackhawk-Camino Tassajara",
 "Highlands-Baywood Park", "Fountain Valley", "Westlake Village", "Sunnyvale", "Poway", "Del Monte Forest",
 "Brea", "San Carlos", "Los Gatos", "Rancho Santa Margarita", "Camarillo", "Cypress", "Newport Coast",
 "San Joaquin Hills", "Folsom", "Arroyo Grande", "Malibu", "Sausalito", "Del Rio", "Green Valley",
 "Mission Viejo", "Aliso Viejo", "Stanford", "Encinitas", "Rancho Mirage" };
}

Geospatial Queries Program

<pre>public class GeospatialExample

{
 public static final String dbName = "geospatial";
 public static final String host = "127.0.0.1";
 public static final int port = 27017;
 public static final String collectionName = "places";
 public static final String indexName = "geospatialIdx";

 Mongo mongo;
 DBCollection collection;

 private Mongo getMongo() {
 try
 {
 mongo = new Mongo(new DBAddress(host, port, dbName));
 }
 catch (MongoException e)
 {
 e.printStackTrace();
 }
 catch (UnknownHostException e)
 {
 e.printStackTrace();
 }
 return mongo;
 }

 public static void main(String[] args)
 {
 new GeospatialExample().runExample();

}

private void runExample()
 {
 collection = getMongo().getDB(dbName).getCollection(collectionName);
 collection.ensureIndex(new BasicDBObject("loc", "2d"), indexName);

 addPlaces();
 findWithinCircle();
 findWithinBox();
 findWithinPolygon();
 findCenterSphere();
 findNear();
 findNearSphere();

}

private void findWithinCircle()
 {
 List circle = new ArrayList();
 circle.add(new double[] { 5, 5 }); // Centre of circle
 circle.add(1); // Radius
 BasicDBObject query = new BasicDBObject("loc", new BasicDBObject("$within",
 new BasicDBObject("$center", circle)));

printOutputs(query);

}

private void findWithinBox()
 {
 List box = new ArrayList();
 box.add(new double[] { 4, 4 }); //Starting coordinate
 box.add(new double[]{6,6}); // Ending coordinate
 BasicDBObject query = new BasicDBObject("loc", new BasicDBObject("$within",
 new BasicDBObject("$box", box)));

printOutputs(query);

}

private void findWithinPolygon()
 {
 List polygon = new ArrayList();
 polygon.add(new double[] { 3, 3 }); //Starting coordinate
 polygon.add(new double[]{8,3}); // Ending coordinate
 polygon.add(new double[]{6,7}); // Ending coordinate
 BasicDBObject query = new BasicDBObject("loc", new BasicDBObject("$within",
 new BasicDBObject("$polygon", polygon)));

printOutputs(query);
 }

 private void findNear() {
 BasicDBObject filter = new BasicDBObject("$near", new double[] { 4, 4 });
 filter.put("$maxDistance", 2);

BasicDBObject query = new BasicDBObject("loc", filter);

 printOutputs(query);
 }

 private void findNearSphere() {
 BasicDBObject filter = new BasicDBObject("$nearSphere", new double[] { 5, 5 });
 filter.put("$maxDistance", 0.06);
 // Radius of the earth: 3959.8728

BasicDBObject query = new BasicDBObject("loc", filter);
 printOutputs(query);
 }

 private void findCenterSphere() {
 List circle = new ArrayList();
 circle.add(new double[] { 5, 5 }); // Centre of circle
 circle.add(0.06); // Radius
 BasicDBObject query = new BasicDBObject("loc", new BasicDBObject("$within",
 new BasicDBObject("$centerSphere", circle)));

printOutputs(query);
 }

public void printOutputs(BasicDBObject query)
 {
 DBCursor cursor = collection.find(query);
 List<BasicDBList> outputs = new ArrayList<BasicDBList>();
 while (cursor.hasNext())
 {
 DBObject result = cursor.next();
 System.out.println(result.get("name") + "--->" + result.get("loc"));
 outputs.add((BasicDBList) result.get("loc"));
 }

 for (int y = 9; y >= 0; y--)
 {
 String s = "";
 for (int x = 0; x < 10; x++)
 {
 boolean found = false;
 for (BasicDBList obj : outputs)
 {
 double xVal = (Double) obj.get(0);
 double yVal = (Double) obj.get(1);
 if (yVal == y && xVal == x)
 {
 found = true;
 }
 }
 if(found) {
 s = s + " @";
 } else {
 s = s + " +";
 }
 }
 System.out.println(s);
 }
 }


private void addPlaces()
 {
 for (int i = 0; i < 100; i++)
 {
 double x = i % 10;
 double y = Math.floor(i / 10);
 addPlace(collection, Places.cities[i], new double[] { x, y });
 }
 }

 private void addPlace(DBCollection collection, String name, final double[] location)
 {
 final BasicDBObject place = new BasicDBObject();
 place.put("name", name);
 place.put("loc", location);
 collection.insert(place);
 }

}

 

One thought on “Writing Geospatial Queries for MongoDB in Java

  1. This is the perfect webpage for anybody who would like to find out about this topic. You understand so much its almost hard to argue with you (not that I actually would want to…HaHa). You certainly put a brand new spin on a topic that’s been written about for ages. Great stuff, just great!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s