【问题标题】:Find circles which the user is in, according to each circle's relative radius根据每个圆的相对半径查找用户所在的圆
【发布时间】:2014-10-29 18:33:52
【问题描述】:

这里是球场。我有一个 Circles 集合,主要有两个属性:location 是一个点,radius 是一个以米为单位的距离。

用户还有一个profile.location Point 属性。

在我的出版物中,我想找到用户“加入”的所有圈子,因此根据每个圈子的radius 属性,找到他或她足够近的圈子。总而言之,它的外观如下:

Meteor.publish('circles', function() {
    var curUser = Meteor.users.findOne({_id:this.userId});
    if (curUser) {
    return Circles.find({
        location: {$near: 
            {$geometry:curUser.profile.location,$maxDistance:self.radius} // HERE
        }
    }));
    }
    this.ready();
});

self.radius 除外,这完全是代表我编造的术语。但是有可能实现这样的目标吗?

求解后编辑:

感谢Electric Jesus,我的匹配与多边形完美配合,因为圆目前还不是 GeoJSON 类型。 (因此它们不是可以查询的单个属性)所以我将我的圆圈转换为多边形!这是一个执行此操作的 JavaScript 函数:

function generateGeoJSONCircle(center, radius, numSides) {

  var points = [];
  var earthRadius = 6371;
  var halfsides = numSides / 2;

  //angular distance covered on earth's surface
  var d = parseFloat(radius / 1000.) / earthRadius;

  var lat = (center.coordinates[1] * Math.PI) / 180;
  var lon = (center.coordinates[0] * Math.PI) / 180;

  for(var i = 0; i < numSides; i++) {
    var gpos = {};
    var bearing = i * Math.PI / halfsides; //rad
    gpos.latitude = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(bearing));
    gpos.longitude = ((lon + Math.atan2(Math.sin(bearing) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(gpos.latitude))) * 180) / Math.PI;
    gpos.latitude = (gpos.latitude * 180) / Math.PI;
    points.push([gpos.longitude, gpos.latitude]);
  };

  points.push(points[0]);
  return {
    type: 'Polygon',
    coordinates: [ points ]
  };
}

给你。我真的不知道我应该使用多少边,所以我也为此留下了一个论据。从那里,您可以使用 Electric Jesus 的答案来了解我要去的地方。不要忘记在你的多边形上放置一个 2dsphere 索引!

Circles._ensureIndex({'polygonConversion': "2dsphere"});

【问题讨论】:

标签: mongodb collections meteor geometry


【解决方案1】:

不,地理索引永远不会以您要求它根据文档的“半径”动态的方式工作。您必须将您的圆转换为 Polygon 几何并使用 $geoIntersects 查询来查找哪个圆(多边形几何)与您当前的位置/位置参数(点几何)相交。

var location = {
  longitude: -1.85549,
  latitude: 52.9445
}

// create a circle with a Polygon geometry location, with converted coordinates
Circles.insert({name: "My Circle 1", loc: {
        type: "Polygon",
        coordinates: [[[ ... ]]], 
     }
});

// finding one or more Circles that intersect with current location.
Circles.find({loc: {
  $geoIntersects: {
    $geometry: {
      type: "Point" coordinates: [location.longitude, location.latitude]
    }
  }
}});

【讨论】:

  • 有效!承认很痛苦,但这是正确的答案。希望我能有圈子......
【解决方案2】:

Mongo 的地理空间运算符包括 $centerSphere,它返回一个圆圈范围内的文档:

Entities.find({
  location : { 
    $geoWithin : { 
      $centerSphere: [ 
        [ curUser.profile.location.lng , curUser.profile.location.lat ],
        radius / 6378100  // convert radians to meters by dividing by the Earth's radius
      ]
    }
  }
} );

【讨论】:

  • 在您的示例中radius 是什么?
  • 不,这不是我要找的。我想找到其中包含curUser.profile.location 的所有圆(每个圆都有不同的半径)。不是与当前用户固定距离内的“圆心”。
【解决方案3】:

您可以尝试加法加权 voronoi 图。距离函数是欧克里德距离减去权重。权重较大的站点和附近的其他站点会被分类到同一个单元格中。

【讨论】:

    猜你喜欢
    • 2011-01-14
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 2014-01-21
    相关资源
    最近更新 更多