GeoJsonPoints的问题

项目里存储车辆位置用到了mongdb的GeoJsonPoints,但是报错说反序列化找不到默认的构造器
(no args construtor like new GeoJsonpoints(){}…)

查找了相似的问题和帖子:
https://stackoverflow.com/questions/52915203/jackson-serialize-geojsonpoint-as-latitude-longitude
https://stackoverflow.com/questions/48088738/spring-requestbody-with-geojsonpoint

更奇怪的是,写了个简单的demo,并没问题…

1、POJO类

    /**
     * ClassName SiteExt
     * Author  Lin
     * Date 2019/5/30 16:56
     **/
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Document(collection = "SiteExt")
        @CompoundIndexes({
                @CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}"),
        })
        public class SiteExt {
            @Id
            private String plateNo;
        
            private GeoJsonPoint location;
        }

2、DAO类

package com.skywilling.cn.manager.car.service.impl;

import com.skywilling.cn.manager.car.model.AutonomousCarInfo;
import com.skywilling.cn.manager.car.model.SiteExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
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 java.util.List;

/**
 * ClassName SiteExtDao
 * Author  Lin
 * Date 2019/5/30 16:57
 **/

@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;
    }

    public List<SiteExt> findByDist(GeoJsonPoint geoJsonPoint, double dis) {

        Criteria geoCriteria = Criteria.where("location").nearSphere(geoJsonPoint).maxDistance(dis);
        Query query = Query.query(geoCriteria);
        return  mongoTemplate.find(query,SiteExt.class);
    }

    public SiteExt nearVehicle(GeoJsonPoint point) {
        Criteria geoCriteria = Criteria.where("location").nearSphere(point);
        Query query= Query.query(geoCriteria);
        query.with(new PageRequest(0,1));
        return mongoTemplate.find(query,SiteExt.class).get(0);
    }
}

3、测试类

    @Test
    public void TestGeoJsonPoints(){
        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");
    }
    @Test
    public void TestGeoPolgy(){
        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());
                }
        );
        SiteExt near = siteExtDao.nearVehicle(new GeoJsonPoint(new Point(113.330908,23.155678)));
        System.out.println(near);
        List<SiteExt> res = siteExtDao.findByDist(new GeoJsonPoint(new Point(113.33,23.14)),2000);
        System.out.println(res);
    }

4、测试结果

Point [x=113.330908, y=23.155678]

SiteExt(plateNo=A, location=Point [x=113.330908, y=23.155678])

[SiteExt(plateNo=B, location=Point [x=113.338310, y=23.137335]), SiteExt(plateNo=A, location=Point [x=113.330908, y=23.155678])]

demo测试结果完全没毛病

4、项目中也是当做自己类的一个字段,


@Data
@AllArgsConstructor
@NoArgsConstructor
@Repository
@Document(collection = "autonomousCarInfo")
//复合索引,加复合索引后通过复合索引字段查询将大大提高速度,如@CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}")
//lastName和age将作为复合索引age_idx,数字参数指定索引的方向,1为正序,-1为倒序。方向对单键索引和随机存不要紧,但如果你要执行分组和排序操作的时候,它就非常重要了
//空间索引(判断一个点POINT是否在一个区域POLYGON内)
@CompoundIndexes({
        @CompoundIndex(name = "location_index", def = "{'position':'2dsphere'}"),
        @CompoundIndex(name = "lane_station_idx", def = "{'lane':1, 'station':1}"),
})

public class AutonomousCarInfo implements Serializable {

  private static final long serialVersionUID = 23412341209L;
  @Id
  private String vin;
  @Field
  private String tripId;
  @Field
  private int state;
  @Field
  private String taskId;
  @Field
  private double velocity;
  @Field
  private double wheelAngle;
  @Field
  private double gear;
  @Field
  private Pose pose;
  @Field
  private String station;
  /** 当前的lane*/
  @Field
  private String fromLane;
  /** 预瞄的lane*/
  @Field
  private String lane;
  @Field
  private long timestamp;
  @Field
  private List<ModuleInfo> RosNodes;
  /**
  * 便于直接使用geohash索引
   * */
  private GeoJsonPoint geoJsonPoint;

  public AutonomousCarInfo(String vin) {
    this.vin = vin;
    this.tripId = null;
  }
/*  public AutonomousCarInfo(String vin, GeoJsonPoint jsonPoint){
    this.vin = vin;
    this.setGeoJsonPoint(jsonPoint);
  }*/

}

6、总结
猜想是我们字段直接使用了GeoJsonPoints这个数据结构,但是这个库中类没有默认构造函数,序列化不受控,利用fastJson解析的时候找不到反序列化标准。

后来思考可能是demo用的带参构造函数来创建实例,而我项目中是用new AutonomoCarinfo();然后setXXX来传入的方式,尝试了加入了新的带参数构造函数,也没解决。

最后也没解决这个问题,直接不用了。-。-

你可能感兴趣的:(Java,自动驾驶)