当前位置: 首页 > news >正文

建筑在线河南网站优化排名

建筑在线,河南网站优化排名,电商网站功能设计,企业内部管理系统背景介绍 前两天研究GeoServer发布存储在PostGIS中栅格数据,最终目的是想在PostGIS中存储金字塔瓦片,用GeoServer发布,但是最后经过研究不改GeoServer源码的情况下,好像只支持将大图tif存在PostGIS数据库中进行发布,金…

背景介绍

前两天研究GeoServer发布存储在PostGIS中栅格数据,最终目的是想在PostGIS中存储金字塔瓦片,用GeoServer发布,但是最后经过研究不改GeoServer源码的情况下,好像只支持将大图tif存在PostGIS数据库中进行发布,金字塔存入数据库后由于PostGIS的raster类型只存了瓦片的scale没有存类似层级的东西,导致发布后所有的金字塔层级一起显示了(没有层级控制),导致了很多影像叠加到一起了,后来又想到在数据库新增一个level字段,然后使用sld来进行控制显示,最后发现sld读不到字段表,这个路径也就放弃了(也许是我没弄对,有大佬点拨一下的话万分感谢)。

今天灵感来了(自己弄着玩),想到直接把瓦片的编号以及原始数据存到数据库,然后写个网络接口按照xyz数据源的格式请求,接口里查询数据库返回一张image给客户端,是不是就相当于一个xyz的瓦片服务器了?最终经过测试是可行的,先上两张效果图。

QGIS加载效果:

c432545dfa224e2983d1b205f59a75ab.png

水经微图加载效果:

8e7123471c8a47f580e4696bcdefe3cf.png

下面就说一下实现的具体流程

数据准备

数据是wgs84的瓦片,xyz都是从0开始,从左上角开始逆时针编号,以下是瓦片本地存储示例:

2dc62ce18d9d4c5d8877e1f74e3bc5a7.png

组织结构最外层为z值,第二层为x值,图片名称为y值。

数据库表示例:

b9a129b65fe84e6190d35f0748fb899c.png

然后使用Qt将瓦片读入并写入数据库,相关代码如下:

#pragma once#include <QString>
#include <QSqlDatabase>class CImageUploader
{
public:CImageUploader();~CImageUploader();void Init();void CreateTable();void UploadTileImage(const QString& strTileDir);private:QSqlDatabase m_db;
};
#include "ImageUploader.h"
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QFileInfo>
#include <QSqlQuery>
#include <QSqlError>
#include <QByteArray>
#include <QBuffer>QString strHostName = "192.168.1.7";
QString strDatabaseName = "Tile";
QString strUserName = "postgres";
QString strPassword = "root";
QString strPort = "4321";CImageUploader::CImageUploader()
{Init();CreateTable();
}CImageUploader::~CImageUploader()
{}void CImageUploader::Init()
{m_db = QSqlDatabase::addDatabase("QPSQL");m_db.setHostName(strHostName);m_db.setDatabaseName(strDatabaseName);m_db.setUserName(strUserName);m_db.setPassword(strPassword);m_db.setPort(strPort.toInt());if (!m_db.open()){qDebug() << "Failed to open database connection!" << m_db.lastError().text();}
}void CImageUploader::CreateTable()
{// 使用 IF NOT EXISTS 判断表是否存在QString strCreateTableQuery = QString(R"(CREATE TABLE IF NOT EXISTS Tile (id SERIAL PRIMARY KEY,x BIGINT NOT NULL,y BIGINT NOT NULL,z INT NOT NULL,data BYTEA NOT NULL);)");QSqlQuery query(m_db);if (!query.exec(strCreateTableQuery)){qDebug() << "Exec failed:" << query.lastError().text().toLocal8Bit();}
}void CImageUploader::UploadTileImage(const QString& strTileDir)
{QDir zDir(strTileDir);if (!zDir.exists()) {qDebug() << "Directory does not exist:" << strTileDir;return;}// 遍历 z 值文件夹QStringList zFolders = zDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);foreach(const QString &zFolder, zFolders) {bool zOk;int z = zFolder.toInt(&zOk);if (!zOk) {qDebug() << "Invalid z folder:" << zFolder;continue;}QDir xDir(zDir.filePath(zFolder));// 遍历 x 值文件夹QStringList xFolders = xDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);foreach(const QString &xFolder, xFolders) {bool xOk;qint64 x = xFolder.toLongLong(&xOk);if (!xOk) {qDebug() << "Invalid x folder:" << xFolder;continue;}QDir yDir(xDir.filePath(xFolder));// 遍历 y 值的图片文件QStringList imageFiles = yDir.entryList(QDir::Files);foreach(const QString &imageFile, imageFiles) {QString yValueStr = QFileInfo(imageFile).baseName();bool yOk;qint64 y = yValueStr.toLongLong(&yOk);if (!yOk) {qDebug() << "Invalid y file name:" << imageFile;continue;}QString imagePath = yDir.filePath(imageFile);QFile file(imagePath);if (!file.open(QIODevice::ReadOnly)) {qDebug() << "Failed to open image file:" << imagePath;continue;}QByteArray imageData = file.readAll();file.close();// 上传图片数据到数据库QSqlQuery query(m_db);query.prepare("INSERT INTO Tile (x, y, z, data) VALUES (:x, :y, :z, :data)");query.bindValue(":x", x);query.bindValue(":y", y);query.bindValue(":z", z);query.bindValue(":data", imageData);if (!query.exec()) {qDebug() << "Failed to upload tile image:" << query.lastError().text();}else {qDebug() << "Successfully uploaded tile image:"<< "z=" << z << ", x=" << x << ", y=" << y;}}}}
}
#include <QCoreApplication>
#include "ImageUploader.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);CImageUploader imageUploader;imageUploader.UploadTileImage(QString::fromLocal8Bit(R"(H:\data)"));return a.exec();
}

服务实现

数据写入数据库后只需要弄一个http接口了,我这里使用的是Node.js直连PostGIS数据库,然后根据请求去查数据库对应的image值,然后返回给客户端,Node代码如下:

const express = require('express');
const { Pool } = require('pg');
const app = express();
const port = 3000;// 配置PostgreSQL连接池
const pool = new Pool({user: 'postgres',host: '192.168.1.7',database: 'Tile',password: 'root',port: 4321,
});// XYZ瓦片接口
app.get('/tiles/:z/:x/:y', async (req, res) => {let { z, x, y } = req.params;// 提取数字部分的 y 值(去除文件扩展名)y = y.split('.')[0];try {// 确保 z, x, y 是有效的数字const zInt = parseInt(z, 10);const xInt = parseInt(x, 10);const yInt = parseInt(y, 10);if (isNaN(zInt) || isNaN(xInt) || isNaN(yInt)) {return res.status(400).send('Invalid tile coordinates');}// 查询数据库获取瓦片数据const queryText = `SELECT data FROM Tile WHERE z = $1 AND x = $2 AND y = $3`;const result = await pool.query(queryText, [zInt -1, xInt, yInt]);if (result.rows.length > 0) {const tileData = result.rows[0].data;res.setHeader('Content-Type', 'image/jpeg'); // 确保设置正确的图片格式res.send(tileData);} else {res.status(404).send('Tile not found');}} catch (err) {console.error('Error fetching tile:', err);res.status(500).send('Internal Server Error');}
});// 启动服务器
app.listen(port, () => {console.log(`Tile server is running at http://localhost:${port}`);
});

 安装依赖:

npm init -y
npm install express pg

 启动:

node server.js

然后就可以在浏览器请求测试(图片格式后缀其实没影响加不加都可):

http://localhost:3000/tiles/{z}/{x}/{y}.jpg

例如:

localhost:3000/tiles/1/0/0.jpg

 效果如下:

bc78f7cd1cdc4923bae70fd8ee18d0eb.png

然后就是QGIS加载测试,在XYZ Tiles新建链接,输入名称和网址,网址直接输入http://localhost:3000/tiles/{z}/{x}/{y}.jpg即可,Node做了z-1处理),图块分辨率可以不管也可以设为256*256,如下:

8d7dc05ab57c47ed881115df9f901acf.png

在水经微图里点击在线地图(自定义),在弹出的页面中,输入前面所说的网址即可,如下:

3eb740a032664fb3a502a122cafa8b35.png

最后给两张放大的效果图(数据只有6级):

QGIS:

92f813507a384ff38ce3dc2a3d063603.png

水经微图:

7deb52c1be7e4c9abd5e412391980ee1.png

分享到此结束。

 

http://www.wangmingla.cn/news/21448.html

相关文章:

  • 做网站用什么电脑配置做网络推广有哪些平台
  • 古风网站怎么做论坛外链代发
  • 北京正规做网站公司百度推广河南总部
  • wordpress语言翻译网站排名优化手机
  • 门户网站建设整改报告网站超级外链
  • 哪个公司的卡网络最好班级优化大师客服电话
  • 国外网站推广软件sem工具是什么
  • avada如何做中英文网站泽成seo网站排名
  • 镇江网站建设优化制作公司推广网站都有哪些
  • 自己做网站需要做服务器seo指什么
  • php 手机网站cms系统最新军事新闻 今日 最新消息
  • 有趣的网站知乎网站制作的重要性及步骤详解
  • 庐山网站建设百度学术论文查重免费
  • 界面设计好看的网站手机营销推广方案
  • 哈尔滨最专业的网站建设搜索大全引擎入口网站
  • 沈阳淘宝网站建设资源搜索引擎搜索神器网
  • 网站推广必做软文营销怎么写
  • 中国最大的私人定制公司云优化seo
  • wordpress网站地图提交最新军事新闻
  • 做企业网站的尺寸是多少钱福州百度快照优化
  • 软件科技有限公司东莞网站seo优化
  • 建设网站分析网站seo网络优化
  • 东营网站推广岳阳seo
  • 宣威网站建设c3salesbaidu百度首页
  • 如何做招聘网站运营seo教程网站
  • 做网站后端用户用什么写十大网络营销经典案例
  • wordpress优秀网站企业微信会话内容存档
  • 科技广告公司网站建设深圳做网站公司
  • 百度自然排名网站的logo怎么做长春做网站推广的公司
  • 重庆做网站公司哪家好郑州抖音推广