• Spring Data MongDB空间索引(判断一个点Point是否在一个区域Polygon内)


    这里要连接MongoDB数据库,在配置文件里:spring.data.mongodb.uri = mongodb://root:root@localhost:27017/happy

    两个root分别是用户名和密码,happy是数据库名。

    首先创建一个实体类SiteExt.java

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
    import org.springframework.data.mongodb.core.index.CompoundIndex;
    import org.springframework.data.mongodb.core.index.CompoundIndexes;
    import org.springframework.data.mongodb.core.mapping.Document;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Document(collection = "SiteExt")
    @CompoundIndexes({
            @CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}"),
    })
    public class SiteExt {
        @Id
        private String plateNo;
    
        private GeoJsonPoint location;
    }

    注意这里使用了2dsphere索引

    {'location': '2dsphere'}


    测试用的就不再规范地写接口了,只写个实现类了。
    SiteExtDao.java
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.mongodb.core.BulkOperations;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
    import org.springframework.data.mongodb.core.query.Criteria;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.stereotype.Repository;
    import xy.study.mongdb.model.SiteExt;
    
    import java.util.List;
    
    @Repository
    public class SiteExtDao {
    
        @Autowired
        private MongoTemplate mongoTemplate;
    
    
        public List<SiteExt> findPointInPolygon(GeoJsonPolygon geoJsonPolygon, String collectionName) {
            Query query = new Query(Criteria.where("location").within(geoJsonPolygon));
            List<SiteExt> list = mongoTemplate.find(query, SiteExt.class,collectionName);
            return list;
        }
    
        public void insert(SiteExt siteExt, String collectionName) {
            mongoTemplate.insert(siteExt,collectionName);
        }
    
        public void insertBatch(List<SiteExt> list, String collectionName) {
    
            // BulkMode.UNORDERED:表示并行处理,遇到错误时能继续执行不影响其他操作;BulkMode.ORDERED:表示顺序执行,遇到错误时会停止所有执行
            BulkOperations ops = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, collectionName);
            ops.insert(list);
    
            // 执行操作
            ops.execute();
        }
    
    
        public List<SiteExt> findAll(String collectionName) {
            Query query=new Query();
            List<SiteExt> list = mongoTemplate.find(query, SiteExt.class,collectionName);
            return list;
        }
    }
    注意这里创建查询条件这里:Query query = new Query(Criteria.where("location").within(geoJsonPolygon));
    location是实体类SiteExt中建立了2dsphere索引的字段名,再调用within方法,传入区域对象GeoJsonPloygon。
    GeoJsonPlaygon代表的是一个区域对象,这个类在org.springframework.data.mongodb.core.geo包下面。

    先插入两条数据做测试:
    @Autowired
    private SiteExtDao siteExtDao;

    GeoJsonPoint geoJsonPoint1 = new GeoJsonPoint(new Point(113.330908,23.155678)); SiteExt siteExt1 = new SiteExt("A",geoJsonPoint1); GeoJsonPoint geoJsonPoint2 = new GeoJsonPoint(new Point(113.33831,23.137335)); SiteExt siteExt2 = new SiteExt("B",geoJsonPoint2);
    siteExtDao.insert(siteExt1,
    "SiteExt"); siteExtDao.insert(siteExt2,"SiteExt");
    
    
    
    然后查询哪些点在指定区域的操作来了:
            Point p1 = new Point(113.314882,23.163055);
            Point p2 = new Point(113.355845,23.167042);
            Point p3 = new Point(113.370289,23.149564);
            Point p4 = new Point(113.356779,23.129758);
            Point p5 = new Point(113.338238,23.13913);
            Point p6 = new Point(113.330979,23.124706);
            Point p7 = new Point(113.313588,23.140858);
            Point p8 = new Point(113.323865,23.158204);
            Point p9 = new Point(113.314882,23.163055);
    
            List<Point> list = new ArrayList<>();
            list.add(p1);
            list.add(p2);
            list.add(p3);
            list.add(p4);
            list.add(p5);
            list.add(p6);
            list.add(p7);
            list.add(p8);
            list.add(p9);
    
         //用9个点围成一个区域,首尾两个点p1和p9要相同,才能构成一个区域
            GeoJsonPolygon geoJsonPolygon = new GeoJsonPolygon(list);
    
         //传入区域数据库表名 List
    <SiteExt> pointInPolygon = siteExtDao.findPointInPolygon(geoJsonPolygon,"SiteExt");

          
            pointInPolygon.forEach(
    p -> {
    System.out.println(p.getLocation());
    }
    );
     
    
    
    
    上面9个点围成了一个多边形,在"SiteExt"表中查询哪些记录在这个多边形区域中。
    结果如下:
    Point [x=113.330908, y=23.155678]

    总结:就是建立2dsphere索引,利用查询语句
    Query query = new Query(Criteria.where("location").within(geoJsonPolygon))查询符合该区域的所有点;

    MongoDB原生查询数据表中哪些点记录在指定的区域:https://www.jb51.net/article/105796.htm
     
    
    
  • 相关阅读:
    省选模拟47 题解
    省选模拟46 题解
    死磕 java集合之PriorityQueue源码分析
    拜托,面试别再问我堆(排序)了!
    死磕 java集合之ConcurrentSkipListSet源码分析——Set大汇总
    死磕 java集合之CopyOnWriteArraySet源码分析——内含巧妙设计
    死磕 java集合之TreeSet源码分析
    死磕 java集合之LinkedHashSet源码分析
    死磕 java集合之HashSet源码分析
    死磕 java集合之ConcurrentSkipListMap源码分析——发现个bug
  • 原文地址:https://www.cnblogs.com/theRhyme/p/9483076.html
Copyright © 2020-2023  润新知