ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MapLibre 瓦片源工厂:多域名轮询+压级别+注记叠加

MapLibre 瓦片源工厂:多域名轮询+压级别+注记叠加 摘要在线底图不是一个 URL那么简单。本文用 MapLibre 的 TileSet 模板数组实现多域名轮询防限流、maxZoom 压级别防空白、主图注记双层叠加并扩展原生矢量瓦片源全部收口在一个瓦片源工厂单例里。文章导读适用引擎/版本MapLibre Android完整源码https://gitcode.com/qq_16064871/android_osmdroid_maplibre阅读场景接入 OSM/谷歌/天地图等在线瓦片底图需要多域名轮询、级别钳制、多底图热切换问题引入接入MapLibre 在线底图看似填个{z}/{x}/{y}模板就行但真实工程马上会遇到单域名限流、名义级别 ≠ 实际可用级别、多套底图热切换三件事。本文用一个瓦片源工厂单例把怎么拼 URL、怎么轮询域名、怎么钳级别全部收口TileSet.tileUrlTemplates模板数组天然支持多域轮询maxZoom一处压级别防空白天地图主图注记双层用RasterLayer叠加并扩展到原生矢量瓦片.pbf源。与 osmdroid 篇03/04同源不同源模型。副标题在线底图不是一个 URL而是轮询防限流 压级别防空白 多底图可切换。与 osmdroid 篇03/04同源不同源模型。一、问题在线底图不是一个 URL那么简单接一个在线瓦片底图看似只是填个{z}/{x}/{y}模板。但真实工程会立刻撞上三件事单域名被限流瓦片请求极密集一个域名会被服务端限速/封 IP。名义级别 ≠ 实际可用级别服务商标称支持到 20 级实际 18 级以上返回 404/空白。多套底图要能热切换OSM / 谷歌 / 天地图影像 / 矢量 / 注记组合繁多。把怎么拼 URL、怎么轮询域名、怎么钳级别散落在每个页面里会迅速失控。DEMO 用一个瓦片源工厂单例统一管理。二、工厂的核心TileSet 模板数组移动端地图引擎此处为 MapLibre 系用TileSet的tileUrlTemplates声明一组 URL 模板引擎自动调度加载。工厂本质就是按类型拼出对的模板数组// OSM单域名 XYZ 模板funosmRaster():RasterSourceRasterSource(osm-src,TileSet(2.1.0,*OsmDomains.map{$it/{z}/{x}/{y}.png}.toTypedArray()))// 谷歌影像多域名 接管参数拼接fungoogleImageRaster():RasterSourceRasterSource(google-image-src,TileSet(2.1.0,*GoogleImageDomains.map{$itx{x}y{y}z{z}}.toTypedArray()))要点模板里{z}/{x}/{y}是占位符引擎运行时替换成真实行列号。谷歌系用x{x}y{y}z{z}是因为它把坐标当查询参数OSM/天地图用路径式。返回的是RasterSource 配套RasterLayer页面拿到直接addSource/addLayer无需关心 URL。三、多域名轮询防限流的关键把多个镜像域名放进模板数组引擎会在多个域名间轮换发请求天然摊薄单域名压力// OSM 域名DEMO 仅一个公共域OsmDomains[https://tile.openstreetmap.org]// 谷歌影像域名mts1~mts3 轮询GoogleImageDomains[http://mts1.google.com/vt/lyrsy,http://mts2.google.com/vt/lyrsy,http://mts3.google.com/vt/lyrsy]// 天地图域名t1~t6 轮询TianDiTuDomains[t1,t2,t3,t4,t5,t6]天地图的轮询写法更典型——域名段t1~t6循环拼到固定服务地址前privatefuntianDiTuRaster(sourceId,service):RasterSource{valtilesTianDiTuDomains.map{domain-http://$domain.tianditu.gov.cn/DataServer?T$serviceX{x}Y{y}L{z}tk$Token}.toTypedArray()valtileSetTileSet(2.1.0,*tiles)tileSet.maxZoomTDT_MAX_USABLE_ZOOM.toFloat()// 压级别returnRasterSource(sourceId,tileSet)}说明DEMO 把域名列表集中放在配置对象里OsmDomains/GoogleImageDomains/TianDiTuDomains工厂只负责拼。这样将来加域名、换密钥都不用动工厂逻辑。四、压级别名义级别 ≠ 实际可用级别这是最容易踩的坑。天地图标注支持到 18 级但部分服务类型注记cia/cva实际在更高缩放会返回空瓦片。不处理的结果放大到 18 级以上底图突然变空白、业务点悬空。解法给TileSet设maxZoom把请求级别钳在服务端真实可用上限tileSet.maxZoomTDT_MAX_USABLE_ZOOM.toFloat()// 18超过该级别的视野引擎不再请求瓦片避免无效请求与空白但地图视图本身仍可继续放大——业务绘制点、线、矢量不受影响。DEMO 还配合缩放联动超过HUGE_ZOOM18时隐藏底图/注记图层仅保留业务层避免空白底图 悬浮点的诡异观感。五、四类服务 注记叠加层天地图一个底图其实是主图 注记两层影像img_w/ 注记cia_w矢量vec_w/ 注记cva_w注记是独立的第二层盖在主图之上。工厂为每个服务都产出主源 主层 注记源 注记层四件套页面切换底图时一次性addSource/addLayer主图与注记funswitchBaseMap(baseSource,baseLayer,annotationSource?,annotationLayer?,name){applyTileSource(baseSource,baseLayer)removeAnnotationLayer()if(annotationSource!nullannotationLayer!null){style.addSource(annotationSource)style.addLayer(annotationLayer)// 注记盖在主图之上this.annotationLayerannotationLayer}}OSM 没有注记层annotationSource null调用时传空即可逻辑统一。六、矢量瓦片源同一工厂扩展工厂不止光栅瓦片也产出矢量瓦片源VectorSource指向.pbf瓦片fundemoVectorSource():VectorSourceVectorSource(demo-vector-src,TileSet(2.1.0,VECTOR_TILE_URL/{z}/{x}/{y}.pbf))fundemoVectorLabelLayer():SymbolLayerSymbolLayer(demo-vector-label,demo-vector-src).withSourceLayer(place)// 必须指定矢量瓦片内部图层名.withProperties(textField({name}),...)矢量瓦片要指定source-layer瓦片内部的图层名如place否则渲染不出。这是光栅/矢量两套源在用法上的最大差异。七、与 osmdroid 的异同通用原理 vs MapLibre 实现通用原理一致多域名轮询防限流、把名义缩放钳到实际可用级别、主图注记双层叠加、OSM/谷歌/天地图多底图切换——这些是接入任何在线瓦片源的通用工程要点与引擎无关。MapLibre 专属实现差异维度osmdroid 篇03/04本文MapLibre源模型MapTileProviderArray/ 自定义IMapTileProvider拼多 providerTileSet.tileUrlTemplates直接填模板数组引擎内部轮询多域轮询需自己实现 provider 数组调度把多域名模板丢进数组引擎自动轮换压级别在 provider 里限制请求 zoom设TileSet.maxZoom一处搞定矢量瓦片无原生矢量瓦片概念原生VectorSourcesource-layer矢量瓦片是一等公民注记层多叠一个Overlay多叠一个RasterLayer同属源图层模型一句话轮询、压级别、多底图是通用知识MapLibre 把它们收口成TileSet 模板数组 maxZoom的声明式配置比 osmdroid 的 provider 数组更简洁且原生支持矢量瓦片.pbf这是 osmdroid 不具备的能力。八、落地清单与坑坑 1忘设maxZoom高缩放下底图空白。务必把名义级别钳到实际可用值。坑 2单域名硬扛被限流。OSM 公共域虽只有一个生产应自建代理或多域镜像谷歌/天地图务必用多域轮询。坑 3密钥写死在代码。DEMO 把tk等集中到配置对象生产应走构建注入/服务端下发避免泄露。坑 4矢量瓦片漏source-layer渲染空白。工厂做成无状态单例页面只消费Source/LayerURL 拼接、轮询、钳级别全收口在工厂内。九、小结在线底图接入的真正难点不在拼 URL而在轮询防限流、压级别防空白、多套底图可切换。用一个瓦片源工厂把这些收口页面侧只剩选哪个底图的复合动作维护成本陡降。完整工程源码见https://gitcode.com/qq_16064871/android_osmdroid_maplibre
返回列表