MongoDB中空间数据的存储和操作
本文使用官方C# Driver,实现在MongoDB中存储,查询空间数据(矢量) 空间数据的存储 本例中,从一个矢量文件(shapefile格式)中读取矢量要素空间信息以及属性表,并写入到MongoDB中去,其中读取shapefile文件以及将空间信息转成json的功能通过Ogr库实现 [csh
本文使用官方C# Driver,实现在MongoDB中存储,查询空间数据(矢量)
空间数据的存储
本例中,从一个矢量文件(shapefile格式)中读取矢量要素空间信息以及属性表,并写入到MongoDB中去,其中读取shapefile文件以及将空间信息转成json的功能通过Ogr库实现
[csharp] view plaincopyprint?01.//打开MongoDB的Collection
02. MongoDatabase db = server.GetDatabase("aa");
03. MongoCollection colSheng = db.GetCollection("sheng");
04. //使用Ogr库打开Shapefile文件
05. DataSource ds = Ogr.Open(@"c:\temp\sheng.shp", 0);
06. Layer lyr = ds.GetLayerByIndex(0);
07. //读取要素数量和字段数量
08. int feaCount = lyr.GetFeatureCount(0);
09. int fieldCount = lyr.GetLayerDefn().GetFieldCount();
10. //读取所有字段名
11. List
12. for (int i = 0; i
13. {
14. fieldNames.Add(lyr.GetLayerDefn().GetFieldDefn(i).GetName());
15. }
16. //循环将所有要素添加到MongoDB中
17. for (int i = 0; i
18. {
19. //使用Ogr库将矢量要素的空间信息转成Json格式
20. Feature fea = lyr.GetFeature(i);
21. Geometry geo = fea.GetGeometryRef();
22. string json = geo.ExportToJson(null);
23.
24. BsonDocument doc = new BsonDocument();
25.
26. //将Json格式的空间信息存到Collection中
27. //BsonValue bs = BsonValue.Create(json); //这种方法是不可以的,添加到库里之后无法使用空间查询语句查询
28. BsonValue bs2 = BsonDocument.Parse(json); //这种方法才是正确的
29. //doc.Add(new BsonElement("geom", bs));
30. doc.Add(new BsonElement("geo",bs2));
31. //通过循环将所有字段的属性信息存入Collection中
32. for (int j = 0; j
33. {
34. string tmpFieldVal = fea.GetFieldAsString(j);
35. doc.Add(new BsonElement(fieldNames[j],tmpFieldVal));
36. }
37. var res = colSheng.Insert
38. }
//打开MongoDB的Collection
MongoDatabase db = server.GetDatabase("aa");
MongoCollection colSheng = db.GetCollection("sheng");
//使用Ogr库打开Shapefile文件
DataSource ds = Ogr.Open(@"c:\temp\sheng.shp", 0);
Layer lyr = ds.GetLayerByIndex(0);
//读取要素数量和字段数量
int feaCount = lyr.GetFeatureCount(0);
int fieldCount = lyr.GetLayerDefn().GetFieldCount();
//读取所有字段名
List
for (int i = 0; i
{
fieldNames.Add(lyr.GetLayerDefn().GetFieldDefn(i).GetName());
}
//循环将所有要素添加到MongoDB中
for (int i = 0; i
{
//使用Ogr库将矢量要素的空间信息转成Json格式
Feature fea = lyr.GetFeature(i);
Geometry geo = fea.GetGeometryRef();
string json = geo.ExportToJson(null);
BsonDocument doc = new BsonDocument();
//将Json格式的空间信息存到Collection中
//BsonValue bs = BsonValue.Create(json); //这种方法是不可以的,添加到库里之后无法使用空间查询语句查询
BsonValue bs2 = BsonDocument.Parse(json); //这种方法才是正确的
//doc.Add(new BsonElement("geom", bs));
doc.Add(new BsonElement("geo",bs2));
//通过循环将所有字段的属性信息存入Collection中
for (int j = 0; j
{
string tmpFieldVal = fea.GetFieldAsString(j);
doc.Add(new BsonElement(fieldNames[j],tmpFieldVal));
}
var res = colSheng.Insert
}
然后,可以查看一下存储到MongoDB中的矢量数据是什么样的
在命令行中输入:
[csharp] view plaincopyprint?01.> db.sheng.find().limit(1)
> db.sheng.find().limit(1)
结果为
[javascript] view plaincopyprint?01.{ "_id" : ObjectId("5371bf4e1dbba31914224563"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 89.8496, 14.093 ], [ 90.3933, 14.004 ], [ 90.2708, 13.4708 ], [ 89.7284, 13.5597 ], [ 89.8496, 14.093 ] ] ] }, "pyname" : "sx", "boxtype" : "inter", "date" : "2012/6/5 12:41:42" }
{ "_id" : ObjectId("5371bf4e1dbba31914224563"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 89.8496, 14.093 ], [ 90.3933, 14.004 ], [ 90.2708, 13.4708 ], [ 89.7284, 13.5597 ], [ 89.8496, 14.093 ] ] ] }, "pyname" : "sx", "boxtype" : "inter", "date" : "2012/6/5 12:41:42" }
可以看到名称为geo的这个Field,里边存的就是矢量要素的坐标信息
空间查询与空间索引
可用的空间操作包括geointersect,geowithin,near等,参考http://docs.mongodb.org/manual/reference/operator/query-geospatial/
这里使用geointersect为例说明一下:
[csharp] view plaincopyprint?01.//获取Collection
02. MongoDatabase db = server.GetDatabase("aa");
03. MongoCollection colSheng = db.GetCollection("sheng");
04.
05. //定义一个查询框或查询多边形
06. var poly = GeoJson.Polygon
07. GeoJson.Position(100, 20),
08. GeoJson.Position(110, 20),
09. GeoJson.Position(110, 40),
10. GeoJson.Position(100, 40),
11. GeoJson.Position(100, 20));
12. //以这个查询多边形为条件定义一条查询语句
13. var queryFilter2 = Query.GeoIntersects("geo", poly);
14. //进行查询,输出MongoCursor
15. cur = colSheng.FindAs
16. //获取结果
17. var res = cur.ToArray();
18. for (int i = 0; i
19. {
20. BsonDocument tmpDoc = res.ElementAt(i);
21. //do something you want
22. }
//获取Collection
MongoDatabase db = server.GetDatabase("aa");
MongoCollection colSheng = db.GetCollection("sheng");
//定义一个查询框或查询多边形
var poly = GeoJson.Polygon
GeoJson.Position(100, 20),
GeoJson.Position(110, 20),
GeoJson.Position(110, 40),
GeoJson.Position(100, 40),
GeoJson.Position(100, 20));
//以这个查询多边形为条件定义一条查询语句
var queryFilter2 = Query.GeoIntersects("geo", poly);
//进行查询,输出MongoCursor
cur = colSheng.FindAs
//获取结果
var res = cur.ToArray();
for (int i = 0; i
{
BsonDocument tmpDoc = res.ElementAt(i);
//do something you want
}
关于空间索引,可参考http://docs.mongodb.org/manual/applications/geospatial-indexes/
这里不详细说了
空间查询运算的问题:
在使用GeoIntersect进行空间查询时,遇到了查询结果与ArcGIS不一致的情况,详细看了一下,像是MongoDB的一个BUG(目前使用的是2.6.0版本)
具体信息如下(在命令行中操作):
Collection中的坐标
[csharp] view plaincopyprint?01.> db.test.find()
02.{ "_id" : ObjectId("535884771dbba31858ad2101"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 96.722, 38.755 ], [ 97.3482, 38.6922 ], [ 97.1674, 38.0752 ], [ 96.5474, 38.1383 ], [ 96.722, 38.755 ] ] ] } }
> db.test.find()
{ "_id" : ObjectId("535884771dbba31858ad2101"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 96.722, 38.755 ], [ 97.3482, 38.6922 ], [ 97.1674, 38.0752 ], [ 96.5474, 38.1383 ], [ 96.722, 38.755 ] ] ] } }
使用的查询语句
[csharp] view plaincopyprint?01.> db.test.find({ "geo" : { "$geoIntersects" : { "$geometry" : { "type" : "Polygon", "coordinates" : [[[91.0, 33.0], [102.0, 33.0], [102.0, 38.0], [91.0, 38.0], [91.0, 33.0]]] } } } })
> db.test.find({ "geo" : { "$geoIntersects" : { "$geometry" : { "type" : "Polygon", "coordinates" : [[[91.0, 33.0], [102.0, 33.0], [102.0, 38.0], [91.0, 38.0], [91.0, 33.0]]] } } } })
查询结果:
[csharp] view plaincopyprint?01.{ "_id" : ObjectId("535884771dbba31858ad2101"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 96.722, 38.755 ], [ 97.3482, 38.6922 ], [ 97.1674, 38.0752 ], [ 96.5474, 38.1383 ], [ 96.722, 38.755 ] ] ] } }
{ "_id" : ObjectId("535884771dbba31858ad2101"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 96.722, 38.755 ], [ 97.3482, 38.6922 ], [ 97.1674, 38.0752 ], [ 96.5474, 38.1383 ], [ 96.722, 38.755 ] ] ] } }
但可以看到,collection中只有一条记录,且该记录所有点的Y坐标均大于38.0,为什么查询结果里,这条记录与语句中的Box相交呢。。。很奇怪
因为有这样的问题,所以还不放心直接将空间查询用于实际应用,而是通过一种变通的方法进行简单的空间查询,测试后发现,可能是由于空间索引的问题,这种方式查询比自带的GeoIntersects方法要快
大致思路为:为每一条记录均生成一个最小外接矩形,得到其xmax,xmin,ymax,ymin四个边界值,用数值的形式保存至Collection中,每次进行空间查询时,首先通过最小外接矩形进行一次筛选,判断这些最小外接矩形与查询语句中多边形的最小外接矩形之间的关系,如果相交,那么进行第二步判断,通过Ogr组件判断实际的多边形是否相交,返回最后结果
首先是生成最小外接矩形的代码:
[csharp] view plaincopyprint?01.//获取Collection
02. MongoDatabase db = server.GetDatabase("aa");
03. MongoCollection colsheng= db.GetCollection("sheng");
04. //查询所有记录
05. var cur = colsheng.FindAllAs
06. long totalCount = cur.Count();
07. //遍历所有记录
08. for (int i = 0; i
09. {
10. if (i * 1000 >= totalCount) continue;
11. int skip = i * 1000;
12. var cur2 = cur.Clone
13. var lst = cur2.ToArray();
14. for (int j = 0; j
15. {
16. //获取一条记录对应的BsonDocument
17. BsonDocument doc = lst[j];
18. var id = doc["_id"]; //该记录对应的ID
19. BsonDocument geo = doc["geo"].ToBsonDocument();
20. string geostr = geo[1].ToString(); //该记录对应空间信息的Json字符串
21. List
22. double xmin = 181, xmax = -181, ymin = 91, ymax = -91; //四个边界值,由于图层为经纬度,所以初值设为这些值
23. //计算最大最小值
24. for (int k = 0; k
25. {
26. if (k % 2 == 0)
27. {
28. if (coords[k]
29. if (coords[k] > xmax) xmax = coords[k];
30. }
31. else
32. {
33. if (coords[k]
34. if (coords[k] > ymax) ymax = coords[k];
35. }
36. }
37. //将最大最小值写入Collection
38. var tmpQuery = Query.EQ("_id", id);
39. var tmpUpdate = MongoDB.Driver.Builders.Update.Set("xmax", xmax);
40. var tmpres = col02c.Update(tmpQuery, tmpUpdate);
41. tmpUpdate = MongoDB.Driver.Builders.Update.Set("xmin", xmin);
42. tmpres = col02c.Update(tmpQuery, tmpUpdate);
43. tmpUpdate = MongoDB.Driver.Builders.Update.Set("ymax", ymax);
44. tmpres = col02c.Update(tmpQuery, tmpUpdate);
45. tmpUpdate = MongoDB.Driver.Builders.Update.Set("ymin", ymin);
46. tmpres = col02c.Update(tmpQuery, tmpUpdate);
47. }
48. }
//获取Collection
MongoDatabase db = server.GetDatabase("aa");
MongoCollection colsheng= db.GetCollection("sheng");
//查询所有记录
var cur = colsheng.FindAllAs
long totalCount = cur.Count();
//遍历所有记录
for (int i = 0; i
{
if (i * 1000 >= totalCount) continue;
int skip = i * 1000;
var cur2 = cur.Clone
var lst = cur2.ToArray();
for (int j = 0; j
{
//获取一条记录对应的BsonDocument
BsonDocument doc = lst[j];
var id = doc["_id"]; //该记录对应的ID
BsonDocument geo = doc["geo"].ToBsonDocument();
string geostr = geo[1].ToString(); //该记录对应空间信息的Json字符串
List
double xmin = 181, xmax = -181, ymin = 91, ymax = -91; //四个边界值,由于图层为经纬度,所以初值设为这些值
//计算最大最小值
for (int k = 0; k
{
if (k % 2 == 0)
{
if (coords[k]
if (coords[k] > xmax) xmax = coords[k];
}
else
{
if (coords[k]
if (coords[k] > ymax) ymax = coords[k];
}
}
//将最大最小值写入Collection
var tmpQuery = Query.EQ("_id", id);
var tmpUpdate = MongoDB.Driver.Builders.Update.Set("xmax", xmax);
var tmpres = col02c.Update(tmpQuery, tmpUpdate);
tmpUpdate = MongoDB.Driver.Builders.Update.Set("xmin", xmin);
tmpres = col02c.Update(tmpQuery, tmpUpdate);
tmpUpdate = MongoDB.Driver.Builders.Update.Set("ymax", ymax);
tmpres = col02c.Update(tmpQuery, tmpUpdate);
tmpUpdate = MongoDB.Driver.Builders.Update.Set("ymin", ymin);
tmpres = col02c.Update(tmpQuery, tmpUpdate);
}
}
然后是查询的代码:
[csharp] view plaincopyprint?01.//获取Collection
02. MongoDatabase db = server.GetDatabase("aa");
03. MongoCollection colSheng = db.GetCollection("zy02c");
04. //第一步,通过四边界筛选,
05. var query = Query.And(Query.GT("xmax", 91.0), Query.LT("xmin", 102.0), Query.GT("ymax", 33.0), Query.LT("ymin", 38.0));
06. var cur = colSheng.FindAs
07. //定义第二空间运算时的条件多边形(Ogr格式的定义)
08. Geometry queryGeoLR = new Geometry(wkbGeometryType.wkbLinearRing);
09. queryGeoLR.AddPoint(91.0, 33.0,0);
10. queryGeoLR.AddPoint(102.0, 33.0,0);
11. queryGeoLR.AddPoint(102.0, 38.0,0);
12. queryGeoLR.AddPoint(91.0, 38.0,0);
13. queryGeoLR.AddPoint(91.0, 33.0,0);
14. Geometry queryGeo = new Geometry(wkbGeometryType.wkbPolygon);
15. queryGeo.AddGeometry(queryGeoLR);
16. //循环查询到的结果
17. var lst = cur.ToArray();
18. for (int i = lst.Length-1; i >=0; i--)
19. {
20. //获取当前记录对应的BsonDocument
21. BsonDocument doc = lst[i];
22. var id = doc["_id"]; //当前记录的ID
23. BsonDocument geo = doc["geo"].ToBsonDocument();
24. string geostr = geo[1].ToString(); //当前记录对应空间信息的Json字符串
25.
26. //通过Json串获取坐标值,并生成对应的Geometry对象
27. List
28. Geometry resGeoLR = new Geometry(wkbGeometryType.wkbLinearRing);
29. for (int j = 0; j
30. {
31. resGeoLR.AddPoint_2D(coords[j], coords[j + 1]);
32. }
33. resGeoLR.AddPoint_2D(coords[0], coords[1]);
34. Geometry resGeo = new Geometry(wkbGeometryType.wkbPolygon);
35. resGeo.AddGeometry(resGeoLR);
36. //判断是该Geometry与条件多边形是否相交
37. if (resGeo.Intersects(queryGeo))
38. {
39. //do something
40. }
41. }

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在開發一個電商網站時,我遇到了一個棘手的問題:如何為用戶提供個性化的商品推薦。最初,我嘗試了一些簡單的推薦算法,但效果並不理想,用戶的滿意度也因此受到影響。為了提升推薦系統的精度和效率,我決定採用更專業的解決方案。最終,我通過Composer安裝了andres-montanez/recommendations-bundle,這不僅解決了我的問題,還大大提升了推薦系統的性能。可以通過一下地址學習composer:學習地址

本文介紹如何在Debian系統上配置MongoDB實現自動擴容,主要步驟包括MongoDB副本集的設置和磁盤空間監控。一、MongoDB安裝首先,確保已在Debian系統上安裝MongoDB。使用以下命令安裝:sudoaptupdatesudoaptinstall-ymongodb-org二、配置MongoDB副本集MongoDB副本集確保高可用性和數據冗餘,是實現自動擴容的基礎。啟動MongoDB服務:sudosystemctlstartmongodsudosys

直接通過 Navicat 查看 MongoDB 密碼是不可能的,因為它以哈希值形式存儲。取回丟失密碼的方法:1. 重置密碼;2. 檢查配置文件(可能包含哈希值);3. 檢查代碼(可能硬編碼密碼)。

CentOS系統下MongoDB高效備份策略詳解本文將詳細介紹在CentOS系統上實施MongoDB備份的多種策略,以確保數據安全和業務連續性。我們將涵蓋手動備份、定時備份、自動化腳本備份以及Docker容器環境下的備份方法,並提供備份文件管理的最佳實踐。手動備份:利用mongodump命令進行手動全量備份,例如:mongodump-hlocalhost:27017-u用戶名-p密碼-d數據庫名稱-o/備份目錄此命令會將指定數據庫的數據及元數據導出到指定的備份目錄。

CentOS系統上GitLab數據庫部署指南選擇合適的數據庫是成功部署GitLab的關鍵步驟。 GitLab兼容多種數據庫,包括MySQL、PostgreSQL和MongoDB。本文將詳細介紹如何選擇並配置這些數據庫。數據庫選擇建議MySQL:一款廣泛應用的關係型數據庫管理系統(RDBMS),性能穩定,適用於大多數GitLab部署場景。 PostgreSQL:功能強大的開源RDBMS,支持複雜查詢和高級特性,適合處理大型數據集。 MongoDB:流行的NoSQL數據庫,擅長處理海

要設置 MongoDB 用戶,請按照以下步驟操作:1. 連接到服務器並創建管理員用戶。 2. 創建要授予用戶訪問權限的數據庫。 3. 使用 createUser 命令創建用戶並指定其角色和數據庫訪問權限。 4. 使用 getUsers 命令檢查創建的用戶。 5. 可選地設置其他權限或授予用戶對特定集合的權限。

在Debian系統上為MongoDB數據庫加密,需要遵循以下步驟:第一步:安裝MongoDB首先,確保您的Debian系統已安裝MongoDB。如果沒有,請參考MongoDB官方文檔進行安裝:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/第二步:生成加密密鑰文件創建一個包含加密密鑰的文件,並設置正確的權限:ddif=/dev/urandomof=/etc/mongodb-keyfilebs=512

MongoDB與關係型數據庫:深度對比本文將深入探討NoSQL數據庫MongoDB與傳統關係型數據庫(如MySQL和SQLServer)的差異。關係型數據庫採用行和列的表格結構組織數據,而MongoDB則使用靈活的面向文檔模型,更適應現代應用的需求。主要區別數據結構:關係型數據庫使用預定義模式的表格存儲數據,表間關係通過主鍵和外鍵建立;MongoDB使用類似JSON的BSON文檔存儲在集合中,每個文檔結構可獨立變化,實現無模式設計。架構設計:關係型數據庫需要預先定義固定的模式;MongoDB支持
