项目中的生成slpk模块遇到问题,记录一下。初步判定是slpk内的文件组织方式有误,没有按照
i3s和slpk是什么
i3s(indexed 3D scene layer)存储3d场景数据的一个标准,slpk是这个标准的一个具体实现,在1.6的版本支持四种数据类型,项目中用到的是integrated mesh,跟其他几个的区别在哪,我目前也不太懂(),在他们的github中有详细描述,如果要自己实现slpk的话,建议去看ogc上的规范细则(slpkV1.6),个人感觉比GitHub写得详细。
libzip
源自c时代的一个用于压缩文件的库,官网手册写得一塌糊涂,在外网找到一些别人写的例子才慢慢摸明白怎么用。。。libzip example to create archive · GitHub
#include <iostream>
#include <string>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <zip.h>
static bool is_dir(const std::string& dir)
{
struct stat st;
::stat(dir.c_str(), &st);
return S_ISDIR(st.st_mode);
}
static void walk_directory(const std::string& startdir, const std::string& inputdir, zip_t *zipper)
{
DIR *dp = ::opendir(inputdir.c_str());
if (dp == nullptr) {
throw std::runtime_error("Failed to open input directory: " + std::string(::strerror(errno)));
}
struct dirent *dirp;
while ((dirp = readdir(dp)) != NULL) {
if (dirp->d_name != std::string(".") && dirp->d_name != std::string("..")) {
std::string fullname = inputdir + "/" + dirp->d_name;
if (is_dir(fullname)) {
if (zip_dir_add(zipper, fullname.substr(startdir.length() + 1).c_str(), ZIP_FL_ENC_UTF_8) < 0) {
throw std::runtime_error("Failed to add directory to zip: " + std::string(zip_strerror(zipper)));
}
walk_directory(startdir, fullname, zipper);
} else {
zip_source_t *source = zip_source_file(zipper, fullname.c_str(), 0, 0);
if (source == nullptr) {
throw std::runtime_error("Failed to add file to zip: " + std::string(zip_strerror(zipper)));
}
if (zip_file_add(zipper, fullname.substr(startdir.length() + 1).c_str(), source, ZIP_FL_ENC_UTF_8) < 0) {
zip_source_free(source);
throw std::runtime_error("Failed to add file to zip: " + std::string(zip_strerror(zipper)));
}
}
}
}
::closedir(dp);
}
static void zip_directory(const std::string& inputdir, const std::string& output_filename)
{
int errorp;
zip_t *zipper = zip_open(output_filename.c_str(), ZIP_CREATE | ZIP_EXCL, &errorp);
if (zipper == nullptr) {
zip_error_t ziperror;
zip_error_init_with_code(&ziperror, errorp);
throw std::runtime_error("Failed to open output file " + output_filename + ": " + zip_error_strerror(&ziperror));
}
try {
walk_directory(inputdir, inputdir, zipper);
} catch(...) {
zip_close(zipper);
throw;
}
zip_close(zipper);
}
int main(int argc, char *argv[])
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <input_dir> <output_file>\n", argv[0]);
return 1;
}
zip_directory(argv[1], argv[2]);
return 0;
}
参照slpk的格式、压缩要求,很快就能写出来了(虽然我搞了挺久的)