我将GeoJSON存储在用于Leaflet地图的Opa应用程序中。
到目前为止,我设法在集成的MongoDB数据库中支持Point和LineString对象,其方式是将其从Opa类型转换为BSON作为正确的GeoJSON,并被小叶JS正确使用。
问题是JSON字段coordinates对于不同的几何对象具有不同的类型。对于点是位置(数字数组),对于字符串是位置数组(数字数组),对于MultiLineStrings是点数组(数字数组)
{ type: "Point", coordinates: [102.0, 0.5] }
{ type: "LineString", "coordinates": [[102.0, 0.0], [103.0, 1.0]] }
...由于这个原因,我不能依靠type字段来区分几何对象。根据Opa documentation的说法:“如果一个sum的几个案例(即记录)共享一个标签,那么这个标签在每个案例中都必须具有相同的类型。”因此,我不能只添加字段Point和LineString来区分记录类型。我必须使用嵌入了不同类型的sum类型:
type Article.geo_json_point =
{
string `type`,
list(float) coordinates,
};
type Article.geo_json_multipoint =
{
string `type`,
list(list(float)) coordinates,
};
type Article.geo_json =
{ Article.geo_json_point Point } or
{ Article.geo_json_multipoint LineString } or
{ Null };
type Article.t = {
Article.id id,
Article.geo_json location,
... // some other fields
};
database mydb {
Article.t /article[{id}]
/article[_]/location = {Null}
/article[_]/location/Point/`type` = "Point"
/article[_]/location/LineString/`type` = "LineString"
}根据MongoDB documentation,每个集合只能创建一个地理空间索引。在这种情况下,我可以正确地存储可以索引的GeoJSON:
$ mongo mydb
> db.article.findOne({}, {_id:0, location:1})
{
"location" : {
"Point" : {
"type" : "Point",
"coordinates" : [
18.089788,
51.762638
]
}
}
}但我可以对location.Point或location.LineString进行索引,但不能同时对两者进行索引...
如何在Opa中正确地进行GeoJSON数据的地理空间嵌入?它的DB接口和类型系统是可能的,还是限制太多了?非常感谢您的帮助和建议!
发布于 2013-09-20 20:10:06
似乎MongoDB允许创建两个地理空间索引并分别使用它们,但不能在同一查询中同时使用它们。
考虑一下示例输入数据:
db.geo.insert({location: {Point: {type: "Point", coordinates: [15,15]}}});
db.geo.insert({location: {LineString: {type: "LineString", coordinates: [[12,12],[13,13]]}}});
db.geo.insert({location: {Point: {type: "Point", coordinates: [55,55]}}});
db.geo.insert({location: {LineString: {type: "LineString", coordinates: [[52,52],[53,53]]}}});和索引:
db.geo.ensureIndex({"location.Point": "2dsphere"});
db.geo.ensureIndex({"location.LineString": "2dsphere"});location字段的地理空间查询:
db.geo.find({"location": {$geoWithin: {$geometry: {type: "Polygon", coordinates: [[[10,10],[10,20],[20,20],[20,10],[10,10]]]}}}});给出正确的结果,但不使用索引:(
幸运的是,查询location.Point或location.LineString都使用索引:
> [...].explain()
{
"cursor" : "S2Cursor",
"isMultiKey" : true,
"n" : 1,
"nscannedObjects" : 1,
[...]
"matchTested" : NumberLong(1),
"geoTested" : NumberLong(1),
"cellsInCover" : NumberLong(25),
[...]
}不幸的是,Mongo不允许使用{$or: [subquery1, subquery2]}进行“特殊”查询……因此,这并不容易解决问题,但它可以在应用程序级别解决。
https://stackoverflow.com/questions/18902253
复制相似问题