ArcGIS支持MongoDB数据源

2 篇文章 0 订阅


自从NoSQL推出之后,MongoDB就作为比较杰出的代表受到广大用户的推崇,当然,与之而来的大数据的讨论也非常激烈,GIS数据源向来都是以海量来计算,所以,GIS与大数据、GIS与NoSQL,ArcGIS与NoSQL就不谋而合了,其实在去年的Esri全球用户大会也有关于ArcGIS与MongoDB的相关PPT讲座。

在2012年5月份的Esri官方博客也提到了ArcGIS支持Plugin方式的MongoDB数据源

http://blogs.esri.com/esri/arcgis/2012/05/02/mongodb-example-code-for-adding-a-nosql-plug-in-data-source/

后来也公布了相关的源代码:http://www.arcgis.com/sharing/content/items/25d12436c73a43c98c711826f9f662e4/data如果点击该连接出现问题,请复制改连接到URL上即可



下面我们就看看ArcGIS与NoSQL是怎么结合的。


ArcGIS提供的源代码需要

1:MongoDB C#  Driver:http://219.239.26.11/download/33644780/43014936/5/zip/137/196/135480

2:MongoDB 数据库:http://www.mongodb.org/downloads


下载完毕ArcGIS与MongoDB的源代码后,可以看到一个工程,需要在有ArcGIS Desktop或者ArcGIS Engine的机器上,结合VS2010重新编译一下,编译后会得到3个dll,MongoDBCommands.dll,MongoDBPlugIn.dll,MongoDBPluginUI.dll

注意:建议下载最新的MongoDB C# Driver的Dll,而且在编译过程中,最好查看生成的dll是不是最新日期的,如果不是,加载上去点击按钮会没有任何反应的。


获得最新的dll,通过ESRIRegASM将MongoDBCommands.dll,MongoDBPlugIn.dll进行注册,然后在ArcMap的Customize加载Mongo Plugin Commands,里面有两个功能

1:将本地数据导入到MongoDB里面:Load Data to MongoDB


注意:目前来说,只支持点状要素类

--------------------------------------------------------------------------------------------------

最新更新2013年7月17日:在新版本的MongoDB可能会更新支持线类型和面类型

感谢 @小单 的分享

http://docs.mongodb.org/manual/core/2dsphere/

---------------------------------------------------------------------------------------------------------------

需要一个MongoDB的数据连接,其实就是一个内容为:mongodb://mongodb_IP/?safe=true的以mongoconn为后缀名的文本文件,在下载示例中也有。

database需要用户填写指定的名称,系统会自动创建的

2:将MongoDB数据加载到ArcMap上:Add MongoDB DataLayer


使用这种方法可以将MongoDB的要素类加载到ArcMap上,这个要素类应该是在内存中存储(不确定,因为停止mongoDB服务器服务,数据就消失了,也有可能类似ArcGIS的Package对象),因为在ArcMap上虽然可以看到一个类似Geodatabase的存储,但是还是在基于MongoDB的连接文件上。


关于MongoDB的简单介绍

我这边使用的是Windows版本,最主要的是%MongoDBHome%/bin里面的文件,但是需要用户在%MongoDBHome%/路径下创建%MongoDBHome%/data/db和%MongoDBHome%/db/log两个文件夹。

然后启动服务器端进程

mongod.exe --dbpath=C:\MongoDB\data\db --directoryperdb  --logpath =C:\MongoDB\data\logs --logappend


因为MongoDB的端口号为:27017,打开浏览器输入:http://127.0.0.1:27017/,我们看到了这样的提示:

“You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number”
到此,MongoDB数据库服务已经成功启动了。

服务器端进程启动后,我们来启动客户端进程

C:\Users\Administrator>cd c:\mongodb\bin

c:\mongodb\bin>mongo.exe
MongoDB shell version: 2.2.2
connecting to: test

简单看一下常用的命令

> help
        db.help()                    help on db methods
        db.mycoll.help()             help on collection methods
        sh.help()                    sharding helpers
        rs.help()                    replica set helpers
        help admin                   administrative help
        help connect                 connecting to a db help
        help keys                    key shortcuts
        help misc                    misc things to know
        help mr                      mapreduce

        show dbs                     show database names
        show collections             show collections in current database
        show users                   show users in current database
        show profile                 show most recent system.profile entries with time >= 1ms
        show logs                    show the accessible logger names
        show log [name]              prints out the last segment of log in memory, 'global' is default
        use <db_name>                set current database
        db.foo.find()                list objects in collection foo
        db.foo.find( { a : 1 } )     list objects in foo where a == 1
        it                           result of the last line evaluated; use to further iterate
        DBQuery.shellBatchSize = x   set default number of items to display on shell
        exit                         quit the mongo shell


具体解释一下
> show dbs 		// 列出所有数据库
> use memo 		// 使用数据库memo。即使这个数据库不存在也可以执行,但该数据库不会立刻被新建,要等到执行了insert等的操作时,才会建立这个数据库。
> show collections 	// 列出当前数据库的collections
> db 			// 显示当前数据库
> show users 		// 列出用户

个人感觉可以dbs可以比作SQL Server的 Database ,collections可以比作这个Database里面的表。


那么接着上面我们看到的将文件要素类导入到dbs为test里面,那么我们进入test里面,查看一下导入进去后,发生了什么

> use test
switched to db test
> show dbs
czdj    0.203125GB
local   (empty)
test    0.203125GB
> show collections
GDB_ITEMS
VERSION_aa
system.indexes
我导入了一个名字为VERSION_aa的要素类,那么在MongoDB里面创建了三个collections,一个是ArcSDE的系统表GDB_ITEMS(这个非常熟悉),一个是同名,一个是系统索引对象,也就是说,数据库会自动的创建索引。

我们来查看一下各个对象的内容,首先是VERSION_aa,我们可以看到关键的shape是以XY坐标来代替,点对象嘛,比较简单,不知道以后如果支持线或者面,是否也会像ST_Geometry的WKT字符串来表示呢?


> db.VERSION_aa.find();

---
Unicode text could not be correctly displayed.
Please change your console font to a Unicode font (e.g. Lucida Console).
---

{ "_id" : 0, "shape" : [ 117.35368762500002, 39.984925316000044 ], "GRADE" : "0", "ID" : "1202251010b201", "INTENSITY" :
 0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "京哈公路互通立交æ¡
¥", "NOTE_" : "0", "STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 1, "shape" : [ 117.38540904700005, 39.901151936000076 ], "GRADE" : "0", "ID" : "1202251090b201", "INTENSITY" :
 0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县上仓大桥", "NOTE
_" : "0", "STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 2, "shape" : [ 117.43795697100006, 39.868482097000026 ], "GRADE" : "0", "ID" : "1202251180b201", "INTENSITY" :
 0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县杨津庄大桥", "N
OTE_" : "0", "STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 3, "shape" : [ 117.71767576500008, 40.02316650200004 ], "GRADE" : "0", "ID" : "1202251200b201", "INTENSITY" :
0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县果河大桥", "NOTE_
" : "0", "STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 4, "shape" : [ 117.43090199900007, 40.18651066600006 ], "GRADE" : "0", "ID" : "1202251040b201", "INTENSITY" :
0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县下营青年桥", "NO
TE_" : "0", "STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 5, "shape" : [ 117.39934450100009, 40.14910033900003 ], "GRADE" : "0", "ID" : "1202251120b201", "INTENSITY" :
0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县王庄大桥", "NOTE_
" : "0", "STRUCTURE" : "0", "CLASS" : "0" }
>

注意:我们看到乱码,这个错误是由于MongoDB的客户端使用的编码是UTF-8,而Windows 命令行程序 cmd.exe 使用的gb2312(我目前使用中文语言) 造成的。


> db.VERSION_aa.find();
{ "_id" : 0, "shape" : [ 117.35368762500002, 39.984925316000044 ], "GRADE" : "0", "ID" : "1202251010b201", "INTENSITY" :
 0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "京哈公路互通立交桥", "NOTE_" : "0",
 "STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 1, "shape" : [ 117.38540904700005, 39.901151936000076 ], "GRADE" : "0", "ID" : "1202251090b201", "INTENSITY" :
 0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县上仓大桥", "NOTE_" : "0", "S
TRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 2, "shape" : [ 117.43795697100006, 39.868482097000026 ], "GRADE" : "0", "ID" : "1202251180b201", "INTENSITY" :
 0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县杨津庄大桥", "NOTE_" : "0", "
STRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 3, "shape" : [ 117.71767576500008, 40.02316650200004 ], "GRADE" : "0", "ID" : "1202251200b201", "INTENSITY" :
0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县果河大桥", "NOTE_" : "0", "ST
RUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 4, "shape" : [ 117.43090199900007, 40.18651066600006 ], "GRADE" : "0", "ID" : "1202251040b201", "INTENSITY" :
0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县下营青年桥", "NOTE_" : "0", "S
TRUCTURE" : "0", "CLASS" : "0" }
{ "_id" : 5, "shape" : [ 117.39934450100009, 40.14910033900003 ], "GRADE" : "0", "ID" : "1202251120b201", "INTENSITY" :
0, "LENGTH" : 0, "BUILT_ERA" : "0", "WIDTH" : 0, "LOCATION" : "0", "MAX_LOAD" : 0, "NAME" : "蓟县王庄大桥", "NOTE_" : "0", "ST
RUCTURE" : "0", "CLASS" : "0" }


ArcGIS的系统表GDB_ITEMS

> db.GDB_ITEMS.find();
{ "_id" : ObjectId("510b36e37bd08f16946bf176"), "Name" : "VERSION_aa", "Fields" : BinData(0,"PG5zOlRlc3QgeHNpOnR5cGU9J3R
5cGVuczpGaWVsZHMnIHhtbG5zOm5zPSdUZXN0JyB4bWxuczp4c2k9J2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJyB4bWxuczp
4cz0naHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnIHhtbG5zOnR5cGVucz0naHR0cDovL3d3dy5lc3JpLmNvbS9zY2hlbWFzL0FyY0dJUy8xMC4
xJz48bnM6RmllbGRBcnJheSB4c2k6dHlwZT0ndHlwZW5zOkFycmF5T2ZGaWVsZCc+PG5zOkZpZWxkIHhzaTp0eXBlPSd0eXBlbnM6RmllbGQnPjxOYW1lPl9
pZDwvTmFtZT48VHlwZT5lc3JpRmllbGRUeXBlT0lEPC9UeXBlPjxJc051bGxhYmxlPmZhbHNlPC9Jc051bGxhYmxlPjxMZW5ndGg+NDwvTGVuZ3RoPjxQcmV
jaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48UmVxdWlyZWQ+dHJ1ZTwvUmVxdWlyZWQ+PEVkaXRhYmxlPmZhbHNlPC9FZGl0YWJsZT48QWx
pYXNOYW1lPk9CSkVDVElEPC9BbGlhc05hbWU+PE1vZGVsTmFtZT5PQkpFQ1RJRDwvTW9kZWxOYW1lPjwvbnM6RmllbGQ+PG5zOkZpZWxkIHhzaTp0eXBlPSd
0eXBlbnM6RmllbGQnPjxOYW1lPnNoYXBlPC9OYW1lPjxUeXBlPmVzcmlGaWVsZFR5cGVHZW9tZXRyeTwvVHlwZT48SXNOdWxsYWJsZT50cnVlPC9Jc051bGx
hYmxlPjxMZW5ndGg+MDwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48UmVxdWlyZWQ+dHJ1ZTwvUmVxdWlyZWQ+PG5
zOkdlb21ldHJ5RGVmIHhzaTp0eXBlPSd0eXBlbnM6R2VvbWV0cnlEZWYnPjxBdmdOdW1Qb2ludHM+MDwvQXZnTnVtUG9pbnRzPjxHZW9tZXRyeVR5cGU+ZXN
yaUdlb21ldHJ5UG9pbnQ8L0dlb21ldHJ5VHlwZT48SGFzTT5mYWxzZTwvSGFzTT48SGFzWj5mYWxzZTwvSGFzWj48bnM6U3BhdGlhbFJlZmVyZW5jZSB4c2k
6dHlwZT0ndHlwZW5zOkdlb2dyYXBoaWNDb29yZGluYXRlU3lzdGVtJz48V0tUPkdFT0dDU1smcXVvdDtHQ1NfWGlhbl8xOTgwJnF1b3Q7LERBVFVNWyZxdW9
0O0RfWGlhbl8xOTgwJnF1b3Q7LFNQSEVST0lEWyZxdW90O1hpYW5fMTk4MCZxdW90Oyw2Mzc4MTQwLjAsMjk4LjI1N11dLFBSSU1FTVsmcXVvdDtHcmVlbnd
pY2gmcXVvdDssMC4wXSxVTklUWyZxdW90O0RlZ3JlZSZxdW90OywwLjAxNzQ1MzI5MjUxOTk0MzNdLEFVVEhPUklUWVsmcXVvdDtFUFNHJnF1b3Q7LDQ2MTB
dXTwvV0tUPjxYT3JpZ2luPi00MDA8L1hPcmlnaW4+PFlPcmlnaW4+LTQwMDwvWU9yaWdpbj48WFlTY2FsZT45OTk5OTk5OTkuOTk5OTk5ODg8L1hZU2NhbGU
+PFpPcmlnaW4+MDwvWk9yaWdpbj48WlNjYWxlPjE8L1pTY2FsZT48TU9yaWdpbj4wPC9NT3JpZ2luPjxNU2NhbGU+MTwvTVNjYWxlPjxYWVRvbGVyYW5jZT4
4Ljk4MzE0ODYxNTkxMDMyODllLTAwOTwvWFlUb2xlcmFuY2U+PFpUb2xlcmFuY2U+MjwvWlRvbGVyYW5jZT48TVRvbGVyYW5jZT4yPC9NVG9sZXJhbmNlPjx
IaWdoUHJlY2lzaW9uPnRydWU8L0hpZ2hQcmVjaXNpb24+PExlZnRMb25naXR1ZGU+LTE4MDwvTGVmdExvbmdpdHVkZT48V0tJRD40NjEwPC9XS0lEPjxMYXR
lc3RXS0lEPjQ2MTA8L0xhdGVzdFdLSUQ+PC9uczpTcGF0aWFsUmVmZXJlbmNlPjxHcmlkU2l6ZTA+MTAwMDwvR3JpZFNpemUwPjwvbnM6R2VvbWV0cnlEZWY
+PEFsaWFzTmFtZT5TaGFwZTwvQWxpYXNOYW1lPjxNb2RlbE5hbWU+U2hhcGU8L01vZGVsTmFtZT48L25zOkZpZWxkPjxuczpGaWVsZCB4c2k6dHlwZT0ndHl
wZW5zOkZpZWxkJz48TmFtZT5HUkFERTwvTmFtZT48VHlwZT5lc3JpRmllbGRUeXBlU3RyaW5nPC9UeXBlPjxJc051bGxhYmxlPnRydWU8L0lzTnVsbGFibGU
+PExlbmd0aD40MDwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48L25zOkZpZWxkPjxuczpGaWVsZCB4c2k6dHlwZT0
ndHlwZW5zOkZpZWxkJz48TmFtZT5JRDwvTmFtZT48VHlwZT5lc3JpRmllbGRUeXBlU3RyaW5nPC9UeXBlPjxJc051bGxhYmxlPnRydWU8L0lzTnVsbGFibGU
+PExlbmd0aD4yODwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48L25zOkZpZWxkPjxuczpGaWVsZCB4c2k6dHlwZT0
ndHlwZW5zOkZpZWxkJz48TmFtZT5JTlRFTlNJVFk8L05hbWU+PFR5cGU+ZXNyaUZpZWxkVHlwZURvdWJsZTwvVHlwZT48SXNOdWxsYWJsZT50cnVlPC9Jc05
1bGxhYmxlPjxMZW5ndGg+ODwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48L25zOkZpZWxkPjxuczpGaWVsZCB4c2k
6dHlwZT0ndHlwZW5zOkZpZWxkJz48TmFtZT5MRU5HVEg8L05hbWU+PFR5cGU+ZXNyaUZpZWxkVHlwZURvdWJsZTwvVHlwZT48SXNOdWxsYWJsZT50cnVlPC9
Jc051bGxhYmxlPjxMZW5ndGg+ODwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48L25zOkZpZWxkPjxuczpGaWVsZCB
4c2k6dHlwZT0ndHlwZW5zOkZpZWxkJz48TmFtZT5CVUlMVF9FUkE8L05hbWU+PFR5cGU+ZXNyaUZpZWxkVHlwZVN0cmluZzwvVHlwZT48SXNOdWxsYWJsZT5
0cnVlPC9Jc051bGxhYmxlPjxMZW5ndGg+NjA8L0xlbmd0aD48UHJlY2lzaW9uPjA8L1ByZWNpc2lvbj48U2NhbGU+MDwvU2NhbGU+PC9uczpGaWVsZD48bnM
6RmllbGQgeHNpOnR5cGU9J3R5cGVuczpGaWVsZCc+PE5hbWU+V0lEVEg8L05hbWU+PFR5cGU+ZXNyaUZpZWxkVHlwZURvdWJsZTwvVHlwZT48SXNOdWxsYWJ
sZT50cnVlPC9Jc051bGxhYmxlPjxMZW5ndGg+ODwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48L25zOkZpZWxkPjx
uczpGaWVsZCB4c2k6dHlwZT0ndHlwZW5zOkZpZWxkJz48TmFtZT5MT0NBVElPTjwvTmFtZT48VHlwZT5lc3JpRmllbGRUeXBlU3RyaW5nPC9UeXBlPjxJc05
1bGxhYmxlPnRydWU8L0lzTnVsbGFibGU+PExlbmd0aD44MDwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2FsZT4wPC9TY2FsZT48L25zOkZ
pZWxkPjxuczpGaWVsZCB4c2k6dHlwZT0ndHlwZW5zOkZpZWxkJz48TmFtZT5NQVhfTE9BRDwvTmFtZT48VHlwZT5lc3JpRmllbGRUeXBlRG91YmxlPC9UeXB
lPjxJc051bGxhYmxlPnRydWU8L0lzTnVsbGFibGU+PExlbmd0aD44PC9MZW5ndGg+PFByZWNpc2lvbj4wPC9QcmVjaXNpb24+PFNjYWxlPjA8L1NjYWxlPjw
vbnM6RmllbGQ+PG5zOkZpZWxkIHhzaTp0eXBlPSd0eXBlbnM6RmllbGQnPjxOYW1lPk5BTUU8L05hbWU+PFR5cGU+ZXNyaUZpZWxkVHlwZVN0cmluZzwvVHl
wZT48SXNOdWxsYWJsZT50cnVlPC9Jc051bGxhYmxlPjxMZW5ndGg+ODA8L0xlbmd0aD48UHJlY2lzaW9uPjA8L1ByZWNpc2lvbj48U2NhbGU+MDwvU2NhbGU
+PC9uczpGaWVsZD48bnM6RmllbGQgeHNpOnR5cGU9J3R5cGVuczpGaWVsZCc+PE5hbWU+Tk9URV88L05hbWU+PFR5cGU+ZXNyaUZpZWxkVHlwZVN0cmluZzw
vVHlwZT48SXNOdWxsYWJsZT50cnVlPC9Jc051bGxhYmxlPjxMZW5ndGg+MjE0NzQ4MzY0NzwvTGVuZ3RoPjxQcmVjaXNpb24+MDwvUHJlY2lzaW9uPjxTY2F
sZT4wPC9TY2FsZT48L25zOkZpZWxkPjxuczpGaWVsZCB4c2k6dHlwZT0ndHlwZW5zOkZpZWxkJz48TmFtZT5TVFJVQ1RVUkU8L05hbWU+PFR5cGU+ZXNyaUZ
pZWxkVHlwZVN0cmluZzwvVHlwZT48SXNOdWxsYWJsZT50cnVlPC9Jc051bGxhYmxlPjxMZW5ndGg+NjA8L0xlbmd0aD48UHJlY2lzaW9uPjA8L1ByZWNpc2l
vbj48U2NhbGU+MDwvU2NhbGU+PC9uczpGaWVsZD48bnM6RmllbGQgeHNpOnR5cGU9J3R5cGVuczpGaWVsZCc+PE5hbWU+Q0xBU1M8L05hbWU+PFR5cGU+ZXN
yaUZpZWxkVHlwZVN0cmluZzwvVHlwZT48SXNOdWxsYWJsZT50cnVlPC9Jc051bGxhYmxlPjxMZW5ndGg+ODA8L0xlbmd0aD48UHJlY2lzaW9uPjA8L1ByZWN
pc2lvbj48U2NhbGU+MDwvU2NhbGU+PC9uczpGaWVsZD48L25zOkZpZWxkQXJyYXk+PC9uczpUZXN0Pg=="), "Extent" : BinData(0,"PG5zOlRlc3Qge
HNpOnR5cGU9J3R5cGVuczpFbnZlbG9wZU4nIHhtbG5zOm5zPSdUZXN0JyB4bWxuczp4c2k9J2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc
3RhbmNlJyB4bWxuczp4cz0naHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnIHhtbG5zOnR5cGVucz0naHR0cDovL3d3dy5lc3JpLmNvbS9zY2hlb
WFzL0FyY0dJUy8xMC4xJz48WE1pbj4xMTcuMzUzNjg3NjI1MDAwMDI8L1hNaW4+PFlNaW4+MzkuODY4NDgyMDk3MDAwMDI2PC9ZTWluPjxYTWF4PjExNy43M
Tc2NzU3NjUwMDAwODwvWE1heD48WU1heD40MC4xODY1MTA2NjYwMDAwNjE8L1lNYXg+PG5zOlNwYXRpYWxSZWZlcmVuY2UgeHNpOnR5cGU9J3R5cGVuczpHZ
W9ncmFwaGljQ29vcmRpbmF0ZVN5c3RlbSc+PFdLVD5HRU9HQ1NbJnF1b3Q7R0NTX1hpYW5fMTk4MCZxdW90OyxEQVRVTVsmcXVvdDtEX1hpYW5fMTk4MCZxd
W90OyxTUEhFUk9JRFsmcXVvdDtYaWFuXzE5ODAmcXVvdDssNjM3ODE0MC4wLDI5OC4yNTddXSxQUklNRU1bJnF1b3Q7R3JlZW53aWNoJnF1b3Q7LDAuMF0sV
U5JVFsmcXVvdDtEZWdyZWUmcXVvdDssMC4wMTc0NTMyOTI1MTk5NDMzXSxBVVRIT1JJVFlbJnF1b3Q7RVBTRyZxdW90Oyw0NjEwXV08L1dLVD48WE9yaWdpb
j4tNDAwPC9YT3JpZ2luPjxZT3JpZ2luPi00MDA8L1lPcmlnaW4+PFhZU2NhbGU+OTk5OTk5OTk5Ljk5OTk5OTg4PC9YWVNjYWxlPjxaT3JpZ2luPjA8L1pPc
mlnaW4+PFpTY2FsZT4xPC9aU2NhbGU+PE1PcmlnaW4+MDwvTU9yaWdpbj48TVNjYWxlPjE8L01TY2FsZT48WFlUb2xlcmFuY2U+OC45ODMxNDg2MTU5MTAzM
jg5ZS0wMDk8L1hZVG9sZXJhbmNlPjxaVG9sZXJhbmNlPjI8L1pUb2xlcmFuY2U+PE1Ub2xlcmFuY2U+MjwvTVRvbGVyYW5jZT48SGlnaFByZWNpc2lvbj50c
nVlPC9IaWdoUHJlY2lzaW9uPjxMZWZ0TG9uZ2l0dWRlPi0xODA8L0xlZnRMb25naXR1ZGU+PFdLSUQ+NDYxMDwvV0tJRD48TGF0ZXN0V0tJRD40NjEwPC9MY
XRlc3RXS0lEPjwvbnM6U3BhdGlhbFJlZmVyZW5jZT48L25zOlRlc3Q+"), "NEXT_OID" : 200 }


还有索引对象

> db.system.indexes.find();
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.GDB_ITEMS", "name" : "_id_" }
{ "v" : 1, "key" : { "Name" : 1 }, "ns" : "test.GDB_ITEMS", "name" : "Name_1" }
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.VERSION_aa", "name" : "_id_" }
{ "v" : 1, "key" : { "shape" : "2d" }, "ns" : "test.VERSION_aa", "name" : "shape_2d" }


ArcGIS不支持直接在MongoDB里面的直接编辑数据,如果编辑数据,然后在加载在ArcMap,数据并没有发生变化,打开属性表会报如下错误

> db.bb.insert({"_id":6,"shape":[117.72,40.04],"ID":"123"});
> db.bb.find();
{ "_id" : 0, "shape" : [ 117.35368762500002, 39.984925316000044 ], "ID" : "1202251010b201" }
{ "_id" : 1, "shape" : [ 117.38540904700005, 39.901151936000076 ], "ID" : "1202251090b201" }
{ "_id" : 2, "shape" : [ 117.43795697100006, 39.868482097000026 ], "ID" : "1202251180b201" }
{ "_id" : 3, "shape" : [ 117.71767576500008, 40.02316650200004 ], "ID" : "1202251200b201" }
{ "_id" : 4, "shape" : [ 117.43090199900007, 40.18651066600006 ], "ID" : "1202251040b201" }
{ "_id" : 5, "shape" : [ 117.39934450100009, 40.14910033900003 ], "ID" : "1202251120b201" }
{ "_id" : 6, "shape" : [ 117.72, 40.04 ], "ID" : "123" }

但是可以更新属性、甚至Shape的XY坐标(慎用),更新过后,熟悉以及坐标已经更改,而且在ArcMap可以正常显示

> db.bb.find();
{ "_id" : 0, "shape" : [ 117.35368762500002, 39.984925316000044 ], "ID" : "1202251010b201" }
{ "_id" : 1, "shape" : [ 117.38540904700005, 39.901151936000076 ], "ID" : "1202251090b201" }
{ "_id" : 2, "shape" : [ 117.43795697100006, 39.868482097000026 ], "ID" : "1202251180b201" }
{ "_id" : 3, "shape" : [ 117.71767576500008, 40.02316650200004 ], "ID" : "1202251200b201" }
{ "_id" : 4, "shape" : [ 117.43090199900007, 40.18651066600006 ], "ID" : "1202251040b201" }
{ "_id" : 5, "shape" : [ 117.39934450100009, 40.14910033900003 ], "ID" : "1202251120b201" }
> db.bb.update({"_id":1},{$set:{"ID":"123"}});
> db.bb.find();
{ "_id" : 0, "shape" : [ 117.35368762500002, 39.984925316000044 ], "ID" : "1202251010b201" }
{ "ID" : "123", "_id" : 1, "shape" : [ 117.38540904700005, 39.901151936000076 ] }
{ "_id" : 2, "shape" : [ 117.43795697100006, 39.868482097000026 ], "ID" : "1202251180b201" }
{ "_id" : 3, "shape" : [ 117.71767576500008, 40.02316650200004 ], "ID" : "1202251200b201" }
{ "_id" : 4, "shape" : [ 117.43090199900007, 40.18651066600006 ], "ID" : "1202251040b201" }
{ "_id" : 5, "shape" : [ 117.39934450100009, 40.14910033900003 ], "ID" : "1202251120b201" }
> db.bb.update({"_id":1},{$set:{"shape":[117.3,40]}});
> db.bb.find();
{ "_id" : 0, "shape" : [ 117.35368762500002, 39.984925316000044 ], "ID" : "1202251010b201" }
{ "ID" : "123", "_id" : 1, "shape" : [ 117.3, 40 ] }
{ "_id" : 2, "shape" : [ 117.43795697100006, 39.868482097000026 ], "ID" : "1202251180b201" }
{ "_id" : 3, "shape" : [ 117.71767576500008, 40.02316650200004 ], "ID" : "1202251200b201" }
{ "_id" : 4, "shape" : [ 117.43090199900007, 40.18651066600006 ], "ID" : "1202251040b201" }
{ "_id" : 5, "shape" : [ 117.39934450100009, 40.14910033900003 ], "ID" : "1202251120b201" }




怎么调试代码


源代码都是生成的dll,如果我们想了解数据怎么存储到mongoDB里面已经怎么从MongoDB解析出来,就需要调试代码,调试代码,我们需要将MongoDBCommands工程的属性,选择Debug-Start external program(选择ArcMap.exe)即可


如果仔细研究一下代码,可以使用参考代码来对mongoDB的数据库编辑ArcGIS点状要素。

关于点对象以及GDB_ITEMS的Extent的存储成BSON,那么从ArcGIS对象到BSON对象的相互转化,主要是调用了以下几个函数

  /// <summary>
    /// Transforms an ArcObjects IPoint into a BSON Value consisting of an array
    /// i.e. {shape=[-28.460325240999964, 26.267370224000047]}
    /// </summary>
    /// <param name="pt">The point to transform</param>
    /// <returns>BSON value representing point</returns>
    internal static BsonValue PointToBson(IPoint pt)
    {
      // stored as Y, X order because of MongoDB spatial indexing
      return BsonArray.Create(new double[2] { pt.X, pt.Y });
    }

    /// <summary>
    /// Populates an ArcObjects IPoint X and Y from a BSON Value consisting of an array
    /// i.e. {shape=[-28.460325240999964, 26.267370224000047]}
    /// </summary>
    /// <param name="elem">The BSON Element holding the x and y</param>
    /// <param name="pGeometry">The Geometry to update</param>
    internal static void BsonToGeometry(BsonElement elem, IGeometry pGeometry)    
    {
      try      
      {
        BsonValue[] shapeBuffer = elem.Value.AsBsonArray.ToArray();
        // stored as Y, X order because of MongoDB spatial indexing
        if (pGeometry is IPoint)        
          (((IPoint)pGeometry)).PutCoords(shapeBuffer[0].AsDouble, shapeBuffer[1].AsDouble);
        else
          throw new COMException("non-point geometries unsupported");
      }
      catch (InvalidCastException e)      
      {
        throw new COMException("Corrupt shape buffer");
      }
    }

    /// <summary>
    /// Gets an object serialized using ArcObjects xml serialization from a BSON Element
    /// Used by the CatalogDataset to extract metadata
    /// </summary>
    /// <param name="byteStuff">The BSON element containing the bytes</param>
    /// <returns>The object deserialized</returns>
    internal static System.Object BsonToObject(BsonElement byteStuff)
    {
      try
      {
        byte[] bytes = byteStuff.Value.AsByteArray;
        IXMLStream ipXmlStream = new XMLStreamClass();
        ipXmlStream.LoadFromBytes(ref bytes);
        IXMLReader ipXmlReader = new XMLReaderClass();
        ipXmlReader.ReadFrom((IStream)ipXmlStream);
        IXMLSerializer ipXmlSer = new XMLSerializerClass();
        return ipXmlSer.ReadObject(ipXmlReader, null, null);
      }
      catch (Exception)
      {
        throw new COMException("Value expected as byte array isn't");
      }
    }

    /// <summary>
    /// Serializes an object using ArcObjects xml serialization into a BSON Element
    /// Used by the CatalogDataset to store metadata
    /// </summary>
    /// <param name="ipItem">The object to serialize</param>
    /// <returns>The BSON element containing the bytes</returns>
    internal static BsonValue ObjectToBson(System.Object ipItem)
    {
      IXMLStream ipXmlStream = new XMLStreamClass();
      IXMLWriter ipXmlWriter = new XMLWriterClass();
      ipXmlWriter.WriteTo((IStream)ipXmlStream);
      IXMLSerializer ipXmlSer = new XMLSerializerClass();
      ipXmlSer.WriteObject(ipXmlWriter, null, null, "Test", "Test", ipItem);
      byte[] bytes = ipXmlStream.SaveToBytes();
      return BsonValue.Create(bytes);
    }


将要素类写入MongoDB的核心代码如下

 /// <summary>
    /// Pulls data from the source feature class and loads it into the new dataset
    /// </summary>
    /// <param name="ipSrc">The feature class we are loading from</param>
    /// <param name="ipTarget">The dataset we are loading to</param>
    public static void LoadData(IFeatureClass ipSrc, MongoDBDataset ipTarget)
    {
      // only bring fields which we know are compatible
      // at this point we do not bring BLOBs, GUIDs, etc
      // though that could be added in the future
      List<FieldInfo> fieldMap = new List<FieldInfo>();
      for (int i = 0; i < ipSrc.Fields.FieldCount; i++)
      {
        IField ipField = ipSrc.Fields.get_Field(i);
        switch (ipField.Type)
        {
          case esriFieldType.esriFieldTypeDate:
          case esriFieldType.esriFieldTypeDouble:
          case esriFieldType.esriFieldTypeInteger:
          case esriFieldType.esriFieldTypeSingle:
          case esriFieldType.esriFieldTypeSmallInteger:
          case esriFieldType.esriFieldTypeString:
            fieldMap.Add(new FieldInfo() { Name = ipField.Name, Idx = i, Type = ipField.Type });
            break;
          default:
            continue;
        }
      }

      // create the buffer of BSON documents for loading
      // and initialize
      BsonDocument[] buffer = new BsonDocument[BUFFERLEN];
      for (int i = 0; i < BUFFERLEN; i++)
        buffer[i] = new BsonDocument();


      IFeatureCursor ipFromCursor = ipSrc.Search(null, true);
      IFeature ipCurrent = ipFromCursor.NextFeature();
      int bufferIdx = -1;
      while (null != ipCurrent)
      {

        if (bufferIdx == (BUFFERLEN - 1)) // flush the buffer
        {
          bufferIdx = 0;
          ipTarget.InsertBlock(buffer);
        }
        else
          bufferIdx++;

        // load the current buffer from the feature
        LoadValues(ipCurrent, fieldMap, buffer[bufferIdx]);

        //move to next
        ipCurrent = null;
        ipCurrent = ipFromCursor.NextFeature();

      } // end while
      bufferIdx++;

      if (bufferIdx < BUFFERLEN) // if there are unwritten records, flush them now
      {
        BsonDocument[] remainingBuffer = new BsonDocument[bufferIdx];
        System.Array.Copy(buffer, remainingBuffer, bufferIdx);
        ipTarget.InsertBlock(remainingBuffer);
      }

      // keep indices fresh
      ipTarget.ReIndex();
    }

   /// <summary>
    /// Load a single feature's information into a BSON document
    /// </summary>
    /// <param name="ipSrc">The feature class we are loading from</param>
    /// <param name="fieldMap">Information on the fields</param>
    /// <param name="target">The BSON document we are loading into</param>
    private static void LoadValues(IFeature ipSrc, List<FieldInfo> fieldMap, BsonDocument target)
    {
      if ((ipSrc.Shape == null) || (ipSrc.Shape.IsEmpty))
        return;
      // get shape, transform it into a BSON value, and add it to the document
      IPoint pt = (IPoint)ipSrc.Shape;
      target.Set(CommonConst.SHAPEFIELD, BsonValue.Create(esriBsonUtilities.PointToBson(pt)));

      // loop the fields and pull values into the document
      // note that we filtered the fields based on field type earlier - no BLOBS, etc
      foreach (var field in fieldMap)
      {
        object val = ipSrc.get_Value(field.Idx);
        if (val != DBNull.Value)
        {
        switch (field.Type)
        {
          case esriFieldType.esriFieldTypeDate:
            DateTime dt = (DateTime)val;
            target.Set(CommonConst.TIME, BsonValue.Create(dt));
            break;
          default:
            target.Set(field.Name, BsonValue.Create(val));
            break;
        }
          }
      }
    }

目前,保存在ArcMap数据源为MongoDB的MXD还不支持ArcGIS Server的服务发布。


因为ArcGIS与NoSQL的结合,还处于摸索当中,里面的操作特别是直接对数据库进行编辑,仅供参考!


MongoDB GUI客户端:RockMongo - Best PHP MongoDB Administrator



扩展阅读:

使用Python 将shapefile导入mongodb


参考文档http://www.giser.net/?p=1085


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值