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

使用Apache发布PostGIS数据库存储的栅格影像

前面有使用Node.js读取存储在PostGIS数据库中栅格影像发布xyz服务的文章,这篇是Apache版本。性能还需要优化直接上代码:

#ifndef TILE_DATABASE_HANDLER_H
#define TILE_DATABASE_HANDLER_H#include <libpq-fe.h>
#include <stdlib.h>typedef struct {PGconn* conn;
} TileDatabaseHandler;// Create and initialize the TileDatabaseHandler
TileDatabaseHandler* createTileDatabaseHandler();// Destroy the TileDatabaseHandler and free its resources
void destroyTileDatabaseHandler(TileDatabaseHandler* handler);// Get the tile data from the database given z, x, y coordinates
char* getTile(TileDatabaseHandler* handler, int z, int x, int y, size_t* dataLength);#endif // TILE_DATABASE_HANDLER_H
#include "TileDatabaseHandler.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>// Function to create and initialize TileDatabaseHandler
TileDatabaseHandler* createTileDatabaseHandler() {TileDatabaseHandler* handler = (TileDatabaseHandler*)malloc(sizeof(TileDatabaseHandler));if (!handler) {return NULL;}// Connection stringconst char* conninfo = "host=192.168.101.201 port=4321 dbname=Tile user=postgres password=root";// Establish connection to the databasehandler->conn = PQconnectdb(conninfo);// Check to ensure the connection was successfulif (PQstatus(handler->conn) != CONNECTION_OK) {fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(handler->conn));destroyTileDatabaseHandler(handler);return NULL;}return handler;
}// Function to destroy the TileDatabaseHandler and free its resources
void destroyTileDatabaseHandler(TileDatabaseHandler* handler) {if (handler) {if (handler->conn) {PQfinish(handler->conn);}free(handler);}
}// Function to get tile data from the database given z, x, y coordinates
char* getTile(TileDatabaseHandler* handler, int z, int x, int y, size_t* dataLength) {if (!handler || !handler->conn) return NULL;const char* queryTemplate = "SELECT data FROM Tile WHERE z = $1 AND x = $2 AND y = $3";// Allocate memory for query parameters//const int paramCount = 3;const char* params[3];char zStr[12];char xStr[22];char yStr[22];snprintf(zStr, sizeof(zStr), "%d", z - 1);snprintf(xStr, sizeof(xStr), "%ld", (long)x);snprintf(yStr, sizeof(yStr), "%ld", (long)y);params[0] = zStr;params[1] = xStr;params[2] = yStr;// Execute the queryPGresult* res = PQexecParams(handler->conn, queryTemplate, 3, NULL, params, NULL, NULL, 1);if (PQresultStatus(res) != PGRES_TUPLES_OK) {fprintf(stderr, "SELECT failed: %s", PQerrorMessage(handler->conn));PQclear(res);return NULL;}// Check if we have any resultif (PQntuples(res) == 0) {PQclear(res);return NULL;}// Get the length of the data*dataLength = PQgetlength(res, 0, 0);if (*dataLength == 0) {PQclear(res);return NULL;}// Allocate memory for the tile datachar* tileData = (char*)malloc(*dataLength);if (!tileData) {PQclear(res);return NULL;}// Copy the binary data to tileData buffermemcpy(tileData, PQgetvalue(res, 0, 0), *dataLength);// Clear the result to free memoryPQclear(res);return tileData;
}
#include "httpd.h"
#include "http_log.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_strings.h>// Include the C header for the TileDatabaseHandler functions
#include "TileDatabaseHandler.h"// A wrapper to handle database context in C codetypedef struct {TileDatabaseHandler* dbHandler;  // Database handler structchar* tileDataBuffer;            // Buffer to hold the tile datasize_t tileDataLength;           // Length of the tile data
} tilehandler_context;tilehandler_context* create_tilehandler_context() {tilehandler_context* context = (tilehandler_context*)malloc(sizeof(tilehandler_context));if (context) {context->dbHandler = createTileDatabaseHandler();context->tileDataBuffer = NULL;context->tileDataLength = 0;}return context;
}void destroy_tilehandler_context(tilehandler_context* context) {if (context) {if (context->tileDataBuffer) {free(context->tileDataBuffer);}destroyTileDatabaseHandler(context->dbHandler);free(context);}
}// Get tile data and its length
const char* get_tile_data(tilehandler_context* context, int z, int x, int y) {if (!context) return NULL;if (context->tileDataBuffer) {free(context->tileDataBuffer);context->tileDataBuffer = NULL;}// Assuming getTile is modified to return BLOB data and its lengthcontext->tileDataBuffer = getTile(context->dbHandler, z, x, y, &(context->tileDataLength));if (!context->tileDataBuffer || context->tileDataLength == 0) {return NULL;}return context->tileDataBuffer;
}/* The sample content handler */
static int tilehandler_module_handler(request_rec* r) {if (strcmp(r->handler, "tilehandler_module")) {return DECLINED;}if (r->method_number != M_GET) {return HTTP_METHOD_NOT_ALLOWED;}int z, x, y;// Extract coordinates from the URI, removing possible file extensionif (sscanf(r->uri, "/tiles/%d/%d/%d", &z, &x, &y) != 3) {ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Failed to parse URI: %s", r->uri);return HTTP_BAD_REQUEST;}// Create contexttilehandler_context* context = create_tilehandler_context();if (!context) {return HTTP_INTERNAL_SERVER_ERROR;}const char* tileData = get_tile_data(context, z, x, y);if (tileData && context->tileDataLength > 0) {// Set correct MIME type based on your image formatap_set_content_type(r, "image/jpeg"); // Change to "image/png" if needed// Set Content-Length headerapr_table_setn(r->headers_out, "Content-Length", apr_psprintf(r->pool, "%zu", context->tileDataLength));// Write the image dataap_rwrite(tileData, context->tileDataLength, r);}else {ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Tile not found for z=%d, x=%d, y=%d", z, x, y);ap_set_content_type(r, "text/plain");ap_rprintf(r, "Tile not found");destroy_tilehandler_context(context);return HTTP_NOT_FOUND;}destroy_tilehandler_context(context);return OK;
}static void tilehandler_module_register_hooks(apr_pool_t* p) {ap_hook_handler(tilehandler_module_handler, NULL, NULL, APR_HOOK_MIDDLE);
}/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA tilehandler_module = {STANDARD20_MODULE_STUFF,NULL,                  /* create per-dir    config structures */NULL,                  /* merge  per-dir    config structures */NULL,                  /* create per-server config structures */NULL,                  /* merge  per-server config structures */NULL,                  /* table of config file commands       */tilehandler_module_register_hooks  /* register hooks                      */
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 应急响应:挖矿木马-实战 案例一.【Linux 系统-排查和删除】
  • 搭建个人网站
  • 限流算法思想
  • HarmonyOS 开发
  • Simple RPC - 04 从零开始设计一个客户端(上)
  • 用Python爬取高德地图路径规划数据——02. 批量爬取-Python程序及详解
  • PostgreSQL的Logical Replication Launcher进程
  • Lumos学习王佩丰Excel第十二讲:Match与Index
  • 【PyCharm】配置“清华镜像”地址
  • Educational Codeforces Round 169 (Rated for Div. 2)(A-D)
  • 深度学习--参数报错问题
  • 网络硬盘录像机NVR解決方案:海思3520D模组与全面的NVR方案支持
  • 【信息学奥赛一本通】1007:计算(a+b)×c的值
  • Unity3D 自定义窗口
  • HiveSQL:提取json串内容——get_json_oject和json_tuple
  • 4个实用的微服务测试策略
  • create-react-app项目添加less配置
  • FineReport中如何实现自动滚屏效果
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Python3爬取英雄联盟英雄皮肤大图
  • 阿里云Kubernetes容器服务上体验Knative
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 关于Flux,Vuex,Redux的思考
  • 排序(1):冒泡排序
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 阿里云服务器如何修改远程端口?
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​zookeeper集群配置与启动
  • #{} 和 ${}区别
  • #Lua:Lua调用C++生成的DLL库
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (二)WCF的Binding模型
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (十) 初识 Docker file
  • (原)Matlab的svmtrain和svmclassify
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .NET 回调、接口回调、 委托
  • .NET上SQLite的连接
  • .NET正则基础之——正则委托
  • /etc/skel 目录作用
  • :如何用SQL脚本保存存储过程返回的结果集
  • @hook扩展分析
  • @RestControllerAdvice异常统一处理类失效原因
  • [14]内置对象
  • [20171101]rman to destination.txt
  • [240527] 谷歌 CEO 承认 AI 编造虚假信息问题难解(此文使用 @gemini 命令二次创作)| ICQ 停止运作
  • [Android Studio 权威教程]断点调试和高级调试
  • [C++] 从零实现一个ping服务
  • [C++]unordered系列关联式容器
  • [Django ]Django 的数据库操作