前沿

地图瓦片指将一定范围内的地图按照一定的尺寸和格式,按缩放级别或者比例尺,切成若干行和列的正方形栅格图片,对切片后的正方形栅格图片被形象的称为瓦片[。瓦片通常应用于B/S软件架构下,浏览器从服务器获取地图数据,由于瓦片相比正射影像底图数据量小,查询检索块,因此是一种改善地图浏览用户体验的优化策略。

地图瓦片是一种标准,只要按照标准执行,每个人都能从遥感影像或矢量制作地图瓦片。也可以从公开的地图服务中获取瓦片。目前多家GIS地图厂商都有自己的在线地图瓦片服务。例如天地图的在线服务(天地图API)谷歌的地图瓦片服务(https://developers.google.com/maps,需科学上网),Esri的在线地图服务(https://www.arcgis.com/home/webmap/viewer.html)等等。也可以从专门的地图瓦片服务提供商获取,例如水经注,91卫图。不过后者也都是从GIS地图厂商下载数据,然后缓存到本地,提供区域定制,时间定制等个性化服务。

本文从纯技术的角度粗浅谈一下技术原理和C++编码实现。

需求分析

序号

需求描述

1

支持TIF、jpeg、PNG三种瓦片格式。

2

支持瓦片存储到MongoDB数据库、亚马逊S3、SQLite、Mbtiles文件以及直接存储到磁盘文件。

3

生成指定位置的瓦片集。

4

瓦片多时态索引加载。

5

瓦片多时态索引更新。

6

支持从遥感正射影像生成瓦片。

7

支持从GIS厂商下载瓦片。支持百度地图,高德地图,天地图(需要token),google earth,ESRI下载。类型涵盖卫星图、带标签的卫星图、矢量底图、矢量注记等多种类型瓦片。支持设置代理。支持多线程下载。支持从上次任务继续下载。支持下载失败的瓦片多次下载确保完整性。

8

如果将瓦片输出到磁盘文件,支持并行化下载,支持多种瓦片命名。例如z/x/y.png, z/y/x.png, z/z_x_y.png, z/z_y_x.png, z/x_y.png,z/y_x.png

9

遥感正射影像裁切成瓦片,支持支持WGS1984、CGCS2000、WebMercator、百度坐标系等多种坐标系定义。

10

遥感正射影像裁切成瓦片支持8位,16位格式切片。支持动态拉伸。支持无效值填充或替换。支持边切边计算以实现类似NDVI类产品。支持自定义波段。

11

下载的磁盘文件形式瓦片,支持按行政区划,自定义范围打包压缩。

12

MBtile形式的瓦片支持按自定义等级划分多个存储文件。例如下载全国1-18级瓦片,支持按照6级划分为多个MBtiles文件存储。

性能需求

  1. 支持并行化影像切片,支持集群模式调用。具备全国1-18级瓦片24小时完成的能力(需要硬件支持)。
  2. 支持并行化瓦片下载。支持自定义线程数目,支持集群模式调用。支持设置下载格式。

 原理实现

瓦片数据是为了提高地图服务的响应速度,将配好效果的电子地图按照一定的规则渲染和切割成的 地图图片数据。 (1)瓦片切图范围和规则:地图投影数据范围为 (-20037508.34米 , -20037508.34米), (20037508.34米, 20037508.34米)的正方形范围;利用金字塔规则映射成不同显示比 例的像素范围,之后利用瓦片编号生成规则(见 3)从西北(-20037508.34 米, 20037508.34 米)向东南陆续把数据分成瓦片。(瓦片大小为 256*256 像素)。

(2)金字塔规则:采用四叉树规则构建金字塔,各层的显示比例(即分辨率)固定。显示比例计算方法如下: 由此确定金字塔各层瓦片如下表 1 所示。 zoom 表示缩放的级别,最小为 0; resolution(分辨率):为投影距离与像素距离之比,单位是米/像素 width、height为每一级别数据的像素宽高,乘号左边为每一级别的宽或高的瓦片数,乘号右边的 为瓦片的像素宽高。

(3)瓦片编号生成规则:生成的像素范围左上角为最小值(0,0)右下角为最大值,如图:

金字塔生成 0-18 级的像素范围后,利用 256*256 像素大小把像素范围划分成一张张正方形瓦片,即用像 素范围的宽高除以瓦片宽高。瓦片编号与像素位置的关系为: 横/纵瓦片编号与像素位置整除256。

二、栅格取图规则

(1)最直观的取图规则: x=横向的瓦片编号 y=纵向的瓦片编号 z=zoom 级别 唯一定位一张瓦片图。

(2)高德取图规则: 将切割好的瓦片数据按照一定的目录规则存放,并将每张瓦片图片命名,目录存放规则:

x=(横向瓦片编号/10)取整 y=(纵向瓦片编号/10)取整 z=zoom 级别唯一定位一张瓦片图。

 核心代码设计

地图瓦片类型定义


/**
* @brief 地图瓦片类型。
* @note 1、每个类型的值不可随意变动。枚举值用4位16进制表示,左起第一位表示厂商,后三位表示
*       瓦片类型。并且瓦片类型值支持组合,以便于后续程序支持多类型同时下载。
*       2、谷歌地图瓦片需要设置代理翻墙。已经是无偏移的瓦片。
*/
enum class TileType
{unknown = 0x0000,///<未知类型,未初始化类型google_image        = 0x0001,///<google卫星图google_image_mark   = 0x0002,///<google带标签的卫星图google_terrain      = 0x0004,///<google地形图google_terrain_mark = 0x0008,///<google带标签的地形图google_route        = 0x0010,///<google路线图google_label        = 0x0020,///<google标签层(路名、地名等)tianditu_vector          = 0x1000,///<天地图矢量底图tianditu_vector_mark     = 0x1001,///<天地图矢量注记tianditu_image           = 0x1002,///<天地图影像底图tianditu_image_mark      = 0x1004,///<天地图影像注记tianditu_shading_terrain = 0x1008,///<天地图地形晕渲tianditu_label_terrain   = 0x1010,///<天地图地形注记tianditu_boundary        = 0x1020,///<天地图全球境界tianditu_vector_mark_en  = 0x1040,///<天地图矢量英文注记tianditu_image_mark_en   = 0x1080,///<天地图影像英文注记esri_imagery             = 0x2000 ///<Arcgis卫星地图};

文件组织方式

/**
* @brief 输出瓦片文件组织方式。枚举类型中的d代表directory,n代表name
*/
enum class SaveOrder {zd_xd_yn,  ///> z/x/y.pngzd_yd_xn,  ///> z/y/x.pngzd_z_x_yn, ///> z/z_x_y.pngzd_z_y_xn, ///> z/z_y_x.pngzd_x_yn,   ///> z/x_y.pngzd_y_xn    ///> z/y_x.png
};

 瓦片计算器


class LIB_WIMBASE TileCalculator
{
public:TileCalculator(size_t t_size);virtual ~TileCalculator();TileYDirection GetYDirection() const { return ydirect; };TileResolutionUnit GetUnit() const { return tile_unit; };//瓦片实际边长virtual double GetTileXSize(int level) = 0;virtual double GetTileYSize(int level) = 0;virtual int GetLevelByXResolution(double res) = 0;virtual int GetLevelByYResolution(double res) = 0;virtual double GetLevelXResolution(int level) = 0;virtual double GetLevelYResolution(int level) = 0;virtual int GetLevelByXSize(double res) = 0;virtual int GetLevelByYSize(double res) = 0;virtual int GetColByX(int level, double x) = 0;virtual int GetRowByY(int level, double y) = 0;virtual wim::Envelope GetExtentByLevelRowCol(int level, int row, int col) = 0;virtual wim::Point2D GetLTByLevelRowCol(int level, int row, int col) = 0;	/*** @brief 根据总的Envelope,获取一个最高尺度,该尺度及以下才会更新瓦片。更高尺度的瓦片更新将因为更新区域太小而变得无意义。* @param dst_env 是指瓦片空间参考下的范围。*/virtual void GetProperTopPos(const wim::Envelope& extent, TilePos&) = 0;/*** @brief 根据extent,获取一个最高尺度,该最高尺度的宽和高是大于extent范围的最接近的一个尺度。* @param extent 是指瓦片空间参考下的范围。* @return 满足条件的最高尺度;*/virtual int GetTopLevel(const wim::Envelope& extent) = 0;/*** @brief 根据给定尺度level,获取所有位于空间范围extent之内的瓦片位置。* @param extent 是指瓦片空间参考下的范围。* @param level 尺度* @param v 位于空间范围之内的瓦片位置集合;*/virtual void GetLevelPos(const wim::Envelope& extent, int level, std::vector<TilePos> &v) = 0;/*** @brief 根据给定尺度level,获取所有位于空间范围extent之内的瓦片位置。* @param extent 是指瓦片空间参考下的范围。* @param count 数量上限,即:v的大小不超过此数* @param level 符合条件下的level等级,是输出值。* @param v 位于空间范围之内的瓦片位置集合;*/virtual void GetSizedPos(const wim::Envelope& extent, int count, int& level, std::vector<TilePos> &v) = 0;protected:TileYDirection	ydirect;size_t			tile_size;//边长TileResolutionUnit tile_unit;
};
typedef boost::shared_ptr<TileCalculator> TileCalculatorPtr;

瓦片坐标系

//定义瓦片坐标系
enum class TileProjection{TileProjWGS1984,    //EPSG:4326,[-180.0, 180.0], [-85.0511288, 85.0511288]TileProjCGCS2000,   //EPSG:4490, [-180.0, 180.0], [-90, 90]TileProjWebMercator,//EPSG:3857, [-20037508.3427892, 20037508.3427892], [-20037508.3427892, 20037508.3427892] //TileProjTianDiTu,   //EPSG:4490, [-180.0, 180.0], [-90, 90],屏蔽掉,直接用TileProjCGCS2000替代TileProjArcGIS,     //EPSG:3857, [-20037508.342787, 20037508.342787], [-19971868.88040859, 19971868.88040859]TileProjBaidu       //参考椭球:Clarke_1866,坐标系:NAD27, 投影:Mercator
};

瓦片切片上下文环境


/***  @brief 切片处理的上下文环境。*  @note 该类定义了切片的执行参数和必备的环境信息,需要在切片之前就被构建和设置。*/
class LIB_IMGTILE TileContext
{
public:TileContext(const TileSetting &tilesetting, TileFormat fmt, Date timestamp, const std::string& theme, bool updating);virtual ~TileContext() { }virtual void Cleanup() const;TileProjection tile_projection;                  //投影类型SpatialRefPtr  tile_srs;                         //瓦片空间参考对象TileFormat     tile_format;                      //输出瓦片格式Timestamp      timestamp;                        //时间戳std::string    theme_name;                       //对应的主题名称int            top_level;                        //切片的最高级别,如0级int			   bottom_level;                     //切片的最低级别,例如18级int            tile_size;                        //瓦片大小,现在必须是256size_t         jpeg_quality;                     //瓦片压缩质量,仅用于JPG格式,取值在50-100之间bool           is_initial;                       //是否是对应主题的初次瓦片生成(即忽略历史瓦片数据,默认false)bool           is_updating;                      //是否更新模式(默认false,即增加新时间戳数据),注意is_initial和is_updating的区别,前者负责是否读取历史数据,后者负责是否覆盖历史数据.bool           force_stretch_8bit;               //切片时是否拉伸波段类型为8位字节型的影像(默认是不拉伸),如果卫星影像不是8位的,该参数无效,算法内部将强制拉伸.bool		   use_global_minmax;                //影像像素值拉伸时使用全局相同的最值(raster_min_value,raster_max_value)int			   raster_min_value[TILE_NUM_BANDS]; //影像集的全局最小值,该参数仅在需要对原始图像数据进行拉伸处理时生效。int			   raster_max_value[TILE_NUM_BANDS]; //影像集的全局最大值,该参数仅在需要对原始图像数据进行拉伸处理时生效。StretchType    stretch_type;                     //拉伸类型.如果遥感影像是8位字节型的影像,仅当force_stretch_8bit为true有效.如果不是8位影像,仅当use_global_minmax为false时候有效int			   tile_min_value;                   //瓦片数据最小值,该参数仅在需要对原始图像数据进行拉伸处理时生效。int			   tile_max_value;                   //瓦片数据最大值,该参数仅在需要对原始图像数据进行拉伸处理时生效。double         no_data_value;                    //影像集的默认无数据值,当影像未设置无效值时,该参数有效。bool           is_full_range_8bit;               //输入的8bit影像中0~255都是有效值。如果该值为true,将算法内部将会把0值变成1,把255变成254。如果该值为false,算法内部不做处理。该参数仅对8bit数据有效。int            band_order_rgb[3];                //设置输出瓦片RGB对应的输入遥感影像哪3个波段,波段号最小是1.例如可以是{1,2,3},{3,2,1},{1,1,1}等,用户需要确保波段号真实存在于每个输入数据.如果用户没有设置,内部将按照{1,2,3}多光谱和{1,1,1}全色来处理.uint8_t        no_data_rgb[3];                   //瓦片无效区域的颜色填充值SpatialRefPtr  default_srs;                      //对于不包含参考系信息的数据使用此默认参考系ResamplingMode resampling;                       //生成瓦片时的重采样方式,默认最邻近。该参数控制遥感影像生成瓦片的采样方式。std::string    storage_uri;                      //瓦片存储信息,可以为数据库地址或磁盘路径std::string    backup_storage;                   //写失败时瓦片的备份路径TileCalculatorPtr calculator;                    //瓦片信息计算对象// 读取瓦片回调函数typedef boost::function<DataArrayPtr(const TileContext& ctx, int level, int col, int row, size_t& len)> ReadTileProxy;ReadTileProxy ReadTile;// 写出瓦片回调函数typedef boost::function<bool(const TileContext& ctx, int level, int col, int row, DataArrayPtr, size_t len)> WriteTileProxy;WriteTileProxy WriteTile;
}

 单张瓦片定义


/*** @brief 单张瓦片的原始图像数据。*/
struct LIB_IMGTILE TileImage
{/*** @param nodata RGB三通道的无效值因此nodata为长度是3的数组。*/TileImage(int w, int h, const uint8_t* nodata_rgb);~TileImage();int width;int height;DataArrayPtr img_data; // RRRGGGBBBDataArrayPtr alpha_data; //单波段数组,该数组最终作为输出图像的透明度参考.但是在中间处理过程中,用一些特殊值来标记像素位置的特殊的处理过程.//并且约定取值只可能是几种情况//0代表未处理的区域. 该位置的值填充的是默认值(往往是无效值)。//255代表处理过的区域,该位置包含有效像素值.//1代表该位置在当前过程中被处理.//2代表该位置在当前过程中被进行了无效值替换处理.
};

瓦片索引定义


class LIB_IMGTILE TileIndex
{
public://高度自定义瓦片类型的初始化TileIndex(const TileSetting& ts, int num_levels);~TileIndex();// 增加一个Patch到索引中void AddTilePatch(Timestamp timestamp, int top_level, int bottom_level, const char* wkt);// 更新一个已有的Patch索引bool UpdateTilePatch(Timestamp timestamp, const char* wkt, int top_level, int bottom_level);/*** @brief 查询指定瓦片的有效时间。* @param timestamp 瓦片的查询时间,同时用以返回有效时间* @param pos 瓦片的位置* @param overall 不存在时是否返回最接近的瓦片时间* @return 是否查询到有效的时间*/bool QueryTile(Timestamp& timestamp, TilePos& pos, bool overall);// 查询指定时间点Patch在其最底层的WKT表示bool QueryTilePatch(Timestamp timestamp, std::string& patch);struct TilePatch;struct TilePatchTree;typedef std::unordered_map<int, TilePatch*> TilePatchMap;private:int               total_levels;TileCalculatorPtr calculator;TilePatchMap      tile_patches;TilePatchTree*    tile_tree;
};

瓦片存储相关

/**
* @brief 简单文件存储上下文环境
* @note 简单文件存储将瓦片按照指定的文件布局保存,不考虑时间戳,因此多次切片的结果总是合并为一个整体,
*       便于浏览和检查切片结果正确性。
*/
class LIB_IMGTILE TileFileContext : public TileContext
{
public:TileFileContext(TileProjection pj, TileFormat fmt, Date timestamp, const std::string& theme, bool updating);TileFileContext(const TileSetting &tilesetting, TileFormat fmt, Date timestamp, const std::string& theme, bool updating);virtual ~TileFileContext() { }virtual bool SetTilePatch(const std::string& wkt);//对于JPG、PNG这种格式,是否创建.tfw坐标文件bool make_world_file;//如果是输出tiff切片数据,是否将空间参考和坐标信息写入tiff文件,写入操作会占用一定的时间。默认写入!bool write_coodinate_to_tiff;std::string tile_layout;
};class LIB_IMGTILE TileFileStorage
{
public:static DataArrayPtr Read(const TileContext& ctx, int level, int col, int row, size_t& len);static bool Write(const TileContext& ctx, int level, int col, int row, DataArrayPtr data, size_t len);private:TileFileStorage() { };
};class LIB_IMGTILE TileMongoStorage
{
public:TileMongoStorage();~TileMongoStorage();DataArrayPtr Read(const TileContext& ctx, int level, int col, int row, size_t& len);bool Write(const TileContext& ctx, int level, int col, int row, DataArrayPtr data, size_t len);bool Flush(const TileContext& ctx, int index = -1);struct TileData{TileData(int level, int col, int row, DataArrayPtr data, size_t len): tile_pos(level, row, col), tile_data(data), tile_len(len) { }TilePos      tile_pos;size_t       tile_len;DataArrayPtr tile_data;};typedef std::list<TileData> TileList;std::vector<TileList> tile_cache; // 每一个collection的分片都有一个缓存列表int tile_threshold;
};class LIB_IMGTILE TileS3Storage
{
public:static DataArrayPtr Read(const TileContext& ctx, int level, int col, int row, size_t& len);static bool Write(const TileContext& ctx, int level, int col, int row, DataArrayPtr data, size_t len);private:TileS3Storage() { };
};/**
* @brief 存储瓦片数据到SQLite文件。
*/
class LIB_IMGTILE TileSQLiteStorage
{
public:TileSQLiteStorage(std::string db_path, int watershed_level, Envelope env, TileCalculatorPtr);~TileSQLiteStorage();DataArrayPtr Read(int level, int col, int row, size_t& len);bool Write(int level, int col, int row, DataArrayPtr data, size_t len);bool Flush(std::string dbname);inline std::string GetDBName(int level, int col, int row);int cache_size;//每个DB文件的缓存大小,直白点就是攒够多少个瓦片写入一次。struct TileCache{TileCache(int level, int col, int row, DataArrayPtr data, size_t len): tile_pos(level, row, col), tile_data(data), tile_len(len) { }TilePos      tile_pos;size_t       tile_len;DataArrayPtr tile_data;};typedef std::list<TileCache> TileList;//tile_caches容器大小会根据切片任务的总范围,确定6级瓦片个数,根据6级瓦片个数确定。std::map<std::string, TileList> tile_caches; //<dbname, TileList>//数据库DB文件所在路径,注意是文件夹地址,例如“D:\ImageData\Tile\tiledb”std::string db_path;int watershed_level;Envelope env;//TileSQLiteContextPtr context;
};/**
* @brief 存储瓦片数据到Mbtiles文件。
*/class LIB_IMGTILE TileMbtilesStorage
{
public:TileMbtilesStorage(std::string db_path);~TileMbtilesStorage();DataArrayPtr Read(int level, int col, int row, size_t& len);bool Write(int level, int col, int row, DataArrayPtr data, size_t len);/*** @brief 将缓冲区内的数据写到Mbtiles。注意调用者在析构该对象前一定要显式调用一遍Flush以确保数据完全被保存。*/bool Flush();struct TileCache{TileCache(int level, int col, int row, DataArrayPtr data, size_t len): tile_pos(level, row, col), tile_data(data), tile_len(len) { }TilePos      tile_pos;size_t       tile_len;DataArrayPtr tile_data;};typedef std::list<TileCache> TileList;std::list<TileCache> tile_caches;std::string db_file;     //Mbtiles数据库文件路径int cache_size;          //每个瓦片文件的缓存大小,直白点就是攒够多少个瓦片写入一次。std::mutex storemutex;   //数据库锁
};
typedef std::shared_ptr<TileMbtilesStorage> TileMbtilesStoragePtr;

 案例

根据提供的矢量范围,下载Google Earth瓦片

【这里CSDN不让展示矢量范围.jpg】

下载参数设置

		std::string path = R"(D:\ImageData\tiledownload\Tile)";std::string shp =  R"(D:\ImageData\tiledownload\shp\range.shp)";CommonTileDownloader tiler(path, TileSaveType::file, TileType::google_image);tiler.SetProxy("127.0.0.1:33210");tiler.SetDvideLevel(6);tiler.SetTryTimes(6);tiler.Download(shp, 18, 18, progress);

下载成果

将瓦片合并到TIF(带地理坐标) 

		std::string tile_path = wim::String::UTF8ToLocal(R"(D:\ImageData\tiledownload\Tile)");std::string dest_tiff = wim::String::UTF8ToLocal(R"(D:\ImageData\tiledownload\Tile\img_tile18.tif)");TileMosaicFromFiles(tile_path, dest_tiff, SaveOrder::zd_z_x_yn, TileProjection::TileProjWebMercator, 18, progress);

tif图像展示(实际范围很大,分辨率0.5米)

地图瓦片下载器V1.1说明

程序参见“WimTileDownloader”工程

参数说明

参数

说明

--help

打印帮助信息

-s [ --shppath ] arg

矢量文件所在目录,将遍历目录下的shp或者geojson进行下载

                         瓦片或者解压

-r [ --tilepath ] arg

存储瓦片的根目录.程序将在该根目录下按照:z/x/y顺序进行

                         组织

-z [ --zippath ] arg

瓦片压缩包保存目录.

-t [ --tiletype ] arg

瓦片类型:img:影像图片 cia:影像注记  vec:矢量图片

                         cva:矢量注记

-m [ --mode ] arg (=0)

程序运行模式,1:下载瓦片,2:压缩瓦片

下载瓦片举例:

 -s "D:\ImageData\Tile\测试可删\2024年省级行政区划数据" -r "D:\ImageData\Tile\测试可删\Tileroot" -m 1 -t "cia"

压缩瓦片举例:

 -s "D:\ImageData\Tile\测试可删\2024年省级行政区划数据" -r "D:\ImageData\Tile\测试可删\Tileroot" -z "D:\ImageData\Tile\测试可删\ziproot" -m 2 -t "cia"

注意事项:

1、每种瓦片类型需要单独设置瓦片根目录,否则会重名。

2、如果有token失效,瓦片下载会结束,下次重新执行相同的命令可继续下载。

3、下载完的矢量会被挪到tilepath文件夹下。压缩完的矢量会被挪到zippath,以防止重复劳动。

本文章仅供技术交流。更多技术交流请联系作者:hanbing6174@163.com   V:hanbing6174

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87208.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87208.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/87208.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机屏亮点缺陷修复及相关液晶线路激光修复原理

摘要 手机屏亮点缺陷严重影响显示品质&#xff0c;液晶线路短路、电压异常是导致亮点的关键因素。激光修复技术凭借高能量密度与精准操控性&#xff0c;可有效修复液晶线路故障&#xff0c;消除亮点缺陷。本文分析亮点缺陷成因&#xff0c;深入探究液晶线路激光修复原理、工艺…

MySQL数据一键同步至ClickHouse数据库

随着数据量的爆炸式增长和业务场景的多样化&#xff0c;传统数据库系统如MySQL虽然稳定可靠&#xff0c;但在海量数据分析场景下逐渐显露出性能瓶颈。这时&#xff0c;ClickHouse凭借其列式存储架构和卓越的OLAP&#xff08;在线分析处理&#xff09;能力脱颖而出&#xff0c;成…

Android中Compose常用组件以及布局使用方法

一、基础控件详解 1. Text - 文本控件 Text(text "Hello Compose", // 必填&#xff0c;显示文本color Color.Blue, // 文字颜色fontSize 24.sp, // 字体大小&#xff08;注意使用.sp单位&#xff09;fontStyle FontStyle.Italic, // 字体样式&…

SCI一区黑翅鸢优化算法+三模型光伏功率预测对比!BKA-CNN-GRU、CNN-GRU、GRU三模型多变量时间序列预测

SCI一区黑翅鸢优化算法三模型光伏功率预测对比&#xff01;BKA-CNN-GRU、CNN-GRU、GRU三模型多变量时间序列预测 目录 SCI一区黑翅鸢优化算法三模型光伏功率预测对比&#xff01;BKA-CNN-GRU、CNN-GRU、GRU三模型多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 …

创客匠人视角:创始人 IP 打造为何成为知识变现的核心竞争力

在互联网流量成本高企的当下&#xff0c;知识变现行业正经历从 “产品竞争” 到 “IP 竞争” 的范式迁移。创客匠人 CEO 老蒋指出&#xff0c;创始人 IP 已成为企业突破增长瓶颈的关键支点 —— 美特斯邦威创始人周成建首次直播即创下 1500 万元成交额&#xff0c;印证了创始人…

类图+案例+代码详解:软件设计模式----生成器模式(建造者模式)

生成器模式&#xff08;建造者模式&#xff09; 把复杂对象的建造过程和表示分离&#xff0c;让同样的建造过程可以创建不同的表示。 假设你去快餐店买汉堡&#xff0c;汉堡由面包、肉饼、蔬菜、酱料等部分组成。 建造者模式的角色类比&#xff1a; 产品&#xff08;Product…

UI前端与数字孪生融合探索:为智慧物流提供可视化解决方案

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在全球供应链数字化转型的浪潮中&#xff0c;智慧物流正从概念走向落地 —— 据 MarketsandMa…

远程办公与协作新趋势:从远程桌面、VDI到边缘计算,打造高效、安全的混合办公环境

一、引言 随着数字化转型的加速&#xff0c;越来越多的企业开始采用远程办公和混合办公模式&#xff0c;以提升员工的灵活性和企业的敏捷性。然而&#xff0c;异地办公也带来了诸如桌面环境不一致、安全风险增加、沟通协作效率降低等诸多挑战。因此&#xff0c;如何打造一致、…

算法总结篇:二叉树

二叉树解题整体框架&#xff1a; 1、确定当前题型是做高度还是深度还是搜索树还是其他 高度&#xff08;从下往上&#xff0c;求根深度、高度等&#xff09;&#xff1a; 使用后序遍历会更加简单&#xff0c;递归方法一般需要返回值返回上级&#xff0c;让上级对返回值进行判断…

【Elasticsearch】most_fields、best_fields、cross_fields 的区别与用法

most_fields、best_fields、cross_fields 的区别与用法 1.核心区别概述2.详细解析与用法2.1 best_fields&#xff08;最佳字段匹配&#xff09;2.2 most_fields&#xff08;多字段匹配&#xff09;2.3 cross_fields&#xff08;跨字段匹配&#xff09; 3.对比案例3.1 使用 best…

力扣网C语言编程题:在数组中查找目标值位置之暴力解法

一. 简介 本文记录一下力扣网上涉及数组的问题&#xff1a;排序数组中查找目标值的位置。主要以C语言实现。 二. 力扣网C语言编程题&#xff1a;在数组中查找目标值位置 题目&#xff1a;在排序数组中查找元素的第一个和最后一个位置 给你一个按照非递减顺序排列的整数数组 …

OSCP - Proving Grounds - tre

主要知识点 突破边界的方法比较多样观察pspy64的检测结果 具体步骤 依旧nmap扫描开始,开放了80,8082,22端口 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-16 03:39 UTC Nmap scan report for 192.168.56.84 Host is up (0.00083s latency). Not shown: 65532 c…

【Mars3d】支持的basemaps数组与layers数组的坐标系列举

问题场景&#xff1a; basemap 是epsg4326的。&#xff0c;layer 图层是 epsg 4450的。可以在一个页面中展示吗&#xff1f; 回复&#xff1a; 可以不同坐标系叠加&#xff0c;但layer 图层是 epsg 4450的只支持arcgis动态服务&#xff0c;其他情况的不支持 wmts只支持3个坐标…

【算法】509. 斐波那契数

509. 斐波那契数 简单 相关标签 premium lock icon 相关企业 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 …

FOC学习笔记(5)内嵌式电机与表贴式电机的区别

1. 引言 在现代电机设计中&#xff0c;永磁同步电机&#xff08;Permanent Magnet Synchronous Motor, PMSM&#xff09;因其高效率、高功率密度和优异的动态性能&#xff0c;在工业、新能源汽车、航空航天等领域得到广泛应用。根据永磁体在转子中的安装方式不同&#xff0c;永…

算法 按位运算

按位与&#xff08;Bitwise AND&#xff09;和按位异或&#xff08;Bitwise XOR&#xff09; 按位与&#xff08;&&#xff09; 按位与是对两个数的二进制表示的每一位进行逻辑与操作。 规则&#xff1a;两个对应位都为1时&#xff0c;结果位才为1&#xff0c;否则为0。…

python3GUI--基于PyQt5+SQLite3的网址审核系统(详细图文)

文章目录 一&#xff0e;前言二&#xff0e;相关知识1.PyQt52.sqlite3 三&#xff0e;效果预览1.登录2.注册3.普通用户身份权限4.管理员身份权限 三、技术讨论1.数据展示表格1. 更强的表现力和交互性&#xff08;前端功能丰富&#xff09;2. 数据处理效率更高&#xff08;支持大…

与后端现场联调mock数据

当我们后端在现场没办法连后端本地就可以使用mock数据&#xff0c;模拟后端返回数据。使用工具&#xff1a;apifox 一、安装好以后--新建接口 举个栗子&#xff1a; 我想建个接口http://123.123.123.123:8080/api/login 二、 新建期望&#xff0c;返回固定值&#xff0c;否则…

C# 事件(发布者和订阅者)

发布者和订阅者 很多程序都有一个共同的需求&#xff0c;即当一个特定的程序事件发生时&#xff0c;程序的其他部分可以得到 该事件已经发生的通知。 发布者/订阅者模式&#xff08;publisher/subscriber pattem&#xff09;可以满足这种需求。在这种模式中&#xff0c;发布 …

RediSearch高性能全文搜索引擎

RediSearch 是 RedisLabs 团队开发的一个高性能全文搜索引擎&#xff0c;可作为一个 Redis Module 运行在 Redis 上。 Redis7&#xff1a;百万数据级Redis Search 超越 ElasticSearch Redis Search是基于Redis的全文搜索引擎模块&#xff08;RediSearch&#xff09;&#xff0c…