Spring boot and mongodb with geo-localisation queries 1/3

MongoDB offers a number of indexes and query mechanisms to handle geospatial information, below are some of the features offered by the database :

  • Surfaces
  • Location Data
  • Query Operations
  • Geospatial indexes
  • .....

More detailed information can be found at their website : MongoDB Geospatial queries

In this 3 part post we will be creating a sample REST API application using Spring Boot, Spring Data and MongoDB to determinate if a given "Interest Point" is within a certain distance of the provided coordinates

1. Setup

Before we start please ensure that you have a running MongoDB instance

So let's get things started, we will be using Gradle as our build tool for this project, if you're not familiar with this build tool you can read the documentation

Below is the build file used to build our project, there is some noise in here that is related to IDE support as well as a few things needed to deploy this application in heroku which can be avoided but I've chosen to leave here for the sake of completion, the most interesting parts for us are the dependencies



buildscript {
 ext {
  springBootVersion = '1.5.2.RELEASE'
 }
 repositories {
  mavenCentral()
 }
 dependencies {
  classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
 }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'




jar {
 baseName = 'spring_mongodb_geospatial_api'
 version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
 mavenCentral()
}

task stage {
    dependsOn build
}


task wrapper(type: Wrapper) {
    gradleVersion = '2.6'
}


task copyToLib(type: Copy) {
    into "$buildDir/lib"
    from(configurations.compile)
}

stage.dependsOn(copyToLib)

dependencies {
 compile('org.springframework.boot:spring-boot-starter-data-mongodb') {
  exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
 }
 compile('org.springframework.boot:spring-boot-starter-web') {
  exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
 }
 compile('org.springframework.boot:spring-boot-starter-actuator'){
  exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
 }

 compile('org.springframework.boot:spring-boot-starter-log4j')

 compileOnly ("org.projectlombok:lombok:1.16.14")

 testCompile('org.springframework.boot:spring-boot-starter-test'){
  exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
 }
}


eclipse {
 classpath {
   containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
   containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
 }
}


Let's configure our spring boot application with the base info for our application to run (default profile, MongoDB info, etc.):

spring:
    application:
        name: spring_mongodb_geospatial_api
    profiles:
      active: dev



---
spring:
  profiles: dev
  data:
    mongodb:
      host: localhost
      port: 27017
      repositories:
        enabled: true

Let's now configure our bootstrap class :


package com.ufasoli.tutorials.mongogeospatial.ws;

import com.fasterxml.jackson.databind.Module;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.geo.GeoJsonModule;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@Configuration
@EnableAsync
public class SpringMongoDBGeospatial {

     public static void main(String[] args) {
 SpringApplication.run(SpringMongoDBGeospatial.class, args);
     }

    //Register a custom Serializer/Deserializer for the geospatial information
    @Bean
    public Module registerGeoJsonModule(){
        return new GeoJsonModule();
    }
}

This is a pretty standard spring boot class except for the fact that we are declaring a custom JSON Serializer/Deserializer for handling geospatial information

Finally let's create our data model :

package com.ufasoli.tutorials.mongogeospatial.ws.model;

import lombok.Data;

import java.util.Date;


@Data
public class Updatable {

    private Date createdAt;
    private Date updatedAt;

    private Long updatedTimestamp;


}



package com.ufasoli.tutorials.mongogeospatial.ws.model;

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.mapping.Document;

import java.io.Serializable;
import java.util.List;


@Document
@Data
public class InterestPoint extends Updatable implements Serializable {

    @Id
    private String uuid;

    @NotBlank
    private String displayName;

    private String displayPhoto;


    private List categories;

    @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
    private GeoJsonPoint location;


    public InterestPoint() {
    }

    public InterestPoint(String uuid, String displayName) {
        this.uuid = uuid;
        this.displayName = displayName;
    }

    public InterestPoint(String uuid, String displayName, GeoJsonPoint location) {
        this.uuid = uuid;
        this.displayName = displayName;
        this.location = location;
    }


}


package com.ufasoli.tutorials.mongogeospatial.ws.model;

import java.io.Serializable;

/**
 * Created by ufasoli
 */
public enum Category implements Serializable{

    CAFE,
    BAR,
    RESTAURANT,
    MUSEUM,
    BANK,
    METRO_STATION,
    BUS_STATION,
    THEATRE,
    HOTEL
}


And that it's for today, on the next part we will set up the web application and controllers

1 comment:

  1. The effectiveness of IEEE Project Domains depends very much on the situation in which they are applied. In order to further improve IEEE Final Year Project Domains practices we need to explicitly describe and utilise our knowledge about software domains of software engineering Final Year Project Domains for CSE technologies. This paper suggests a modelling formalism for supporting systematic reuse of software engineering technologies during planning of software projects and improvement programmes in Project Centers in Chennai for CSE.

    Spring Framework has already made serious inroads as an integrated technology stack for building user-facing applications. Spring Framework Corporate TRaining the authors explore the idea of using Java in Big Data platforms.
    Specifically, Spring Framework provides various tasks are geared around preparing data for further analysis and visualization. Spring Training in Chennai

    ReplyDelete

OSX show used ports or listening applications with their PID

On OSX you can display applications listening on a given port using the lsof the commands described below will show listening application...