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 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

전자 상거래 웹 사이트를 개발할 때 어려운 문제가 발생했습니다. 사용자에게 개인화 된 제품 권장 사항을 제공하는 방법. 처음에는 간단한 권장 알고리즘을 시도했지만 결과는 이상적이지 않았으며 사용자 만족도에도 영향을 미쳤습니다. 추천 시스템의 정확성과 효율성을 향상시키기 위해보다 전문적인 솔루션을 채택하기로 결정했습니다. 마지막으로 Composer를 통해 Andres-Montanez/Residations-Bundle을 설치하여 문제를 해결했을뿐만 아니라 추천 시스템의 성능을 크게 향상 시켰습니다. 다음 주소를 통해 작곡가를 배울 수 있습니다.

해시 값으로 저장되기 때문에 MongoDB 비밀번호를 Navicat을 통해 직접 보는 것은 불가능합니다. 분실 된 비밀번호 검색 방법 : 1. 비밀번호 재설정; 2. 구성 파일 확인 (해시 값이 포함될 수 있음); 3. 코드를 점검하십시오 (암호 하드 코드 메일).

CentOS 시스템의 GitLab 데이터베이스 배포 안내서 올바른 데이터베이스를 선택하는 것은 GitLab을 성공적으로 배포하는 데 중요한 단계입니다. Gitlab은 MySQL, PostgreSQL 및 MongoDB를 포함한 다양한 데이터베이스와 호환됩니다. 이 기사는 이러한 데이터베이스를 선택하고 구성하는 방법을 자세히 설명합니다. 데이터베이스 선택 권장 사항 MySQL : 널리 사용되는 RDBMS (Relational Database Management System). PostgreSQL : 강력한 오픈 소스 RDBM은 복잡한 쿼리 및 고급 기능을 지원하며 대형 데이터 세트를 처리하는 데 적합합니다. MongoDB : 인기있는 NOSQL 데이터베이스, 바다 취급에 능숙합니다

CentOS 시스템 하에서 MongoDB 효율적인 백업 전략에 대한 자세한 설명이 기사는 CentOS 시스템에서 MongoDB 백업을 구현하기위한 다양한 전략을 자세히 소개하여 데이터 보안 및 비즈니스 연속성을 보장 할 것입니다. Docker 컨테이너 환경에서 수동 백업, 시간이 정해진 백업, 자동 스크립트 백업 및 백업 메소드를 다루고 백업 파일 관리를위한 모범 사례를 제공합니다. 수동 백업 : MongoDump 명령을 사용하여 Manual 전체 백업을 수행하십시오 (예 : Mongodump-HlocalHost : 27017-U username-P password-d 데이터베이스 이름 -o/백업 디렉토리이 명령은 지정된 데이터베이스의 데이터 및 메타 데이터를 지정된 백업 디렉토리로 내보내게됩니다.

MongoDB 및 Relational Database : 심층 비교이 기사는 NOSQL 데이터베이스 MongoDB와 전통적인 관계형 데이터베이스 (예 : MySQL 및 SQLServer)의 차이점을 심층적으로 탐구합니다. 관계형 데이터베이스는 행 및 열의 테이블 구조를 사용하여 데이터를 구성하는 반면 MongoDB는 유연한 문서 지향 모델을 사용하여 최신 응용 프로그램의 요구에 더 잘 어울립니다. 주로 데이터 구조를 차별화합니다. 관계형 데이터베이스는 사전 정의 된 스키마 테이블을 사용하여 데이터를 저장하고 기본 키와 외부 키를 통해 테이블 간의 관계가 설정됩니다. MongoDB는 JSON과 같은 BSON 문서를 사용하여 컬렉션에 저장하며 각 문서 구조는 패턴없는 설계를 달성하기 위해 독립적으로 변경할 수 있습니다. 건축 설계 : 관계형 데이터베이스는 사전 정의 된 고정 스키마가 필요합니다. MongoDB는 지원합니다

MongoDB 사용자를 설정하려면 다음 단계를 따르십시오. 1. 서버에 연결하고 관리자 사용자를 만듭니다. 2. 사용자에게 액세스 권한을 부여 할 데이터베이스를 작성하십시오. 3. CreateUser 명령을 사용하여 사용자를 생성하고 자신의 역할 및 데이터베이스 액세스 권한을 지정하십시오. 4. GetUsers 명령을 사용하여 생성 된 사용자를 확인하십시오. 5. 선택적으로 다른 컬렉션에 대한 다른 권한을 설정하거나 사용자 권한을 부여합니다.

데비안 시스템에서 MongoDB 데이터베이스를 암호화하려면 다음 단계에 따라 필요합니다. 1 단계 : 먼저 MongoDB 설치 먼저 Debian 시스템이 MongoDB가 설치되어 있는지 확인하십시오. 그렇지 않은 경우 설치를위한 공식 MongoDB 문서를 참조하십시오 : https://docs.mongodb.com/manual/tutorial/install-mongodb-ondodb-on-debian/step 2 : 암호화 키 파일 생성 암호화 키를 포함하는 파일을 만듭니다.

MongoDB에 연결하기위한 주요 도구는 다음과 같습니다. 1. MongoDB 쉘, 데이터를 신속하게보고 간단한 작업을 수행하는 데 적합합니다. 2. 언어 드라이버 (Pymongo, MongoDB Java 드라이버, MongoDB Node.js 드라이버 등)는 응용 프로그램 개발에 적합하지만 사용 방법을 마스터해야합니다. 3. GUI 도구 (예 : Robo 3T, Compass)는 초보자를위한 그래픽 인터페이스와 빠른 데이터보기를 제공합니다. 도구를 선택할 때는 응용 프로그램 시나리오 및 기술 스택을 고려하고 연결 문자열 구성, 권한 관리 및 연결 풀 및 인덱스 사용과 같은 성능 최적화에주의를 기울여야합니다.
