1. 程式人生 > >mongodb-mongotemplate進行地理座標操作

mongodb-mongotemplate進行地理座標操作

因為專案中使用的springboot + mongotemplate, 所以還是需要mongotemplate的操作方式

首先建立一個bean: 

package com.iwhere.easy.travel.entity;

import java.io.Serializable;
import java.util.Arrays;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

/**
 * 收費poi
 * 
 * @author wenbronk
 * @time 2017年7月19日 下午4:46:39
 */

@Document(collection = "charge_poi")
public class ChargePoi implements Serializable {
    private static final long serialVersionUID = 2653147280472201924L;

    @Id
    private String _id;

    @Indexed
    private String poi_id;
    private String poi_name;
    @GeoSpatialIndexed
    private Double[] location;
    private String media_url;
    private Double price;

    public ChargePoi() {
        super();
    }

    @PersistenceConstructor
    ChargePoi(String _id, String poi_id, String poi_name, Double[] location, String media_url, Double price) {
        super();
        this._id = _id;
        this.poi_id = poi_id;
        this.poi_name = poi_name;
        this.location = location;
        this.media_url = media_url;
        this.price = price;
    }

    public ChargePoi(String _id, String poi_id, String poi_name, Double x, Double y, String media_url, Double price) {
        super();
        this._id = _id;
        this.poi_id = poi_id;
        this.poi_name = poi_name;
        this.location = new Double[]{x, y};
        this.media_url = media_url;
        this.price = price;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    public String getPoi_id() {
        return poi_id;
    }

    public void setPoi_id(String poi_id) {
        this.poi_id = poi_id;
    }

    public String getPoi_name() {
        return poi_name;
    }

    public void setPoi_name(String poi_name) {
        this.poi_name = poi_name;
    }

    public Double[] getLocation() {
        return location;
    }

    public void setLocation(Double[] location) {
        this.location = location;
    }

    public String getMedia_url() {
        return media_url;
    }

    public void setMedia_url(String media_url) {
        this.media_url = media_url;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "ChargePoi [_id=" + _id + ", poi_id=" + poi_id + ", poi_name=" + poi_name + ", location="
                + Arrays.toString(location) + ", media_url=" + media_url + ", price=" + price + "]";
    }
}

注: @GeoSpatialIndexed 註解的作用:

Mark a field to be indexed using MongoDB's geospatial indexing feature.
開始沒有加這個註解, 然後計算距離的時候就會報錯

1, 準備測試資料: 

 /**
     * save
     */
    @Test
    public void test1() {
        for (int x = 100; x < 131; x++) {
            for (int y = 30; y < 61; y++) {
                Double loca[] = new Double[]{Double.valueOf(x), Double.valueOf(y)};
                ChargePoi chargePoi = new ChargePoi();
                chargePoi.setPoi_id("poiid" + x);
                chargePoi.setMedia_url("http://www.baidu.com?params=" + x);
                chargePoi.setPoi_name("vini" + Arrays.toString(loca));
                chargePoi.setPrice(Math.random() * 100);
                chargePoi.setLocation(loca);
                mongoTemplate.insert(chargePoi);
            }
        }
    }

2, 圓形查詢

    /**
     * circle
     */
    @Test
    public void test2() {
        Circle circle = new Circle(30, 20, 20);
        List<ChargePoi> find = mongoTemplate.find(new Query(Criteria.where("location").within(circle)), ChargePoi.class);
        System.out.println(find);
        System.out.println(find.size());
    }

3, 球星查詢

    /**
     * spherical 
     */
    @Test
    public void test3() {
        Circle circle = new Circle(30,20, 20);
        List<ChargePoi> find = mongoTemplate.find(new Query(Criteria.where("location").withinSphere(circle)), ChargePoi.class);
        System.out.println(find.size());
        System.out.println(find);
    }

4, 矩形查詢, box

/**
     * box
     */
    @Test
    public void test4() {
        Box box = new Box(new Point(10, 11), new Point(10, 20));  
        List<ChargePoi> find = 
                mongoTemplate.find(new Query(Criteria.where("location").within(box)), ChargePoi.class);
        System.out.println(find.size());
        System.out.println(find);
    }

5, 按距離由近到元查詢

/**
     * near
     */
    @Test
    public void test5() {
        Point point = new Point(12, 12);
        List<ChargePoi> venues = 
                mongoTemplate.find(new Query(Criteria.where("location").near(point).maxDistance(20)), ChargePoi.class);
        System.out.println(venues.size());
        System.out.println(venues);
    }

6, 空間距離查詢

/**
     * nearSphere
     */
    @Test
    public void test6() {
        Point point = new Point(12, 12);
        List<ChargePoi> venues = 
                mongoTemplate.find(new Query(Criteria.where("location").nearSphere(point).maxDistance(20)), ChargePoi.class);
        System.out.println(venues.size());
        System.out.println(venues);
    }

7, 最近點查詢

@Test
    public void test7() {
        Point location = new Point(12, 12);
        NearQuery query = NearQuery.near(location).maxDistance(new Distance(100000, Metrics.KILOMETERS));
        GeoResults<ChargePoi> result = mongoTemplate.geoNear(query, ChargePoi.class);
        System.out.println(result);
    }

http://docs.spring.io/spring-data/data-mongo/docs/1.5.2.RELEASE/reference/html/mongo.core.html#mongo.geospatial