- 前端
- 跨平台
- 桌面应用
- 移动开发
【免费下载链接】flet
Build realtime web, mobile and desktop apps in Python only. No frontend experience required.
导读
本指南围绕 Flet 官方地图扩展flet-map中的PolylineMarker(折线标记)控件展开,讲解如何在 Python 编写的 Flet 应用中绘制地图折线(路线、轨迹、边界线等),并对线条颜色、描边、渐变、线型(实线/虚线/点线)、线帽与线端接合样式进行精细化控制。读完本文,你将掌握PolylineMarker的全部属性、PolylineLayer的图层级渲染优化参数,以及它们如何映射到底层 Flutter 渲染实现,可直接在真实地图应用中落地使用。
一、什么是 PolylineMarker
PolylineMarker是flet-map扩展中用于在交互式地图上绘制**折线(polyline)**的控件。它属于PolylineLayer(折线图层)的一部分:一个PolylineLayer承载一组PolylineMarker,每个PolylineMarker定义一条独立折线的坐标点与外观样式。
在仓库中,该控件定义于 polyline_layer.py:
PolylineMarker通过@ft.control("PolylineMarker")注册为 Flet 控件;PolylineLayer通过@ft.control("PolylineLayer")注册,并继承自MapLayer基类(见 map_layer.py);- 两者均在 flet_map/init.py 中被公开导出。
从实现层面看,flet-map基于 Flutter 的flutter_map包构建(见 README.md),PolylineMarker的 Python 属性在 Dart 侧被映射为flutter_map的Polyline对象与PolylineLayer渲染组件。因此,本文所述的每一项属性都能在真实地图渲染中找到对应实现,而不仅仅是 Python 层的占位定义。
典型应用场景
- 展示出行路线(公交、骑行、驾车轨迹);
- 绘制地理边界线(行政区划、禁飞区轮廓);
- 在地图上叠加路径分析结果(如最短路径、等时圈边界);
- 以渐变线条呈现数据趋势(如按温度、速度着色的轨迹)。
二、安装与环境准备
PolylineMarker属于flet-map扩展包,需要独立安装。参考 README.md,使用 pip 安装:
pip install flet-map或使用 uv:
uv add flet-map安装后,在 Python 代码中导入:
import flet as ft import flet_map as ftmpyproject.toml(sdk/python/packages/flet-map/pyproject.toml)声明requires-python = ">=3.10",依赖仅有flet,说明它是一个轻量的纯 Python 封装扩展。该包支持 Windows、macOS、Linux、iOS、Android 与 Web 全平台(见 README.md 的平台支持表)。
三、PolylineMarker 属性详解
所有属性均来自 polyline_layer.py 中的字段定义。下面按功能分组逐一说明。
3.1 坐标:coordinates(必填)
coordinates: list[MapLatitudeLongitude]折线的经纬度点列表,使用MapLatitudeLongitude类型(定义于 types.py),包含latitude与longitude两个字段(单位:度):
ftm.MapLatitudeLongitude(latitude=30.0, longitude=15.0)coordinates是PolylineMarker唯一没有默认值的必填属性——没有坐标点就无法构成一条折线。它至少需要两个点,渲染时按列表顺序依次连接。
3.2 颜色:color 与 border_color
color: ft.ColorValue = ft.Colors.YELLOW # 线条主体颜色 border_color: ft.ColorValue = ft.Colors.YELLOW # 描边颜色color控制折线主体的颜色;border_color控制折线**描边(边框)**的颜色,默认与主体色相同(黄色Colors.YELLOW)。
两者均接受 Flet 颜色值(如ft.Colors.RED、十六进制字符串、ft.Colors.with_opacity(0.6, ft.Colors.GREEN)等)。在 Dart 侧(polyline_layer.dart),二者分别映射为 flutter_mapPolyline的color与borderColor,默认值同样为Colors.yellow,Python 层与 Dart 层默认值保持一致。
3.3 描边宽度:stroke_width 与 border_stroke_width
stroke_width: ft.Number = 1.0 # 主体线宽 border_stroke_width: ft.Number = 0.0 # 描边线宽stroke_width:线条主体宽度,默认1.0;border_stroke_width:描边宽度,默认0.0(即默认不显示描边)。当设置border_stroke_width > 0且border_color与color不同时,折线会呈现「外框 + 内芯」的双层视觉效果。
校验逻辑:PolylineMarker.before_update()(polyline_layer.py)会在控件更新前校验这两个值,若小于0.0则抛出ValueError:
stroke_width must be greater than or equal to 0, got -1.0 border_stroke_width must be greater than or equal to 0, got -2.03.4 以米为单位的线宽:use_stroke_width_in_meter
use_stroke_width_in_meter: bool = False默认False时,stroke_width以逻辑像素为单位;设为True后,线宽将采用米作为单位,线宽会随地图缩放级别自适应变化(放大后线更粗,缩小时更细)。该属性在 Dart 侧映射为Polyline.useStrokeWidthInMeter(polyline_layer.dart)。适合模拟真实道路宽度或物理尺寸边界的场景。
3.5 渐变:gradient_colors 与 colors_stop
gradient_colors: Optional[list[ft.ColorValue]] = None colors_stop: Optional[list[ft.Number]] = Nonegradient_colors:渐变颜色列表。提供后折线将按列表颜色沿路径渐变着色(而非纯色);colors_stop:渐变颜色的停靠点(stops),与gradient_colors一一对应,控制每种颜色在线段上出现的位置比例。
两者配合使用,可以做出如「红→黄→绿」的轨迹热力效果。Dart 侧将它们映射为Polyline.gradientColors与Polyline.colorsStop(polyline_layer.dart)。
3.6 线型:stroke_pattern
stroke_pattern: StrokePattern = field(default_factory=lambda: SolidStrokePattern())决定线条是实线、虚线还是点线,以及各自的具体参数。StrokePattern是抽象基类(types.py),实际使用以下三个子类:
| 类 | 说明 | 关键参数 |
|---|---|---|
SolidStrokePattern() | 实线(默认) | 无 |
DashedStrokePattern(segments, pattern_fit) | 虚线,由「线段长度 + 间隔长度」交替组成 | segments:偶数长度列表,如[50, 10, 10, 10];pattern_fit:PatternFit |
DottedStrokePattern(spacing_factor, pattern_fit) | 点线,按点间距绘制圆点 | spacing_factor:点间距系数,默认1.5 |
DashedStrokePattern.segments的语义(types.py):
- 列表长度至少为 2 且必须为偶数,形如
[a₁, b₁, (a₂, b₂, ...)]; a为线段长度(单位:像素),b为线段后空白长度;- 若提供多于两项,则按顺序交替循环。例如
[50, 10, 10, 10]表示:50px 线段 → 10px 空白 → 10px 线段 → 10px 空白 → 再回到 50px 线段……; - 校验失败会抛出
ValueError(segments少于两项或长度为奇数)。
DottedStrokePattern.spacing_factor必须大于 0,否则抛ValueError;值为1.0时点间距等于线宽,增大该值则按比例拉大点间距。
此外,PatternFit(types.py)决定线型图案与折线长度不成整数倍时的适配策略:
NONE:按指定图案原样重复,可能在末端留下缺口(不推荐);SCALE_DOWN/SCALE_UP:缩放图案使其整数次适配整条折线(分别取小/取大方向);APPEND_DOT:截断最后的短线,若末端有缺口则补一个点;EXTEND_FINAL_DASH:截断最后的短线,或将最后一段延长到终点(仅对虚线有意义)。
3.7 线帽与线端接合:stroke_cap 与 stroke_join
stroke_cap: ft.StrokeCap = ft.StrokeCap.ROUND # 线端点样式 stroke_join: ft.StrokeJoin = ft.StrokeJoin.ROUND # 线段转折处的接合样式stroke_cap:控制折线端点的形状。ft.StrokeCap提供BUTT(平头)、ROUND(圆头,默认)、SQUARE(方头)等取值;stroke_join:控制相邻线段转折点处的接合方式。ft.StrokeJoin提供ROUND(圆角接合,默认)、MITER(尖角)、BEVEL(斜切)等取值。
Dart 侧映射为 flutter_mapPolyline的strokeCap/strokeJoin,默认同为StrokeCap.round/StrokeJoin.round(polyline_layer.dart)。
3.8 可见性:visible
visible: bool = True控制该折线是否渲染在地图上。设为False可临时隐藏某条折线而无需从列表中移除,适合做图层显隐切换(如「显示/隐藏轨迹」开关)。
四、PolylineLayer:承载与渲染折线的图层
PolylineLayer(polyline_layer.py)继承自MapLayer,将一组PolylineMarker组合为图层,并暴露三个渲染性能调优参数:
ftm.PolylineLayer( polylines=[...], # list[PolylineMarker] culling_margin=10.0, # 视口外裁切边距 min_hittable_radius=10.0, # 最小可点击半径(逻辑像素) simplification_tolerance=0.3, # 折线简化容差(地图单位) )| 参数 | 默认值 | 作用 |
|---|---|---|
polylines | 必填 | 要绘制的PolylineMarker列表 |
culling_margin | 10.0 | 允许在视口范围之外多少距离内仍渲染折线段(超出即裁切掉),用于平衡平移流畅度与绘制开销 |
min_hittable_radius | 10.0 | 每条折线周围可点击区域的最小半径(逻辑像素)。整段可见区域本身总是可点击的;当可见区域小于该值时,以此半径为准,保证细线也能被轻松点中 |
simplification_tolerance | 0.3 | 渲染前对折线进行简化的容差(地图单位)。值越大简化越激进,性能越好,但显示精度会下降 |
在 Dart 侧(polyline_layer.dart),这三个参数分别映射为 flutter_mapPolylineLayer的cullingMargin、minimumHitbox与simplificationTolerance。其中:
- 折线子控件通过
control.children("polylines")收集,并过滤type == "PolylineMarker"的子控件; PolylineMarker的coordinates由getLatLngList("coordinates")解析(utils/map.dart),每个点被解析为 flutter_map 的LatLng。
性能建议:当折线点非常密集(如 GPS 轨迹)时,可适度提高simplification_tolerance以减少顶点数量;当地图上折线众多且需要频繁平移时,可调整culling_margin平衡渲染开销。
五、完整实战示例
仓库中的官方示例 multi_layers/main.py 演示了PolylineLayer与PolylineMarker的典型用法,结合了描边、渐变与半透明主体色:
import flet as ft import flet_map as ftm def main(page: ft.Page): page.add( ft.SafeArea( expand=True, content=ft.Column( expand=True, controls=[ ftm.Map( expand=True, initial_center=ftm.MapLatitudeLongitude(15, 10), initial_zoom=4.2, layers=[ ftm.TileLayer( url_template="https://tile.openstreetmap.org/{z}/{x}/{y}.png", user_agent_package_name="flet-map-examples/1.0", ), ftm.PolylineLayer( polylines=[ ftm.PolylineMarker( border_stroke_width=3, border_color=ft.Colors.RED, gradient_colors=[ ft.Colors.BLACK, ft.Colors.BLACK, ], color=ft.Colors.with_opacity( 0.6, ft.Colors.GREEN ), coordinates=[ ftm.MapLatitudeLongitude(10, 10), ftm.MapLatitudeLongitude(30, 15), ftm.MapLatitudeLongitude(25, 45), ], ), ], ), ], ), ], ), ) ) ft.run(main)运行python main.py后,地图上会渲染一条经过三个坐标点的绿色半透明折线,外圈带 3px 红色描边。ft.Colors.with_opacity(0.6, ft.Colors.GREEN)表示主体色为 60% 不透明度的绿色。
示例二:虚线路线
利用DashedStrokePattern绘制一条「50px 线段 + 10px 空白」的虚线路径:
ftm.PolylineMarker( stroke_pattern=ftm.DashedStrokePattern(segments=[50, 10]), stroke_width=4, stroke_cap=ft.StrokeCap.ROUND, stroke_join=ft.StrokeJoin.ROUND, color=ft.Colors.BLUE, coordinates=[ ftm.MapLatitudeLongitude(39.90, 116.40), # 北京 ftm.MapLatitudeLongitude(31.23, 121.47), # 上海 ftm.MapLatitudeLongitude(22.54, 114.06), # 深圳 ], )示例三:米制线宽与点线
模拟真实宽度的路线(线宽随缩放变化)并叠加点线样式:
ftm.PolylineMarker( coordinates=[ftm.MapLatitudeLongitude(10, 10), ftm.MapLatitudeLongitude(30, 15)], color=ft.Colors.PURPLE, stroke_width=100, # 表示 100 米宽的路线 use_stroke_width_in_meter=True, stroke_pattern=ftm.DottedStrokePattern(spacing_factor=2.0), )六、底层实现原理:Python 属性如何映射到 Flutter 渲染
理解PolylineMarker的底层链路有助于排查渲染问题与把握性能边界。整个调用链如下:
- Python 层:
PolylineMarker是ft.BaseControl的子类(polyline_layer.py),通过@ft.control("PolylineMarker")声明控件类型标识,属性在控件更新时序列化并发送给客户端; - Dart 解析层:
PolylineLayerControl(polyline_layer.dart)接收控件树,过滤出PolylineMarker子控件,将每个属性解析为Polyline对象:color/border_color→getColor(..., Colors.yellow)stroke_width/border_stroke_width→getDouble(...)stroke_pattern→getStrokePattern(...),内部通过parseStrokePattern按_type分发到dotted/solid/dashed三种 flutter_map 线型(utils/map.dart)coordinates→getLatLngList(...)逐点解析为LatLng- 图层级参数 →
PolylineLayer(cullingMargin, minimumHitbox, simplificationTolerance)
- 渲染层:最终交给
flutter_map的PolylineLayer组件绘制。
校验的传递:Python 侧before_update()中的ValueError在控件更新前抛出(polyline_layer.py);线型类内部的__setattr__/__post_init__则在赋值/构造时立即校验(如DashedStrokePattern的 segments 长度奇偶性、DottedStrokePattern的spacing_factor > 0),两类校验分工明确。
七、进阶:渐变轨迹与动态交互
7.1 渐变轨迹
gradient_colors与colors_stop组合可绘制沿路径渐变的轨迹线。例如「黑→白」过渡的路线(对应官方示例中的[BLACK, BLACK]渐变,详见 multi_layers/main.py):
ftm.PolylineMarker( coordinates=[...], # 轨迹点 gradient_colors=[ft.Colors.RED, ft.Colors.YELLOW, ft.Colors.GREEN], colors_stop=[0.0, 0.5, 1.0], # 对应三种颜色出现的位置比例 stroke_width=6, )colors_stop的比例值应与gradient_colors一一对应;不指定时由渲染端按均分处理。
7.2 动态增删折线
由于PolylineLayer.polylines是一个 Python 列表,可以像操作普通列表一样在事件回调中增删PolylineMarker并调用page.update()刷新:
def add_route(e: ft.Event): polyline_layer.polylines.append( ftm.PolylineMarker( color=ft.Colors.random(), coordinates=[...], ) ) page.update()结合visible属性,还可以实现「轨迹显隐」开关而不需要重建列表。
八、相关资源
- 控件源码:polyline_layer.py(
PolylineMarker与PolylineLayer) - 线型与坐标类型:types.py(
StrokePattern、SolidStrokePattern、DashedStrokePattern、DottedStrokePattern、PatternFit、MapLatitudeLongitude) - Flutter 端实现:polyline_layer.dart 与 utils/map.dart
- 官方示例:multi_layers/main.py(含
PolylineLayer的完整用法) - 包说明与安装:README.md、pyproject.toml
- 包公开导出:flet_map/init.py
总结
PolylineMarker是 Flet 地图应用中绘制折线的最小单元,配合PolylineLayer使用即可实现路线展示、描边、渐变着色、虚线/点线等多种效果。它的全部属性在 Python 层与 Flutter 渲染层一一对应,默认值、校验规则与渲染行为均可在仓库源码中得到印证。实际开发中,建议根据折线密度与地图交互复杂度调整simplification_tolerance、culling_margin等图层参数,以获得流畅的渲染性能。
- 前端
- 跨平台
- 桌面应用
- 移动开发
【免费下载链接】flet
Build realtime web, mobile and desktop apps in Python only. No frontend experience required.
相关推荐
Flet Map 控件 PolygonMarker 完全指南:在 Python 中绘制多边形标记
Flet Map 控件 PolygonMarker 完全指南:在 Python 中绘制多边形标记 导读 PolygonMarker 是 Flet 地图扩展包(
前端跨平台桌面应用移动开发Flet Map StrokePattern 类型详解:为地图折线与多边形定制实线、虚线与点线描边
Flet Map StrokePattern 类型详解:为地图折线与多边形定制实线、虚线与点线描边 导读 flet_map.StrokePattern 是 Fl
前端跨平台桌面应用移动开发@angular/google-maps MapPolyline 完全指南:在 Angular 中绘制与管理 Google 地图折线
@angular/google maps MapPolyline 完全指南:在 Angular 中绘制与管理 Google 地图折线 MapPolyline 是
前端UI组件设计系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考