龙空技术网

Asp.Net Core MongoDB 空间定位(点)与距离检索

CShap新势力 104

前言:

当前咱们对“net空间可以干什么”大约比较注意,你们都需要学习一些“net空间可以干什么”的相关知识。那么小编在网上网罗了一些关于“net空间可以干什么””的相关资讯,希望我们能喜欢,咱们一起来学习一下吧!

一:我们先准备点数据

采用高德坐标系来拾取点数 ()

注意:要注册成开发者,否则拾取到的经纬度只精确到2位

第一百货 119.647437,29.083693欧景名城 119.639798,29.080843金华网络经济中心 119.644604,29.074617金华市第十五中学 119.652758,29.075029金磐医院 119.642716,29.072554龙腾江南建材市场 119.636579,29.072366宝莲广场 119.644433,29.079568新世纪大厦 119.655548,29.08088泰地世璟园 119.658809,29.073379美兰湖公馆 119.639497,29.06824西京大厦 119.63645,29.081855星月花园 119.635592,29.078292兰溪街商业步行街 119.649325,29.082606阳光城市花园 119.666963,29.082456华园小区 119.666491,29.073604印象城 119.658509,29.070716

地理位置

二:把数据存到mongodb中,便于后面使用

db.mapinfo.insert({"address": "第一百货", "name":"第一百货", "location": {"type": "Point", "coordinates": [119.647437,29.083693]}})db.mapinfo.insert({"address": "欧景名城", "name":"欧景名城", "location": {"type": "Point", "coordinates": [119.639798,29.080843]}})db.mapinfo.insert({"address": "金华网络经济中心", "name":"金华网络经济中心", "location": {"type": "Point", "coordinates": [119.644604,29.074617]}})db.mapinfo.insert({"address": "金华市第十五中学", "name":"金华市第十五中学", "location": {"type": "Point", "coordinates": [119.652758,29.075029]}})db.mapinfo.insert({"address": "金磐医院", "name":"金磐医院", "location": {"type": "Point", "coordinates": [119.642716,29.072554]}})db.mapinfo.insert({"address": "龙腾江南建材市场", "name":"龙腾江南建材市场", "location": {"type": "Point", "coordinates": [119.636579,29.072366]}})db.mapinfo.insert({"address": "宝莲广场", "name":"宝莲广场", "location": {"type": "Point", "coordinates": [119.644433,29.079568]}})db.mapinfo.insert({"address": "新世纪大厦", "name":"新世纪大厦", "location": {"type": "Point", "coordinates": [119.655548,29.08088]}})db.mapinfo.insert({"address": "泰地世璟园", "name":"泰地世璟园", "location": {"type": "Point", "coordinates": [119.658809,29.073379]}})db.mapinfo.insert({"address": "美兰湖公馆", "name":"美兰湖公馆", "location": {"type": "Point", "coordinates": [119.639497,29.06824]}})db.mapinfo.insert({"address": "西京大厦", "name":"西京大厦", "location": {"type": "Point", "coordinates": [119.63645,29.081855]}})db.mapinfo.insert({"address": "星月花园", "name":"星月花园", "location": {"type": "Point", "coordinates": [119.635592,29.078292]}})db.mapinfo.insert({"address": "兰溪街商业步行街", "name":"兰溪街商业步行街", "location": {"type": "Point", "coordinates": [119.649325,29.082606]}})db.mapinfo.insert({"address": "阳光城市花园", "name":"阳光城市花园", "location": {"type": "Point", "coordinates": [119.666963,29.082456]}})db.mapinfo.insert({"address": "华园小区", "name":"华园小区", "location": {"type": "Point", "coordinates": [119.666491,29.073604]}})db.mapinfo.insert({"address": "印象城", "name":"印象城", "location": {"type": "Point", "coordinates": [119.658509,29.070716]}})

一定要加索引

mongodb 提供的地图索引有两种,分别是 2d 和 2dsphere。

2d 索引通过二维平面记录点坐标,支持在平面几何中计算距离,而 2dsphere 则支持在球面上进行距离的计算,并且支持 mongodb 的所有地理空间查询方法。

简单的理解,2dsphere 是 2d 的增强版。根据官方推荐,如果你的mongodb版本大于2.6

db.mapinfo.ensureIndex({location : "2dsphere"})

数据库数据

假设当前位置在“1921文化创意园” 具体坐标 119.627438,29.078988

当前位置

检索规定半径以内数据(单位为米)

这里取2000米

db.mapinfo.find({location: {$near: {$geometry: {type: "Point", coordinates: [119.627438,29.078988]}, $maxDistance: 2000}}})

或者

db.mapinfo.find({location: {$nearSphere: {$geometry: {type: "Point", coordinates: [119.627438,29.078988]}, $maxDistance: 2000}}})

查询结果,由近到远

按照离我最近排序,除了使用 $nearSphere 查询外,我们还可以使用 aggregate 来实现。

使用 aggregate 有两个好处。

1.我们在进行排序的后,可以返回两点之间的距离。

2.我们可以进行更为复杂的排序,例如我们可以先根据某个字段进行排序,然后该字段相同的情况下再根据距离排序。

db.mapinfo.aggregate([   {     $geoNear: {        near: {type: "Point", coordinates: [119.627438,29.078988]},        distanceField: "distance",        spherical: true,               maxDistance: 15000,				query: {			    address: {$regex:'建材'}				}     }   },   { $skip: 0 },   { $limit: 2 }])

aggregate 查询

如果我们希望查询以某个点为中心的圆几公里以内的数据,那你可以如下操作:

地球表面1弧度距离约为6378137米, 0.001弧度距离为6378米

db.mapinfo.find({    "location": {        "$geoWithin": {            "$centerSphere": [                [                    119.627438,29.078988                ],                0.025 // 单位为弧度            ]        }    }})

以某个点为中心的圆几公里以内的数据

写到这里,其实已经实现了基于MongoDB 空间定位(点)与距离检索

那.net中代码如何实现,看下面具体说明。

编写实体对象 mapinfo

public class mapinfo    {        /// <summary>        /// 主键        /// </summary>        [BsonId]        [BsonRepresentation(BsonType.ObjectId)]        public string id { get; set; }        /// <summary>        /// 地址        /// </summary>        public string address { get; set; }        /// <summary>        /// 社区名称        /// </summary>        public string name { get; set; }        /// <summary>        /// 距离        /// </summary>        public double? distance { get; set; }        /// <summary>        /// 经纬度坐标        /// </summary>        public GeoJsonPoint<GeoJson2DGeographicCoordinates> location { get; set; }    }

IMapinfoMongoRepository

 public interface IMapinfoMongoRepository    {        public List<Models.MongoEnity.mapinfo> QueryNear(string keywords,int pageIndex, int pageSize, double longitude, double latitude, int maxDistance);    }

MapinfoMongoRepository

public class MapinfoMongoRepository : IMapinfoMongoRepository    {        private readonly ILogger<MapinfoMongoRepository> _logger;        private readonly IMongoDbGenericHelper<Models.MongoEnity.mapinfo> _mapinfoHelper;        public MapinfoMongoRepository(ILogger<MapinfoMongoRepository> logger, IMongoDbGenericHelper<Models.MongoEnity.mapinfo> mapinfoHelper)        {            _logger = logger;            _mapinfoHelper = mapinfoHelper;        }        /// <summary>        /// 查询附近的信息        /// </summary>        /// <param name="keywords"></param>        /// <param name="pageIndex"></param>        /// <param name="pageSize"></param>        /// <param name="longitude"></param>        /// <param name="latitude"></param>        /// <param name="maxDistance"></param>        /// <returns></returns>        public List<Models.MongoEnity.mapinfo> QueryNear(string keywords, int pageIndex, int pageSize, double longitude, double latitude, int maxDistance)        {               IList<IPipelineStageDefinition> stages = new List<IPipelineStageDefinition>();            string temp1 = "";            if (!string.IsNullOrEmpty(keywords))            {                temp1 = "{\"$geoNear\": {\"near\": {\"type\": \"Point\",\"coordinates\": [" + longitude + "," + latitude + "]},\"distanceField\": \"distance\",\"spherical\": true,\"maxDistance\": " + maxDistance + ",query:{\"address\": { $regex: '" + keywords + "' }}}}";            }            else            {                temp1 = "{\"$geoNear\": {\"near\": {\"type\": \"Point\",\"coordinates\": [" + longitude + "," + latitude + "]},\"distanceField\": \"distance\",\"spherical\": true,\"maxDistance\": " + maxDistance + "}}";            }            PipelineStageDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo> stage1 = new JsonPipelineStageDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo>(temp1);            stages.Add(stage1);            string temp2 = "{$skip:" + (pageIndex - 1) * pageSize + "}";            PipelineStageDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo> stage2 = new JsonPipelineStageDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo>(temp2);            stages.Add(stage2);            string temp3 = "{$limit:" + pageSize + "}";            PipelineStageDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo> stage3 = new JsonPipelineStageDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo>(temp3);            stages.Add(stage3);            PipelineDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo> pipeline = new PipelineStagePipelineDefinition<Models.MongoEnity.mapinfo, Models.MongoEnity.mapinfo>(stages);            //聚合结果            List<Models.MongoEnity.mapinfo> result = _mapinfoHelper.GetCollection(nameof(Models.MongoEnity.mapinfo)).Aggregate(pipeline).ToList();            return result;        }    }

Action

 [HttpGet]        public IActionResult TestQueryNear()        {            var data = _mapinfoMongoRepository.QueryNear(keywords: string.Empty, pageIndex: 1, pageSize: 2, longitude: 119.627438, latitude: 29.078988, maxDistance: 15000);            return Ok(data);        }

查询结果:

查询结果

查询结果 distance单位是米

[  {    "id": "64ae31fe6412e519c80f4b3d",    "address": "星月花园",    "name": "星月花园",    "distance": 797.0567583679608,    "location": {      "Coordinates": {        "Values": [          119.635592,          29.078292        ],        "Longitude": 119.635592,        "Latitude": 29.078292      },      "Type": 7,      "BoundingBox": null,      "CoordinateReferenceSystem": null,      "ExtraMembers": null    }  },  {    "id": "64ae31fe6412e519c80f4b3c",    "address": "西京大厦",    "name": "西京大厦",    "distance": 933.0219480837998,    "location": {      "Coordinates": {        "Values": [          119.63645,          29.081855        ],        "Longitude": 119.63645,        "Latitude": 29.081855      },      "Type": 7,      "BoundingBox": null,      "CoordinateReferenceSystem": null,      "ExtraMembers": null    }  }]

知识整理不易,喜欢的朋友家个guanzhu呗

标签: #net空间可以干什么