地圖瓦片介紹與地圖瓦片編程下載

前沿

地圖瓦片指將一定范圍內的地圖按照一定的尺寸和格式,按縮放級別或者比例尺,切成若干行和列的正方形柵格圖片,對切片后的正方形柵格圖片被形象的稱為瓦片[。瓦片通常應用于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…