地理位置数据

优质
小牛编辑
128浏览
2023-12-01

bugu-mongo支持地理位置数据的存储、索引、查询。相关的类都位于com.bugull.mongo.geo包中。

注意: MongoDB对于地理位置数据,默认使用的是WGS84坐标系。如果你的地理位置数据来源是其他坐标系的,请记得先进行转换。

存储、索引

MongoDB能够存储不同类型的地理位置数据,这些数据都是GeoJSON格式。

目前,bugu-mongo支持:

  • Point
  • LineString
  • Polygon
  • MultiPolygon

上述都是GeoJSON类型,而且都是普通的POJO,需要用@Embed来标注。

例:

@Entity
@EnsureIndex(value = "{location:2dsphere}")
public class MyPoint extends SimpleEntity {

    private String deviceName;

    @Embed
    private Point location;

    ...getter and setter...

}

注意,像上面的例子中那样,为了能够进行地理位置的查询,需要建立2dsphere索引。

上述MyPoint,保存到数据库后的一个document例子如下:

{
    deviceName : "D-SH-001",
    location : { type: "Point", coordinates: [ 40.8932, 5.3046 ] }
}

查询

bugu-mongo提供了GeoQuery,专门用来进行地理位置查询。GeoQuery继承自BuguQuery,在父类的基础上添加了地理位置相关的查询。

创建一个GeoQuery:

MyPointDao dao = new MyPointDao();
GeoQuery<MyPoint> query = dao.geoQuery();

GeoQuery中提供了如下几个方法:

public GeoQuery<T> nearSphere(String key, Point point)

public GeoQuery<T> nearSphere(String key, Point point, double maxDistance)

public GeoQuery<T> nearSphere(String key, Point point, double maxDistance, double minDistance)

public GeoQuery<T> geoWithin(String key, GeoJSON geo)

public GeoQuery<T> geoIntersects(String key, GeoJSON geoJson)

对Point的查询

对于一个给定的点(-73.856076, 40.848446),查询数据库中位于其附近的点,并取出距离最近的10条:

List<MyPoint> list = dao.geoQuery().nearSphere("location", new Point(-73.856076, 40.848446)).pageSize(10).pageNumber(1).results();

对于一个给定的点(-73.856081, 40.848451),查询数据库中与其距离在1000米以内的所有记录:

List<MyPoint> list = dao.geoQuery().nearSphere("location", new Point(-73.856081, 40.848451), 1000).results();

对Polygon的查询

假设用户在地图上画了一个多边形,要从数据库中查询出哪些点是位于这个多边形以内:

Polygon polygon = new Polygon();
double[] p1 = new double[]{1.1, 1.1};
double[] p2 = new double[]{2.2, 2.2};
double[] p3 = new double[]{3.3, 3.3};
double[] p4 = new double[]{4.4, 4.4};
polygon.setSingleRing(p1, p2, p3, p4, p1);

List<MyPoint> list = dao.geoQuery().geoWithin("location", polygon).results();

注意,Polygon中的形状,必须是个闭环,第一个点和最后一个点必须是同一个点。