zoukankan      html  css  js  c++  java
  • 使用Mongodb存放文件系统的离线栅格数据,供Cesium访问

    整体思路:1.使用python将文件系统的瓦片数据导入到mongodb数据库中,根据层级和图片编号建立索引

         2.使用node和mongooes搭建一个地图服务供cesium的接口使用,

         3.根据Cesium加载瓦片数据的内部实现,是通过UrlTemplateImageryProvider()实现的

          主要是这个接口内部有一个templateValue通过正则表达式

          var templateRegex = /{[^}]+}/g;来替换掉文件服务器上的模板url:

          根据发布的服务接口,修改原本的模板url来匹配发布的地图服务接口,就可以是使用Cesium添加了

    这个思路是参考网上别人的访问OpenLayer的方法来实现的,别人的文章地址如下https://blog.csdn.net/u013420816/article/details/84141464

          

    1. 将文件系统中的文件夹导入monogodb的方法如下,因为我的文件夹组织结构和文章中的不一样所以自己又修改了一下,只有10级

                                                               

      首先要下载python,然后肯定要装pymongo的库的嘛,然后我根据文章的代码自己修改了下就是下面这个样子

    from pymongo import MongoClient
    import os
    from bson import binary
    
    class file2db(object):
        def __init__(self,database,setname,level):
            mongodb_url='localhost'
            mongodb_port=27017
            conn=MongoClient(mongodb_url,mongodb_port)
            db=conn[database]
            self.my_set=db[setname]
            self.max_level=level
    
        def read_png_file(self,root_path):
            _files=[]
            if os.path.exists(root_path):
                list=os.listdir(root_path)
                print(list)
                for i in range(0,len(list)):
                    path=os.path.join(root_path,list[i])
                    if os.path.isdir(path):
                        _files.extend(self.read_png_file(path))
                    if os.path.isfile(path):
                        _files.extend(path)
    
                        file_name=os.path.basename(path).split('.')[0]
                        file_type=os.path.basename(path).split('.')[1]
                        print(file_name)
                        print(file_type)
        
                        dir_path=os.path.dirname(path).split("\")
    
                        row_name=dir_path[len(dir_path)-1]
                        zoom_name=dir_path[len(dir_path)-2]
                        
    
                        if file_type=='png':
                            self.insert_file(zoom_name,row_name,file_name,path)
                return _files
            else:
                return None
    
        def insert_file(self,zoom,row,column,path):
            level=zoom
            if int(level)<=self.max_level:
                png_list=self.my_set.find({"x":row,"y":column,"z":zoom})
                print(png_list.count())
                if png_list.count()==0:
                    print("------")
                    print(zoom)
                    print(row)
                    print(column)
                    print(path)
    ##                print('zoom:%s row:%s fileName:%s path:%s' (zoom,row,column,path))
                    file=open(path,mode='rb')
                    content=binary.Binary(file.read())
                    self.my_set.insert({"x":row,"y":column,"z":zoom,"img":content})
                    file.close()
                else:
                    print('this file is exist')
            else:
                print('this zoom greater than max level')
    
    if __name__=='__main__':
        file2db=file2db('png','layer',10)
        file2db.read_png_file('F:worldImage_鏁版嵁澶囦唤Img')

    插入数据库中的瓦片数据如下

      

        2.使用node和monogoose来搭建一个地图服务器连接mongodb这一部分也是借鉴文章中的代码,同时在node服务器这端处理了一个跨域问题

    'use strict';
    var mongoose = require('mongoose'),
        DB_URL = 'mongodb://localhost:27017/png';
    
    mongoose.connect(DB_URL);
    
    
    mongoose.connection.on('connected', function () {    
        console.log('Mongoose connection open to ' + DB_URL);  
    });    
    
    
    mongoose.connection.on('error',function (err) {    
        console.log('Mongoose connection error: ' + err);  
    });    
    
    mongoose.connection.on('disconnected', function () {    
        console.log('Mongoose connection disconnected');  
    });    
    
    module.exports = mongoose;
    

      

    'use strict';
    var mongoose = require('./db'),
        Schema = mongoose.Schema;
    
    var GGSchema = new Schema({          
        x : { type: String },                    
        y: {type: String},                       
        z: {type: String},                        
        img : { type: Buffer},                       
    });
    
    module.exports = mongoose.model('layer',GGSchema,'layer');
    

      

    'use strict';
    var express = require('express');
    var mylayer = require("./layer");
    var app = express();
    
    // 获取图片
    app.get('/getimage/',function(req, res) {
        res.header("Access-Control-Allow-Origin","*")
        var x = req.query.x
        var y = req.query.y
        var z = req.query.z
        console.log(req.originalUrl+"node");
        
        var whereStr = {"x":x,"y":y,"z":z};
        console.log(whereStr);
        mylayer.findOne(whereStr,function(err, doc){
            if(err){
                console.log("Error: "+err)
            }else{
                let img = null 
                if(doc){
                    if(doc.img){
                        img = doc.img
                    }
                }
                if(img){
                    res.writeHead('200', {'Content-Type': 'image/png'});    //写http头部信息
                    res.end(img,'binary'); 
                }else{
                    res.status(404);
                    res.end()
                }
                
            }
        })
        
    })
    var server = app.listen(8081, function () {
     
      var host = server.address().address
      var port = server.address().port
     
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
     
    })

    一共三个文件,第一个连接数据库,第二个模式约束,第三个使用express发布服务

    3.修改Cesium.UrlTemplateImageryProvider中默认的Url的模板适配发布的服务即可

  • 相关阅读:
    QML Image Element
    QML基本可视化元素--Text
    联想笔记本电脑的F1至F12键盘问题。怎么设置才能不按FN就使用F1
    Qt Creator 黑色主题配置
    虚拟机配置
    虚拟机下安装ubuntu后root密码设置
    联想(Lenovo)小新310经典版进bios方法
    带有对话框的父窗口
    添加菜单的窗口
    添加组件的窗口
  • 原文地址:https://www.cnblogs.com/1521681359qqcom/p/13292575.html
Copyright © 2011-2022 走看看