mongoTemplate 查询圆形范围类数据 圆与矩形范围类数据 圆与多边形范围类数据

package cn.com.reformer.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageInfo;

import cn.com.reformer.common.util.DataUtil;
import cn.com.reformer.model.event.EventCondition;
import cn.com.reformer.model.vo.AnalysisVo;

@Service
public class MongoDBService {

    @Resource
    private MongoTemplate mongoTemplate;
    
    //分页获取圆形数据
    public PageInfo<AnalysisVo> getCircleEventPage(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS)).limit(condition.getPageSize())
                .skip((condition.getPageNum() - 1) * condition.getPageSize());
        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
        PageInfo<AnalysisVo> pageInfo = new PageInfo<>(DataUtil.convert(geoResults.getContent(), condition));
        pageInfo.setTotal(this.getCircleEventCount(condition));
        pageInfo.setPageNum(condition.getPageNum());
        pageInfo.setPageSize(condition.getPageSize());
        return pageInfo;
    }

    // 获取圆形范围类数据
    public List<AnalysisVo> getCircleEvent(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS)).limit(condition.getPageSize())
                .skip((condition.getPageNum() - 1) * condition.getPageSize());
        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
        return DataUtil.convert(geoResults.getContent(),condition);
    }
    
    // 获取圆形范围类数据数量
    public Long getCircleEventCount(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        Circle circle = new Circle(new Point(condition.getLongitude(), condition.getLatitude()),
                new Distance(condition.getRadius(), Metrics.KILOMETERS));
        querys.addCriteria(Criteria.where("point").withinSphere(circle));
        return mongoTemplate.count(querys, "resource");
//        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
//                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS));
//        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
//        return geoResults.getContent().size();
    }
    
    /*--------------------------------------------------------------------------------------------------------------------------*/
    
    // 分页获取矩形内点范围类数据
    public PageInfo<AnalysisVo> getCircleBoxEventPage(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        Box box = new Box(condition.getBox().get(0).stream().mapToDouble(Double::valueOf).toArray(),
                condition.getBox().get(1).stream().mapToDouble(Double::valueOf).toArray());
        querys.addCriteria(Criteria.where("point").within(box));
        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS)).limit(condition.getPageSize())
                .skip((condition.getPageNum() - 1) * condition.getPageSize());
        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
        PageInfo<AnalysisVo> pageInfo = new PageInfo<>(DataUtil.convert(geoResults.getContent(), condition));
        pageInfo.setTotal(this.getCircleBoxEventCount(condition));
        pageInfo.setPageNum(condition.getPageNum());
        pageInfo.setPageSize(condition.getPageSize());
        return pageInfo;
    }

    // 获取矩形内点范围类数据
    public List<AnalysisVo> getCircleBoxEvent(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        Box box = new Box(condition.getBox().get(0).stream().mapToDouble(Double::valueOf).toArray(),condition.getBox().get(1).stream().mapToDouble(Double::valueOf).toArray());
        querys.addCriteria(Criteria.where("point").within(box));
        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude()))
                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS)).query(querys)
                .limit(condition.getPageSize())
                .skip((condition.getPageNum() - 1) * condition.getPageSize());
        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
        return DataUtil.convert(geoResults.getContent(),condition);
    }
    
    // 获取矩形内点范围类数据量
    public Long getCircleBoxEventCount(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        Box box = new Box(condition.getBox().get(0).stream().mapToDouble(Double::valueOf).toArray(),
                condition.getBox().get(1).stream().mapToDouble(Double::valueOf).toArray());
        Circle circle = new Circle(new Point(condition.getLongitude(), condition.getLatitude()),
                new Distance(condition.getRadius(), Metrics.KILOMETERS));
        querys.addCriteria(Criteria.where("point").withinSphere(circle).andOperator(Criteria.where("point").within(box)));
        return mongoTemplate.count(querys, "resource");
//        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
//                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS));
//        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
//        return geoResults.getContent().size();
    }
    
    /*--------------------------------------------------------------------------------------------------------------------------*/
    
    // 获取多边形内点坐标范围类数据
    public PageInfo<AnalysisVo> getCirclePolygonEventPage(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        List<Point> points = new ArrayList<Point>();
        Point point = null;
        for (int i = 0; i < condition.getBox().size(); i++) {
            Double X = condition.getBox().get(i).stream().mapToDouble(Double::valueOf).toArray()[0];
            Double Y = condition.getBox().get(i).stream().mapToDouble(Double::valueOf).toArray()[1];
            point = new Point(X, Y);
            points.add(point);
        }
        Polygon poly = new Polygon(points);
        querys.addCriteria(Criteria.where("point").within(poly));
        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS)).limit(condition.getPageSize())
                .skip((condition.getPageNum() - 1) * condition.getPageSize());
        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
        PageInfo<AnalysisVo> pageInfo = new PageInfo<>(DataUtil.convert(geoResults.getContent(), condition));
        pageInfo.setTotal(this.getCirclePolygonEventCount(condition));
        pageInfo.setPageNum(condition.getPageNum());
        pageInfo.setPageSize(condition.getPageSize());
        return pageInfo;
    }

    // 获取多边形内点坐标范围类数据
    public List<AnalysisVo> getCirclePolygonEvent(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        List<Point> points = new ArrayList<Point>();
        Point point = null;
        for (int i = 0; i < condition.getBox().size(); i++) {
            Double X = condition.getBox().get(i).stream().mapToDouble(Double::valueOf).toArray()[0];
            Double Y = condition.getBox().get(i).stream().mapToDouble(Double::valueOf).toArray()[1];
            point = new Point(X, Y);
            points.add(point);
        }
        Polygon poly = new Polygon(points);
        querys.addCriteria(Criteria.where("point").within(poly));
        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude()))
                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS)).query(querys)
                .limit(condition.getPageSize())
                .skip((condition.getPageNum() - 1) * condition.getPageSize());
        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
        return DataUtil.convert(geoResults.getContent(),condition);
    }
    
    // 获取多边形内点坐标范围类数量
    public Long getCirclePolygonEventCount(EventCondition condition) {
        Query querys = this.getCommonQuery(condition);
        List<Point> points = new ArrayList<Point>();
        Point point = null;
        for (int i = 0; i < condition.getBox().size(); i++) {
            Double X = condition.getBox().get(i).stream().mapToDouble(Double::valueOf).toArray()[0];
            Double Y = condition.getBox().get(i).stream().mapToDouble(Double::valueOf).toArray()[1];
            point = new Point(X, Y);
            points.add(point);
        }
        Polygon poly = new Polygon(points);
        Circle circle = new Circle(new Point(condition.getLongitude(), condition.getLatitude()),
                new Distance(condition.getRadius(), Metrics.KILOMETERS));
        querys.addCriteria(Criteria.where("point").withinSphere(circle).andOperator(Criteria.where("point").within(poly)));
        return mongoTemplate.count(querys, "resource");
//        NearQuery query = NearQuery.near(new Point(condition.getLongitude(), condition.getLatitude())).query(querys)
//                .maxDistance(new Distance(condition.getRadius(), Metrics.KILOMETERS));
//        GeoResults<Object> geoResults = mongoTemplate.geoNear(query, Object.class, "resource");
//        return geoResults.getContent().size();
    }
    
    /*--------------------------------------------------------------------------------------------------------------------------*/
    
    //通用条件类
    public Query getCommonQuery(EventCondition condition) {
        Query querys = new Query();
        List<String> typeList = new ArrayList<String>();
        typeList.addAll(condition.getYjType());//应急类型
        typeList.addAll(condition.getFhType());//防护类型
        typeList.addAll(condition.getWxType());//危险源类型
        typeList.addAll(condition.getSpType());//视频监控类型
        querys.addCriteria(Criteria.where("typeCode").exists(true));//typeCode为空不计入统计
        // 模块名
        if (StringUtils.isNotEmpty(condition.getModuleName())) {
            querys.addCriteria(Criteria.where("moduleName").is(condition.getModuleName()));
        }
        // 通用名称
        if (StringUtils.isNotEmpty(condition.getName())) {
            Pattern pattern = Pattern.compile("^.*" + condition.getName() + ".*$", Pattern.CASE_INSENSITIVE);
            querys.addCriteria(Criteria.where("name").regex(pattern));
        }
        // 应急类型+防护类型+风险类型 + 区域
        if (typeList.size() > 0 || condition.getArea().size() > 0) {
            Criteria criteria = new Criteria();
            List<Criteria> list1 = new ArrayList<Criteria>();
            List<Criteria> list2 = new ArrayList<Criteria>();
            Criteria criteria1 = new Criteria();
            Criteria criteria2 = new Criteria();
            //类别
            for (String type : typeList) {
                list1.add(Criteria.where("typeCode").is(type));
            }
            //区域
            for (String area : condition.getArea()) {
                Pattern pattern = Pattern.compile("^.*" + area + ".*$", Pattern.CASE_INSENSITIVE);
                list2.add(Criteria.where("jsonObj").regex(pattern));
            }
            criteria1.orOperator(list1.stream().toArray(Criteria[]::new));
            criteria2.orOperator(list2.stream().toArray(Criteria[]::new));
            if (list1.size() + list2.size() > 0) {
                // 没有等于号
                if (list1.size() > 0 && list2.size() > 0) {
                    criteria.andOperator(criteria1, criteria2);
                }
                // 一个等于号
                if (list1.size() == 0 && list2.size() > 0) {
                    criteria.andOperator(criteria2);
                }
                if (list1.size() > 0 && list2.size() == 0) {
                    criteria.andOperator(criteria1);
                }
                querys.addCriteria(criteria);
            }
        }
        return querys;
    }

}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NuoleAQ

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值