基于Springboot使用MongoDB进行简单Gis操作
2017-09-15 15:26
791 查看
MongoDB使用json数据结构进行数据存储和组织,并提供了对gis的操作支持。mongoDB中基于GeoJson数据格式存储地理信息,并提供了一组函数对地理信息进行操作。因为项目需要,需要进行简单gis操作。在此就简单应用详述一二。
关于GeoJson数据的详细形式,及说明可参见官网。
下面列举项目中一个简单的geojson字符串,描述的是一个地理区域。
描述一个点的geojson字符串。
可以在geojson.io得到在线生成的geojson数据。
新建Springboot项目,添加mongoDB的相关依赖jar包,并配置好数据库连接,使用mongo中数据库为gis,具体方式参见之前的文章。新建Collection,名称为geographicalRegion,保存地理信息对象。示例如下:
创建geoJson的domain对象。Spring-data-mongodb提供了对geoJson的抽象封装。提供了GeoJsonPolygon、Polygon、Line、GeoJsonPoint等类对geojson相关属性进行封装。
我们定义GisRegion对象,用来保存geojson地理信息,以及相关区域的名称和标识码code。如下所示:
自定义数据库dao并使用MongoTemplate。
测试方法:
关于mongoDB中对地理位置的其他操作,例如搜索指定范围内的指定目标,目标点附近的指定目标等功能都有支持,spring-data-mongodb中都提供了封装函数。可以在MongoTemplate中查看更多的gis操作方法。基于MongoDB更复杂的gis交互,有待进一步研究。
GeoJson数据格式
GeoJson数据本质是一个json字符串,保存地理位置信息。关于GeoJson数据的详细形式,及说明可参见官网。
下面列举项目中一个简单的geojson字符串,描述的是一个地理区域。
{ "_id" : 1, "regionName" : "北京市", "regionCode" : "010", "regionType" : "province" "geometry" : { "type" : "Polygon", //geojson中地理类型,在此表示一个区域类型,其他类型可参考geojson官方文档。 "coordinates" : [ //用于描述地理详细信息,一个[x,y]表示一个点的坐标[经度,纬度],在此区域信息,可以是一个包含多个点的闭环区域,首末坐标相同,形成闭环。 [ [ 117.209782, 40.082243 ], [ 117.116937, 40.071038 ], ... , [ 117.209782, 40.082243 ] ] ] } }
描述一个点的geojson字符串。
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [ 110.654296875, 41.902277040963696 ] } } ] }
可以在geojson.io得到在线生成的geojson数据。
基于Springboot的mongodb gis操作
下面介绍一个地理围栏功能的功能实现,以此论述mongoDB对gis的操作过程。地理围栏功能,即给定一个点坐标,判断是否在一个指定区域内,超出就报警。新建Springboot项目,添加mongoDB的相关依赖jar包,并配置好数据库连接,使用mongo中数据库为gis,具体方式参见之前的文章。新建Collection,名称为geographicalRegion,保存地理信息对象。示例如下:
{ "_id" : 1, "regionName" : "北京市", "regionCode" : "010", "regionType" : "province", "geometry" : { "type" : "Polygon", "coordinates" : [...] } }
创建geoJson的domain对象。Spring-data-mongodb提供了对geoJson的抽象封装。提供了GeoJsonPolygon、Polygon、Line、GeoJsonPoint等类对geojson相关属性进行封装。
我们定义GisRegion对象,用来保存geojson地理信息,以及相关区域的名称和标识码code。如下所示:
@Document(collection = "geographicalRegion") //spring.data为mongodb定义的注解,直接映射数据库的document名称 public class GisRegion { @Id //指定字段的主键字段 private int locationId; @Field("regionName") //属性映射数据库document属性名称,若未指定,默认存储实体类属性名称 private String regionName; private String regionCode; private String regionType; private GeoJsonPolygon geometry; public int getLocationId() { return locationId; } public void setLocationId(int locationId) { this.locationId = locationId; } public String getRegionName() { return regionName; } public void setRegionName(String regionName) { this.regionName = regionName; } public String getRegionCode() { return regionCode; } public void setRegionCode(String regionCode) { this.regionCode = regionCode; } public String getRegionType() { return regionType; } public void setRegionType(String regionType) { this.regionType = regionType; } public GeoJsonPolygon getGeometry() { return geometry; } public void setGeometry(GeoJsonPolygon geometry) { this.geometry = geometry; } }
自定义数据库dao并使用MongoTemplate。
@Component public class GeoJsonDaoImpl { @Autowired private MongoTemplate mongoTemplate; public void savePolygon(Polygon polygon){ mongoTemplate.save(polygon); } public void saveRegions(List<GisRegion> gisRegionList){ mongoTemplate.insert(gisRegionList,GisRegion.class); } //使用mongoTemplate封装的intersects方法判断输入geojson信息是否在数据库保存的地理区域内。并返回相关区域信息列表 public List<Polygon> findIntersective(GeoJson geoJson){ Query query=new Query(Criteria.where("geometry").intersects(geoJson)); List<Polygon> list=mongoTemplate.find(query,Polygon.class); return list; } //查找目标区域是否在指定的几个区域内,locations的set中保存指定的区域id //有时数据库中保存的geojson地理信息数据集比较大,整个对象返回往往会消耗很大的io和带宽,所以我们在这里指定仅返回区域的_id,并且只要判断目标geojson是指定的一个区域的子集就返回结果,降低数据库的处理开销 public boolean isInRegion(GeoJsonPoint point,Set locations){ Criteria geoCriteria=Criteria.where("geometry").intersects(point); Criteria[] orArr=new Criteria[locations.size()]; Iterator<Integer> iterator=locations.iterator(); int i=0; while(iterator.hasNext()){ orArr[i]=new Criteria("_id").is(iterator.next()); i++; } Criteria orCriteria=new Criteria().orOperator(orArr); Criteria andCriteria=new Criteria().andOperator(geoCriteria,orCriteria); DBObject field=new BasicDBObject(); field.put("_id",true); Query query=new BasicQuery(new BasicDBObject(),field); query.addCriteria(andCriteria); GeographicalRegion region=mongoTemplate.findOne(query, GeographicalRegion.class); if(region==null){ return false; } return true; } }
测试方法:
public void findIntersectiveTest() throws IOException { GeoJsonDaoImpl geoJsonDaoImpl=new GeoJsonDaoImpl(); GeoJson geoJson=new GeoJsonPoint(1,1); System.out.println(geoJsonDaoImpl.findIntersective(geoJson)); Set<Integer> locationIds=new HashSet<Integer>(); locationIds.add(1); locationIds.add(2); System.out.println(mongoDao.isInRegion(point, locationIds)); }
关于mongoDB中对地理位置的其他操作,例如搜索指定范围内的指定目标,目标点附近的指定目标等功能都有支持,spring-data-mongodb中都提供了封装函数。可以在MongoTemplate中查看更多的gis操作方法。基于MongoDB更复杂的gis交互,有待进一步研究。
相关文章推荐
- MongoDB最简单的入门教程之四:使用Spring Boot操作MongoDB
- Spring Boot快速入门(五):使用MyBatis(注解形式)进行数据库操作
- 基于Spring Boot 2.0 及MongoDB 3.6.2 实现的简单文件共享服务器
- 三、springboot项目的简单使用之:JPA使用操作数据库
- 第一个基于Spring-Boot框架的项目以及Java8新特新之stream流操作的简单细说
- springboot中通用mapper结合mybatis generator的使用 通用mapper是为了方便开发人员对单表进行crud操作而产生的一套通用方法。 通用mapper只支持单表操作,可以
- SpringBoot中连接MYSQL数据库,并使用JPA进行数据库的相关操作
- SpringBoot中简单使用mongodb
- SpringBoot中简单使用mongodb
- spring boot整合Morphia对MongoDB进行操作
- 使用IDEA创建一个简单的基于Spring Boot的RESTful Web Service
- SpringBoot 使用@Aspect进行日志管理(基于反射代理模式+注解Log)
- Springboot 之 使用JPA进行分页操作
- 使用Flask+MongoDB实现基于REST的接口简单操作
- SpringBoot中连接MYSQL数据库,并使用JPA进行数据库的相关操作
- 1.2 使用IntelliJ IDEA搭建Spring-Boot与MongoDB数据的简单登录项目
- SpringBoot 使用@Aspect进行日志管理(基于反射代理模式)
- Spring Data MongoDB 使用group和unwind实现对数组数据进行简单统计
- Iphone——使用SQLite3进行简单的数据库操作
- C# 对MongoDB 进行增删改查的简单操作