*
* util.cpp
*
* Copyright (C) 2021-2024 SuperMap Software Co., Ltd.
*
* Yukon is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see <http://www.gnu.org/licenses/>. *
*/
#include "util.h"
#include "json-c/json.h"
#include "json-c/json_object.h"
#include "json-c/json_types.h"
static double
toDegrees(double angrad)
{
return angrad * 180.0 / PI;
}
static double
toRadians(double angdeg)
{
return angdeg / 180.0 * PI;
}
double
tile2lat(int y, int z)
{
double n = PI - (2.0 * PI * y) / pow(2.0, z);
return toDegrees(atan(sinh(n)));
}
double
tile2lon(int x, int z)
{
return x / pow(2.0, z) * 360.0 - 180;
}
BoundingBox
tile2boundingBox(int x, int y, int z)
{
BoundingBox box;
box.ymin = tile2lat(y, z);
box.ymax = tile2lat(y + 1, z);
box.xmin = tile2lon(x, z);
box.ymax = tile2lon(x + 1, z);
return box;
}
Tile
getTileNumber(double lat, double lon, int z)
{
int xtile = (int)floor((lon + 180) / 360 * (1 << z));
int ytile = (int)floor((1 - log(tan(toRadians(lat)) + 1 / cos(toRadians(lat))) / PI) / 2 * (1 << z));
if (xtile < 0)
xtile = 0;
if (xtile >= (1 << z))
xtile = ((1 << z) - 1);
if (ytile < 0)
ytile = 0;
if (ytile >= (1 << z))
ytile = ((1 << z) - 1);
Tile tile;
tile.x = xtile;
tile.y = ytile;
tile.z = z;
return tile;
}
* @brief 将一个 LevelConfig 对象转换为一个 json 字符串
*
* @return std::string
*/
std::string
LevelConfig::to_string()
{
#if 0
std::ostringstream output;
output << std::setprecision(15);
output << "level:" + std::to_string(level) + "\n";
output << "bbox:" + bbox + "\n";
output << "gridrule:" + gridrule + "\n";
output << "extent:" + std::to_string(extent) + "\n";
output << "buffer:" + std::to_string(buffer) + "\n";
output << "srid:" + std::to_string(srid) + "\n";
output << "filter:" + filter + "\n";
output << "attribute:";
for (size_t i = 0; i < attribute.size(); i++)
{
output << attribute[i] + " ";
}
output << "\n";
output << "buildrule:" + buildrule + "\n";
output << "tolerance:" << tolerance << "\n";
output << "preserveCollapsed:" + preserveCollapsed + "\n";
output << "resolution:" << resolution << "\n";
return output.str();
#endif
json_object *root;
const char *jsonString;
std::string res;
root = json_object_new_object();
json_object_object_add(root, "level", json_object_new_int(level));
json_object_object_add(root, "resolution", json_object_new_double(resolution));
json_object_object_add(root, "filter", json_object_new_string(filter.c_str()));
json_object *attriarray = json_object_new_array();
for (auto a : attribute)
{
json_object_array_add(attriarray, json_object_new_string(a.c_str()));
}
json_object_object_add(root, "attribute", attriarray);
jsonString = json_object_to_json_string(root);
res = std::string(jsonString);
json_object_put(root);
return res;
}
* @brief 解析具体的配置规则
*
* @param config 配置规则
* @param rules 解析后的结果
* @param index 配置规则数组的下标
* @param errmsg 错误信息
* @return int
* 0 - 解析正常
* -1 - 解析错误
*/
static int
parseConfigDetial(json_object *config, std::vector<LevelConfig> &rules, int index, std::string &errmsg)
{
LevelConfig &elem = rules.at(index);
json_object *jo_level = json_object_object_get(config, "level");
if (!jo_level || json_object_get_type(jo_level) != json_type_int)
{
errmsg = std::string("config must be contain level field and it's type is integer value");
return -1;
}
elem.level = json_object_get_uint64(jo_level);
json_object *jo_resolution = json_object_object_get(config, "resolution");
if (jo_resolution && json_object_get_type(jo_resolution) == json_type_double)
{
elem.resolution = json_object_get_double(jo_resolution);
}
json_object *jo_bbox = json_object_object_get(config, "bbox");
if (jo_bbox && json_object_get_type(jo_bbox) == json_type_string)
{
elem.bbox = std::string(json_object_get_string(jo_bbox));
}
json_object *jo_gridrule = json_object_object_get(config, "gridrule");
if (jo_gridrule && json_object_get_type(jo_gridrule) == json_type_string)
{
elem.gridrule = std::string(json_object_get_string(jo_gridrule));
}
json_object *jo_extent = json_object_object_get(config, "extent");
if (jo_extent && json_object_get_type(jo_extent) == json_type_int)
{
elem.extent = json_object_get_uint64(jo_extent);
}
json_object *jo_buffer = json_object_object_get(config, "buffer");
if (jo_buffer && json_object_get_type(jo_buffer) == json_type_int)
{
elem.buffer = json_object_get_uint64(jo_buffer);
}
json_object *jo_srid = json_object_object_get(config, "srid");
if (jo_srid && json_object_get_type(jo_srid) == json_type_int)
{
elem.srid = json_object_get_uint64(jo_srid);
}
json_object *jo_filter = json_object_object_get(config, "filter");
if (jo_filter && json_object_get_type(jo_filter) == json_type_string)
{
elem.filter = std::string(json_object_get_string(jo_filter));
}
json_object *jo_attribute = json_object_object_get(config, "attribute");
if (jo_attribute && json_object_get_type(jo_attribute) == json_type_array)
{
int n = json_object_array_length(jo_attribute);
for (int i = 0; i < n; i++)
{
json_object *jo_str = json_object_array_get_idx(jo_attribute, i);
if (json_object_get_type(jo_str) == json_type_string)
{
elem.attribute.push_back(std::string(json_object_get_string(jo_str)));
}
}
}
json_object *jo_buildrule = json_object_object_get(config, "buildrule");
if (jo_buildrule && json_object_get_type(jo_buildrule) == json_type_string)
{
elem.buildrule = json_object_get_string(jo_buildrule);
}
json_object *jo_tolerance = json_object_object_get(config, "tolerance");
if (jo_tolerance && json_object_get_type(jo_tolerance) == json_type_double)
{
elem.tolerance = json_object_get_double(jo_tolerance);
}
json_object *jo_preserveCollapsed = json_object_object_get(config, "preserveCollapsed");
if (jo_preserveCollapsed && json_object_get_type(jo_preserveCollapsed) == json_type_boolean)
{
elem.preserveCollapsed =
json_object_get_boolean(jo_preserveCollapsed) ? std::string("true") : std::string("false");
}
if (elem.level > MAX_LEVEL && elem.resolution == 0)
{
errmsg = std::string("the level has exceeded .provide the resolution parameter");
return -1;
}
return 0;
}
* @brief 解析配置文件
*
* @param config 配置字符串
* @return std::vector<LevelConfig>
*/
std::vector<LevelConfig>
parseConfig(const char *config, std::string &errmsg)
{
json_object *jo_root_obj = json_tokener_parse(config);
std::vector<LevelConfig> vres;
if (!jo_root_obj)
{
return vres;
}
if (json_object_get_type(jo_root_obj) != json_type_array)
{
fprintf(stderr, "levels parse error!\n");
json_object_put(jo_root_obj);
return vres;
}
int levels_size = json_object_array_length(jo_root_obj);
vres.resize(levels_size);
for (int i = 0; i < levels_size; i++)
{
json_object *jo_detail = json_object_array_get_idx(jo_root_obj, i);
if (parseConfigDetial(jo_detail, vres, i, errmsg) != 0)
{
vres.clear();
break;
}
}
json_object_put(jo_root_obj);
return vres;
}
* @brief 这个函数将单个配置字符串解析为一个 LevelConfig 对象,
* 这个函数只用于更新时使用
*
* @param config
* @return LevelConfig
*/
int
parseConfig(const char *config, LevelConfig &levelconfig)
{
json_object *jo_root_obj = json_tokener_parse(config);
if (jo_root_obj != nullptr)
{
json_object *jo_level = json_object_object_get(jo_root_obj, "level");
if (!jo_level || json_object_get_type(jo_level) != json_type_int)
{
return -1;
}
levelconfig.level = json_object_get_uint64(jo_level);
json_object *jo_resolution = json_object_object_get(jo_root_obj, "resolution");
if (jo_resolution && json_object_get_type(jo_resolution) == json_type_double)
{
levelconfig.resolution = json_object_get_double(jo_resolution);
}
json_object *jo_attribute = json_object_object_get(jo_root_obj, "attribute");
if (jo_attribute && json_object_get_type(jo_attribute) == json_type_array)
{
int n = json_object_array_length(jo_attribute);
for (int i = 0; i < n; i++)
{
json_object *jo_str = json_object_array_get_idx(jo_attribute, i);
if (json_object_get_type(jo_str) == json_type_string)
{
levelconfig.attribute.push_back(std::string(json_object_get_string(jo_str)));
}
}
}
}
json_object_put(jo_root_obj);
return 0;
}
RateConfig rateconfigs[] = {
{0, "1:591658710.91", 1.406250000000, 78271.51696}, {1, "1:295829355.455", 0.703125000000, 39135.75848},
{2, "1:147914677.727", 0.351562500000, 19567.87924}, {3, "1:73957338.864", 0.175781250000, 9783.939621},
{4, "1:36978669.432", 0.087890625000, 4891.96981}, {5, "1:18489334.716", 0.043945312500, 2445.984905},
{6, "1:9244667.358", 0.021972656250, 1222.992453}, {7, "1:4622333.679", 0.010986328125, 611.4962263},
{8, "1:2311166.839", 0.005493164063, 305.7481131}, {9, "1:1155583.42", 0.002746582031, 152.8740566},
{10, "1:577791.71", 0.001373291016, 76.43702829}, {11, "1:288895.855", 0.000686645508, 38.21851414},
{12, "1:144447.927", 0.000343322754, 19.10925707}, {13, "1:72223.964", 0.000171661377, 9.554628536},
{14, "1:36111.982", 0.000085830688, 4.777314268}, {15, "1:18055.991", 0.000042915344, 2.388657134},
{16, "1:9027.995", 0.000021457672, 1.194328567}, {17, "1:4513.998", 0.000010728836, 0.597164283},
{18, "1:2256.999", 0.000005364418, 0.298582142}, {19, "1:1128.499", 0.000002682209, 0.149291071}};