栅格瓦片转mongodb离线部署

前提

​ 上一篇博客中讲到了如何将TMS标准的瓦片转换成mbtiles格式发布服务,但是在现实环境中,使用的切图工具或者切图的人并没有按照标准切图。有的人切片为ArcServer切片或者GeoWebCache切片。这样的话上篇博客的方法就不能适用了。那么本篇博客就讲述上篇解决不了的切片。

实现思路

​ 使用NoSQL(这里指Mongodb)对瓦片的png图片进行入库存储,通过x,y,z来关联对应的图片,然后通过Nodejs查询得到图片的二进制写到页面中。完成展示瓦片的功能

准备工作

  1. 切好的瓦片(我这里是ArcServer切片)
  2. Python(我使用的版本:3.6.2)
  3. NodeJS(我使用的版本:8.11.3)
  4. Mongodb(我使用的版本:4.0.4)

工具安装

这里的Python,NodeJS,Mongodb 可以按照网上的教程安装,这里我就不再赘述了

步骤

  1. 下载栅格瓦片地图

  2. 编写脚本,将瓦片存入Mongodb库中,这里基于瓦片的图都比较小,就以二进制存到库中,不使用GridFS

    下面的脚本只是我自己要用的,不能满足所有情况,如果自己有特殊需求,可以对代码进行修改。大概思路就是:

    1. 循环遍历切片文件夹中的所有切片
    2. 将读取到的切片转成二进制并存储到库中
from pymongo import MongoClient
import os
from bson import binaryclass file2db(object):def __init__(self, database, setname, level):mongodb_url = 'localhost'mongodb_port = 27017conn = MongoClient(mongodb_url, mongodb_port)db = conn[database]self.my_set = db[setname]self.max_level = leveldef read_png_file(self, root_path):# 遍历文件形成dict# D:\Tomcat 8.5\webapps\Layers\_alllayers_files = []if os.path.exists(root_path):list = os.listdir(root_path)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)# get columnfile_name = os.path.basename(path).split('.')[0]file_type = os.path.basename(path).split('.')[1]dir_path = os.path.dirname(path).split('\\')# get rowrow_name = dir_path[len(dir_path) - 1]# get zoom levelzoom_name = dir_path[len(dir_path) - 2]# insert mongodbif file_type == 'png':self.insert_file(zoom_name, row_name, file_name, path)return _fileselse:return Nonedef insert_file(self, zoom, row, column, path):# 将data 存到mongo中level = zoom[1:]if int(level) <= self.max_level:png_list = self.my_set.find({"x": row, "y": column, "z": zoom})if png_list.count() == 0: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', 13)file2db.read_png_file('D:\Tomcat 8.5\webapps\Layers\_alllayers')

执行完毕后库中的数据

  1. 给数据创建索引
png.layer.createIndex({x:1,y:1,z:1})
--创建完成后可以用explain看看有没有使用索引
  1. 编写node脚本,发布服务

    这里只是简单的写了一下,node我也是边用边学的,如果已经是对node写服务端很熟悉的大佬这段就可以过滤掉了。如果跟我一样也是刚接触的话可以看一下。具体思路:

    1. 连接mongo,查询数据
    2. 写一个接口用于前端调用得到瓦片图

    这里node需要安装的组件有:mongoose,express

新建一个node项目如下:

db.js内容:

'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;

layer.js内容:

'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');

map-server.js内容:

'use strict';
var express = require('express');
var mylayer = require("./layer");
var app = express();// 获取图片
app.get('/getimage/',function(req, res) {var x = req.query.xvar y = req.query.yvar z = req.query.zconsole.log(req.originalUrl)var whereStr = {"x":x,"y":y,"z":z};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().addressvar port = server.address().portconsole.log("应用实例,访问地址为 http://%s:%s", host, port)})
  1. 使用OL预览效果

    这里我的切片是ArcgisServer切片,如果是其他切片(geowebcache等)只要更改加载算法就行

//初始化XYZsource
var source  = new ol.source.XYZ({tileUrlFunction : function (xyz, obj1, obj2) {var z = xyz[0];var x = Math.abs(xyz[1]);var y = Math.abs(xyz[2]) - 1;var x = 'C' + padLeft(8, x.toString(16)).toUpperCase();var y = 'R' + padLeft(8, y.toString(16)).toUpperCase();var z = 'L' + padLeft(2, z);var url = 'http://localhost:8081/getimage?x=' + y + '&y=' + x + '&z=' + z ;return url;}
});
//ArcgisServer切片加载算法
function padLeft(num, val) {return (new Array(num).join('0') + val).slice(-num);
}

最后的效果:

总结

  1. 如果切片比较多,导入数据库的速度会受影响,可以考虑换成多线程进行处理
  2. 上面的效果是在我自己的开发机器上展现的。单机情况下,这个速度还是可以的。感觉做集群部署将请求进行分发,速度应该还能提高。

最后

以上的代码和脚本均已上传到github库中。

栅格瓦片转mongodb离线部署相关推荐

  1. Mars3D开发基础学习:栅格瓦片图层

    前面我们说到地形是三维场景的"骨骼",栅格瓦片图层就是我们浏览三维能感知的"皮肤"了,通常我们叠加的是各种卫星影像或瓦片数据. Mars3D支持多种服务来源的高 ...

  2. linux 离线地图开发包,Mapbox本地离线部署

    一 离线部署说明 从官网抄一个HelloWorld的例子,完整代码如下: Display a map body { margin:0; padding:0; } #map { position:abs ...

  3. 10_Linux ARM架构-离线部署 Docker + MongoDB-银河麒麟V10操作系统

    大家好,我是星仔.本博客收录于华星详谈-学习中心.本学习中心收集了Java整个技术体系的所有技术要点.每篇博客后面或者知识点结尾都附带有面试题,提供给大家巩固本章内容. 为各位同胞们能够系统性的掌握整 ...

  4. 地图瓦片:矢量瓦片和栅格瓦片详解

    地图瓦片:矢量瓦片和栅格瓦片详解 为什么需要瓦片: 地图缓存技术:地图服务的性能需求越来越高:缓存技术大大提高了地图服务的性能:缓存技术降低了服务器端压力,不在需要进行动态出图:地图缓存或瓦块地图可以 ...

  5. 《Linux运维实战:Centos7.6基于ansible一键离线部署mongodb4.2.23容器版副本集群》

    一.部署背景 由于业务系统的特殊性,我们需要针对不同的客户环境部署 mongodb副本集群,由于大都数用户都是专网环境,无法使用外网,为了更便捷,高效的部署,针对业务系统的特性,我这边编写了基于ans ...

  6. Java对点、线、面生成栅格瓦片jpg,并渲染呈现

    Java对点.线.面生成栅格瓦片jpg,并渲染呈现 1. 效果图 2. 原理 2.1 面瓦片的生成 2.2 线瓦片的生成 2.3 多点瓦片的生成 3. 源码 参考 这篇博客将介绍从前端HTML页面到后 ...

  7. 【内网福音】如何离线部署Rancher

    2019独角兽企业重金招聘Python工程师标准>>> 对于在公司内网环境中.无法访问互联网的用户而言,离线安装部署Rancher是解决问题的关键.本文是Rancher离线部署教程, ...

  8. Python 进阶 — 创建本地 PyPI 仓库与 Python 程序的离线部署

    目录 文章目录 目录 创建本地 PyPI 仓库 安装 pypiserver 上传 Python 安装包 使用私有 PyPI 仓库 Python 程序的离线部署 pip download 获取必须的 P ...

  9. EdgeGallery — AIO 离线部署 v1.5 版本

    目录 文章目录 目录 前言 资源配置 软件版本 Pre Installation 安装配置文件解析 hosts-aio var.yml password-var.yml Installation Po ...

最新文章

  1. 熟悉scala命令,scala语言运行超级素数和猴子大王
  2. l3fwd 是什么_服务器DPDK l3fwd性能测试
  3. DataGrid控件读取具体某行某列的值、获取总列数
  4. python2 与 python3的区别整理
  5. 【错误记录】Flutter 报错 ( Dart SDK is not configured )
  6. weblogic.rjvm.PeerGoneException
  7. cisco tftp 操作
  8. php对应哪个oracle版本,Oracle 版本说明
  9. java并发编程笔记_java并发编程笔记(一)——并发编程简介
  10. jquery常见操作分享
  11. PDX模型不靠谱,土豪来发resource;细菌帮助癌转移,诺奖发现被推翻
  12. 如何删除表中的重复记录?等等常用SQL语句的积累
  13. jeesite如何已生成数据的数据源_jeesite 多数据源配置
  14. spss和python有什么不同_python与spss的不同
  15. Android WIFI的管理方法
  16. Python学习(七)if语句
  17. AndroidSDK目录和源码目录详解
  18. 机器学习资料与攻略超强整理吐血推荐(二)
  19. 如何使用 JAVA 开发微信登录教程
  20. C语言实现水果超市信息管理系统

热门文章

  1. Qt on Android : Hello World开发
  2. 第二章 卡耐基与人相处的秘诀 二 与人相处的秘诀
  3. Firing:Preserving the Employee's Dignity(尊严)(2018/07/26)
  4. Qt Creator软件界面配置——自适应屏幕分辨率
  5. 卷积神经网络训练花卉识别分类器
  6. 电脑之间使用串口传输文件
  7. Altium Designer,PCB生成CAD文件
  8. Flutter app打包详解
  9. 洛谷 P2341 - 受欢迎的牛
  10. ae中用粒子系统做的特效怎么循环