使用纬度和对数度创建表示区域的网格?

Use latitude and logitude to create a grid representing zones?

提问人:TrySoHard 提问时间:11/17/2023 最后编辑:vatbubTrySoHard 更新时间:11/18/2023 访问量:61

问:

我正在开发一个交通应用程序的模块。

我的老板给了我这个任务:我们有一个类,叫做 ,其中有一个属性,叫做 ,它存储了公民位置的纬度和经度。CitizenRequestPointPath

此数据存储在 MongoDB 数据库的 JSON 文件中。

我所要做的是:获取这个 JSON,找到最小值(或者最小纬度和经度),最大值,然后用它来定位一个正方形,它将代表我们的运输区域。PointPath

现在,我必须将这个方块分成其他迷你方块,每个方块都将成为“区域”。然后,此区域将具有一个 ID,并且必须存储到另一个集合中。

此集合的目的应该是存储我们对每个区域的请求数。因此,例如,我们将看到在 ID=149 的区域中,我们有 X 个请求。

为此,我应该创建一个算法来分析纬度和经度,以了解它落在哪个区域。

我知道这听起来可能很困难。不过,我完全不知道如何实现这一点。所以我问你是否有解决方案或想法。我真的不认为我必须使用 API 来做到这一点,我认为它只需要一些逻辑。有什么帮助吗?

Java MongoDB

评论

3赞 Andrew S 11/17/2023
。找到最小的 PointPath...相对于什么?当需求被明确定义后,试着画一张图来想象需要做什么。使用它来帮助确定所需的数据结构,以便能够找到 a 所在的区域。PointPath
0赞 David Conrad 11/17/2023
这个问题非常广泛,但听起来你正在寻找像 QuadTreeR-Tree 这样的东西。
1赞 David Conrad 11/17/2023
另外,我认为这个问题与MongoDB没有任何关系。存储请求的位置实际上与如何将它们分组到区域中没有任何关系。
0赞 TrySoHard 11/17/2023
@AndrewS相对于 JSON。我需要找到最小纬度和经度,最大纬度和经度,然后用这两个来创建一个正方形。我说 PointPath 有点简短,但之后也解释了它。但是,这对我来说是一项异常新的任务,所以我真的不知道什么数据结构适合这种情况
0赞 TrySoHard 11/17/2023
@DavidConrad你是对的,我想更具体地说明我面临的问题,但如果没有所有的信息,这将是无法理解的。我会研究四叉树

答:

2赞 Moti Vator 11/17/2023 #1

改写一下,所以我理解正确。 你有一个大方块,它是你的有效区域(交通区域),在这个方块中,你有一个网格,你试图在其中查看最多的请求来自哪里。

第一个 lattitude 和 longlitude 值看起来令人困惑,一开始什么也没说:10,000001 20,002567。 改变它,让它成为人类可读的。

如果我不正确,你需要开始并找到你的点 0。

如果你把你的有效面积想象成一个正方形,它将是左下角的最点。如果是 5.0002345、10.124567,则将所有其他值减去该值。5.0003345 10.124567 => 0.0001, 0 所以比你的起点高一点。

现在,您可以更轻松地找到有效区域中的所有请求。您将获取所有点并将它们绘制在一个简单的 x/y 图中。好吧,我不知道您的开发设置的实现。

我会推荐一个简单的 KNN algorhytmus 来集群请求。Maybee 情节本身就足够了。

评论

0赞 TrySoHard 11/17/2023
我想你几乎什么都懂。我必须创建这个网格(但它只是数据,我的意思是,这里没有图形)。我必须取最小和最大纬度和经度来计算一个平方,这将是我的运输区域。然后,将其划分为网格,为每个区域分配一个 id,因此对于稍后出现的每个请求,我可以对其进行分析并说“好吧,这是纬度,这是经度,所以它属于 id X 的区域”。
0赞 Moti Vator 11/17/2023
我有一个非常简单的想法。
0赞 Moti Vator 11/17/2023
Lattidude 和 lognitude 是 x/y 轴,您希望将它们分组到 togheter。只需将它们向上或向下舍入到您需要的 sie 即可。
0赞 Moti Vator 11/17/2023
因此,如果您有 0.01 的差异,那就是 1.11 公里。
0赞 Moti Vator 11/18/2023
只需将协调的坐标四舍五入到他们的 x.xx 点,这样你就会知道有多少请求来自这个方块,依此类推。
3赞 Buzz Moschetti 11/18/2023 #2

假设文档包含如下点:

{"citizenID:"C2", loc: { type: "Point", coordinates: [ -76.738988, 39.960921 ] }}

然后,像这样的东西将捕获边界矩形内正方形中的位置:

// First, scan the whole collection to get topleft and bottomright max points:
c=db.foo.aggregate([
    {$group: {_id:null,
              L: {$min: {$first: '$loc.coordinates'}},
              R: {$max: {$first: '$loc.coordinates'}},
              T: {$max: {$last: '$loc.coordinates'}},
              B: {$min: {$last: '$loc.coordinates'}}
             }}
]);
d = c.next();

var leftLon = d['L'];
var topLat = d['T'];
var rightLon = d['R'];
var bottomLat = d['B'];

var incr = 0.01;  // this is size of square.  0.01 is 1km.                                       
var totSqr = 0;

// Left to right, top to bottom:                                                   
for(var lon = leftLon; lon < rightLon; lon += incr) {
    for(var lat = topLat; lat > bottomLat; lat -= incr) {

        // Make a square:                                                          
        var coords = [];
        coords.push( [ lon, lat ] );
        coords.push( [ lon+incr, lat ] );
        coords.push( [ lon+incr, lat-incr ] );
        coords.push( [ lon, lat-incr ] );
        coords.push( [ lon, lat ] ); // must close loop!                                 

        c = db.foo.aggregate([
            {$match: { "loc": { $geoWithin: { $geometry:
                              { type: "Polygon", coordinates: [ coords ] } }}
                     }}
            ,{$group: {_id:null, n: {$sum:1}}}
        ]);
        d = c.next();
        if(d != null) {
            print("square region " + lon + "," + lat + ": found " + d['n']);
            // optionally insert the data somewhere as the OP notes.  You can
            // create the zone ID with an incrementing number e.g.
            // db.results.insertOne({"zone": "Z"+(zid++), n: d['n']});
        }
        totSqr++;
    }
}

评论

0赞 TrySoHard 11/18/2023
谢谢!这是我绝对可以努力的事情!