{"id":"edd703c8-8b40-4dd1-8e69-9285fdf35012","entityType":"agent","slug":"clawhub-tencent-adm-tencentmap-map-assistant-skill","name":"tencentmap-map-assistant","canonicalUrl":"https://www.xpersona.co/agent/clawhub-tencent-adm-tencentmap-map-assistant-skill","canonicalPath":"/agent/clawhub-tencent-adm-tencentmap-map-assistant-skill","generatedAt":"2026-10-11T03:54:57.629Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:52:57.656Z","emptyReason":null},"description":"腾讯地图·地图助手 Skill，一句自然语言调用腾讯地图全套能力，开箱即用。提供 AI 旅游攻略、地点搜索（含评分/人均/营业时间）、关键词提示、路线规划（驾车/步行/公交/骑行）、地址解析与逆解析、行政区划、IP 定位、距离计算、天气查询，并可将行程或多 POI 渲染成网页地图或生成腾讯地图小程序指南。涉及找地点、规划路线、旅游行程、查天气、坐标转换等出行场景时使用。","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.2K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s171cxjdnjyqjxa91pj2bfmr6x83gyg1:tencentmap-map-assistant-skill","sourceUrl":"https://clawhub.ai/tencent-adm/tencentmap-map-assistant-skill","homepage":"https://clawhub.ai/tencent-adm/skills/tencentmap-map-assistant-skill","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/tencent-adm/tencentmap-map-assistant-skill","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/tencent-adm/skills/tencentmap-map-assistant-skill","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":62,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"tencentmap-map-assistant technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:52:57.656Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:52:57.656Z","emptyReason":null},"stars":null,"forks":null,"downloads":1214,"packageName":null,"latestVersion":"1.5.2","tractionLabel":"1.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:52:57.578Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T00:52:57.656Z","lastCrawledAt":"2026-10-11T00:52:57.578Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T00:52:57.578Z","lastVerifiedAt":null,"highlights":[{"version":"1.5.2","createdAt":"2026-08-12T08:01:52.517Z","changelog":"tencentmap-map-assistant-skill v1.5.2 - Improved Key 管理: Now supports a prioritized pool of saved Keys, automatic failover, and user notification on Key switching or all-Key failure, with detailed error reporting. - Updated documentation, especially SKILL.md, to reflect the enhanced Key management logic and user guidance for troubleshooting. - Added new JSAPI demo references to assist with map visualization. - Removed outdated QR code images and the obsolete skill-card.md for clarity and maintainability. - General documentation refinements to reflect these changes.","fileCount":228,"zipByteSize":461167},{"version":"1.5.1","createdAt":"2026-08-03T06:30:21.723Z","changelog":"v1.5.1 版本更新","fileCount":229,"zipByteSize":584051},{"version":"1.0.3","createdAt":"2026-07-09T07:18:51.650Z","changelog":"- 更新 Skill 版本至 1.4.8，完善文档细节说明 - 移除 skill-card.md，调整文档结构 - 修改 README.md 与 SKILL.md，优化官网链接描述及部分表述 - 新增脚本编译产物（__pycache__），无业务逻辑变更","fileCount":223,"zipByteSize":442127},{"version":"1.0.2","createdAt":"2026-07-02T07:28:08.531Z","changelog":"- Added Key detection and guided user flow for applying/using temp/official keys; outputs step-by-step options when Key is missing - Introduced new scripts: create_key.py, save_config.py, send_code.py, and a user-facing tempkey-guide.md for streamlined Key management - Updated usage instructions and documentation to clarify required data mapping and key handling, especially for generate_map_guide - Improved sample code and agent operation notes for more reliable POI data and end-to-end flow - Removed skill-card.md; internal references and guides adjusted for new key flow and experience consistency - Bumped version to 1.4.7","fileCount":222,"zipByteSize":417681},{"version":"1.0.1","createdAt":"2026-06-22T07:52:45.366Z","changelog":"- Updated to version 1.4.5 with an enhanced SKILL.md. - Added detailed documentation covering all supported features and usage examples. - New sections provide parameters, return values, and sample code for each method. - Clarified instructions for key configuration, result visualization, and integration with Tencent Map mini programs. - Improved guidance for out-of-the-box use, with or without a developer key.","fileCount":218,"zipByteSize":408649}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171cxjdnjyqjxa91pj2bfmr6x83gyg1:tencentmap-map-assistant-skill","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s171cxjdnjyqjxa91pj2bfmr6x83gyg1:tencentmap-map-assistant-skill` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/tencent-adm/tencentmap-map-assistant-skill before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T03:54:57.625Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-tencent-adm-tencentmap-map-assistant-skill/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:52:57.656Z","emptyReason":null},"readme":"Skill: tencentmap-map-assistant\n\nOwner: tencent-adm\n\nSummary: 腾讯地图·地图助手 Skill，一句自然语言调用腾讯地图全套能力，开箱即用。提供 AI 旅游攻略、地点搜索（含评分/人均/营业时间）、关键词提示、路线规划（驾车/步行/公交/骑行）、地址解析与逆解析、行政区划、IP 定位、距离计算、天气查询，并可将行程或多 POI 渲染成网页地图或生成腾讯地图小程序指南。涉及找地点、规划路线、旅游行程、查天气、坐标转换等出行场景时使用。\n\nTags: latest:1.5.2\n\nVersion history:\n\nv1.5.2 | 2026-08-12T08:01:52.517Z | auto\n\ntencentmap-map-assistant-skill v1.5.2\n\n- Improved Key 管理: Now supports a prioritized pool of saved Keys, automatic failover, and user notification on Key switching or all-Key failure, with detailed error reporting.\n- Updated documentation, especially SKILL.md, to reflect the enhanced Key management logic and user guidance for troubleshooting.\n- Added new JSAPI demo references to assist with map visualization.\n- Removed outdated QR code images and the obsolete skill-card.md for clarity and maintainability.\n- General documentation refinements to reflect these changes.\n\nv1.5.1 | 2026-08-03T06:30:21.723Z | user\n\nv1.5.1 版本更新\n\nv1.0.3 | 2026-07-09T07:18:51.650Z | auto\n\n- 更新 Skill 版本至 1.4.8，完善文档细节说明\n- 移除 skill-card.md，调整文档结构\n- 修改 README.md 与 SKILL.md，优化官网链接描述及部分表述\n- 新增脚本编译产物（__pycache__），无业务逻辑变更\n\nv1.0.2 | 2026-07-02T07:28:08.531Z | auto\n\n- Added Key detection and guided user flow for applying/using temp/official keys; outputs step-by-step options when Key is missing\n- Introduced new scripts: create_key.py, save_config.py, send_code.py, and a user-facing tempkey-guide.md for streamlined Key management\n- Updated usage instructions and documentation to clarify required data mapping and key handling, especially for generate_map_guide\n- Improved sample code and agent operation notes for more reliable POI data and end-to-end flow\n- Removed skill-card.md; internal references and guides adjusted for new key flow and experience consistency\n- Bumped version to 1.4.7\n\nv1.0.1 | 2026-06-22T07:52:45.366Z | auto\n\n- Updated to version 1.4.5 with an enhanced SKILL.md.\n- Added detailed documentation covering all supported features and usage examples.\n- New sections provide parameters, return values, and sample code for each method.\n- Clarified instructions for key configuration, result visualization, and integration with Tencent Map mini programs.\n- Improved guidance for out-of-the-box use, with or without a developer key.\n\nArchive index:\n\nArchive v1.5.2: 228 files, 461167 bytes\n\nFiles: README.md (9177b), references/agent-notes.md (7886b), references/api_reference.md (14209b), references/error-codes.md (2152b), references/jsapi-guide/jsapigl/demos/个性化地图_切换地图个性化样式.html (1535b), references/jsapi-guide/jsapigl/demos/个性化地图_玉露(绿色系活泼风格).html (933b), references/jsapi-guide/jsapigl/demos/个性化地图_墨渊(夜间模式效果).html (949b), references/jsapi-guide/jsapigl/demos/信息窗口_信息窗口偏移设置.html (3542b), references/jsapi-guide/jsapigl/demos/信息窗口_包含图文信息的信息窗口.html (1251b), references/jsapi-guide/jsapigl/demos/信息窗口_拖拽信息窗口.html (6678b), references/jsapi-guide/jsapigl/demos/信息窗口_点击标记弹出信息窗口.html (2746b), references/jsapi-guide/jsapigl/demos/信息窗口_简单信息窗口.html (1201b), references/jsapi-guide/jsapigl/demos/信息窗口_自定义信息窗体.html (5685b), references/jsapi-guide/jsapigl/demos/几何计算库_判断多边形是否在另一个多边形内.html (4355b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点与多边形的关系.html (3263b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点是否在多边形边上.html (3223b), references/jsapi-guide/jsapigl/demos/几何计算库_计算区域面积.html (2215b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形形心.html (2904b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形的交集区域.html (5198b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线上距离P点最近的点.html (3016b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线与多边形是否相交.html (3887b), references/jsapi-guide/jsapigl/demos/几何计算库_计算路径距离.html (2103b), references/jsapi-guide/jsapigl/demos/几何计算库_路径顺逆时针判断与转换.html (4177b), references/jsapi-guide/jsapigl/demos/地图叠加图层_WMS标准图层.html (1736b), references/jsapi-guide/jsapigl/demos/地图叠加图层_自定义贴地图层.html (4301b), references/jsapi-guide/jsapigl/demos/地图叠加图层_静态图贴地图层.html (1289b), references/jsapi-guide/jsapigl/demos/地图操作示例_2D_3D模式切换.html (1498b), references/jsapi-guide/jsapigl/demos/地图操作示例_切换底图类型.html (1518b), references/jsapi-guide/jsapigl/demos/地图操作示例_创建地图.html (1138b), references/jsapi-guide/jsapigl/demos/地图操作示例_区域高亮.html (2798b), references/jsapi-guide/jsapigl/demos/地图操作示例_卫星地图.html (1130b), references/jsapi-guide/jsapigl/demos/地图操作示例_同时加载两个地图.html (1289b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图加载完成事件.html (1408b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图导出图片.html (2775b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图平滑变化至指定状态.html (1089b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图平移.html (1991b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图设置缩放焦点.html (1613b), references/jsapi-guide/jsapigl/demos/地图操作示例_天空盒.html (3735b), references/jsapi-guide/jsapigl/demos/地图操作示例_实时路况.html (2309b), references/jsapi-guide/jsapigl/demos/地图操作示例_异步加载地图.html (1230b), references/jsapi-guide/jsapigl/demos/地图操作示例_点击地图拾取POI.html (1412b), references/jsapi-guide/jsapigl/demos/地图操作示例_点击地图拾取坐标.html (1574b), references/jsapi-guide/jsapigl/demos/地图操作示例_粒子路况.html (1459b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图中心.html (2142b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图显示范围.html (2985b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图视角.html (2689b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图中心点偏移.html (1812b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图显示比例.html (1563b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图边界范围.html (1482b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置控件位置及样式.html (4100b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置鼠标样式.html (2746b), references/jsapi-guide/jsapigl/demos/地图操作示例_调整图层顺序.html (3053b), references/jsapi-guide/jsapigl/demos/地图操作示例_配置矢量底图.html (5369b), references/jsapi-guide/jsapigl/demos/地图操作示例_销毁地图.html (1708b), references/jsapi-guide/jsapigl/demos/地图操作示例.md (61096b), references/jsapi-guide/jsapigl/demos/城市漫游_地面漫游.html (4509b), references/jsapi-guide/jsapigl/demos/城市漫游_空中漫游.html (4587b), references/jsapi-guide/jsapigl/demos/城市漫游_绕点环绕.html (2384b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形拔起_3D棱柱.html (2245b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形点击事件.html (5002b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形选中高亮显示.html (9726b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形飞地.html (3279b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_带飞地的区域实现高亮.html (3688b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_环形(带洞)多边形.html (2319b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_简单圆形.html (1276b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_简单多边形.html (1985b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_自定义多边形样式.html (3271b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_自定义边线样式.html (2507b), references/jsapi-guide/jsapigl/demos/应用工具_开关编辑器键盘事件.html (8473b), references/jsapi-guide/jsapigl/demos/应用工具_测量工具.html (4174b), references/jsapi-guide/jsapigl/demos/应用工具_绘制几何图形.html (6296b), references/jsapi-guide/jsapigl/demos/应用工具_编辑几何图形.html (4853b), references/jsapi-guide/jsapigl/demos/应用工具_编辑器的禁用和启用.html (2468b), references/jsapi-guide/jsapigl/demos/应用工具_设置编辑点为GL模式.html (4418b), references/jsapi-guide/jsapigl/demos/折线_折线-动态箭头.html (2270b), references/jsapi-guide/jsapigl/demos/折线_折线-大圆航线.html (1340b), references/jsapi-guide/jsapigl/demos/折线_折线-彩虹线.html (2868b), references/jsapi-guide/jsapigl/demos/折线_折线-虚线样式.html (2188b), references/jsapi-guide/jsapigl/demos/折线_折线应用_路线规划.html (3570b), references/jsapi-guide/jsapigl/demos/折线_折线样式自定义.html (3619b)\n\nFile v1.5.2:SKILL.md\n\n---\nname: tencentmap-map-assistant-skill\ndescription: \"腾讯地图·地图助手 Skill，一句自然语言调用腾讯地图全套能力，开箱即用。提供 AI 旅游攻略、地点搜索（含评分/人均/营业时间）、关键词提示、路线规划（驾车/步行/公交/骑行）、地址解析与逆解析、行政区划、IP 定位、距离计算、天气查询，并可将行程或多 POI 渲染成网页地图或生成腾讯地图小程序指南。涉及找地点、规划路线、旅游行程、查天气、坐标转换等出行场景时使用。\"\nlicense: MIT\nversion: 1.5.2\ngit_url: https://github.com/TencentLBS/tencentmap-map-assistant\n---\n\n# 地图助手 Skill\n\n腾讯位置服务出品。用一句自然语言即可生成旅游攻略、搜索地点、规划路线、解析地址坐标，并可将结果渲染成网页地图或生成腾讯地图小程序指南。\n\n## 能力\n\n能力命名与腾讯位置服务官网 WebService API 对齐。完整参数签名见下方「参数与返回」。\n\n| 能力 | 说明 | 方法 |\n|------|------|------|\n| AI 旅游攻略 | 自然语言 query → 多日行程攻略，可联动腾讯地图小程序，与朋友共同编辑行程、规划多人出行 | `travel_guide` |\n| 个人地图指南 | 地点列表 → 个人专属地图（保存到腾讯地图小程序，手机随时查看） | `generate_map_guide` |\n| 地点搜索 | 城市/区域搜索、周边圆形搜索、POI 详情 | `poi_search` / `poi_nearby` / `poi_detail` |\n| 关键词输入提示 | 输入补全候选 POI | `poi_sug` |\n| 行政区划 | 省市区列表、下级区划、区划搜索 | `district_list` / `district_children` / `district_search` |\n| 地址解析 | 地址 → 坐标 | `geocoder` |\n| 逆地址解析 | 坐标 → 地址（可附周边 POI） | `regeocoder` |\n| IP 定位 | IP → 位置 | `ip_location` |\n| 路线规划 | 驾车 / 步行 / 公交 / 骑行 | `direction` |\n| 两点间距离 | 计算两点之间的驾车/步行/骑行距离与用时 | `distance_matrix` |\n| 天气查询 | 行政区/坐标 → 实时或预报天气 | `weather` |\n| 坐标系转换 | GPS(WGS-84) / 百度 / sogou / mapbar → GCJ-02 | `coord_translate` |\n| 行程 / POI 可视化 | 把行程或多 POI 结果渲染为网页地图 | — |\n\n## 安装\n\n首次使用前安装：\n\n```\npip install -e .\n```\n\n## 用法\n\n```python\nfrom tmap_client import TmapClient\n\nclient = TmapClient()\n\nresult = client.travel_guide(\"武汉5天攻略\")\npois   = client.poi_search(\"黄鹤楼\", region=\"武汉\")\naddr   = client.geocoder(\"深圳市腾讯滨海大厦\")\n```\n\n配置自己的腾讯位置服务 Key（持久化保存，之后自动启用）：\n\n```python\nfrom tmap_client import save_key_to_dotenv\nsave_key_to_dotenv(\"你的 Key\")\n```\n\n\n## Key 管理\n\n按此顺序自动获取 Key，通常无需干预：`TmapClient(key=...)` → 已保存的 Key。各来源的 Key 会全部进入候选池。\n\n- 无可用 Key → 读取 `tempkey-guide.md` 引导用户申请临时体验 Key。\n- 用户要固定使用或更换 Key → 调用 `save_key_to_dotenv(\"<key>\")` 保存，之后自动生效。\n- Key 已配置但接口报错 → TmapClient 会按优先级自动轮询候选池中的可用 Key 并切换使用。切换后，必须告知用户已自动切换以及切换原因；若所有 Key 均不可用时抛出 TmapError（含每个 Key 的失败原因），必须读取 `references/error-codes.md`，对错误码给出修正方式告知用户。\n\n\n## 参数与返回\n\n### AI 旅游攻略 — travel_guide\n\n`travel_guide(query, lat=30.572815, lng=104.066801)`：自然语言 query → 多日行程攻略。同步等待，单次调用 30-50 秒。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | str | 是 | 目的地 + 天数，例如 \"武汉5天攻略\" / \"成都3天美食游\" |\n| `lat`, `lng` | float | 否 | 用户当前位置（影响 A2A 上下文，不决定目的地） |\n\n**返回**：结构化攻略数据（`title`/`summary`/`days` 行程列表等），以及 **`output_markdown`**（成品攻略 md 文件路径，含小程序二维码，Read 后原样输出）。\n\n### 个人地图指南 — generate_map_guide\n\n`generate_map_guide(pois, city, title=\"我的指南\", query=\"\", description=\"\")`：将任意地点列表（搜索结果、路线点、打卡记录）一键保存为腾讯地图小程序里的个人专属地图，在手机上随时查看和导航。\n\n> **前置步骤**：构造 `pois` 前，先对每个地点调用 `poi_search()`拿到真实的 `id` 与 `location.lat` / `location.lng`，再映射成 `pois` 所需的 `poi_id` / `lat` / `lng`。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `pois` | List[Dict] | 是 | POI 列表，每个 POI 含 `name` / `lat` / `lng` / `poi_id`。这些值应取自 `poi_search()` / `poi_sug()` 的真实返回后填入 |\n| `city` | str | 是 | 城市名称 |\n| `title` | str | 否 | 指南标题，默认\"我的指南\" |\n| `query` | str | 否 | 用户原始输入（用于入库备注） |\n| `description` | str | 否 | 行程/路线描述文本，会嵌入输出 md 正文 |\n\n**返回**：`{travel_guide_id, qr_code, qr_path, mini_program_username, output_markdown}`\n\n### 地点搜索 — poi_search\n\n`poi_search(keyword, region=None, location=None, page_size=10, page_index=1)`：按城市或中心点检索 POI。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `keyword` | str | 是 | 搜索词 |\n| `region` | str | 二选一 | 城市名（\"深圳\"/\"武汉\"） |\n| `location` | str | 二选一 | 中心点 \"lat,lng\"，启用 5km 邻近搜索 |\n| `page_size` | int | 否 | 每页 1-20，默认 10 |\n| `page_index` | int | 否 | 页码，默认 1 |\n\n### 地点搜索（POI 详情）— poi_detail\n\n`poi_detail(poi_id)`：按 POI ID 取详情（来自 `poi_search` / `poi_sug` 返回，或 `travel_guide` 的 `poi_uid`）。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `poi_id` | str | 是 | POI 唯一 ID |\n\n### 地点搜索（周边）— poi_nearby\n\n`poi_nearby(keyword, location, radius=1000, page_size=10, page_index=1)`：圆形范围内的 POI 检索。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `keyword` | str | 是 | 搜索词（\"咖啡\" / \"加油站\"） |\n| `location` | str | 是 | 中心点 \"lat,lng\" |\n| `radius` | int | 否 | 半径（米），取值 10-1000，默认 1000 |\n| `page_size` / `page_index` | int | 否 | 同 `poi_search` |\n\n### 关键词输入提示 — poi_sug\n\n`poi_sug(keyword, region=None, location=None)`：候选 POI（常用于\"先 sug 拿 ID 再查 detail\"）。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `keyword` | str | 是 | 搜索词 |\n| `region` | str | 否 | 城市名 |\n| `location` | str | 否 | 中心点 \"lat,lng\" |\n\n### 路线规划 — direction\n\n`direction(from_addr, to_addr, mode=\"driving\", region=None)`：起终点 → 路线方案。地址/景点名自动转坐标（建议传 `region` 城市消歧）。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `from_addr` | str | 是 | 起点地址 / 景点名 / \"lat,lng\" |\n| `to_addr` | str | 是 | 终点地址 / 景点名 / \"lat,lng\" |\n| `mode` | str | 否 | `driving` / `walking` / `bicycling` / `transit`，默认 `driving` |\n| `region` | str | 否 | 城市名，辅助把\"象鼻山\"等景点名解析到正确城市 |\n\n### 地址解析 — geocoder\n\n`geocoder(address, policy=1)`：把地址 / 地标 / 景点名解析成坐标。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `address` | str | 是 | 地址或地点名。含城市更准；不含城市也可（靠默认 policy=1 兜底） |\n| `policy` | int | 否 | 解析策略。`1`=宽松（默认，支持\"象鼻山\"等景点/地标名）；`0`=标准（地址须含城市，否则报错） |\n\n### 逆地址解析 — regeocoder\n\n`regeocoder(lat, lng, get_poi=False)`：把坐标解析成语义化地址。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `lat`, `lng` | float | 是 | GCJ02 坐标 |\n| `get_poi` | bool | 否 | 是否附带周边 POI 列表，默认 False |\n\n### IP 定位 — ip_location\n\n`ip_location(ip=None)`：IP → 所在省市区。不传 IP 则定位调用方公网 IP。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `ip` | str | 否 | IPv4 字符串 |\n\n### 行政区划 — district_list / district_children / district_search\n\n```python\ndistrict_list()                  # 全国省级列表\ndistrict_children(parent_id)     # 下级区划（parent_id=\"110000\" → 北京下属）\ndistrict_search(keyword)         # 关键词搜区划\n```\n\n### 两点间距离 — distance_matrix\n\n`distance_matrix(origin, dest, mode=\"driving\")`：计算两点之间的驾车/步行/骑行距离与用时。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `origin` | str | 是 | 起点坐标 `\"lat,lng\"` |\n| `dest` | str | 是 | 终点坐标 `\"lat,lng\"` |\n| `mode` | str | 否 | `driving` / `walking` / `bicycling`，默认 `driving` |\n\n### 天气查询 — weather\n\n`weather(adcode=None, location=None, type=\"now\")`：查实时或预报天气。`adcode` 与 `location` 二选一。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `adcode` | str | 否 | 行政区划代码，如北京 `\"110000\"` |\n| `location` | str | 否 | 坐标 `\"lat,lng\"` |\n| `type` | str | 否 | `now` 实时 / `future` 预报，默认 `now` |\n\n### 坐标系转换 — coord_translate\n\n`coord_translate(locations, type=1)`：把 GPS(WGS-84) / 百度 / sogou / mapbar 等坐标批量转成腾讯地图使用的 GCJ-02。单次最多 100 个点。**处理 GPS 原始坐标（如手机定位、GPX 轨迹、外部数据源）时必须先转再传给 `regeocoder` / `poi_nearby` / `direction` 等接口，否则会有几十米～百米级偏移。**\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `locations` | str \\| tuple \\| list | 是 | 支持 `\"lat,lng\"` / `\"lat1,lng1;lat2,lng2\"` 字符串、`(lat, lng)` 元组、`[(lat, lng), ...]` 列表 |\n| `type` | int | 否 | 输入坐标类型。**1=GPS(WGS-84)**（默认，最常用）/ 2=sogou 经纬度 / 3=baidu / 4=mapbar / 5=GCJ-02（不转）/ 6=sogou 墨卡托 |\n\n**返回**：单点入参 → `{\"lat\": .., \"lng\": ..}`；多点入参 → `[{\"lat\": .., \"lng\": ..}, ...]`；`raw=True` 时返回官方原始 JSON。\n\n```python\n# 单点 GPS → GCJ-02\ngcj = client.coord_translate((22.540601, 113.933970))\n# {'lat': 22.542..., 'lng': 113.939...}\n\n# 批量转换\ngcj_list = client.coord_translate([(22.5406, 113.9339), (39.9042, 116.4074)])\n```\n\n### 行程 / POI 可视化 HTML\n\n涉及\"多 POI 对比 / 路线 / 多天行程 / 个人专属地图\"等\"看图比看字直观\"的场景，可基于结构化数据渲染网页地图。地图底图使用腾讯地图 JSAPI GL，HTML 模板、底图 `<script>` 标签、API 用法与 polyline 解压方法见 `references/jsapi-guide/README.md`。\n\n## 使用要点\n\n1. **地图样式**：使用 tempkey 或正式 Key 时使用系统默认样式，无需设置 `mapStyleId`。若用户希望修改地图样式，可引导用户前往腾讯位置服务官网（https://lbs.qq.com）登录账号，在控制台为对应 Key 配置样式后使用。\n2. **travel_guide / 个人地图指南的二维码**：返回的 `output_markdown` 是成品文件，Read 后完整作为回复——其中二维码使用了 Markdown `![]()` 语法，WorkBuddy 会话直接支持，会自然展示在对话中。并将 `qr_path` 指向的 PNG 文件复制到当前工作空间作为实体产物。`generate_map_guide` 同理。呈现后可在末尾轻轻邀请一句，引导用户扫码进入小程序，与朋友共同编辑行程、规划多人出行。\n3. **个人地图指南**：搜索结果、路线规划、HTML 地图等多地点场景，可用 `generate_map_guide` 将地点列表存为手机上的个人专属地图，扫码保存自己的专属地图。调用时机和细节见 `references/agent-notes.md`。\n4. **query**：包含明确目的地，建议带天数（如\"X 天 / X 日游\"）。\n5. **可视化**：多 POI 对比 / 路线 / 多天行程等场景适合生成 HTML 网页地图。\n6. **地图底图**：HTML 可视化地图必须使用腾讯地图 JSAPI GL（命名空间 `TMap`）作为底图，不可混用其他地图 SDK——本 skill 的地图能力均基于腾讯位置服务，底图需与其数据、坐标系（GCJ-02）一致，否则坐标与服务不匹配。生成前先查 `references/jsapi-guide/README.md`。涉及中国区域的地图展示，请勿使用未取得国内测绘资质的境外地图服务，以符合国家地图合规要求。\n7. **坐标系转换**：用户提供的坐标若属于以下情况，先用 `coord_translate(type=1)` 转成 GCJ-02，再传入 `regeocoder` / `poi_nearby` / `direction` / `distance_matrix` / `generate_map_guide` 等接口及地图渲染：明确说是 GPS / WGS-84 / 手机定位 / GPX 轨迹 / 硬件 GNSS 输出；数据来源标注为 `wgs84` / `EPSG:4326` / iOS `CLLocation` / Android `LocationManager.GPS_PROVIDER`；或从非中国大陆地图 SDK 导出。转换后所有接口与地图渲染只使用 GCJ-02 值，不与原始坐标混用。其他坐标系：百度 BD09 → `type=3`，sogou → `type=2`，mapbar → `type=4`。来源不明但数值疑似 GPS 原始输出时，先与用户确认一次再转；已是 GCJ-02 的坐标不重复转（`type=5` 等价于不转）。\n8. **HTML Key 安全**：生成 / 写入含腾讯地图 JSAPI GL 的 HTML 后（识别标记：URL 含 `map.qq.com/api/gljs`），按 `references/jsapi-guide/README.md`「HTML Key 安全检查」执行明文 Key 检测；命中则原样输出其中的固定安全提示文案，提醒用户盗用风险与代理方案。\n\n## 隐私与数据\n\n- AI 旅游攻略（`travel_guide`）与个人地图指南（`generate_map_guide`）会将用户输入的行程/POI 数据发送至腾讯地图服务器，用于生成攻略内容和微信小程序二维码。服务器端数据留存与使用遵循[腾讯位置服务隐私政策](https://lbs.qq.com/userAgreements/agreements/privacy)。\n\n## 示例\n\n```python\nclient = TmapClient()\n\n# 旅游攻略（返回 output_markdown 成品文件，Read 后作为回复）\nr = client.travel_guide(\"成都3天美食游\")\n\n# POI 搜索\nres = client.poi_search(\"咖啡馆\", location=\"22.540601,113.93397\", page_size=5)\n\n# 路线规划\nroute = client.direction(\"深圳北站\", \"深圳湾口岸\", mode=\"driving\")\n\n# 个人地图指南：先用 poi_search 拿到真实 POI，再映射成 pois\np1 = client.poi_search(\"深圳北站\", region=\"深圳\", raw=True)[\"data\"][0]\np2 = client.poi_search(\"深圳湾口岸\", region=\"深圳\", raw=True)[\"data\"][0]\nguide = client.generate_map_guide(\n    [{\"name\": p1[\"title\"], \"lat\": p1[\"location\"][\"lat\"], \"lng\": p1[\"location\"][\"lng\"], \"poi_id\": p1[\"id\"], \"day\": 1, \"num\": 1},\n     {\"name\": p2[\"title\"], \"lat\": p2[\"location\"][\"lat\"], \"lng\": p2[\"location\"][\"lng\"], \"poi_id\": p2[\"id\"], \"day\": 1, \"num\": 2}],\n    city=\"深圳\")\n\n# 场景：用户手上是 WGS-84（GPS）坐标，先转 GCJ-02 再用\nwgs_points = [(22.540601, 113.933970), (22.532000, 113.929500)]   # 用户提供\ngcj_points = client.coord_translate(wgs_points, type=1)           # → [{\"lat\":..,\"lng\":..}, ...]\n\n# 1) 逆解析：坐标 → 地址（必须传 GCJ-02）\naddr = client.regeocoder(gcj_points[0][\"lat\"], gcj_points[0][\"lng\"])\n\n# 2) 周边 POI 检索（location 也必须是 GCJ-02）\nnearby = client.poi_nearby(\"咖啡\", location=f'{gcj_points[0][\"lat\"]},{gcj_points[0][\"lng\"]}')\n\n# 3) 个人地图指南 / HTML 可视化：直接把 GCJ-02 传入 pois / markers\n```\n\n> 调用细节、Key 流程、HTML 生成规范与 JSAPI 资料见 `references/`。\n\nFile v1.5.2:README.md\n\n# tencentmap-map-assistant-skill\n\n腾讯位置服务出品。一句自然语言调用腾讯地图全套能力——AI 旅游攻略、地点搜索、路线规划、地址解析、天气查询，无需开发者账号、开箱即用。\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Version](https://img.shields.io/badge/version-1.5.2-green.svg)](https://github.com/TencentLBS/tencentmap-map-assistant)\n\n---\n\n## ✨ 能力一览\n\n| 能力 | 说明 | 方法 |\n|:-----|:-----|:-----|\n| 🗺 AI 旅游攻略 | 自然语言生成多日行程，含小程序二维码入口 | `travel_guide` |\n| 📋 个人地图指南 | 从 POI 列表生成地图指南，含小程序二维码入口 | `generate_map_guide` |\n| 🔍 地点搜索 | 城市/区域搜索、周边圆形搜索、POI 详情 | `poi_search` / `poi_nearby` / `poi_detail` |\n| 💡 关键词输入提示 | 输入补全候选 POI | `poi_sug` |\n| 🏛 行政区划 | 省市区列表、下级区划、区划搜索 | `district_list` / `district_children` / `district_search` |\n| 📍 地址解析 | 地址 → 坐标 | `geocoder` |\n| 📍 逆地址解析 | 坐标 → 地址（可附周边 POI） | `regeocoder` |\n| 🌐 IP 定位 | IP → 位置 | `ip_location` |\n| 🚗 路线规划 | 驾车 / 步行 / 公交 / 骑行 | `direction` |\n| 📏 两点间距离 | 计算两点之间的驾车/步行/骑行距离与用时 | `distance_matrix` |\n| 🌤 天气查询 | 行政区/坐标 → 实时或预报天气 | `weather` |\n| 🎨 行程可视化 | 把行程或多 POI 渲染成网页地图 | HTML 生成 |\n\n## 🚀 快速开始\n\n### 安装依赖\n\n```bash\npip install -e .\n```\n\n> 仅依赖 `requests`，多数环境已自带。\n\n### 基本用法\n\n```python\nfrom tmap_client import TmapClient\n\nclient = TmapClient()\n\n# AI 旅游攻略\nresult = client.travel_guide(\"武汉5天攻略\")\n\n# 地点搜索（含评分、人均、营业时间）\npois = client.poi_search(\"黄鹤楼\", region=\"武汉\")\n\n# 周边搜索\nnearby = client.poi_nearby(\"咖啡\", location=\"22.540601,113.93397\", radius=1000)\n\n# 路线规划\nroute = client.direction(\"深圳北站\", \"深圳湾口岸\", mode=\"driving\")\n\n# 地址 → 坐标\naddr = client.geocoder(\"深圳市腾讯滨海大厦\")\n\n# 坐标 → 地址\nloc = client.regeocoder(22.540601, 113.93397, get_poi=True)\n\n# 天气查询\nweather = client.weather(adcode=\"110000\", type=\"now\")\n```\n\n### 配置正式 Key\n\n未配置 Key 时可通过 tempkey 流程申请 AI 场景临时体验 Key（手机验证，1 年有效，覆盖 WebService API + JSAPI 底图加载）。如已有腾讯位置服务 Key：\n\n```python\nfrom tmap_client import save_key_to_dotenv\n\nsave_key_to_dotenv(\"你的 Key\")  # 持久化保存（~/.tencentmap/tempkey.json），之后自动走正式通道\n```\n\n> 申请正式 Key：https://lbs.qq.com/dev/console/quick-register\n\n## 📖 API 参考\n\n### `travel_guide(query, lat=30.572815, lng=104.066801)`\n\n生成 AI 旅游攻略，含行程详情与腾讯地图小程序入口二维码。\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `query` | str | ✅ | 自然语言描述，如 \"成都3天美食游\" |\n| `lat` / `lng` | float | | 用户当前位置（辅助上下文，不影响目的地） |\n\n返回：结构化攻略数据 + `output_markdown`（成品攻略文件路径）+ `qr_path`（小程序二维码 PNG）。\n\n> 单次调用约 30-50 秒。\n\n### `poi_search(keyword, region=None, location=None, page_size=10, page_index=1)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `keyword` | str | ✅ | 搜索关键词 |\n| `region` | str | 二选一 | 城市/区域名 |\n| `location` | str | 二选一 | 中心点 \"lat,lng\"，启用 5km 邻近搜索 |\n| `page_size` | int | | 每页 1-20，默认 10 |\n| `page_index` | int | | 页码，默认 1 |\n\n### `poi_nearby(keyword, location, radius=1000, page_size=10, page_index=1)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `keyword` | str | ✅ | 搜索词 |\n| `location` | str | ✅ | 中心点 \"lat,lng\" |\n| `radius` | int | | 半径（米），10-1000，默认 1000 |\n| `page_index` | int | | 页码，默认 1 |\n\n### `poi_detail(poi_id)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `poi_id` | str | ✅ | POI 唯一 ID（从搜索结果获取） |\n\n### `poi_sug(keyword, region=None, location=None)`\n\n关键词输入提示，用于补全候选 POI。\n\n### `direction(from_addr, to_addr, mode=\"driving\", region=None)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `from_addr` | str | ✅ | 起点地址/景点名/\"lat,lng\" |\n| `to_addr` | str | ✅ | 终点地址/景点名/\"lat,lng\" |\n| `mode` | str | | `driving` / `walking` / `bicycling` / `transit` |\n| `region` | str | | 城市名，辅助消歧 |\n\n> 起终点支持地址/景点名自动转坐标。\n\n### `geocoder(address, policy=1)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `address` | str | ✅ | 地址或地点名 |\n| `policy` | int | | `1`=宽松（支持景点名），`0`=标准 |\n\n### `regeocoder(lat, lng, get_poi=False)`\n\n坐标 → 地址，`get_poi=True` 时附带周边 POI 列表。\n\n### `ip_location(ip=None)`\n\nIP → 位置。不传 IP 则定位调用方公网 IP。\n\n### `district_list()` / `district_children(parent_id)` / `district_search(keyword)`\n\n行政区划查询：全国省级列表 / 下级区划 / 关键词搜索。\n\n### `distance_matrix(origin, dest, mode=\"driving\")`\n\n计算两点之间的驾车/步行/骑行距离与用时。\n\n### `weather(adcode=None, location=None, type=\"now\")`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `adcode` | str | 二选一 | 行政区划代码 |\n| `location` | str | 二选一 | 坐标 \"lat,lng\" |\n| `type` | str | | `now` 实时 / `future` 预报 |\n\n## 📁 项目结构\n\n```\ntencentmap-map-assistant-skill/\n├── SKILL.md                          # Skill 定义与使用说明\n├── scripts/\n│   ├── send_code.py / create_key.py / save_config.py  # tempkey 临时 Key 配置工具\n│   ├── tmap_client.py                # 核心客户端（所有 API 封装）\n│   └── test_all.py                   # 测试套件\n├── references/\n│   ├── agent-notes.md                # AI 调用指引\n│   └── jsapi-guide/\n│       ├── README.md                 # JSAPI GL 开发指南 + HTML 模板\n│       ├── jsapigl/\n│       │   ├── docs/                 # 核心 API 文档（21 篇）\n│       │   └── demos/                # 核心 API Demo（85+ 个 HTML）\n│       └── visualization/\n│           ├── docs/                 # 可视化扩展文档（15 篇）\n│           └── demos/                # 可视化 Demo（44 个 HTML）\n├── setup.py                           # pip install -e . 安装入口\n├── .env.example                      # 环境变量模板\n├── tempkey-guide.md                  # 临时 Key 申请指南\n└── README.md                         # 本文件\n```\n\n## 🎨 可视化渲染\n\n多 POI 对比、路线、多天行程等场景可将数据渲染为交互式网页地图：\n\n```python\nimport json\n\n# POI 数据（实际用 client 返回的坐标）\npois = [\n    {\"name\": \"象鼻山\", \"lat\": 25.2675, \"lng\": 110.2966},\n    {\"name\": \"两江四湖\", \"lat\": 25.2798, \"lng\": 110.2904},\n]\n\n# 生成 HTML 地图（底图 key 已内置，直接使用）\nmarkers_js = json.dumps(\n    [{\"id\": str(i), \"position\": [p[\"lat\"], p[\"lng\"]], \"title\": p[\"name\"]}\n     for i, p in enumerate(pois)],\n    ensure_ascii=False,\n)\n\nhtml = f'''<!DOCTYPE html><html><head><meta charset=\"utf-8\">\n<style>html,body,#map{{height:100%;margin:0}}</style>\n<script src=\"https://map.qq.com/api/gljs?v=1&key={TMAP_KEY}\"></script>\n</head><body><div id=\"map\"></div><script>\nconst pts = {markers_js};\nconst map = new TMap.Map('map', {{\n  center: new TMap.LatLng(pts[0].position[0], pts[0].position[1]), zoom: 12\n}});\nnew TMap.MultiMarker({{ map, geometries: pts.map(p => ({{\n  id: p.id, position: new TMap.LatLng(p.position[0], p.position[1])\n}})) }});\nnew TMap.MultiPolyline({{ map, geometries: [{{\n  id: 'route', paths: pts.map(p => new TMap.LatLng(p.position[0], p.position[1]))\n}}] }});\n</script></body></html>'''\n\nwith open(\"map.html\", \"w\", encoding=\"utf-8\") as f:\n    f.write(html)\n```\n\n> 更多渲染能力（散点图、热力图、弧线图、轨迹回放等）参见 `references/jsapi-guide/`。\n\n## 🔒 隐私与数据\n\n- AI 旅游攻略（`travel_guide`）与个人地图指南（`generate_map_guide`）会将用户输入的行程/POI 数据发送至腾讯地图服务器，用于生成攻略内容和微信小程序二维码。服务器端数据留存与使用遵循[腾讯位置服务隐私政策](https://lbs.qq.com/userAgreements/agreements/privacy)。\n\n## 🔑 Key 策略\n\n| 场景 | 行为 |\n|:-----|:-----|\n| 未配置 Key | 需通过 tempkey 流程申请临时体验 Key，或配置正式 Key |\n| 已配置 Key | 走正式通道（apis.map.qq.com），使用你自己的额度 |\n| Key 优先级 | 传入参数 → 环境变量 `TMAP_KEY` → `~/.tencentmap/tempkey.json` |\n\nFile v1.5.2:references/jsapi-guide/README.md\n\n# 腾讯地图 JSAPI GL 资料（内嵌）\n\n> 本目录是腾讯地图 JS API GL 的完整开发资料，内嵌在本 skill 包里，\n> 在需要为旅游攻略 / 多 POI / 路线出 HTML 可视化时直接查阅。\n>\n> HTML 地图底图使用腾讯地图 JSAPI GL。底图 `<script>` 标签见下方「API Key」段，直接照抄即可。\n\n## ⚠️ 强制约束：底图 & 命名空间\n\n- **底图**：本 skill 全链路绑定腾讯位置服务——WebService API、GCJ-02 坐标系、Key 与额度体系均为腾讯地图。因此所有 HTML 可视化地图必须使用腾讯地图 JSAPI GL 作为底图，与数据层保持一致；换用其他地图 SDK 会导致坐标系、服务接口、样式体系不匹配。涉及中国区域的地图展示，也需符合国家地图合规要求，不使用未取得国内测绘资质的境外地图服务。\n- **命名空间**：JSAPI GL 挂在全局 **`TMap`** 上（大小写严格：**T** 大写、**M** 大写，其余小写）。所有 API 必须走 `TMap.xxx`：`new TMap.Map(container, opts)`、`new TMap.LatLng(lat, lng)`、`new TMap.MultiMarker(...)`、`new TMap.MultiPolyline(...)`、`new TMap.InfoWindow(...)`、`new TMap.MultiLabel(...)` 等。\n- ❌ 常见错误：把地图 API 写成非 `TMap` 的全局对象（如错误大小写 `TMAP.Map` / `Tmap.Map`、旧版 `qq.maps.Map`，或其他地图 SDK 的全局命名空间）——一律不允许，统一改用 `TMap.xxx`。\n\n## 何时读这里\n\n当需要把行程 / POI / 路线渲染成 HTML 地图时，按以下顺序查阅：\n\n1. **底图 key 与 HTML 生成示例** → 下方「API Key」与「HTML 生成示例」段（照抄即可出图）\n2. **画路线** → 下方「画路线：polyline 解压」段\n3. **JSAPI 核心 API（地图初始化 / marker / 路线连线 / 弹窗等基础能力）** → `jsapigl/docs/*.md`（下方有完整文件名清单）\n4. **可视化扩展库（热力图 / 轨迹 / 弧线 / 区域图等高级可视化）** → `visualization/docs/*.md`（下方有完整文件名清单）\n5. **demo 代码** → `*/demos/`\n\n## jsapigl/docs/ 文件清单（21 个核心 API 文档）\n\n| 文档 | 说明 / 何时读 |\n|------|--------------|\n| `概述.md` | API 总览，第一次接入先看 |\n| `地图.md` | 地图初始化、移动、缩放等核心 API |\n| `基础类.md` | LatLng / Point 等基础数据类型 |\n| `点标记.md` | Marker（POI 标记必读） |\n| `点聚合.md` | MarkerCluster（多 POI 聚合） |\n| `信息窗体.md` | InfoWindow（POI 弹窗，旅游攻略必读） |\n| `矢量图形.md` | Polyline / Polygon（路线连线必读） |\n| `文本标记.md` | Label 文字标注 |\n| `DOM覆盖物.md` | 自定义 HTML 覆盖物 |\n| `事件.md` | 地图/marker 事件处理 |\n| `控件.md` | 缩放/比例尺等内置控件 |\n| `室内图.md` | 室内地图 |\n| `自定义图层.md` | 自定义图层 |\n| `环境检测.md` | 浏览器/WebGL 支持检测 |\n| `附加库：几何计算库.md` | geometry 库（距离/面积计算） |\n| `附加库：地图工具.md` | tools 库（标尺/绘图工具） |\n| `附加库：地图视角附加库.md` | view 库（视角控制） |\n| `附加库：天气图层.md` | weather 图层 |\n| `附加库：服务类库.md` | service 库（地理编码等） |\n| `附加库：模型库.md` | model 库（3D GLTF/3DTiles） |\n| `附加库：矢量数据图层.md` | vector 库（GeoJSON/MVT） |\n\n## visualization/docs/ 文件清单（14 个可视化扩展）\n\n| 文档 | 说明 / 何时读 |\n|------|--------------|\n| `参考手册.md` | 可视化扩展库总览 |\n| `基础类.md` | 通用基础类 |\n| `事件.md` | 可视化层事件 |\n| `散点图.md` | 散点图（旅游 POI 可用） |\n| `热力图.md` | 热力图 |\n| `网格热力图.md` | 网格化热力图 |\n| `蜂窝热力图.md` | 六边形热力图 |\n| `辐射圈.md` | 辐射圈（POI 影响范围） |\n| `弧线图.md` | 弧线（跨城路线视觉化好） |\n| `轨迹图.md` | 轨迹动画（旅游路线播放） |\n| `管道图.md` | 管道连线 |\n| `区域图.md` | 多边形区域 |\n| `围墙面.md` | 立体围墙 |\n| `水晶体.md` | 立体水晶 |\n\n\n## 目录结构\n\n```\njsapi-guide/\n├── README.md            本文档\n├── jsapigl/\n│   ├── docs/            核心 API 文档（上方 21 个 md）\n│   └── demos/           核心 API 的 demo HTML\n└── visualization/\n    ├── docs/            可视化扩展库文档（上方 14 个 md）\n    └── demos/           可视化扩展库的 demo HTML\n```\n\n## API Key\n\nHTML 地图底图使用 client 解析到的 Key（tempkey / 环境变量 `TMAP_KEY` / `.env` 文件），在 `<script>` 标签中引用。生成 HTML 时将 `TMAP_KEY` 替换为实际解析到的 Key：\n\n```html\n<script src=\"https://map.qq.com/api/gljs?v=1&key={TMAP_KEY}\"></script>\n```\n\ntempkey 生成的 Key 同时支持 JSAPI 底图加载和 WebService API 调用，放进 HTML `<head>` 即可显示底图。未配置 Key 时需先通过 tempkey 流程申请临时体验 Key。\n\n> ⚠️ **安全提示**：将 Key 明文写在 HTML `<script src=\"...gljs?key=XXX\">` 中，任何访问该页面的人都能通过查看源码或抓包拿到 Key，从而盗用你的额度。**仅在本地开发/内部预览场景可用**。若要将网页发布到公网，请务必改用下方「Key 安全 / 代理服务转发」方案。生成 HTML 后必须按 SKILL.md「HTML Key 安全检查」条目主动提示用户。\n\n### HTML Key 安全检查 — 检测与提示\n\n每次生成 / 写入含腾讯地图 JSAPI GL 的 HTML 后（识别标记：URL 含 `map.qq.com/api/gljs`），在同一轮内执行：\n\n- **检测**：对文件内容执行正则 `gljs\\?[^\"']*[?&]key=[A-Z0-9-]{20,}`，判断是否含明文 Key。\n- **命中时**：在最终回复中原样输出下方「固定安全提示文案」整段，逐字复制，不改写、翻译、精简、合并、拆分、加 emoji、调换顺序或省略。唯一允许的替换：将 `<HTML_FILE>` 替换为实际文件路径；命中多个文件则按行列出所有路径。\n- **未命中时**：不输出安全提示，避免噪音。\n- 不在未告知用户的情况下将带明文 Key 的 HTML 发布 / 部署到公网。\n\n**固定安全提示文案（命中时原样输出，勿改动）：**\n\n> ⚠️ **HTML Key 安全提示**：检测到 `<HTML_FILE>` 中包含明文 Key（形如 `gljs?...&key=...`），任何人可通过查看源码或抓包获取，存在盗用风险；当前形式仅限本地/内网使用，若需公网发布请参考官方代理方案：https://lbs.qq.com/webApi/javascriptGL/glGuide/glKeyDelegate 。\n\n## Key 安全 / 代理服务转发\n\n**官方文档**：https://lbs.qq.com/webApi/javascriptGL/glGuide/glKeyDelegate\n\n将 Key 存到自有服务器，前端通过代理服务器请求腾讯 JSAPI，Key 完全不出现在 HTML 与网络请求中。核心两步：\n\n### 1. 服务器端配置代理（以 Nginx 为例）\n\n将下面配置里的 `XXXX-XXXX-XXXX-XXXX-XXXX-XXXX` 替换为你的正式 Key：\n\n```nginx\nserver {\n  listen 8080;\n  server_name your.domain.com;   # 你的服务器域名或 IP\n\n  location /_TMapService {\n    set $args \"$args&key=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX\";\n    proxy_pass https://pr.map.qq.com/pingd?appid=jsapi_v3;\n  }\n  location /_TMapService/checkKey {\n    set $args \"$args&key=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX\";\n    proxy_pass https://apikey.map.qq.com/mkey/index.php/mkey/check;\n  }\n  location /_TMapService/oversea {\n    set $args \"$args&apikey=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX\";\n    proxy_pass https://overseactrl.map.qq.com;\n  }\n  location /_TMapService/service {\n    set $args \"$args&key=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX\";\n    proxy_pass https://apis.map.qq.com/ws;\n  }\n}\n```\n\n### 2. 前端 HTML 改造（去掉明文 key）\n\n在引入 JSAPI **之前**声明代理地址，`<script>` 引用去掉 `&key=` 参数：\n\n```html\n<!-- 必须写在 gljs <script> 之前 -->\n<script>\n  window._TMapSecurityConfig = {\n    serviceHost: \"https://your.domain.com/_TMapService\"\n  };\n</script>\n<!-- 注意：URL 不再包含 &key=... -->\n<script src=\"https://map.qq.com/api/gljs?v=1\"></script>\n```\n\n改造后，前端源码与网络请求都不再含 Key，达到防泄露目的。\n\n### 地图样式\n\n**使用系统默认样式即可，无需设置 `mapStyleId`**。若用户希望修改地图样式，可引导其前往腾讯位置服务官网登录账号，在控制台为对应 Key 配置样式后使用；下方样式表供已在控制台配置自定义样式的用户参考。\n\n```js\nconst map = new TMap.Map('map', {\n  center: new TMap.LatLng(39.9, 116.4), zoom: 12\n  // 使用系统默认样式；如需自定义样式，在官网控制台为 Key 配置后再设置 mapStyleId\n});\n```\n\n| styleId | 样式名称 | 说明 |\n|---------|---------|------|\n| style1 | 可视化官网黑光字 | 黑底 |\n| style2 | 星渊 | 深蓝黑底 |\n| style3 | 玉露 | 绿底 |\n| style4 | 黑色极简 | 黑底 |\n| style5 | 璃青 | 浅绿底 |\n| style6 | 玄青 | 深灰黑底 |\n| style7 | 浅色底图-可视化 | 浅灰白 |\n| style8 | 白浅 | 白色 |\n| style9 | 经典 | 标准 |\n\n> 以上样式均需在官网控制台为 Key 配置后可用。tempkey 及未配置的正式 Key 使用系统默认样式，无需设置 `mapStyleId`。\n\n## HTML 生成示例\n\n地图能力使用 `TMap.Map` + `TMap.MultiMarker` + `TMap.MultiPolyline` + `TMap.InfoWindow`。把 POI 数据换成 client 返回的真实坐标即可：\n\n```python\nimport os, json\n\n# POI 数据（实际用 client 返回的坐标）\npois = [\n    {\"name\": \"象鼻山\", \"lat\": 25.2675, \"lng\": 110.2966},\n    {\"name\": \"两江四湖\", \"lat\": 25.2798, \"lng\": 110.2904},\n    {\"name\": \"靖江王府\", \"lat\": 25.2858, \"lng\": 110.2992},\n]\nmarkers_js = json.dumps(\n    [{\"id\": str(i), \"position\": [p[\"lat\"], p[\"lng\"]], \"title\": p[\"name\"]} for i, p in enumerate(pois)],\n    ensure_ascii=False,\n)\n\nhtml = f'''<!DOCTYPE html><html><head><meta charset=\"utf-8\">\n<style>html,body,#map{{height:100%;margin:0}}</style>\n<script src=\"https://map.qq.com/api/gljs?v=1&key={TMAP_KEY}\"></script>\n</head><body><div id=\"map\"></div><script>\nconst pts = {markers_js};\nconst map = new TMap.Map('map', {{\n  center: new TMap.LatLng(pts[0].position[0], pts[0].position[1]), zoom: 12\n}});\nnew TMap.MultiMarker({{ map, geometries: pts.map(p => ({{\n  id: p.id, position: new TMap.LatLng(p.position[0], p.position[1]), properties: {{title: p.title}}\n}})) }});\nnew TMap.MultiPolyline({{ map, geometries: [{{\n  id: 'route', paths: pts.map(p => new TMap.LatLng(p.position[0], p.position[1]))\n}}] }});\n</script></body></html>'''\n\nout = os.path.expanduser(\"~/Documents/itinerary_map.html\")\nwith open(out, \"w\", encoding=\"utf-8\") as f:\n    f.write(html)\nprint(out)\n```\n\n旅游攻略类 HTML 还可把 `travel_guide` 返回的 `qr_path` 嵌入网页右下角浮窗（约 120×120）；POI 按天分色 + 数字角标 + polyline 连线。\n\n## 画路线：polyline 解压\n\n`direction` 返回腾讯路线接口原生响应（`result.routes`）。驾车/步行/骑行的 `routes[0].polyline` 是**压缩格式的一维数组**，画线前需解压成 `[lat,lng]` 点序列：前两个值是首点真实经纬度，其后每个值是相对前一点的差值（×1e6），逐项累加还原。\n\n```python\ndef decode_polyline(coors):\n    \"\"\"腾讯压缩 polyline 一维数组 → [[lat,lng], ...]\"\"\"\n    if not coors or len(coors) < 2:\n        return []\n    pts = [[coors[0], coors[1]]]\n    for i in range(2, len(coors) - 1, 2):\n        lat = pts[-1][0] + coors[i] / 1_000_000.0\n        lng = pts[-1][1] + coors[i + 1] / 1_000_000.0\n        pts.append([round(lat, 6), round(lng, 6)])\n    return pts\n```\n\n解压后转成 `new TMap.LatLng(lat, lng)` 数组喂给 `MultiPolyline` 的 `paths`。\n\n> 公交 `transit` 的 route 没有顶层 polyline，折线分散在 `steps` 各换乘段里（步行段的 `polyline` 字段、乘车段 `lines[0].polyline`），按需分别解压。\n\nFile v1.5.2:_meta.json\n\n{\n  \"ownerId\": \"kn77cw5hbmapf54rv89jdqwp7x835m4k\",\n  \"slug\": \"tencentmap-map-assistant-skill\",\n  \"version\": \"1.5.2\",\n  \"publishedAt\": 1786521712517\n}\n\nFile v1.5.2:references/agent-notes.md\n\n# 调用指引（供 AI 阅读）\n\n本文件补充 SKILL.md 未展开的调用细节，帮助 AI 稳定完成任务。\n\n## 能力命中本 skill 时，用 client 完成\n\n用户需求涉及旅游攻略、找地点、路线规划、地址坐标转换、行政区划、距离计算等，均通过 `TmapClient` 完成，返回的是腾讯位置服务真实数据。\n\n- client 仅依赖 `requests`，多数环境已自带，可直接调用；仅当报 `ModuleNotFoundError: requests` 时执行 `pip install requests` 后重试。\n- 调用报错时，读返回的报错信息定位。API 错误码见 `error-codes.md` 分类表，参数类错误可修正后重试；其余错误不可绕过或降级，引导用户修正。\n\n\n## Key 策略：检查 tempkey，按需配置正式 Key\n\n每个使用者的腾讯位置服务额度独立。\n\n- **Key 解析顺序**：用户传入参数 → 环境变量 `TMAP_KEY` → `~/.tencentmap/tempkey.json`（持久化 key 源，含手动指定的 Key 与申请的临时体验 Key）。\n- **无 Key 时**：client 初始化成功，但调用 WebService API 时会抛出 `TmapError`。此时 AI 应引导用户通过 tempkey 流程申请 AI 场景临时体验 Key（手机验证，1 年有效，覆盖 WebService API + JSAPI 底图加载）。**必须读取 `tempkey-guide.md` 获取完整申请流程**（协议展示、脚本调用、错误码表、输出模板等），严格按照其中步骤执行。\n- **配置正式 Key**：使用者提供 Key 时，用 `save_key_to_dotenv(\"Key\")` 持久化保存（写入 `~/.tencentmap/tempkey.json`），重新初始化 client 后自动走正式通道。\n\n```python\nfrom tmap_client import TmapClient, save_key_to_dotenv\nc = TmapClient()                 # 自动解析 Key（env / tempkey.json）\n# save_key_to_dotenv(\"XXX-...\")  # 使用者提供 Key 时调用\n```\n\n## 返回结构：默认语义化文本\n\n所有 WebService 能力（搜索、提示、详情、地址解析、区划、IP、距离矩阵、路线规划）默认直接返回**语义化文本**——中文、带单位、可直接展示给用户。禁止重新解析 raw JSON 自己拼接文字。\n\n如需原始 JSON 做下游计算（例如取 route_id 调沿途搜索、取 poi_id/坐标调 generate_map_guide），传 `raw=True`：\n\n## 错误处理：直接展示错误信息\n\nAPI 报错时（TmapError），`e.message` 含错误码和原因描述。对应操作指引见 `references/error-codes.md`，按错误码查找后引导用户修正，不得自行估算或编造。\n\n```python\n# 默认：返回可读文本\ntext = client.poi_search(\"黄鹤楼\", region=\"武汉\")\n# → \"找到约223条结果，以下为其中10条\\n(1) 黄鹤楼...\"\n\n# raw=True：返回原始 JSON\ndata = client.poi_search(\"深圳北站\", region=\"深圳\", raw=True)\np1 = data[\"data\"][0]  # 取 id、坐标等精确字段\n```\n\n> 行政区划三个方法的 `result` 是**二维数组**——`result[0]` 才是区划对象列表。\n\n路线规划 `direction` 仅在调用前自动把起终点的地址/景点名转成坐标，默认返回语义化文本。如需原始 JSON（例如取 `polyline` 画地图），传 `raw=True` 后从 `result.routes` 获取。其中驾车/步行/骑行的 `polyline` 为压缩格式，画线前需解压（解压方法见 `jsapi-guide/README.md`）。\n\n## travel_guide 的回复方式\n\n`travel_guide` 返回的 `output_markdown` 是成品攻略文件（含行程正文与小程序入口二维码图片）。\n\n**必须做的事（缺一不可）：**\n\n1. 用 Read 读取 `result[\"output_markdown\"]`，将文件内容**完整作为回复**——包含末尾的 `![腾讯地图小程序入口图](...)` 图片语法。**Markdown 图片语法 `![]()` 完全可以直接在 WorkBuddy 会话中渲染显示**，不需要转换成 base64、不需要上传、不需要用其他方式——直接输出 `![]()` 语法就能看到二维码图。\n2. **同时**将 `result[\"qr_path\"]` 指向的二维码 PNG 文件复制到当前工作空间，确保二维码作为实体文件留存在工作区，用户可以随时找到和使用。复制命令参考：macOS/Linux 用 `cp`，Windows 用 `copy`。示例：`cp /path/to/qrcodes/xxx.png <工作空间路径>/`\n\n文件末尾结构示例：\n\n```markdown\n---\n![腾讯地图小程序入口图](/path/to/qrcodes/travel_guide_xxx.png)\n\n👆 扫码保存自己的专属地图，在手机上随时查看和导航。\n```\n\n> ⚠️ Markdown 图片语法 `![...](...)` 可在 WorkBuddy 会话中内联渲染，请务必通过此方式展示二维码图片，而非仅提供文件路径、转 base64 或其他方式。\n\n## 网页生成（HTML 地图可视化）\n\n涉及\"多 POI 对比 / 路线 / 多天行程 / 个人专属地图\"等\"看图比看字更直观\"的场景，可基于结构化数据生成 HTML 网页地图。底图 key、HTML 生成示例、polyline 解压方法、各类 API 与 demo 全部见 `references/jsapi-guide/README.md`，照其中模板生成即可。\n\n> 使用系统默认样式即可。若用户希望修改地图样式，可引导其前往腾讯位置服务官网登录账号，在控制台为对应 Key 配置样式后使用。\n\n## 个人地图指南（generate_map_guide）\n\n`generate_map_guide` 是独立于 A2A 攻略的指南生成能力，可将任意 POI 列表直接生成腾讯地图小程序指南（含二维码），用户扫码即可在手机上查看、导航、分享、编辑。与 `travel_guide` 内含出码不同，本方法需显式调用。\n\n### 业务场景\n\n| 用户说… | 动作 |\n|---------|------|\n| \"帮我记录这几个打卡点\" / \"生成一个XX地图\" / \"存到手机上\" | 调用 `generate_map_guide()` 生成指南 |\n| \"帮我搜一下深圳的咖啡馆\" → 返回 ≥2 个 POI | 同一回复中调用 `generate_map_guide()` |\n| \"从A到B怎么走\" → direction 路线规划 | 同一回复中调用 `generate_map_guide()` |\n| 生成了 HTML 地图可视化 | 同一回复中调用 `generate_map_guide()`，HTML 桌面看 + 小程序手机导航 |\n| `travel_guide` 攻略 | 已内置出码，直接 Read `output_markdown`，**无需额外调用** |\n| 单点查询 | 只返回数据，不出码 |\n\n### 调用示例\n\n```python\n# 路线规划 + 出码的标准流程\nroute = client.direction(\"深圳北站\", \"深圳湾口岸\", mode=\"driving\")\n\n# 先用 poi_search 获取真实 POI（id + location 坐标），再映射生成指南\np1 = client.poi_search(\"深圳北站\", region=\"深圳\", raw=True)[\"data\"][0]\np2 = client.poi_search(\"深圳湾口岸\", region=\"深圳\", raw=True)[\"data\"][0]\nguide = client.generate_map_guide(\n    [{\"name\": p1[\"title\"], \"lat\": p1[\"location\"][\"lat\"], \"lng\": p1[\"location\"][\"lng\"], \"poi_id\": p1[\"id\"], \"day\": 1, \"num\": 1},\n     {\"name\": p2[\"title\"], \"lat\": p2[\"location\"][\"lat\"], \"lng\": p2[\"location\"][\"lng\"], \"poi_id\": p2[\"id\"], \"day\": 1, \"num\": 2}],\n    city=\"深圳\",\n    description=\"深圳北站 → 深圳湾口岸，约15公里，驾车约30分钟\"\n)\n# guide[\"output_markdown\"] → Read 后作为回复的一部分输出\n```\n\n### pois 字段说明\n\n> **数据来源**：`lat` / `lng` / `poi_id` 取自 `poi_search()` / `poi_sug()` 的真实返回（搜索结果中坐标位于 `location.lat/lng`、ID 为 `id`），映射后填入。生成指南前先逐点搜索。\n\n| 字段 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `name` | str | 是 | 地点名称，取自搜索返回的 `title` |\n| `lat` / `lng` | float | 是 | GCJ02 坐标，取自搜索返回的 `location.lat` / `location.lng` |\n| `poi_id` | str | 是 | POI ID，取自搜索返回的 `id`，保证定位精度 |\n| `day` | int | 否 | 天分组，默认 1 |\n| `num` | int | 否 | 序号，默认按输入顺序编号 |\n| `type` | int | 否 | POI 类型，默认 1。`2` 表示搜索词类型（需配合 `search_query`） |\n| `search_query` | str | 否 | 仅在 `type=2` 时使用 |\n| `inday` | int | 否 | 散点所属天数，默认 0 |\n\nFile v1.5.2:references/api_reference.md\n\n# 腾讯位置服务 AI 场景 Key 申请接口文档\n\n---\n\n## 域名\n\n| 项目 | 值 |\n|------|-----|\n| API 域名 | `lbsconsole.map.qq.com` |\n\n---\n\n## 通用说明\n\n### 鉴权与防重放\n\nSkill 三个接口（`/nosession/http/skill/*`）无需 Cookie 登录态，需在 HTTP Header 中携带：\n\n| Header | 必填 | 说明 |\n|--------|:----:|------|\n| `X-Skill-Nonce` | 是 | 随机字符串，用于防重放，时间窗内（默认 300 秒）只能使用一次 |\n| `X-Skill-Timestamp` | 是 | 客户端时间戳（秒级），与服务端偏差超时间窗则拒绝 |\n\n控制台接口（`/console/*`）走 Cookie 鉴权，不需要上述 Header。**Skill 不使用控制台接口。**\n\n### 统一响应格式\n\n```json\n{\n  \"info\": {\n    \"error\": 0,\n    \"msg\": \"成功\"\n  },\n  \"detail\": { ... }\n}\n```\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| info.error | int | 0=成功，非 0=失败（值即错误码） |\n| info.msg | string | 成功为 \"成功\"，失败为错误码字符串（如 \"SKILL_INVALID_PHONE\"） |\n| detail | object | 业务数据，失败时通常为空对象或不存在 |\n\n### 错误码\n\n| 错误码 | code | 触发场景 |\n|--------|------|---------|\n| `OK` | 0 | 成功 |\n| `MISSING_PARAM` | 2000 | 参数缺失 |\n| `ILLEGAL_PARAM` | 2999 | 参数非法 |\n| `SKILL_INVALID_PHONE` | 500081 | 手机号格式不正确 |\n| `SKILL_TIMESTAMP_EXPIRED` | 500071 | 时间戳超出时间窗 |\n| `SKILL_NONCE_REPLAY` | 500070 | nonce 已使用过 |\n| `SKILL_SMS_COOLDOWN` | 500072 | 发送冷却中 |\n| `SKILL_SMS_PHONE_DAY_LIMIT` | 500073 | 手机号当日发送达上限 |\n| `SKILL_SMS_IP_DAY_LIMIT` | 500074 | IP 当日发送达上限 |\n| `SKILL_VERIFY_CODE_EXCEEDED` | 500075 | 验证码错误超 3 次 |\n| `AUTH_EXPIRED` | 1007 | session_token 或 supplement_token 不存在/已过期 |\n| `AUTH_FAILED` | 1008 | 验证码错误 |\n| `SKILL_SMS_SEND_ERROR` | 500080 | 短信发送失败 |\n| `SKILL_USER_REGISTER_ERROR` | 500079 | 新用户注册失败 |\n| `SKILL_CREATE_IN_PROGRESS` | 500083 | 该手机号正在创建 Key（分布式锁） |\n| `SKILL_SUPPLEMENT_IN_PROGRESS` | 500088 | 该用户正在补额（分布式锁） |\n| `SKILL_NO_SUITABLE_KEY` | 500085 | mkey 不满足条件 |\n| `SKILL_AI_CLAIM_ONCE_USED` | 500084 | 已领取过 AI 场景 Key（且已到期，不再扩容） |\n| `SKILL_QUOTA_WRITE_ERROR` | 500086 | 临时额度写入失败 |\n| `SKILL_CLAIM_WRITE_ERROR` | 500089 | 领取记录写入失败 |\n| `INNER_ERROR` | 3001 | DB/Redis 异常 |\n\n---\n\n## 一、发送验证码\n\n### 基本信息\n\n| 项目 | 值 |\n|------|-----|\n| 路径 | `POST /nosession/http/skill/auth/send-code` |\n| Content-Type | application/json |\n| 鉴权 | Header nonce + timestamp |\n\n### 请求参数\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|:----:|------|\n| customer_phone | string | 是 | 中国大陆手机号，11 位，1 开头 |\n\n### 请求示例\n\n```bash\ncurl -s -X POST 'https://lbsconsole.map.qq.com/nosession/http/skill/auth/send-code' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Skill-Nonce: abc123def456' \\\n  -H 'X-Skill-Timestamp: 1752662400' \\\n  -d '{\"customer_phone\":\"13800138000\"}'\n```\n\n### 响应示例\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"session_token\": \"sk_a1b2c3d4e5f67890123456789abcdef0\"\n  }\n}\n```\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| detail.session_token | string | 会话令牌，前缀 `sk_`，用于 create 接口。有效期 300 秒 |\n\n---\n\n## 二、创建临时 Key\n\n### 基本信息\n\n| 项目 | 值 |\n|------|-----|\n| 路径 | `POST /nosession/http/skill/v2/tempkey/create` |\n| Content-Type | application/json |\n| 鉴权 | Header nonce + timestamp + session_token 验证 |\n\n### 请求参数\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|:----:|------|\n| customer_phone | string | 是 | 中国大陆手机号 |\n| verify_code | string | 是 | 短信验证码（6 位数字） |\n| session_token | string | 是 | send-code 返回的会话令牌 |\n| scene | int | 否 | 场景：1=Skill（默认），2=MCP。**Skill 固定传 1** |\n\n### 响应形态\n\n| type | 含义 | 返回字段 | 触发场景 |\n|------|------|---------|---------|\n| `created` | Key 已就绪 | `key`, `expire_time`, `is_existing`(可选) | 新用户 / 老用户无合适 Key / 幂等返回(claim_type∈{1,2}) |\n| `reused` | 幂等返回已补额的老 Key | `key`, `expire_time`, `is_existing` | 老用户幂等命中且 claim_type=3（reuse） |\n| `select` | 返回 Key 列表 | `key_list`, `supplement_token`, `supplement_token_expire` | 老用户有名下满足条件的 Key |\n\n### 响应示例 1：type=created（新建 Key）\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"type\": \"created\",\n    \"key\": \"AB3D-CDEF-GHIJ-KLMN-OPQR\",\n    \"expire_time\": \"2027-07-17 19:59:59\"\n  }\n}\n```\n\n### 响应示例 2：type=created（幂等返回已有 Key，claim_type∈{1,2}）\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"type\": \"created\",\n    \"key\": \"AB3D-CDEF-GHIJ-KLMN-OPQR\",\n    \"expire_time\": \"2027-07-17 19:59:59\",\n    \"is_existing\": true\n  }\n}\n```\n\n### 响应示例 3：type=reused（幂等返回已补额的老 Key，claim_type=3）\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"type\": \"reused\",\n    \"key\": \"AB3D-CDEF-GHIJ-KLMN-OPQR\",\n    \"expire_time\": \"2027-07-17 19:59:59\",\n    \"is_existing\": true\n  }\n}\n```\n\n### 响应示例 4：type=select（返回 Key 列表）\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"type\": \"select\",\n    \"key_list\": [\n      {\n        \"key_name\": \"我的地图应用\",\n        \"key_value\": \"AB3D-CDEF-GHIJ-KLMN-OPQR\"\n      },\n      {\n        \"key_name\": \"测试Key\",\n        \"key_value\": \"F8E2-WXYZ-ABCD-EFGH-IJKL\"\n      }\n    ],\n    \"supplement_token\": \"sk_xxx_yyy_zzz\",\n    \"supplement_token_expire\": 300\n  }\n}\n```\n\n### 字段说明\n\n#### 顶层字段（位于 detail 对象内）\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| type | string | `created` / `reused` / `select` |\n| key | string | type=created/reused 时返回，Key 值 |\n| expire_time | string | type=created/reused 时返回，到期时间 `YYYY-MM-DD HH:mm:ss` |\n| is_existing | bool | type=created/reused 时返回，true=幂等返回已有 Key |\n| key_list | array | type=select 时返回，合适 Key 列表 |\n| supplement_token | string | type=select 时返回，用于 supplement 接口 |\n| supplement_token_expire | int | token 过期剩余秒数（默认 300） |\n\n#### key_list 数组元素\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| key_name | string | Key 名称（appname） |\n| key_value | string | Key 值（完整值，前端脱敏展示） |\n\n### 业务流程\n\n```\n请求进入\n  ├─ nonce + timestamp 校验\n  ├─ 参数解析 + 手机号格式校验\n  ├─ 分布式锁（per phone）\n  ├─ IP / 手机号 日限额校验\n  ├─ SMS 验证码校验\n  ├─ 查询用户 sid = QueryUser(phone)\n  │\n  ├─ sid > 0（老用户）→ handleOldUser:\n  │    ├─ 幂等检查 QueryActiveAiClaim(sid)\n  │    │   ├─ claim_type=3 → type=reused, is_existing=true\n  │    │   └─ claim_type∈{1,2} → type=created, is_existing=true\n  │    ├─ FindSuitableKeys(sid)\n  │    │   ├─ 有合适 Key → type=select, 返回 key_list + supplement_token\n  │    │   └─ 无合适 Key → createAiKeyWithQuota(claim_type=2) → type=created\n  │\n  └─ sid == 0（新用户）:\n       └─ 注册 + createAiKeyWithQuota(claim_type=1) → type=created\n```\n\n> **注意**：若 SID 曾扩容但 Key 已过期，create 返回错误码 `500084`（SKILL_AI_CLAIM_ONCE_USED），不再再次扩容。\n\n### 合适 Key 条件（8 个）\n\n1. `FIND_IN_SET(2, pf) > 0`（WebService 权限开启）\n2. `status = 1`（可用）\n3. `super = 0`（非超级 Key）\n4. `ws_whitelist` 为空（未设置 IP 白名单）\n5. `miniapp_whitelist` 为空（未设置小程序白名单）\n6. `sk` 为空（未开启签名鉴权）\n7. `web_whitelist` 为空（未设置 Web 白名单）\n8. 不在 ban 表中（`status=1 AND end_time > NOW()`）\n\n### claim_type 枚举\n\n| 值 | 含义 | 使用位置 |\n|----|------|---------|\n| 1 | 新用户新建 Key | create（新用户） |\n| 2 | 老用户新建 Key | create（老用户无合适Key）/ supplement(action=create) |\n| 3 | 老用户复用 Key | supplement(action=reuse) |\n\n---\n\n## 三、补额 / 新建 Key（supplement）\n\n### 基本信息\n\n| 项目 | 值 |\n|------|-----|\n| 路径 | `POST /nosession/http/skill/v2/tempkey/supplement` |\n| Content-Type | application/json |\n| 鉴权 | Header nonce + timestamp + supplement_token |\n\n### 请求参数\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|:----:|------|\n| supplement_token | string | 是 | create 接口 type=select 时返回的令牌 |\n| mkey | string | action=reuse 时必填 | 用户选定的 Key |\n| action | string | 否 | `reuse`（默认，复用老 Key）/ `create`（新建 Key） |\n\n### 请求示例 1：action=reuse（复用老 Key 补额）\n\n```bash\ncurl -s -X POST 'https://lbsconsole.map.qq.com/nosession/http/skill/v2/tempkey/supplement' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Skill-Nonce: reuse001' \\\n  -H 'X-Skill-Timestamp: 1752662460' \\\n  -d '{\n    \"supplement_token\": \"sk_xxx_yyy_zzz\",\n    \"mkey\": \"AB3D-CDEF-GHIJ-KLMN-OPQR\",\n    \"action\": \"reuse\"\n  }'\n```\n\n### 请求示例 2：action=create（新建 Key）\n\n```bash\ncurl -s -X POST 'https://lbsconsole.map.qq.com/nosession/http/skill/v2/tempkey/supplement' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Skill-Nonce: create001' \\\n  -H 'X-Skill-Timestamp: 1752662460' \\\n  -d '{\n    \"supplement_token\": \"sk_xxx_yyy_zzz\",\n    \"action\": \"create\"\n  }'\n```\n\n### 响应示例\n\n#### action=reuse（复用老 Key 补额）→ type=reused\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"type\": \"reused\",\n    \"key\": \"AB3D-CDEF-GHIJ-KLMN-OPQR\",\n    \"expire_time\": \"2027-07-17 19:59:59\",\n    \"is_existing\": true\n  }\n}\n```\n\n#### action=create（新建 Key）→ type=created\n\n```json\n{\n  \"info\": {\"error\": 0, \"msg\": \"成功\"},\n  \"detail\": {\n    \"type\": \"created\",\n    \"key\": \"F8E2-WXYZ-ABCD-EFGH-IJKL\",\n    \"expire_time\": \"2027-07-17 19:59:59\"\n  }\n}\n```\n\n### 响应字段（supplement，位于 detail 对象内）\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| type | string | `reused`（action=reuse，复用补额）/ `created`（action=create，新建 Key） |\n| key | string | Key 值 |\n| expire_time | string | 到期时间 `YYYY-MM-DD HH:mm:ss` |\n| is_existing | bool | `type=reused` 时为 true；`type=created` 时不返回 |\n\n### 处理流程\n\n#### 公共流程\n\n```\n0. nonce + timestamp 校验\n1. 验证 supplement_token → 获取 sid\n2. 分布式锁（per sid）\n3. mkey 校验（仅 action=reuse：3 个条件）\n4. 幂等检查 CheckAiClaimOnce\n5. 消费 token（一次性）\n```\n\n#### action=reuse 分支\n\n```\n6. ComputeSupplementMissing → 查 custom + tmp_quota_record，算差额\n7. 事务（GORM Transaction）：\n   ├─ 写 tmp_quota_record（source=1 AI场景）\n   └─ 写 t_ai_key_claim（claim_type=3）\n8. 重建索引\n10. 返回老 Key（type=reused, is_existing=true）\n```\n\n#### action=create 分支\n\n```\n6. CreateSkillApp + CreateSkillKey → 创建新 Key\n7. buildInitQuotaRecords → 构建全量 AI 基线配额\n8. 事务（GORM Transaction）：\n   ├─ 写 tmp_quota_record（source=1 AI场景）\n   └─ 写 t_ai_key_claim（claim_type=2）\n9. 重建索引\n10. 返回新 Key（type=created）\n```\n\n### 补额差额逻辑（action=reuse）\n\n对每个 AI 基线接口，PV 和 QPS 独立计算：\n\n```\ndesired = baseline - formal   （正式配额已够则 desired <= 0，不写）\n```\n\n| desired | 已有临时配额 | 过期时间 vs 365天 | 操作 | 写入值 |\n|---------|-------------|------------------|------|--------|\n| > 0 | < desired | 任意 | 提升额度 | `desired` |\n| > 0 | >= desired | >= 365天 | 不动 | — |\n| > 0 | >= desired | < 365天 | 续期（不降额） | `existing` |\n| > 0 | = 0 | — | 新建 | `desired` |\n| <= 0 | 任意 | 任意 | 不动 | — |\n\n**提升额度时**：原过期时间 > 365天则保持原值，否则用 365天。\n\n**已过期的临时配额**（`expire_time <= NOW()`）不计入已有额度，会被覆盖。\n\n---\n\n## 四、控制台临时配额列表（Skill 不使用）\n\n> **说明**：此接口走 Cookie 鉴权，Skill 模式下用户无登录态，不使用此接口。仅作记录。\n\n| 项目 | 值 |\n|------|-----|\n| 路径 | `GET /console/tmp_quota_list` |\n| 鉴权 | 控制台 Cookie（中间件解析 sid） |\n\n请求参数：`mkey`（必填）、`funcid`（必填，指定接口 ID）。\n\n---\n\n## 五、控制台配额查询 OrderStat（Skill 不使用）\n\n> **说明**：此接口走 Cookie 鉴权，Skill 模式下用户无登录态，不使用此接口。仅作记录。\n\n| 项目 | 值 |\n|------|-----|\n| 路径 | `GET /console/orderstat` |\n| 鉴权 | 控制台 Cookie（中间件解析 sid） |\n\n请求参数：`mkey`（必填）、`function_type`/`key_word`/`funcid`/`showinner`（可选）。\n\n---\n\n## 接口清单\n\n| 接口 | Method | 路径 | 鉴权 | Skill 使用 |\n|------|--------|------|------|:----------:|\n| 发送验证码 | POST | `/nosession/http/skill/auth/send-code` | nonce + timestamp | ✅ |\n| 创建临时 Key | POST | `/nosession/http/skill/v2/tempkey/create` | nonce + timestamp + session_token | ✅ |\n| 补额/新建 Key | POST | `/nosession/http/skill/v2/tempkey/supplement` | nonce + timestamp + supplement_token | ✅ |\n| 临时配额列表 | GET | `/console/tmp_quota_list` | Cookie | ❌ |\n| 配额查询（OrderStat） | GET | `/console/orderstat` | Cookie | ❌ |\n\n---\n\n## AI 场景额度规格\n\n| 项目 | 说明 |\n|------|------|\n| 有效期 | 1 年（365 天） |\n| 每个 SID 限制 | 每个 SID 仅可使用一次 AI 场景扩容机会（无论扩到老 Key 还是新建 Key） |\n| 配额（每个接口） | PV = 5000 次/天，QPS = 5 次/秒 |\n| 接口范围 | WebService API（AI 场景基线，具体清单以控制台为准） |\n| 过期处理 | 临时额度到期后停用，不再允许再次扩容，引导用户前往 lbs.qq.com 分配正式额度或办理商业授权 |\n\nFile v1.5.2:references/error-codes.md\n\n# 腾讯地图 API 错误码速查\n\nAPI 报错时把原始错误码 + 错误信息如实呈现给用户，禁止自行判断原因\n控制台 Key 管理：https://lbs.qq.com/dev/console/key/manage\n控制台工单：https://lbs.qq.com/dev/console/ticket/create\n\n## Key 不可用时的处理\n\n`TmapClient` 调用时会按优先级自动轮询候选池中的所有可用 Key，遇到失败自动切换下一个。当所有 Key 均不可用时抛出 `TmapError`（异常信息中列出每个 Key 的失败原因及错误码），此时 AI 须按下表查出每个错误码的对应修正方式并告知用户，引导其前往控制台修改配置或按 `tempkey-guide.md` 重新申请。\n\n## 鉴权 / 配额类\n\n| 错误码 | 原因 | 操作步骤 |\n|--------|------|----------|\n| 110 | 请求来源未授权 | 在控制台 Key 管理页找到对应 Key，检查 Referer 白名单或 IP 白名单是否包含当前请求来源 |\n| 111 | 签名验证失败 | 在控制台找到对应 Key，点击编辑，将正确的 Secret Key 填入后保存 |\n| 112 | IP 未被授权 | 在控制台找到对应 Key，编辑 IP 白名单，添加当前出口 IP |\n| 113 | 功能未授权 | 在控制台找到对应 Key，编辑其配置，开启所需 API 权限 |\n| 120 | QPS 超限 | 降低调用频率，或在「配额管理 → Key 额度」中调整该 Key 的 QPS 配额 |\n| 121 | 日调用量达上限 | 在「配额管理 → Key 额度」中调整日调用量配额 |\n| 160 | sig 不支持此请求类型 | — |\n| 161 | sig 不支持和非 object POST JSON 一起用 | — |\n| 190 | Key 无效 | 确认该 Key 是否存在、是否被删除或已过期 |\n| 199 | Key 未开启 WebService | 控制台 → 应用管理 → 我的应用 → 找到 Key → 编辑 → 勾选 WebService API |\n\n## 参数错误（301-408）\n\n错误码 301-408 统一为「参数错误」，按报错信息中的具体说明修正即可。\n\n其中 **311（key格式错误）** 属于 Key 类错误：用户填错、粘贴不全等场景会命中，处理方式见上方「Key 不可用时的处理」。\n\n## 系统错误（500+）\n\n后端异常，前往控制台创建工单报备。\n\nFile v1.5.2:references/jsapi-guide/jsapigl/demos/地图操作示例.md\n\n# 地图操作示例 Demo 合集\n\n> 本文件合并自 28 个原始 demo HTML，每节为一个独立可运行示例。使用时把对应代码块中的 JS 部分套入标准 HTML 骨架（见 `jsapi-guide/README.md` 的「HTML 生成示例」，底图 `<script src=\"https://map.qq.com/api/gljs?v=1&key={TMAP_KEY}\"></script>`），或直接整块复制替换 `<body>` 内容。\n\n\n## 2D_3D模式切换\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>2D/3D模式切换</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        width: 100%;\n        height: 100%;\n        position: relative;\n    }\n    input {\n      position: absolute;\n      top: 30px;\n      z-index: 9999;\n    }\n    #btn-2d {\n      left: 20px;\n    }\n    #btn-3d {\n      left: 80px;\n    }\n</style>\n\n<body>\n    <div id=\"container\"></div>\n    <input type=\"button\" id=\"btn-2d\" onclick=\"change2D()\" value=\"切换2D\">\n    <input type=\"button\" id=\"btn-3d\" onclick=\"change3D()\" value=\"切换3D\">\n    <script type=\"text/javascript\">\n            var center = new TMap.LatLng(39.984104, 116.307503);\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                zoom:12,\n          mapStyleId: \"style8\",\n                center: center//设置地图中心点坐标\n            });\n            \n            function change2D() {\n              map.setViewMode('2D');\n            }\n\n            function change3D() {\n              map.setViewMode('3D');\n              map.setPitch(70);\n            }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 切换底图类型\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>切换底图类型</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0px;\n      padding: 0px;\n      overflow: hidden;\n    }\n\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n    .btn {\n      position: absolute;\n      top: 30px;\n      z-index: 1001;\n      padding: 6px 8px;\n    }\n    .btn-left {\n      left: 30px;\n    }\n    .btn-right {\n      left: 150px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n\t\t<input type=\"button\" class=\"btn btn-left\" onclick=\"changeBaseMap({type: 'satellite'})\" value=\"设置为卫星图\">\n\t\t<input type=\"button\" class=\"btn btn-right\" onclick=\"changeBaseMap({type: 'vector'})\" value=\"设置为矢量图\">\n\t\t<script type=\"text/javascript\">\n\t\t\tvar map;\n\n\t\t\tfunction initMap() {\n\t\t\t\tvar center = new TMap.LatLng(39.984104, 116.307503);\n\t\t\t\t//初始化地图\n\t\t\t\tmap = new TMap.Map(\"container\", {\n                    zoom: 12,\n          mapStyleId: \"style8\",\n                    center: center,//设置地图中心点坐标\n\t\t\t\t});\n\n\t\t\t}\n\t\t\t\n\t\t\t// 动态设置底图类型\n\t\t\tfunction changeBaseMap(baseMap) {\n\t\t\t\tmap.setBaseMap(baseMap);\n\t\t\t}\n    </script>\n</body>\n\n</html>\n```\n\n\n## 创建地图\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>创建地图</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <script type=\"text/javascript\">\n        function initMap() {\n            var center = new TMap.LatLng(39.984104, 116.307503);\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                rotation: 20,//设置地图旋转角度\n                pitch:30, //设置俯仰角度（0~45）\n                zoom:12,\n          mapStyleId: \"style8\",\n                center: center//设置地图中心点坐标\n            });\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 区域高亮\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>区域高亮</title>\n  </head>\n  <script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}&libraries=service\"></script>\n  <style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0;\n      padding: 0;\n      overflow: hidden;\n    }\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n  </style>\n  <body onload=\"initMap()\">\n    <div id=\"container\"></div>\n  </body>\n  <script>\n    var map;\n    var district;\n    function initMap() {\n      // 初始化地图\n      map = new TMap.Map('container', {\n        // Map文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap\n        zoom: 9,\n          mapStyleId: \"style8\",\n        center: new TMap.LatLng(40.15739276079734, 116.43926381582764), // 设置地图中心点坐标\n        pitch: 20, // 俯仰度\n        rotation: 0, // 旋转角度，baseMap: [\n          { type: 'vector', features: ['base'] },\n          {\n            type: 'traffic',\n            opacity: 1,\n          },\n        ],\n        renderOptions: {\n          enableBloom: true, // 是否启用泛光效果 注：为true才会有效果\n        },\n      });\n      highlight();\n    }\n\n    function highlight() {\n      // 服务类库文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocService\n      district = new TMap.service.District({\n        // 新建一个行政区划类\n        polygon: 2, // 返回行政区划边界的类型\n      });\n      // 关键字搜索行政区划，110000 = 北京行政区划代码\n      district.search({ keyword: 110000 }).then((result) => {\n        if (!result && !result.result) return;\n\n        // 获取省市区列表及其边界信息\n        var paths = result.result[0][0].polygon;\n\n        map.enableAreaHighlight({\n          paths: paths,\n          highlightColor: 'rgba(0,0,0,0)', // 高亮颜色\n          shadeColor: 'rgba(4,8,14,1)', // 其余阴影部分\n        });\n        // MultiPolyline文档地址：https://lbs.qq.com/javascript_gl/doc/multiPolylineOptions.html\n        new TMap.MultiPolyline({\n          map: map,\n          styles: {\n            polyline: new TMap.PolylineStyle({\n              color: '#017cf7', // 线条填充色，\n              width: 8,\n              lineCap: 'round',\n              enableBloom: true, // 是否启用泛光  注：为true才会有效果\n            }),\n          },\n          geometries: [\n            {\n              styleId: 'polyline', // 样式id\n              paths: paths,\n            },\n          ],\n        });\n      });\n    }\n  </script>\n</html>\n```\n\n\n## 卫星地图\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>卫星地图</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <script type=\"text/javascript\">\n        function initMap() {\n            var center = new TMap.LatLng(39.984104, 116.307503);\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                zoom:12,\n          mapStyleId: \"style8\",\n                center: center,//设置地图中心点坐标\n                baseMap: {  // 设置卫星地图\n                  type: 'satellite'\n                }\n            });\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 同时加载两个地图\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>同时加载2个地图</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n    }\n\n    #containerOne {\n        width: 100%;\n        height: 45%;\n       \n    }\n    #containerTwo {\n        width: 100%;\n        height: 45%;\n    }\n    p{\n        margin: 0;\n        margin-bottom: 20px;\n        text-align: center;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"containerOne\"></div>\n    <p>地图一</p>\n    <div id=\"containerTwo\"></div>\n    <p>地图二</p>\n    <script>\n        function initMap() {\n            //初始化地图一\n            var mapOne = new TMap.Map(\"containerOne\", {\n                pitch:45,\n                center: new TMap.LatLng(39.984104, 116.307503)\n            });\n            //初始化地图二\n            var mapTwo = new TMap.Map(\"containerTwo\", {\n                center: new TMap.LatLng(39.984104, 116.307503)\n            });\n        }\n\n    </script>\n</body>\n\n</html>\n```\n\n\n## 地图加载完成事件\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>地图加载完成事件</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    #tip {\n        position: absolute;\n        left: 20px;\n        top: 20px;\n        background: #FFF;\n        color: #666;\n        width: 200px;\n        height: 30px;\n        line-height: 30px;\n        border-radius: 3px;\n        padding-left: 5px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <div id=\"tip\">地图正在加载中......</div>\n    <script>\n        function initMap() {\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                center: new TMap.LatLng(39.984104, 116.307503)\n            });\n            //监听地图瓦片加载完成事件\n            map.on(\"tilesloaded\", function () {\n                document.getElementById(\"tip\").innerHTML = \"地图瓦片已加载完成\"\n            })\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 地图导出图片\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>地图导出为图片</title>\n    <style>\n      html,\n      body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n      }\n      #container {\n        position: relative;\n        width: 100%;\n        height: 100vh;\n      }\n      button {\n        position: absolute;\n        left: 10px;\n        top: 10px;\n        z-index: 9999;\n        padding: 10px 14px;\n        box-sizing: border-box;\n        border: none;\n        border-radius: 2px;\n        color: #fff;\n        font-size: 14px;\n        line-height: 14px;\n        transition: .3s;\n      }\n      .disabled {\n        background-color: #979595;\n      }\n      .enable {\n        background-color: #3876ff;\n      }\n    </style>\n  </head>\n  <body>\n    <button onclick=\"screenshot()\" disabled=\"disabled\" id=\"export\" class=\"disabled\">\n      点击导出地图截图\n    </button>\n\n    <div id=\"container\"></div>\n    <script src=\"https://mapapi.qq.com/web/jsapi/jsapi-gl/js/dom-to-image.min.js\"></script>\n    <!-- dom-to-image 官方地址：https://github.com/tsayen/dom-to-image -->\n    <script src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n    <script>\n      var map = new TMap.Map('container', {\n        rotation: 20, // 设置地图旋转角度\n        pitch: 30, // 设置俯仰角度（0~45）\n        zoom: 17,\n          mapStyleId: \"style8\",\n        center: new TMap.LatLng(39.984104, 116.307503), // 设置地图中心点坐标\n        baseMap: [\n          { type: 'vector' }, // 设置矢量底图\n        ],\n        renderOptions: {\n          // renderOptions文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap#10\n          preserveDrawingBuffer: true, // 保留地图的渲染缓冲 默认false\n        },\n      });\n      function screenshot() {\n        // 截图操作\n        var node = document.getElementById('container');\n        domtoimage\n          .toPng(node)\n          .then(function (dataUrl) {\n            // 导出图片\n            var link = document.createElement('a');\n            link.download = 'image.png';\n            link.href = dataUrl;\n            link.click();\n          })\n          .catch(function (error) {\n            console.error('domtoimage 出现问题! ', error);\n          });\n      }\n\n      map.on('tilesloaded', function () {\n        // 当地图容器中可见的瓦片加载完后会触发此事件。\n        var button = document.querySelector('#export');\n        button.disabled = false;\n        button.className = 'enable';\n      });\n    </script>\n  </body>\n</html>\n```\n\n\n## 地图平滑变化至指定状态\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n\t<title>地图平滑变化至指定状态</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n\thtml,\n\tbody {\n\t\theight: 100%;\n\t\tmargin: 0px;\n\t\tpadding: 0px;\n        overflow: hidden;\n\t}\n\n\t#container {\n        position: relative;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t}\n\t#set-EaseTo{\n\t\tposition: absolute;\n\t\tz-index: 9999;\n\t\tleft:20px;\n\t\ttop:10px;\n\t}\n</style>\n\n<body>\n<div id=\"container\"></div>\n<input type=\"button\" id=\"set-EaseTo\" onclick=\"easeTo()\" value=\"easeTo\">\n<script>\n\tvar center = new TMap.LatLng(39.907093, 116.396875);//设置中心点坐标\n\t//初始化地图\n\tvar map = new TMap.Map(\"container\", {\n\t\tcenter: center,\n\t  zoom:15,\n          mapStyleId: \"style8\",\n\t});\n\tfunction easeTo() {\n\t\tmap.easeTo({zoom:17,rotation:90},{duration: 2000});//平滑缩放,旋转到指定级别\n\t}\n\n</script>\n</body>\n\n</html>\n```\n\n\n## 地图平移\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>地图平移事件</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n    #info{\n        position: absolute;\n        bottom:50px;\n        left:50%;\n        transform: translateX(-50%);\n        background: #FFF;\n        border-radius: 3px;\n        padding: 10px;\n        width: 440px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <div id=\"info\">\n        <h4 id=\"txt\"></h4>\n        <p>当前中心点：<span id=\"position\"></span></p>\n    </div>\n\n    <script>\n        function initMap() {\n            var position = document.getElementById(\"position\");\n            var txt = document.getElementById(\"txt\");\n            var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                center: center\n            });\n            location.innerHTML = map.getCenter().toString();\n            //监听地图开始平移\n            map.on(\"panstart\", function () {\n                txt.innerHTML = \"地图开始平移\"\n            })\n            //监听地图平移\n            map.on(\"pan\",function(){\n                txt.innerHTML = \"地图正在平移\";\n                position.innerHTML = map.getCenter().toString();//获取地图中心点\n            })\n            //监听地图平移结束\n            map.on(\"panend\",function(){\n                txt.innerHTML = \"地图结束平移\";\n            })\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 地图设置缩放焦点\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>地图设置缩放焦点</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #containerOne {\n        width: 100%;\n        height: 45%;\n       \n    }\n    #containerTwo {\n        width: 100%;\n        height: 45%;\n    }\n\n    p{\n        margin: 0;\n        margin-bottom: 20px;\n        text-align: center;\n    }\n</style>\n\n<body>\n    <div id=\"containerOne\"></div>\n    <p>地图一: 根据鼠标/双指位置缩放</p>\n    <div id=\"containerTwo\"></div>\n    <p>地图二：根据地图中心点缩放</p>\n    <script type=\"text/javascript\">\n            var center = new TMap.LatLng(39.984104, 116.307503);\n             //初始化地图一\n             var mapOne = new TMap.Map(\"containerOne\", {\n                center,\n                // 默认缩放，双指中心位置（移动端），鼠标的光标位置（PC端）\n                mapZoomType: TMap.constants.MAP_ZOOM_TYPE.DEFAULT\n            });\n            //初始化地图二\n            var mapTwo = new TMap.Map(\"containerTwo\", {\n                center,\n                // 根据地图中心点缩放（移动端和PC端）\n                mapZoomType: TMap.constants.MAP_ZOOM_TYPE.CENTER\n            });\n\n    </script>\n</body>\n\n</html>\n```\n\n\n## 天空盒\n\n```html\n<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n        <title>天空盒</title>\n        <style>\n            html,\n            body {\n                height: 100%;\n                margin: 0px;\n                padding: 0px;\n                overflow: hidden;\n            }\n\n            #mapContainer {\n                position: relative;\n                width: 100%;\n                height: 100%;\n            }\n\n            .btnContainer {\n                position: absolute;\n                left: 20px;\n                top: 20px;\n                z-index: 10000;\n            }\n\n            .btnContainer button {\n                padding: 10px 14px;\n                box-sizing: border-box;\n                border: none;\n                background-color: #919aac;\n                border-radius: 2px;\n                color: #fff;\n                font-size: 14px;\n                line-height: 14px;\n            }\n\n            .btnContainer button:focus {\n                outline: none;\n            }\n\n            .btnContainer .btn1 {\n                padding: 10px 14px;\n                background: #3876ff;\n                border-radius: 2px;\n                border: none;\n                box-sizing: border-box;\n                font-size: 14px;\n                color: #fff;\n                line-height: 14px;\n                font-family: PingFangSC-Regular;\n            }\n        </style>\n    </head>\n\n    <body>\n        <div class=\"btnContainer\">\n            <button class=\"btn1\">点击切换天空</button>\n        </div>\n        <div id=\"mapContainer\"></div>\n        <script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n        <script>\n            window.onload = initMap;\n\n            var myMap;\n            var skyBoxConfig = [\n                {\n                    src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/skybox_day.png',\n                    horizontal: TMap.constants.IMAGE_DISPLAY.REPEAT,\n                    vertical: TMap.constants.IMAGE_DISPLAY.SCALE,\n                },\n                {\n                    src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/skybox_night.png',\n                    horizontal: TMap.constants.IMAGE_DISPLAY.REPEAT,\n                    vertical: TMap.constants.IMAGE_DISPLAY.SCALE,\n                },\n            ];\n            var index = 0;\n            function initMap() {\n                myMap = new TMap.Map('mapContainer', {\n                    zoom: 17.058177705186978,\n          mapStyleId: \"style8\",\n                    pitch: 80,\n                    rotation: 320.0308641975305,\n                    center: new TMap.LatLng(39.92119128796626, 116.40041656534902),\n                    baseMap: [\n                        {\n                            type: 'vector',\n                            features: ['base', 'building3d']\n                        }\n                    ],\n                    renderOptions: {\n                        skyOptions: skyBoxConfig[index],\n                    }\n                });\n\n                document.querySelector('.btn1').addEventListener('click', () => {\n                    if (index) {\n                        myMap.setMapStyleId('DEFAULT');\n                        myMap.setSkyOptions(skyBoxConfig[0]);\n                        index = 0;\n                    } else {\n                        myMap.setMapStyleId('DARK');\n                        myMap.setSkyOptions(skyBoxConfig[1]);\n                        index = 1;\n                    }\n                });\n            }\n        </script>\n    </body>\n</html>\n```\n\n\n## 实时路况\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>实时路况</title>\n  </head>\n  <script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n  <style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0px;\n      padding: 0px;\n      overflow: hidden;\n    }\n\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n    .control {\n      position: absolute;\n      top: 0px;\n      left: 0px;\n      z-index: 9999;\n      padding: 10px;\n      background-color: white;\n    }\n  </style>\n\n  <body>\n    <div class=\"control\">\n      <p>\n        设置路况底图透明度：<input id=\"range\" type=\"range\" value=\"10\" min=\"0\" max=\"10\" />\n        <span id=\"number\">1</span>\n      </p>\n    </div>\n    <div id=\"container\"></div>\n    <script type=\"text/javascript\">\n      var center = new TMap.LatLng(39.907093, 116.396875);\n      var range = document.querySelector('#range');\n      var number = document.querySelector('#number');\n      var map;\n      // 初始化地图 MapOptions文档地址:https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap#2\n      map = new TMap.Map('container', {\n        zoom: 11, // 设置地图缩放级别\n        center: center, // 设置地图中心点坐标\n        baseMap: [\n          { type: 'vector' }, // 设置矢量底图\n          // traffic底图文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap#7\n          {\n            type: 'traffic',\n            opacity: 1,\n          }, // 设置路况底图\n        ],\n      });\n\n      range.addEventListener('change', function (e) {\n        // 根据范围值改变路况透明度\n        var val = e.target.value / 10;\n\n        number.innerText = val;\n        map.destroy(); // 销毁之前的地图\n        // 重新渲染地图\n        map = new TMap.Map('container', {\n          zoom: 11,\n          mapStyleId: \"style8\",\n          center: center,\n          baseMap: [\n            { type: 'vector' },\n            {\n              type: 'traffic',\n              opacity: val,\n            },\n          ],\n        });\n      });\n    </script>\n  </body>\n</html>\n```\n\n\n## 异步加载地图\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>异步加载地图</title>\n</head>\n\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n</style>\n\n<body>\n    <div id=\"container\"></div>\n    <script>\n        function initMap() {\n            var map = new TMap.Map(\"container\", {\n                pitch: 45,\n                zoom: 12,\n          mapStyleId: \"style8\",\n                center: new TMap.LatLng(39.984104, 116.307503)\n            });\n        }\n        function loadScript() {\n            //创建script标签，并设置src属性添加到body中\n            var script = document.createElement(\"script\");\n            script.type = \"text/javascript\";\n            script.src = \"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}&callback=initMap\";\n            document.body.appendChild(script);\n        }\n        window.onload = loadScript;\n    </script>\n</body>\n\n</html>\n```\n\n\n## 点击地图拾取POI\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n  <title>点击地图拾取POI</title>\n  <style>\n    html,\n    body {\n      margin: 0;\n      padding: 0;\n      overflow: hidden;\n      height: 100%;\n    }\n\n    #mapContainer {\n      position: relative;\n      height: 100%;\n      width: 100%;\n    }\n  </style>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n\n<body onload=\"init()\">\n  <div id='mapContainer'></div>\n  <script>\n    var map;\n\n    function init() {\n\n      var drawContainer = document.getElementById('mapContainer');\n\n      var center = new TMap.LatLng(39.953416, 116.380945);\n\n      map = new TMap.Map(drawContainer, {\n        zoom: 13,\n          mapStyleId: \"style8\",\n        pitch: 40,\n        center: center\n      });\n\n      // 创建信息窗\n      let info = new TMap.InfoWindow({\n        map,\n        position: map.getCenter()\n      }).close();\n      map.on('click', (evt) => {\n        // 获取click事件返回的poi信息\n        let poi = evt.poi;\n        if (poi) {\n          // 拾取到POI\n          info.setContent(poi.name).setPosition(poi.latLng).open();\n        } else {\n          // 没有拾取到POI\n          info.close();\n        }\n      });\n\n    }\n  </script>\n</body>\n\n</html>\n```\n\n\n## 点击地图拾取坐标\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>点击地图拾取坐标</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n    #info{\n        position: absolute;\n        left: 20px;\n        top: 20px;\n        font-size: 14px;\n        background: #FFF;\n        width: 270px;\n        padding: 10px;\n        border-radius: 3px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <div id=\"info\">当前点击坐标为：<span id=\"position\"></span></div>\n    <script>\n        function initMap() {\n            var position = document.getElementById(\"position\");\n\n            var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                center: center\n            });\n            \n            //绑定点击事件\n            map.on(\"click\",function(evt){\n                var lat = evt.latLng.getLat().toFixed(6);\n                var lng = evt.latLng.getLng().toFixed(6);\n                position.innerHTML = lat + \",\" + lng;\n            })\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 粒子路况\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>粒子路况</title>\n  </head>\n  <script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n  <style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0px;\n      padding: 0px;\n      overflow: hidden;\n    }\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n  </style>\n\n  <body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <script type=\"text/javascript\">\n      function initMap() {\n        var center = new TMap.LatLng(39.960957089008026, 116.44548038611174);\n        // 初始化地图  MapOptions文档地址:https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap#2\n        new TMap.Map('container', {\n          zoom: 11,\n          mapStyleId: \"style8\",\n          center: center, // 设置地图中心点坐标baseMap: [\n            { type: 'vector' }, // 设置矢量底图\n            {\n              // traffic底图文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap#7\n              type: 'traffic',\n              features: ['base', 'flow'], // 路况图要素类型\n              opacity: 0.2, // 路况线网图的透明度\n            },\n          ],\n        });\n      }\n    </script>\n  </body>\n</html>\n```\n\n\n## 设置_获取地图中心\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>设置/获取地图中心点</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n    #info{\n        position: absolute;\n        background: #FFF;\n        width:300px;\n        height: 25px;\n        padding: 20px;\n        z-index: 9999;\n        top: 30px;\n        left: 30px;\n    }\n    #getcenter{\n        position: absolute;\n        left:20px;\n        top:10px;\n\n    }\n    #setcenter{\n        position: absolute;\n        left:110px;\n        top:10px;\n\n    }\n</style>\n\n<body>\n    <div id=\"container\"></div>\n    <div id=\"info\">\n        <input type=\"button\" id=\"getcenter\" onclick=\"getCenter()\" value=\"getCenter\">\n        <input type=\"button\" id=\"setcenter\" onclick=\"setCenter()\" value=\"setCenter\">\n        <p id=\"center-info\">当前地图中心为: 39.984104, 116.307503</p>\n    </div>\n    <script>\n        var centerInfo = document.getElementById(\"center-info\");\n\n        var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标\n        //初始化地图\n        var map = new TMap.Map(\"container\", {\n            center: center\n        });\n        //获取地图中心点事件\n        function getCenter() {            \n            var mapCenter = map.getCenter(); //获取地图中心点坐标\n            centerInfo.innerHTML = \"当前地图中心为: \" + mapCenter.getLat().toFixed(6) + \",\" + mapCenter.getLng().toFixed(6);\n        }\n        //设置地图中心点事件\n        function setCenter() {\n            map.setCenter(new TMap.LatLng(39.908802,116.397502));//坐标为天安门\n            centerInfo.innerHTML = \"当前地图中心为: 39.908802,116.397502\";\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 设置_获取地图显示范围\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>设置/获取地图显示范围</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style>\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n    #info{\n        height: 50px;\n        width: 600px;\n        padding: 10px;\n        background: #FFF;\n        position: absolute;\n        top:20px;\n        left: 10px;\n        border-radius: 5px;\n        font-size: 14px;\n    }\n    p{\n        margin: 0;\n        margin-bottom: 10px;\n    }\n    #fit-bounds{\n        position: absolute;\n        right: 40px;\n        top: 5px;\n        padding: 5px;\n        z-index: 9999;\n    }\n</style>\n<body>\n    <div id=\"container\"></div>\n    <div id=\"info\">\n        <p>当前地图中心点：<span id=\"position\">39.984104, 116.307503</span></p>\n        <p><span id=\"bounds\"></span></p>\n        <!-- 地图图层上的button需要设置z-index>1000 -->\n        <input type=\"button\" id=\"fit-bounds\" onclick=\"fitBounds()\" value=\"fitBounds\">\n    </div>\n    \n    <script>\n            var position = document.getElementById(\"position\");\n            var bounds = document.getElementById(\"bounds\");\n\n            var ne = new TMap.LatLng(39.96693, 116.49369);//东北角坐标\n            var sw = new TMap.LatLng(39.86000, 116.28666);//西南角坐标\n            var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标\n            //初始化地图\n            var map = new TMap.Map(\"container\", {\n                center: center\n            });\n            //监听可视范围改变事件\n            map.on(\"bounds_changed\",function(){   \n                \n                var mapCenter = map.getCenter(); //获取地图中心点坐标          \n                position.innerHTML = mapCenter.getLat().toFixed(6) + \",\" + mapCenter.getLng().toFixed(6);\n                var mapBounds = map.getBounds(); //获取当前地图的视野范围\n                if(mapBounds){\n                    var nothEast =\"当前可视区域范围：东北/右上:[\" + mapBounds.getNorthEast().getLat().toFixed(6) + \",\" + mapBounds.getNorthEast().getLng().toFixed(6)+\"] ；\";\n                    var southWest =\"西南/左下:[\" + mapBounds.getSouthWest().getLat().toFixed(6) + \",\" + mapBounds.getSouthWest().getLng().toFixed(6)+\"]\";\n                    bounds.innerHTML = nothEast + southWest;\n                }    \n            })\n            function fitBounds(){\n                    var latLngBounds = new TMap.LatLngBounds(sw, ne)\n                    map.fitBounds(latLngBounds); //根据指定的范围调整地图视野\n                }\n        </script>\n</body>\n</html>\n```\n\n\n## 设置_获取地图视角\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>设置/获取地图视角</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n    #info{\n        position: absolute;\n        background: #FFF;\n        width:300px;\n        height: 60px;\n        padding: 20px;\n        z-index: 9999;\n        top: 30px;\n        left: 30px;\n    }\n    #set-pitch{\n        position: absolute;\n        left:20px;\n        top:10px;\n\n    }\n    #set-rotate{\n        position: absolute;\n        left:110px;\n        top:10px;\n\n    }\n    p{\n        margin: 0;\n        \n    }\n    #pitch-info{\n        margin-top: 20px;\n        margin-bottom: 10px;\n    }\n</style>\n\n<body>\n    <div id=\"container\"></div>\n    <div id=\"info\">\n        <input type=\"button\" id=\"set-pitch\" onclick=\"setPitch()\" value=\"setPitch\">\n        <input type=\"button\" id=\"set-rotate\" onclick=\"setRotate()\" value=\"setRotate\">\n        <p id=\"pitch-info\">当前地图俯仰角度为: 10</p>\n        <p id=\"rotate-info\">当前地图旋转角度为: 20</p>\n    </div>\n    <script>\n        var pitchInfo = document.getElementById(\"pitch-info\");\n        var rotateInfo = document.getElementById(\"rotate-info\");\n        var txt = document.getElementById(\"txt\");\n        var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标\n        //初始化地图\n        var map = new TMap.Map(\"container\", {\n            rotation: 20,//设置地图旋转角度\n            pitch:10, //设置地图俯仰角度\n            center: center\n        });\n\n        //监听地图旋转事件\n        map.on(\"rotate\",function(){\n            var rotation = map.getRotation(); //获取地图旋转角度\n            rotateInfo.innerHTML = \"当前地图旋转角度为: \" + parseInt(rotation);\n        })\n            \n        //监听地图俯仰角度变化事件\n        map.on(\"pitch\",function(){\n            var pitch = map.getPitch(); //获取地图旋转角度\n            pitchInfo.innerHTML = \"当前地图俯仰角度为: \" + parseInt(pitch);\n        })\n\n        function setRotate() {            \n            map.setRotation(90);//设置地图旋转角度\n        }\n\n        function setPitch() {\n            map.setPitch(30);//设置地图俯仰角度\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 设置地图中心点偏移\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>map中心点偏移</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0px;\n      padding: 0px;\n      position: relative;\n      overflow: hidden;\n    }\n\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n    #container-center {            \n      width: 10px;            \n      height: 10px;            \n      background-color: blue;            \n      position: absolute;            \n      top: 0;            \n      bottom: 0;            \n      left: 0;            \n      right: 0;            \n      margin: auto;        \n    }\n</style>\n\n<body onload=\"initMap()\">\n\t<div id=\"container\"></div>\n\t<div id=\"container-center\"></div>\n\t<script type=\"text/javascript\">\n\t\tvar map;\n\n\t\tfunction initMap() {\n\t\t\tvar center = new TMap.LatLng(40.040452, 116.273486);\n\t\t\t//初始化地图\n\t\t\tmap = new TMap.Map(\"container\", {\n\t\t\t\tzoom: 17,\n          mapStyleId: \"style8\",\n\t\t\t\tcenter: center, //设置地图中心点坐标\n\t\t\t\toffset: { // 中心点偏移\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 100,\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar markerGeo = {\n\t\t\t\tid: 'center',\n\t\t\t\tposition: map.getCenter(),\n\t\t\t};\n\n\t\t\t// 创建一个位于地图中心点的marker\n\t\t\tmarkerLayer = new TMap.MultiMarker({\n\t\t\t\tmap: map,\n\t\t\t\tgeometries: [\n\t\t\t\t\tmarkerGeo\n\t\t\t\t]\n\t\t\t});\n\n\t\t\t// 监听中心点变化事件，更新marker的位置\n\t\t\tmap.on('center_changed', () => {\n\t\t\t\tmarkerGeo.position = map.getCenter();\n\t\t\t\tmarkerLayer.updateGeometries([markerGeo]);\n\t\t\t});\n\t\t}\n\t</script>\n</body>\n\n</html>\n```\n\n\n## 设置地图显示比例\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>地图显示比例设置</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n\t\t\theight: 100%;\n\t\t\tmargin: 0px;\n\t\t\tpadding: 0px;\n\t\t\tposition: relative;\n            overflow: hidden;\n    }\n\n    #container {\n            position: relative;\n\t\t\twidth: 100%;\n\t\t\theight: 100%;\n    }\n    #btn {\n\t\t\tposition: absolute;\n      \t\ttop: 30px;\n      \t\tleft: 30px;\n\t\t\tz-index: 1001;\n\t\t\tpadding: 6px 8px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n\t\t<input type=\"button\" id=\"btn\" onclick=\"changeScale()\" value=\"设置显示比例为2\">\n\t\t<script type=\"text/javascript\">\n\t\t\tvar map, scale = 1;\n\n\t\t\tfunction initMap() {\n\t\t\t\tvar center = new TMap.LatLng(39.984104, 116.307503);\n\t\t\t\t//初始化地图\n\t\t\t\tmap = new TMap.Map(\"container\", {\n                    zoom:12,\n          mapStyleId: \"style8\",\n                    center: center,//设置地图中心点坐标\n\t\t\t\t});\n\n\t\t\t\tmap.on('scale_changed', (e) => {\n\t\t\t\t\tconsole.log(e);\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\t// 改变地图显示比例\n\t\t\tfunction changeScale() {\n\t\t\t\tvar btn = document.getElementById('btn');\n\t\t\t\tbtn.value = `设置显示比例为${scale}`;\n\t\t\t\tif (scale === 1) {\n\t\t\t\t\tscale = 2;\n\t\t\t\t} else {\n\t\t\t\t\tscale = 1;\n\t\t\t\t}\n\t\t\t\tmap.setScale(scale);\n\t\t\t}\n    </script>\n</body>\n\n</html>\n```\n\n\n## 设置地图边界范围\n\n```html\n<!DOCTYPE html>\n<html>\n\n<head>\n\t<title>设置地图边界范围</title>\n\t<meta charset='utf-8'>\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n\t<style>\n\t\t* {\n\t\t\tpadding: 0px;\n\t\t\tmargin: 0px;\n\t\t}\n\n\t\t#mapContainer {\n            position: relative;\n\t\t\twidth: 100vw;\n\t\t\theight: 100vh;\n        }\n        input{\n            position: absolute;\n            left: 30px;\n            top: 30px;\n            z-index: 9999;\n        }\n\t</style>\n</head>\n\n<body>\n\n\t<div id='mapContainer'></div>\n    <input id=\"btn\" type=\"button\" value=\"点击设置boundary\">\n\n\t<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n\t<script>\n\t\twindow.onload = init;\n\n\t\tvar map, polygon;\n\n\t\tfunction init() {\n\t\t\tlet sw = new TMap.LatLng(39.744154,116.124115);\n\t\t\tlet ne = new TMap.LatLng(40.104336,116.691284);\n\t\t\tlet boundary = new TMap.LatLngBounds(sw, ne);\n\n\t\t\tmap = new TMap.Map('mapContainer', {\n\t\t\t\tzoom: 10,\n          mapStyleId: \"style8\",\n\t\t\t\tcenter: new TMap.LatLng(39.919216,116.328735)\n\t\t\t});\n\n\t\t\tpolygon = new TMap.MultiPolygon({\n\t\t\t\tmap,\n\t\t\t\tgeometries: [{\n\t\t\t\t\tpaths: [\n\t\t\t\t\t\tboundary.getSouthWest(),\n\t\t\t\t\t\tboundary.getSouthEast(),\n\t\t\t\t\t\tboundary.getNorthEast(),\n\t\t\t\t\t\tboundary.getNorthWest()\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t});\n\n            let btn = document.getElementById('btn');\n            btn.addEventListener('click', () => {\n                map.setBoundary(boundary);\n            },false);\n\t\t}\n\t</script>\n</body>\n\n</html>\n```\n\n\n## 设置控件位置及样式\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>地图控件设置</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        position: relative;\n    }\n\n    #container {\n        width: 100%;\n        height: 100%;\n    }\n    input[type=\"button\"] {\n        position: absolute;\n        z-index: 1001;\n        width: 160px;\n        padding: 6px 0;\n        font-size: 14px;\n    }\n    #btn-position-default {\n        top: 30px;\n        left: 30px;\n    }\n    #btn-position-right-bottom {\n        top: 30px;\n        left: 200px;\n    }\n  \t#btn-remove {\n      \ttop: 80px;\n      \tleft: 30px;\n  \t}\n  \t#btn-add {\n        top: 80px;\n        left: 200px;\n  \t}\n  \t#btn-add-class {\n      \ttop: 130px;\n      \tleft: 30px;\n  \t}\n  \t#btn-remove-class {\n      \ttop: 130px;\n      \tleft: 200px;\n  \t}\n    #btn-display-zoom-number {\n      \ttop: 180px;\n      \tleft: 30px;\n    }\n    #btn-hide-zoom-number {\n      \ttop: 180px;\n      \tleft: 200px;\n  \t}\n    .control .tmap-zoom-control{\n      \tbackground-color:#F2F2F2;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"container\"></div>\n\t\t<input type=\"button\" id=\"btn-position-default\" onclick=\"setPosition('topRight')\" value=\"缩放控件设为右上角\">\n\t\t<input type=\"button\" id=\"btn-position-right-bottom\" onclick=\"setPosition('bottomRight')\" value=\"缩放控件设为右下角\">\n\t\t<input type=\"button\" id=\"btn-remove\" onclick=\"removeControl()\" value=\"移除缩放控件\">\n\t\t<input type=\"button\" id=\"btn-add\" onclick=\"addControl()\" value=\"添加缩放控件\">\n\t\t<input type=\"button\" id=\"btn-add-class\" onclick=\"setClassName('control')\" value=\"缩放控件背景变灰\">\n\t\t<input type=\"button\" id=\"btn-remove-class\" onclick=\"setClassName('')\" value=\"缩放控件恢复默认\">\n        <input type=\"button\" id=\"btn-display-zoom-number\" onclick=\"displayZoomNumber()\" value=\"缩放控件显示缩放级别\">\n        <input type=\"button\" id=\"btn-hide-zoom-number\" onclick=\"hideZoomNumber()\" value=\"缩放控件不显示缩放级别\">\n\t\t<script type=\"text/javascript\">\n\t\t\tvar map, control;\n\n\t\t\tfunction initMap() {\n\t\t\t\tvar center = new TMap.LatLng(39.984104, 116.307503);\n\t\t\t\t//初始化地图\n\t\t\t\tmap = new TMap.Map(\"container\", {\n\t\t\t\t\t\tzoom: 12,\n          mapStyleId: \"style8\",\n\t\t\t\t\t\tcenter: center,//设置地图中心点坐标\n\t\t\t\t});\n\n\t\t\t\t// 获取缩放控件实例\n\t\t\t\tcontrol = map.getControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM);\n\n\t\t\t\t// 监听控件添加和移除事件\n\t\t\t\tmap.on('control_added', (e) => {\n\t\t\t\t\tconsole.log(e);\n\t\t\t\t});\n\t\t\t\tmap.on('control_removed', (e) => {\n\t\t\t\t\tconsole.log(e);\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\t// 设置控件位置\n\t\t\tfunction setPosition(position) {\n\t\t\t\tif (!control) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tswitch(position) {\n\t\t\t\t\tcase 'topRight':\n\t\t\t\t\t\tcontrol.setPosition(TMap.constants.CONTROL_POSITION.TOP_RIGHT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'bottomRight':\n\t\t\t\t\t\tcontrol.setPosition(TMap.constants.CONTROL_POSITION.BOTTOM_RIGHT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 移除缩放控件\n\t\t\tfunction removeControl() {\n\t\t\t\tif (!map.getControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM)) { // 如果map上不存在该控件则直接返回\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmap.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM);\n\t\t\t}\n\n\t\t\t// 把存储的缩放控件添加到地图上\n\t\t\tfunction addControl() {\n\t\t\t\tmap.addControl(control);\n\t\t\t}\n\n\t\t\t// 为缩放控件添加class，控制样式\n\t\t\tfunction setClassName(name) {\n\t\t\t\tif (!control) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcontrol.setClassName(name);\n\t\t\t}\n            \n            // 缩放控件显示缩放级别\n            function displayZoomNumber() {\n              control.setNumVisible(true);\n            }\n\n            // 缩放控件不显示缩放级别\n            function hideZoomNumber() {\n              control.setNumVisible(false);\n            }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 设置鼠标样式\n\n```html\n<!DOCTYPE html>\n<html>\n\n<head>\n    <title>自定义鼠标样式</title>\n    <meta charset='utf-8'>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n    <style>\n        html,\n        body {\n            height: 100%;\n            margin: 0px;\n            padding: 0px;\n        }\n\n        #container {\n            width: 100%;\n            height: 100%;\n        }\n\n        ul {\n            margin: 0;\n            padding: 0;\n            list-style: none;\n        }\n\n        .input-card {\n            display: flex;\n            flex-direction: column;\n            min-width: 0;\n            word-wrap: break-word;\n            background-color: #fff;\n            background-clip: border-box;\n            border-radius: .25rem;\n            border-width: 0;\n            border-radius: 0.4rem;\n            box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);\n            position: fixed;\n            bottom: 1rem;\n            right: 1rem;\n            -ms-flex: 1 1 auto;\n            flex: 1 1 auto;\n            padding: 0.75rem 1.25rem;\n            width: 110px;\n            z-index: 3000;\n        }\n    </style>\n    <script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n</head>\n\n<body>\n    <div id=\"container\" class=\"map\"></div>\n    <ul id=\"cursorList\" class=\"input-card\">\n        <li> 选择鼠标样式 </li>\n        <li>\n            <input name=\"cursor\" value=\"default\" type=\"radio\" onclick=\"switchCursor(this)\">\n            <span>default</span>\n        </li>\n        <li>\n            <input name=\"cursor\" value=\"pointer\" type=\"radio\" onclick=\"switchCursor(this)\" checked>\n            <span>pointer</span>\n        </li>\n        <li>\n            <input name=\"cursor\" value=\"move\" type=\"radio\" onclick=\"switchCursor(this)\">\n            <span>move</span>\n        </li>\n        <li>\n            <input name=\"cursor\" value=\"progress\" type=\"radio\" onclick=\"switchCursor(this)\">\n            <span>progress</span>\n        </li>\n        <li>\n            <input name=\"cursor\" value=\"url('https://industry.map.qq.com/cloud/webDemoCente/gl/source/custom_cursor.png'),auto\" type=\"radio\" onclick=\"switchCursor(this)\">\n            <span>自定义样式</span>\n        </li>\n    </ul>\n    <script type=\"text/javascript\">\n        //初始化地图对象，加载地图\n        map = new TMap.Map('container', {\n            zoom: 18,\n          mapStyleId: \"style8\",\n            center: new TMap.LatLng(39.98527631559586, 116.37631948391004),\n        });\n        map.setCursorStyle(\"pointer\");\n        //自定义鼠标样式图标\n        function switchCursor(target) {\n            var value = target.value;\n            map.setCursorStyle(value);\n        }\n    </script>\n</body>\n\n</html>\n```\n\n\n## 调整图层顺序\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\"/>\n    <title>调整图层顺序</title>\n</head>\n<script\n        charset=\"utf-8\"\n        src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"\n></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #mapContainer {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    #moveLayerBtn {\n        position: absolute;\n        left: 40px;\n        top: 40px;\n        z-index: 9999;\n    }\n\n    #moveLayerResetBtn {\n        position: absolute;\n        left: 40px;\n        top: 80px;\n        z-index: 9999;\n    }\n</style>\n\n<body onload=\"initMap()\">\n<div id=\"mapContainer\">\n    <button id=\"moveLayerBtn\" onclick=\"moveLayer()\">移动到文字图层上方</button>\n    <button id=\"moveLayerResetBtn\" onclick=\"moveReSet()\">移动到基础底图上方</button>\n</div>\n<script type=\"text/javascript\">\n  var imageTileLayer\n  var map\n\n  function initMap () {\n    var center = new TMap.LatLng(26.870355, 100.239704) //设置中心点坐标\n    //初始化地图\n    map = new TMap.Map('mapContainer', {\n      center: center,\n      zoom: 15,\n          mapStyleId: \"style8\",\n      maxZoom: 16,\n    })\n    //初始化imageTileLayer\n    imageTileLayer = new TMap.ImageTileLayer({\n      getTileUrl: function (x, y, z) {\n        //拼接瓦片URL\n        var url =\n          'https://3gimg.qq.com/visual/lbs_gl_demo/image_tiles_layers/' +\n          z +\n          '/' +\n          x +\n          '_' +\n          y +\n          '.png'\n        return url\n      },\n      tileSize: 256, //瓦片像素尺寸\n      minZoom: 14, //显示自定义瓦片的最小级别\n      maxZoom: 16, //显示自定义瓦片的最大级别\n      visible: true, //是否可见\n      zIndex: 5000, //层级高度（z轴）\n      opacity: 0.95, //图层透明度：1不透明，0为全透明\n      map: map, //设置图层显示到哪个地图实例中\n    })\n  }\n\n  function moveLayer () {\n    var layerId = imageTileLayer.getId() // 获取图层ID\n    // 根据输入 LAYER_LEVEL 常量调整 layerId 对应图层的渲染层级 ，其中layerId可以通过图层getId方法获取。TMap.constants.LAYER_LEVEL 代表图层级别常量，见帮助文档（https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap）\n    map.moveLayer(layerId, TMap.constants.LAYER_LEVEL.TEXT)\n  }\n    //  移动图层至基础图层之上\n  function moveReSet () {\n    var layerId = imageTileLayer.getId() // 获取图层ID\n    // 根据输入 LAYER_LEVEL 常量调整 layerId 对应图层的渲染层级 ，其中layerId可以通过图层getId方法获取。TMap.constants.LAYER_LEVEL 代表图层级别常量，见帮助文档（https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap）\n    map.moveLayer(layerId, TMap.constants.LAYER_LEVEL.BASE)\n\nFile v1.5.2:references/jsapi-guide/jsapigl/demos/点标记&文本标记.md\n\n# 点标记&文本标记 Demo 合集\n\n> 本文件合并自 19 个原始 demo HTML，每节为一个独立可运行示例。使用时把对应代码块中的 JS 部分套入标准 HTML 骨架（见 `jsapi-guide/README.md` 的「HTML 生成示例」，底图 `<script src=\"https://map.qq.com/api/gljs?v=1&key={TMAP_KEY}\"></script>`），或直接整块复制替换 `<body>` 内容。\n\n\n## Marker文本背景色\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>设置Marker文本背景</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #mapContainer {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    .btnContainer {\n        position: absolute;\n        left: 20px;\n        top: 20px;\n        z-index: 10000;\n    }\n\n    .btnContainer button {\n        padding: 10px 14px;\n        box-sizing: border-box;\n        border: none;\n        background-color: #3876ff;\n        border-radius: 2px;\n        color: #fff;\n        font-size: 14px;\n        line-height: 14px;\n        margin-bottom: 10px;\n    }\n</style>\n\n<body>\n    <div class=\"btnContainer\">\n        <button class=\"btn1\">Marker背景样式1</button>\n        <button class=\"btn2\">Marker背景样式2</button>\n    </div>\n    <div id=\"mapContainer\"></div>\n    <script>\n        var center = new TMap.LatLng(40.040074, 116.273519); // 设置中心点坐标\n        var centerHeight = new TMap.LatLng(40.040074, 116.273519, 100); // 带高度的坐标\n        // 初始化地图\n        var map = new TMap.Map('mapContainer', {\n            center: center,\n            zoom: 17,\n          mapStyleId: \"style8\",\n        });\n        // 初始化Marker\n        var marker = new TMap.MultiMarker({\n            id: 'marker-layer',\n            map: map,\n            styles: {\n                marker: new TMap.MarkerStyle({\n                    offset:{x:0, y:40},\n                    color:'#3876ff',\n                    backgroundColor: 'rgba(204, 134, 108,0.6)',\n                    backgroundBorderColor: 'rgba(227, 200, 171,1.0)',\n                    backgroundBorderRadius: 20,\n                    backgroundBorderWidth: 4,\n                    padding:'5px 15px'\n                }),\n            },\n            geometries: [\n                {\n                    id: 'marker', // 点图形数据的标志信息\n                    styleId: 'marker', // 样式id\n                    position: center, // 标注点位置\n                    content: '腾讯北京总部', // 标注文本\n                    properties: {\n                        // 标注点的属性数据\n                        title: 'marker',\n                    },\n                },\n            ],\n        });\n        document.querySelector('button.btn1').onclick = function () {\n            marker.setStyles({\n                'marker': new TMap.MarkerStyle({\n                    offset:{x:0, y:40}, // 标注点文本文字基于direction方位的偏移量\n                    color:'#3876ff', // 字体颜色\n                    backgroundColor: 'rgba(204, 134, 108,0.6)', // 文本背景颜色\n                    backgroundBorderColor: 'rgba(227, 200, 171,1.0)', // 文本背景框边线颜色\n                    backgroundBorderRadius: 20, // 文本背景框圆角\n                    backgroundBorderWidth: 4, // 文字背景框边线宽度\n                    padding:'5px 15px', // 标注点文字背景框内边距，单位为像素，属性支持接受1～2个值，规则符合css规范\n                })\n            });\n        };\n        document.querySelector('button.btn2').onclick = function () {\n            marker.setStyles({\n                'marker': new TMap.MarkerStyle({\n                    width: 30, // 标注点图片的宽度\n                    height: 40, // 标注点图片的高度\n                    color:'#FFFFFF',\n                    offset:{x:0, y:40}, \n                    \"src\": 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png',\n                    size: 16,\n                    backgroundColor: '#68b8ec',\n                    backgroundWidth: 120, // 标注点文本背景的宽度\n                    backgroundHeight: 30, // 标注点文本背景的高度\n                    backgroundBorderColor: '#3470a1', // 文字背景框边线颜色\n                    backgroundBorderRadius: 5,\n                    backgroundBorderWidth: 4,\n                })\n            });\n        };\n    </script>\n</body>\n\n</html>\n```\n\n\n## Marker随地图放大缩小\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>Marker自动缩放</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0;\n        padding: 0;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    .btnContainer {\n        position: absolute;\n        left: 20px;\n        top: 20px;\n        z-index: 10000;\n    }\n\n    .btnContainer button {\n        padding: 10px 14px;\n        box-sizing: border-box;\n        border: none;\n        background-color: #3876ff;\n        border-radius: 2px;\n        color: #fff;\n        font-size: 14px;\n        line-height: 14px;\n        margin-bottom: 10px;\n    }\n</style>\n\n<body>\n    <div class=\"btnContainer\">\n        <button class=\"btn1\" onclick=\"onOff()\">开关Marker自动缩放功能</button>\n    </div>\n    <div id=\"container\"></div>\n    <script type=\"text/javascript\">\n        var center = new TMap.LatLng(39.98210863924864, 116.31310899739151);\n\n        // 初始化地图\n        var map = new TMap.Map('container', {\n            zoom: 17,\n          mapStyleId: \"style8\",\n            center: new TMap.LatLng(39.98210863924864, 116.31310899739151), // 设置地图中心点坐标，\n            pitch: 0, // 俯仰度\n            rotation: 0, // 旋转角度\n        });\n\n        // MultiMarker文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocMarker\n        var marker = new TMap.MultiMarker({\n            map: map,\n            styles: {\n                // 点标记样式\n                'marker_enableScale': new TMap.MarkerStyle({\n                    width: 20, // 样式宽\n                    height: 30, // 样式高\n                    anchor: { x: 10, y: 30 }, // 描点位置\n                    enableRelativeScale: true, // 是否开启相对缩放\n                    relativeScaleOptions: {\n                        scaleZoom: 17, // 设置marker图片宽高像素单位与zoom级别的瓦片像素相同的层级 如当设置为18时，zoom小于18marker会被缩小直至达到minScale设置的最小缩放倍数，大于时marker直至达到maxScale设置的最大缩放倍数；enableRelativeScale为true时生效，默认18\n                        minScale: 0.5, // 设置marker最小缩放倍数，enableRelativeScale为true时生效，默认0.5\n                        maxScale: 1, // 设置marker最大缩放倍数，enableRelativeScale为true时生效，默认1\n                    }\n                }),\n\n                'marker_disabledScale': new TMap.MarkerStyle({\n                    width: 20, // 样式宽\n                    height: 30, // 样式高\n                    anchor: { x: 10, y: 30 }, // 描点位置\n                    enableRelativeScale: false, // 是否开启相对缩放\n                })\n            },\n            geometries: [\n                // 点标记数据数组\n                {\n                    // 标记位置(纬度，经度，高度)\n                    position: center,\n                    id: 'marker',\n                    styleId: 'marker_enableScale'\n                },\n            ],\n        });\n\n        // 开关Marker自动缩放功能\n        function onOff() {\n            marker.updateGeometries({\n                id: 'marker',\n                position: center,\n                styleId: marker.getGeometries()[0].styleId === 'marker_enableScale' ? 'marker_disabledScale' : 'marker_enableScale'\n            });\n        }\n\n    </script>\n</body>\n\n</html>\n```\n\n\n## marker拖动\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n  <title>拖动marker</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n  html,\n  body {\n    height: 100%;\n    margin: 0px;\n    padding: 0px;\n    overflow: hidden;\n  }\n  #container {\n    position: relative;\n    width: 100%;\n    height: 90%;\n  }\n  #information {\n    margin: 5px;\n  }\n</style>\n\n<body onload=\"initMap()\">\n  <div id=\"container\"></div>\n  <div id=\"information\">点击Marker后选中目标，然后进行拖动。</div>\n  <script type=\"text/javascript\">\n    function initMap() {\n      // 初始化地图\n      const map = new TMap.Map(\"container\", {\n        zoom: 12,\n          mapStyleId: \"style8\",\n        center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标\n\t\t  });\n      const marker = new TMap.MultiMarker({\n        map: map,\n        styles: {\n          \"highlight\": new TMap.MarkerStyle({\n            \"src\": \"https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker-pink.png\"\n          })\n        },\n        geometries: [{ //点标注数据数组\n          \"position\": new TMap.LatLng(39.984104, 116.307503),\n        }, {\n          \"position\": new TMap.LatLng(39.984104, 116.337503),\n        }, {\n          \"position\": new TMap.LatLng(39.984104, 116.367503),\n        }]\n      });\n      // 初始化几何图形及编辑器\n      const editor = new TMap.tools.GeometryEditor({\n        map, // 编辑器绑定的地图对象\n        overlayList: [{\n          overlay: marker, // 可编辑图层\n          id: \"marker\",\n          selectedStyleId: \"highlight\"  // 被选中的marker会变为高亮样式\n        }],\n        actionMode: TMap.tools.constants.EDITOR_ACTION.INTERACT, // 编辑器的工作模式\n        activeOverlayId: \"marker\", // 激活图层\n        selectable: true\n      });\n    }\n  </script>\n  </body>\n</html>\n```\n\n\n## marker轨迹回放-全局模式\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>marker轨迹回放-全局模式</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n</style>\n\n<body>\n<div id=\"container\"></div>\n<script type=\"text/javascript\">\n  var center = new TMap.LatLng(39.984104, 116.307503);\n  // 初始化地图\n  var map = new TMap.Map('container', {\n    zoom: 15,\n          mapStyleId: \"style8\",\n    center: center,\n  });\n\n  var path = [\n    new TMap.LatLng(39.98481500648338, 116.30571126937866),\n    new TMap.LatLng(39.982266575222155, 116.30596876144409),\n    new TMap.LatLng(39.982348784165886, 116.3111400604248),\n    new TMap.LatLng(39.978813710266024, 116.3111400604248),\n    new TMap.LatLng(39.978813710266024, 116.31699800491333),\n  ];\n\n  var polylineLayer = new TMap.MultiPolyline({\n    map, // 绘制到目标地图\n    // 折线样式定义\n    styles: {\n      style_blue: new TMap.PolylineStyle({\n        color: '#3777FF', // 线填充色\n        width: 4, // 折线宽度\n        borderWidth: 2, // 边线宽度\n        borderColor: '#FFF', // 边线颜色\n        lineCap: 'round', // 线端头方式\n        eraseColor: 'rgba(190,188,188,1)',\n      }),\n    },\n    geometries: [\n      {\n        id: 'erasePath',\n        styleId: 'style_blue',\n        paths: path,\n      },\n    ],\n  });\n\n  var marker = new TMap.MultiMarker({\n    map,\n    styles: {\n      'car-down': new TMap.MarkerStyle({\n        width: 40,\n        height: 40,\n        anchor: {\n          x: 20,\n          y: 20,\n        },\n        faceTo: 'map',\n        rotate: 180,\n        src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/car.png',\n      }),\n      start: new TMap.MarkerStyle({\n        width: 25,\n        height: 35,\n        anchor: { x: 16, y: 32 },\n        src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png',\n      }),\n      end: new TMap.MarkerStyle({\n        width: 25,\n        height: 35,\n        anchor: { x: 16, y: 32 },\n        src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png',\n      }),\n    },\n    geometries: [\n      {\n        id: 'car',\n        styleId: 'car-down',\n        position: new TMap.LatLng(39.98481500648338, 116.30571126937866),\n      },\n      {\n        id: 'start',\n        styleId: 'start',\n        position: new TMap.LatLng(39.98481500648338, 116.30571126937866),\n      },\n      {\n        id: 'end',\n        styleId: 'end',\n        position: new TMap.LatLng(39.978813710266024, 116.31699800491333),\n      },\n    ],\n  });\n  // 使用marker 移动接口， https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocMarker\n  marker.moveAlong(\n    {\n      car: {\n        path,\n        speed: 250,\n      },\n    },\n    {\n      autoRotation: true,\n    }\n);\n  marker.on('moving', (e) => {\n    var passedLatLngs = e.car && e.car.passedLatLngs;\n    if (passedLatLngs) {\n      // 使用路线擦除接口 eraseTo, https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocVector\n      polylineLayer.eraseTo(\n        'erasePath',\n        passedLatLngs.length - 1,\n        passedLatLngs[passedLatLngs.length - 1]\n      );\n    }\n  });\n</script>\n</body>\n\n</html>\n```\n\n\n## marker轨迹回放-跟随模式\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n        <title>marker轨迹回放-跟随模式</title>\n    </head>\n    <script\n        charset=\"utf-8\"\n        src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}&libraries=geometry\"\n    ></script>\n    <style type=\"text/css\">\n        html,\n        body {\n            height: 100%;\n            margin: 0px;\n            padding: 0px;\n            overflow: hidden;\n        }\n\n        #container {\n            position: relative;\n            width: 100%;\n            height: 100%;\n        }\n\n        .btnContainer {\n            position: absolute;\n            left: 20px;\n            top: 20px;\n            z-index: 10000;\n        }\n\n        .btnContainer button {\n            padding: 10px 14px;\n            box-sizing: border-box;\n            border: none;\n            background-color: #919aac;\n            border-radius: 2px;\n            color: #fff;\n            font-size: 14px;\n            line-height: 14px;\n        }\n\n        .btnContainer button:focus {\n            outline: none;\n        }\n\n        .btnContainer .btn1 {\n            padding: 10px 14px;\n            background: #3876ff;\n            border-radius: 2px;\n            border: none;\n            box-sizing: border-box;\n            font-size: 14px;\n            color: #fff;\n            line-height: 14px;\n            font-family: PingFangSC-Regular;\n        }\n\n        input {\n            height: 25px;\n        }\n\n        .info {\n            background-color: white;\n            padding: 10px;\n            font-size: 14px;\n        }\n    </style>\n\n    <body>\n        <div class=\"btnContainer\">\n            <button class=\"btn1\">点击小车开始移动</button>\n            <button class=\"btn2\">重置</button>\n            <button class=\"btn3\">暂停</button>\n            <button class=\"btn4\">恢复</button>\n            <p>\n                <input type=\"text\" placeholder=\"请输入限制移动距离\" />\n                <button class=\"btn5\">点击限制移动距离</button>\n            </p>\n            <div class=\"info\">\n                <p></p>\n                <p>当前限制小车最大移动距离：0米</p>\n                <p>当前小车行驶距离：0米</p>\n                <p></p>\n            </div>\n        </div>\n        <div id=\"container\"></div>\n        <script type=\"text/javascript\">\n            var center = new TMap.LatLng(39.983860482192014, 116.30891946495672);\n            // 初始化地图\n            var map = new TMap.Map('container', {\n                zoom: 16,\n          mapStyleId: \"style8\",\n                center\n            });\n\n            var isMoving = false;\n            var roation;\n            var position;\n            var path = [\n                new TMap.LatLng(39.98481500648338, 116.30571126937866),\n                new TMap.LatLng(39.982266575222155, 116.30596876144409),\n                new TMap.LatLng(39.982348784165886, 116.3111400604248)\n            ];\n            var limitDistance = 0; // 限制距离\n            // MultiPolyline文档：https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocVector#1\n            var polylineLayer = new TMap.MultiPolyline({\n                map, // 绘制到目标地图\n                // 折线样式定义\n                styles: {\n                    style_blue: new TMap.PolylineStyle({\n                        color: '#2A88FF', // 线填充色\n                        width: 8, // 折线宽度\n                        borderWidth: 3, // 边线宽度\n                        borderColor: '#0569FF', // 边线颜色\n                        lineCap: 'round', // 线端头方式\n                        showArrow: true\n                    }),\n                    style_gray: new TMap.PolylineStyle({\n                        color: '#ccc', // 线填充色\n                        width: 8, // 折线宽度\n                        borderWidth: 3, // 边线宽度\n                        borderColor: '#FFF', // 边线颜色\n                        lineCap: 'round' // 线端头方式\n                    })\n                },\n                geometries: [\n                    {\n                        id: 'path1',\n                        styleId: 'style_blue',\n                        paths: path\n                    },\n                    {\n                        id: 'path2',\n                        styleId: 'style_blue',\n                        paths: path\n                    }\n                ]\n            });\n            // marker文档：https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocMarker\n            var marker = new TMap.MultiMarker({\n                id: 'car',\n                map,\n                styles: {\n                    'car-down': new TMap.MarkerStyle({\n                        width: 48,\n                        height: 72,\n                        anchor: {\n                            x: 24,\n                            y: 36\n                        },\n                        faceTo: 'map',\n                        rotate: 180,\n                        src: 'https://mapapi.qq.com/web/mapComponents/componentsTest/zyTest/static/model_taxi.png?a=1'\n                    }),\n                    start: new TMap.MarkerStyle({\n                        anchor: {\n                            x: 16,\n                            y: 32\n                        },\n                        src: 'https://mapapi.qq.com/web/miniprogram/demoCenter/images/marker-start.png'\n                    }),\n                    end: new TMap.MarkerStyle({\n                        src: 'https://mapapi.qq.com/web/miniprogram/demoCenter/images/marker-end.png'\n                    })\n                },\n                geometries: [\n                    {\n                        id: 'car',\n                        styleId: 'car-down',\n                        position: path[0]\n                    },\n                    {\n                        id: 'start',\n                        styleId: 'start',\n                        position: path[0]\n                    },\n                    {\n                        id: 'end',\n                        styleId: 'end',\n                        position: path[2]\n                    }\n                ]\n            });\n            function initInfo() {\n                // 初始化全程长度及小车起始坐标\n                var distance = TMap.geometry.computeDistance(path);\n                var fullLength = document.querySelectorAll('.info p')[0];\n                fullLength.innerHTML = '路线全程长度：' + parseNumber(distance, 2) + '米';\n                var currentLatLng = document.querySelectorAll('.info p')[3];\n                currentLatLng.innerHTML =\n                    '当前小车坐标：' +\n                    parseNumber(path[0].lat, 6) +\n                    ',' +\n                    parseNumber(path[0].lng, 6);\n            }\n            initInfo();\n            function parseNumber(value, num) {\n                // 解析数字\n                return parseFloat(value).toFixed(num);\n            }\n            function carMove() {\n                map.off('idle', carMove);\n                marker.moveAlong(\n                    {\n                        car: {\n                            path,\n                            speed: 200\n                        }\n                    },\n                    {\n                        autoRotation: true\n                    }\n                );\n                isMoving = true;\n            }\n            marker.on('move_ended', function () {\n                isMoving = false;\n            });\n            marker.on('move_stopped', function (e) {\n                isMoving = false;\n            });\n            marker.on('moving', function (e) {\n                if (!e.car) return;\n                roation = TMap.geometry.computeHeading(\n                    e.car.passedLatLngs[e.car.passedLatLngs.length - 2],\n                    e.car.passedLatLngs[e.car.passedLatLngs.length - 1]\n                );\n                position = TMap.geometry.computeDestination(\n                    marker.getGeometryById('car').position,\n                    roation,\n                    60\n                );\n                map.easeTo(\n                    {\n                        center: position,\n                        rotation: e.car.angle && e.car.angle,\n                        zoom: 20,\n          mapStyleId: \"style8\",\n                        pitch: 70\n                    },\n                    {\n                        duration: 300\n                    }\n                );\n                // 移动路线置灰\n                polylineLayer.updateGeometries([\n                    {\n                        id: 'path2',\n                        styleId: 'style_gray',\n                        paths: e.car.passedLatLngs\n                    }\n                ]);\n                // 计算当前移动距离\n                var currentDistance = TMap.geometry.computeDistance(e.car.passedLatLngs);\n                if (limitDistance && currentDistance > limitDistance) {\n                    // 大于限制距离 停止移动\n                    marker.stopMove();\n                }\n                // 移动过程中更新小车已行驶距离\n                document.querySelectorAll('.info p')[2].innerHTML =\n                    '当前小车行驶距离：' + parseNumber(currentDistance, 2) + '米';\n                // 移动过程中更新小车当前坐标\n                var movingLatLng = e.car.passedLatLngs[e.car.passedLatLngs.length - 1];\n                document.querySelectorAll('.info p')[3].innerHTML =\n                    '当前小车坐标：' +\n                    parseNumber(movingLatLng.lat, 6) +\n                    ',' +\n                    parseNumber(movingLatLng.lng, 6);\n            });\n            document.querySelector('.btn1').onclick = function () {\n                if (isMoving) return;\n                map.easeTo(\n                    {\n                        zoom: 20,\n          mapStyleId: \"style8\",\n                        rotation: 180,\n                        pitch: 80\n                    },\n                    {\n                        duration: 1000\n                    }\n                );\n                map.on('idle', carMove);\n            };\n\n            document.querySelector('.btn2').onclick = function () {\n                marker.stopMove();\n                isMoving = false;\n                polylineLayer.setGeometries([\n                    {\n                        id: 'path1',\n                        styleId: 'style_blue',\n                        paths: path\n                    },\n                    {\n                        id: 'path2',\n                        styleId: 'style_blue',\n                        paths: path\n                    }\n                ]);\n                marker.setGeometries([\n                    {\n                        id: 'car',\n                        styleId: 'car-down',\n                        position: new TMap.LatLng(39.98481500648338, 116.30571126937866)\n                    },\n                    {\n                        id: 'start',\n                        styleId: 'start',\n                        position: new TMap.LatLng(39.98481500648338, 116.30571126937866)\n                    },\n                    {\n                        id: 'end',\n                        styleId: 'end',\n                        position: new TMap.LatLng(39.982348784165886, 116.3111400604248)\n                    }\n                ]);\n                map.easeTo({\n                    center,\n                    zoom: 16,\n          mapStyleId: \"style8\",\n                    rotation: 0,\n                    pitch: 0\n                });\n            };\n            document.querySelector('.btn3').onclick = function () {\n                marker.pauseMove();\n            };\n            document.querySelector('.btn4').onclick = function () {\n                marker.resumeMove();\n            };\n            document.querySelector('.btn5').onclick = function () {\n                // 限制小车移动距离，0||NAN 不限制\n                if (isMoving) return;\n                var value = parseFloat(document.querySelector('input').value);\n                value ? (limitDistance = value) : (limitDistance = 0);\n                document.querySelectorAll('.info p')[1].innerHTML =\n                    '当前限制小车最大移动距离：' + limitDistance + '米';\n            };\n        </script>\n    </body>\n</html>\n```\n\n\n## 为多个marker添加事件\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>为多个marker添加事件</title>\n</head>\n<script charset=\"utf-8\"\n    src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #container {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    #info {\n        position: absolute;\n        left: 30px;\n        top: 30px;\n        background: #FFF;\n        width: 350px;\n        height: 120px;\n        padding: 10px;\n        border-radius: 3px;\n    }\n\n    p,\n    h4 {\n        margin: 0;\n        padding: 0;\n        margin-bottom: 10px;\n    }\n    h4{\n        margin-top: 30px;\n    }\n    #add {\n        position: absolute;\n        left:10px;\n        top: 10px;\n        z-index: 9999;\n    }\n    #remove{\n        position: absolute;\n        left: 120px;\n        top: 10px;\n        z-index: 9999;\n    }\n</style>\n\n<body>\n    <div id=\"container\"></div>\n    <div id=\"info\">\n        <input type=\"button\" id=\"add\" value=\"绑定点击事件\" onclick=\"addClick()\">\n        <input type=\"button\" id=\"remove\" value=\"解绑点击事件\" onclick=\"removeClick()\">\n        <h4 id=\"txt\"></h4>\n        <p id=\"markerid\">markerID:marker1</p>\n        <p id=\"position\">当前marker位置：39.984104,116.407503</p>\n    </div>\n\n    <script>\n        var txt = document.getElementById(\"txt\");\n        var markerID = document.getElementById(\"markerid\");\n\n        var position = document.getElementById(\"position\");\n\n        var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标\n        //初始化地图\n        var map = new TMap.Map(\"container\", {\n            center: center\n        });\n\n        //初始化marker\n        var marker = new TMap.MultiMarker({\n            id: 'marker-layer',\n            map: map,\n            styles: {\n                \"marker\": new TMap.MarkerStyle({\n                    \"width\": 25,\n                    \"height\": 35,\n                    \"anchor\": { x: 16, y: 32 },\n                    \"src\": 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png'\n                })\n            },\n            geometries: [{\n                \"id\": \"marker1\",\n                \"styleId\": 'marker',\n                \"position\": new TMap.LatLng(39.954104, 116.357503),\n                \"properties\": {\n                    \"title\": \"marker1\"\n                }\n            }, {\n                \"id\": \"marker2\",\n                \"styleId\": 'marker',\n                \"position\": new TMap.LatLng(39.994104, 116.287503),\n                \"properties\": {\n                    \"title\": \"marker2\"\n                }\n            }, {\n                \"id\": \"marker3\",\n                \"styleId\": 'marker',\n                \"position\": new TMap.LatLng(39.984104, 116.307503),\n                \"properties\": {\n                    \"title\": \"marker3\"\n                }\n            }\n\n            ]\n        });\n\n        //监听回调函数（非匿名函数）\n        var eventClick = function (evt) {\n            markerID.innerHTML = \"markerID:\" + evt.geometry.id;\n            position.innerHTML = \"当前marker位置：\" + evt.geometry.position.toString();\n        }\n        function addClick() {\n            txt.innerHTML = \"绑定点击事件\";\n            //监听marker点击事件\n            marker.on(\"click\", eventClick)\n        }\n\n        function removeClick() {\n            txt.innerHTML = \"解绑点击事件\";\n            //移除绑定事件\n            marker.off(\"click\", eventClick);\n        }\n\n    </script>\n</body>\n\n</html>\n```\n\n\n## 图文标记\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>图文标记</title>\n  </head>\n  <script\n    charset=\"utf-8\"\n    src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"\n  ></script>\n  <style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0px;\n      padding: 0px;\n      overflow: hidden;\n    }\n\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n  </style>\n\n  <body onload=\"initMap()\">\n    <div id=\"container\"></div>\n    <script>\n      var map;\n      function initMap() {\n        var center = new TMap.LatLng(39.96636559909425, 116.30113309988496);\n\n        // 初始化地图\n        map = new TMap.Map('container', {\n          zoom: 13,\n          mapStyleId: \"style8\",\n          pitch: 30,\n          center: center, // 设置地图中心点坐标\n          //baseMap: {\n            type: 'vector',\n            features: ['base', 'building3d'], // 隐藏矢量文字\n          },\n        });\n\n        // marker文字在图片外  MultiMarker文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocMarker\n        new TMap.MultiMarker({\n          map: map, // 显示Marker图层的底图\n          styles: {\n            small: new TMap.MarkerStyle({\n              // 点标注的相关样式\n              width: 34, // 宽度\n              height: 46, // 高度\n              anchor: { x: 17, y: 23 }, // 标注点图片的锚点位置\n              src: 'https://mapapi.qq.com/web/lbs/visualizationApi/demo/img/small.png', // 标注点图片url或base64地址\n              color: '#333', // 标注点文本颜色\n              size: 16, // 标注点文本文字大小\n              direction: 'bottom', // 标注点文本文字相对于标注点图片的方位\n              offset: { x: 0, y: 8 }, // 标注点文本文字基于direction方位的偏移属性\n              strokeColor: '#fff', // 标注点文本描边颜色\n              strokeWidth: 2, // 标注点文本描边宽度\n            }),\n            big: new TMap.MarkerStyle({\n              width: 58,\n              height: 76,\n              anchor: { x: 36, y: 32 },\n              src: 'https://mapapi.qq.com/web/lbs/visualizationApi/demo/img/big.png',\n              color: '#333',\n              size: 22,\n              direction: 'bottom',\n              strokeColor: '#fff',\n              offset: { x: 0, y: 10 },\n              strokeWidth: 2,\n            }),\n          },\n          enableCollision: true, // 开启碰撞\n          geometries: [\n            {\n              styleId: 'small', // 对应中的样式id\n              position: new TMap.LatLng(39.9944, 116.33066), // 标注点位置\n              content: '全聚德', // 标注点文本\n            },\n            {\n              styleId: 'big',\n              position: new TMap.LatLng(39.978867, 116.371452),\n              content: '北平楼',\n            },\n            {\n              styleId: 'small',\n              position: new TMap.LatLng(39.92442, 116.29199),\n              content: '大董烤鸭店',\n            },\n            {\n              styleId: 'small',\n              position: new TMap.LatLng(39.97912, 116.30563),\n              content: '白家大院',\n            },\n            {\n              styleId: 'small',\n              position: new TMap.LatLng(39.93282, 116.34813),\n              content: '四世同堂',\n            },\n            {\n              styleId: 'small',\n              position: new TMap.LatLng(39.96305, 116.38794),\n              content: '便宜坊',\n            },\n            {\n              styleId: 'small',\n              position: new TMap.LatLng(39.993057, 116.209706),\n              content: '小吊梨汤',\n            },\n            {\n              styleId: 'small',\n              position: new TMap.LatLng(39.972919, 116.229874),\n              content: '那家山城',\n            },\n          ],\n        });\n\n        // marker文字在图片内\n        new TMap.MultiMarker({\n          map: map,\n          styles: {\n            default: new TMap.MarkerStyle({\n              width: 92, // 宽度\n              height: 92, // 高度\n              anchor: { x: 46, y: 46 }, // 锚点位置\n              src: 'https://mapapi.qq.com/web/lbs/visualizationApi/demo/img/circle.png', // 标注点图片url或base64地址\n              color: '#fff', // 标注点文本颜色\n              size: 22, // 标注点文本文字大小\n              offset: { x: 0, y: 16 }, // 标注点文本文字基于direction方位的偏移属性\n            }),\n          },\n          geometries: [\n            {\n              position: new TMap.LatLng(39.9543498091366, 116.3064286563349), // 标注点位置\n              content: '41', // 标注点文本\n            },\n            {\n              position: new TMap.LatLng(39.9891175495767, 116.28076993243667),\n              content: '34',\n            },\n            {\n              position: new TMap.LatLng(39.95959650879512, 116.26144674251236),\n              content: '9',\n            },\n            {\n              position: new TMap.LatLng(39.96950944017182, 116.34323407250122),\n              content: '7',\n            },\n          ],\n        });\n      }\n    </script>\n  </body>\n</html>\n```\n\n\n## 文本标记开启碰撞避让\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n\t<title>文本标记开启碰撞避让</title>\n</head>\n<script charset=\"utf-8\"\n        src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n\thtml,\n\tbody {\n\t\theight: 100%;\n\t\tmargin: 0px;\n\t\tpadding: 0px;\n        overflow: hidden;\n\t}\n\n\t#mapContainer {\n        position: relative;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t}\n</style>\n\n<body>\n<div id=\"mapContainer\"></div>\n<script>\n\tvar center = new TMap.LatLng(40.040074, 116.273519);//设置中心点坐标\n\tvar centerLabel2 = new TMap.LatLng(40.040074, 116.243519);//设置中心点坐标\n\t//初始化地图\n\tvar map = new TMap.Map('mapContainer', {\n\t\t\tcenter: center,\n\t\t\trotation: 30,\n\t\t\tzoom: 12,\n          mapStyleId: \"style8\",\n\t});\n\t//初始化label\n\tvar label = new TMap.MultiLabel({\n\t\tid: 'label-layer',\n\t\tmap: map,\n\t\tcollisionOptions: {\n          sameSource: true,\n        }, //开启图层内部的文本标注碰撞\n\t\tstyles: {\n\t\t\t\t'label': new TMap.LabelStyle({\n\t\t\t\t'color': '#3777FF', //颜色属性\n\t\t\t\t'size': 20, //文字大小属性\n\t\t\t\t'offset': { x: 0, y: 0 }, //文字偏移属性单位为像素\n\t\t\t\t'angle': 0, //文字旋转属性\n\t\t\t\t'alignment': 'center', //文字水平对齐属性\n\t\t\t\t'verticalAlignment': 'middle' //文字垂直对齐属性\n\t\t\t})\n\t\t},\n\t\tgeometries: [\n\t\t\t{\n\t\t\t\t'id': 'label', //点图形数据的标志信息\n\t\t\t\t'styleId': 'label', //样式id\n\t\t\t\t'position': center, //标注点位置\n\t\t\t\t'content': '腾讯北京总部', //标注文本\n\t\t\t\t'properties': { //标注点的属性数据\n\t\t\t\t\t'title': 'label'\n\t\t\t\t},\n\t\t\t\trank:10 //文本碰撞时的优先级，值越大优先级越高\n\t\t\t},\n\t\t\t{\n\t\t\t\t'id': 'labe2', //点图形数据的标志信息\n\t\t\t\t'styleId': 'label', //样式id\n\t\t\t\t'position': centerLabel2, //标注点位置\n\t\t\t\t'content': '腾讯北京总部(低优先级)', //标注文本\n\t\t\t\t'properties': { //标注点的属性数据\n\t\t\t\t\t'title': 'labe2'\n\t\t\t\t},\n\t\t\t\trank:1 //文本碰撞时的优先级，值越大优先级越高\n\t\t\t}\n\t\t]\n\t});\n  map.rotateTo(0,{duration: 5000})\n</script>\n</body>\n\n</html>\n```\n\n\n## 文本标记样式自定义\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>文本标记样式自定义</title>\n</head>\n<script charset=\"utf-8\"\n    src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style>\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #mapContainer {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    #buttonContainer {\n        position: absolute;\n        left: 30px;\n        top: 30px;\n        z-index: 9999;\n    }\n\n    #buttonContainer input {\n        background: #fff;\n        padding: 10px;\n        width: 120xp;\n        outline-style: none;\n        margin-right: 10px;\n        border-radius: 10px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"buttonContainer\">\n        <input type=\"button\" onclick=\"setStyle('styleOne')\" value=\"设置样式1\">\n        <input type=\"button\" onclick=\"setStyle('styleTwo')\" value=\"设置样式2\">\n    </div>\n    <div id=\"mapContainer\"></div>\n</body>\n\n</html>\n<script>\n    var map = null;\n    var label = null;\n    function initMap() {\n        var center = new TMap.LatLng(40.040074, 116.273519);//设置中心点坐标\n        //初始化地图\n        map = new TMap.Map('mapContainer', {\n            center: center,\n            zoom: 18,\n          mapStyleId: \"style8\",\n        });\n        //初始化label\n        label = new TMap.MultiLabel({\n            id: 'label-layer',\n            map: map,\n            styles: {\n                'label': new TMap.LabelStyle({\n                    'color': '#333', //颜色属性\n                    'size': 20, //文字大小属性\n                    'offset': { x: 0, y: 0 }, //文字偏移属性单位为像素\n                    'angle': 0, //文字旋转属性\n                    'alignment': 'center', //文字水平对齐属性\n                    'verticalAlignment': 'middle' //文字垂直对齐属性\n                })\n            },\n            geometries: [{\n                'id': 'label', //点图形数据的标志信息\n                'styleId': 'label', //样式id\n                'position': center, //标注点位置\n                'content': '腾讯北京总部', //标注文本\n                'properties': { //标注点的属性数据\n                    'title': 'label'\n                }\n            }]\n        });\n    }\n    function setStyle(type) {\n        switch (type) {\n            case 'styleOne':\n                label.setStyles({\n                    'label': new TMap.LabelStyle({\n                        'color': '#333',\n                        'size': 20,\n                        'offset': { x: 0, y: 0 },\n                        'angle': 0,\n                        'alignment': 'center',\n                        'verticalAlignment': 'middle'\n                    })\n                });\n                break;\n            case 'styleTwo':\n                label.setStyles({\n                    'label': new TMap.LabelStyle({\n                        'color': '#FF0000',\n                        'size': 16,\n                        'offset': { x: 2, y: 10 },\n                        'angle': 45,\n                        'alignment': 'left',\n                        'verticalAlignment': 'top'\n                    })\n                });\n                break;\n            default: ;\n        }\n    }\n</script>\n```\n\n\n## 文本标记点击事件\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>文本标记点击事件</title>\n</head>\n<script charset=\"utf-8\"\n    src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style>\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #mapContainer {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    #info {\n        display: none;\n        position: absolute;\n        left: 30px;\n        top: 90px;\n        background: #fff;\n        border-radius: 5px;\n        padding: 10px;\n        z-index: 9999;\n    }\n\n    #buttonContainer {\n        position: absolute;\n        left: 30px;\n        top: 30px;\n        z-index: 9999;\n    }\n\n    #buttonContainer input {\n        background: #fff;\n        padding: 10px;\n        width: 120xp;\n        outline-style: none;\n        margin-right: 10px;\n        border-radius: 10px;\n    }\n</style>\n\n<body onload=\"initMap()\">\n    <div id=\"buttonContainer\">\n        <input type=\"button\" id = \"bindClick\" value=\"绑定点击事件\">\n        <input type=\"button\" id = \"unbindClick\" value=\"解绑点击事件\">\n    </div>\n    <div id=\"info\">\n    </div>\n    <div id=\"mapContainer\"></div>\n</body>\n\n</html>\n<script>\n    var map = null;\n    var label = null;\n    var infoDom = document.getElementById('info');\n    var bindBtn = document.getElementById('bindClick');\n    var unbindBtn = document.getElementById('unbindClick');\n    function initMap() {\n        var center = new TMap.LatLng(40.040452,116.274486);//设置中心点坐标\n        //初始化地图\n        map = new TMap.Map('mapContainer', {\n            center: center,\n            zoom: 17,\n          mapStyleId: \"style8\",\n        });\n        //初始化label\n        label = new TMap.MultiLabel({\n            id: 'label-layer',\n            map: map,\n            styles: {\n                'label': new TMap.LabelStyle({\n                    'color': '#3777FF', //颜色属性\n                    'size': 20, //文字大小属性\n                    'offset': { x: 0, y: 0 }, //文字偏移属性单位为像素\n                    'angle': 0, //文字旋转属性\n                    'alignment': 'center', //文字水平对齐属性\n                    'verticalAlignment': 'middle' //文字垂直对齐属性\n                })\n            },\n            geometries: [{\n                'id': 'Tencent', //点图形数据的标志信息\n                'styleId': 'label', //样式id\n                'position': new TMap.LatLng(40.040074, 116.273519), //标注点位置\n                'content': '腾讯北京总部', //标注文本\n                'properties': { //标注点的属性数据\n                    'title': 'Tencent'\n                }\n            },{\n                'id': 'Other',\n                'styleId': 'label',\n                'position':new TMap.LatLng(40.041334, 116.275886),\n                'content': '其他建筑物', \n                'properties': { \n                    'title': 'Other'\n                }\n            }]\n        });\n    }\n    var eventClick = function (res) {\n        var res = res && res.geometry;\n        if (res) {\n            infoDom.style.display = 'block';\n            infoDom.innerHTML = 'label_ID：' + res.id + '; 自定义字段：' + res.properties.title + '; 文本内容：' + res.content + ';坐标：' + res.position.lat + ',' + res.position.lng;\n        }\n    }\n\n    //绑定点击事件\n    bindBtn.addEventListener('click',bindClick,false);\n    function bindClick() {\n        label.on('click', eventClick);\n        bindBtn.removeEventListener('click', bindClick, false); //绑定label点击事件后，解绑绑定按钮（即只绑定一次label）\n        unbindBtn.addEventListener('click',unbindClick,false); //绑定解绑按钮\n    }\n    //解绑点击事件\n    function unbindClick() {\n        infoDom.style.display = 'none';\n        label.off('click', eventClick); //解绑label点击事件\n        unbindBtn.removeEventListener('click', unbindClick, false);\n        bindBtn.addEventListener('click',bindClick,false); //重新绑定按钮点击事件\n    }\n</script>\n```\n\n\n## 文本标记背景\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>设置文本标记背景</title>\n</head>\n<script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n<style type=\"text/css\">\n    html,\n    body {\n        height: 100%;\n        margin: 0px;\n        padding: 0px;\n        overflow: hidden;\n    }\n\n    #mapContainer {\n        position: relative;\n        width: 100%;\n        height: 100%;\n    }\n\n    .btnContainer {\n        position: absolute;\n        left: 20px;\n        top: 20px;\n        z-index: 10000;\n    }\n\n    .btnContainer button {\n        padding: 10px 14px;\n        box-sizing: border-box;\n        border: none;\n        background-color: #3876ff;\n        border-radius: 2px;\n        color: #fff;\n        font-size: 14px;\n        line-height: 14px;\n        margin-bottom: 10px;\n    }\n</style>\n\n<body>\n    <div class=\"btnContainer\">\n        <button class=\"btn1\">label背景样式1</button>\n        <button class=\"btn2\">label背景样式2</button>\n    </div>\n    <div id=\"mapContainer\"></div>\n    <script>\n        var center = new TMap.LatLng(40.040074, 116.273519); // 设置中心点坐标\n        var centerHeight = new TMap.LatLng(40.040074, 116.273519, 100); // 带高度的坐标\n        // 初始化地图\n        var map = new TMap.Map('mapContainer', {\n            center: center,\n            zoom: 18,\n          mapStyleId: \"style8\",\n        });\n        // 初始化label\n        var label = new TMap.MultiLabel({\n            id: 'label-layer',\n            map: map,\n            styles: {\n                label: new TMap.LabelStyle({\n                    color: '#3777FF', // 颜色属性\n                    size: 20, // 文字大小属性\n                    width: 150, // 文字背景框宽度\n                    height: 60, // 文字背景框高度\n                    backgroundColor: 'rgba(175,238,238,0.6)', // 文字背景框颜色属性\n                    borderWidth: 4, // 文字背景框边线宽度\n                    borderRadius: 10,  // 文字背景框圆角\n                    borderColor: 'rgba(255,192,203,1.0)', // 文字背景框边线颜色\n                }),\n            },\n            geometries: [\n                {\n                    id: 'label', // 点图形数据的标志信息\n                    styleId: 'label', // 样式id\n                    position: center, // 标注点位置\n                    content: '腾讯北京总部', // 标注文本\n                    properties: {\n                        // 标注点的属性数据\n                        title: 'label',\n                    },\n                },\n            ],\n        });\n        document.querySelector('button.btn1').onclick = function () {\n            label.setStyles({\n                'label': new TMap.LabelStyle({\n                    color: '#3777FF', // 颜色属性\n                    size: 20, // 文字大小属性\n                    width: 150, // 文字背景框宽度\n                    height: 60, // 文字背景框高度\n                    backgroundColor: 'rgba(175,238,238,0.6)', // 文字背景框颜色属性\n                    borderWidth: 4, // 文字背景框边线宽度\n                    borderRadius: 10, // 文字背景框圆角\n                    borderColor: 'rgba(255,192,203,1.0)', // 文字背景框边线颜色\n                })\n            });\n        };\n        document.querySelector('button.btn2').onclick = function () {\n            label.setStyles({\n                'label': new TMap.LabelStyle({\n                    color: '#3777FF', // 颜色属性\n                    size: 20, // 文字大小属性\n                    width: 160, // 文字背景框宽度\n                    height: 40, // 文字背景框高度\n                    backgroundColor: 'rgba(255,228,181,1.0)', // 文字背景框颜色属性\n                    borderWidth: 8, // 文字背景框边线宽度\n                    borderRadius: 0, // 文字背景框圆角\n                    borderColor: 'rgba(128,128,0,0.5)', // 文字背景框边线颜色\n                })\n            });\n        };\n    </script>\n</body>\n\n</html>\n```\n\n\n## 普通Marker\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>普通Marker</title>\n  </head>\n  <script charset=\"utf-8\" src=\"https://map.qq.com/api/gljs?v=1.exp&key={TMAP_JSAPI_KEY}\"></script>\n  <style type=\"text/css\">\n    html,\n    body {\n      height: 100%;\n      margin: 0;\n      padding: 0;\n      overflow: hidden;\n    }\n    #container {\n      position: relative;\n      width: 100%;\n      height: 100%;\n    }\n    .btnContainer {\n      position: absolute;\n      left: 20px;\n      top: 20px;\n      z-index: 10000;\n    }\n\n    .btnContainer button {\n      padding: 10px 14px;\n      box-sizing: border-box;\n      border: none;\n      background-color: #3876ff;\n      border-radius: 2px;\n      color: #fff;\n      font-size: 14px;\n      line-height: 14px;\n      margin-bottom: 10px;\n    }\n  </style>\n  <body>\n    <div class=\"btnContainer\">\n      <button class=\"btn1\">marker增加高度</button>\n      <button class=\"btn2\">marker去除高度</button>\n    </div>\n    <div id=\"container\"></div>\n    <script type=\"text/javascript\">\n      var center = new TMap.LatLng(39.98210863924864, 116.31310899739151);\n      var centerHeight = new TMap.LatLng(39.98210863924864, 116.31310899739151, 134);\n\n      // 初始化地图\n      var map = new TMap.Map('container', {\n        zoom: 17,\n          mapStyleId: \"style8\",\n        center: new TMap.LatLng(39.98210863924864, 116.31310899739151), // 设置地图中心点坐标，\n        pitch: 0, // 俯仰度\n        rotation: 0, // 旋转角度\n      });\n\n      // MultiMarker文档地址：https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocMarker\n      var marker = new TMap.MultiMarker({\n        map: map,\n        styles: {\n          // 点标记样式\n          marker: new TMap.MarkerStyle({\n            width: 20, // 样式宽\n            height: 30, // 样式高\n            anchor: { x: 10, y: 30 }, // 描点位置\n          }),\n        },\n        geometries: [\n          // 点标记数据数组\n          {\n            // 标记位置(纬度，经度，高度)\n            position: cen\n\nArchive v1.5.1: 229 files, 584051 bytes\n\nFiles: qrcodes/travel_guide_2078008206415630336.png (64319b), qrcodes/travel_guide_2078010837657718784.png (66366b), qrcodes/travel_guide_2078010851276623872.png (66313b), README.md (9177b), references/agent-notes.md (7886b), references/api_reference.md (14209b), references/error-codes.md (2510b), references/jsapi-guide/jsapigl/demos/个性化地图_切换地图个性化样式.html (1535b), references/jsapi-guide/jsapigl/demos/个性化地图_玉露(绿色系活泼风格).html (933b), references/jsapi-guide/jsapigl/demos/个性化地图_墨渊(夜间模式效果).html (949b), references/jsapi-guide/jsapigl/demos/信息窗口_信息窗口偏移设置.html (3542b), references/jsapi-guide/jsapigl/demos/信息窗口_包含图文信息的信息窗口.html (1251b), references/jsapi-guide/jsapigl/demos/信息窗口_拖拽信息窗口.html (6678b), references/jsapi-guide/jsapigl/demos/信息窗口_点击标记弹出信息窗口.html (2746b), references/jsapi-guide/jsapigl/demos/信息窗口_简单信息窗口.html (1201b), references/jsapi-guide/jsapigl/demos/信息窗口_自定义信息窗体.html (5685b), references/jsapi-guide/jsapigl/demos/几何计算库_判断多边形是否在另一个多边形内.html (4355b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点与多边形的关系.html (3263b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点是否在多边形边上.html (3223b), references/jsapi-guide/jsapigl/demos/几何计算库_计算区域面积.html (2215b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形形心.html (2904b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形的交集区域.html (5198b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线上距离P点最近的点.html (3016b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线与多边形是否相交.html (3887b), references/jsapi-guide/jsapigl/demos/几何计算库_计算路径距离.html (2103b), references/jsapi-guide/jsapigl/demos/几何计算库_路径顺逆时针判断与转换.html (4177b), references/jsapi-guide/jsapigl/demos/地图叠加图层_WMS标准图层.html (1736b), references/jsapi-guide/jsapigl/demos/地图叠加图层_自定义贴地图层.html (4301b), references/jsapi-guide/jsapigl/demos/地图叠加图层_静态图贴地图层.html (1289b), references/jsapi-guide/jsapigl/demos/地图操作示例_2D_3D模式切换.html (1498b), references/jsapi-guide/jsapigl/demos/地图操作示例_切换底图类型.html (1518b), references/jsapi-guide/jsapigl/demos/地图操作示例_创建地图.html (1138b), references/jsapi-guide/jsapigl/demos/地图操作示例_区域高亮.html (2798b), references/jsapi-guide/jsapigl/demos/地图操作示例_卫星地图.html (1130b), references/jsapi-guide/jsapigl/demos/地图操作示例_同时加载两个地图.html (1289b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图加载完成事件.html (1408b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图导出图片.html (2775b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图平滑变化至指定状态.html (1089b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图平移.html (1991b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图设置缩放焦点.html (1613b), references/jsapi-guide/jsapigl/demos/地图操作示例_天空盒.html (3735b), references/jsapi-guide/jsapigl/demos/地图操作示例_实时路况.html (2309b), references/jsapi-guide/jsapigl/demos/地图操作示例_异步加载地图.html (1230b), references/jsapi-guide/jsapigl/demos/地图操作示例_点击地图拾取POI.html (1412b), references/jsapi-guide/jsapigl/demos/地图操作示例_点击地图拾取坐标.html (1574b), references/jsapi-guide/jsapigl/demos/地图操作示例_粒子路况.html (1459b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图中心.html (2142b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图显示范围.html (2985b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图视角.html (2689b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图中心点偏移.html (1812b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图显示比例.html (1563b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图边界范围.html (1482b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置控件位置及样式.html (4100b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置鼠标样式.html (2746b), references/jsapi-guide/jsapigl/demos/地图操作示例_调整图层顺序.html (3053b), references/jsapi-guide/jsapigl/demos/地图操作示例_配置矢量底图.html (5369b), references/jsapi-guide/jsapigl/demos/地图操作示例_销毁地图.html (1708b), references/jsapi-guide/jsapigl/demos/城市漫游_地面漫游.html (4509b), references/jsapi-guide/jsapigl/demos/城市漫游_空中漫游.html (4587b), references/jsapi-guide/jsapigl/demos/城市漫游_绕点环绕.html (2384b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形拔起_3D棱柱.html (2245b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形点击事件.html (5002b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形选中高亮显示.html (9726b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形飞地.html (3279b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_带飞地的区域实现高亮.html (3688b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_环形(带洞)多边形.html (2319b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_简单圆形.html (1276b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_简单多边形.html (1985b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_自定义多边形样式.html (3271b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_自定义边线样式.html (2507b), references/jsapi-guide/jsapigl/demos/应用工具_开关编辑器键盘事件.html (8473b), references/jsapi-guide/jsapigl/demos/应用工具_测量工具.html (4174b), references/jsapi-guide/jsapigl/demos/应用工具_绘制几何图形.html (6296b), references/jsapi-guide/jsapigl/demos/应用工具_编辑几何图形.html (4853b), references/jsapi-guide/jsapigl/demos/应用工具_编辑器的禁用和启用.html (2468b), references/jsapi-guide/jsapigl/demos/应用工具_设置编辑点为GL模式.html (4418b), references/jsapi-guide/jsapigl/demos/折线_折线-动态箭头.html (2270b), references/jsapi-guide/jsapigl/demos/折线_折线-大圆航线.html (1340b), references/jsapi-guide/jsapigl/demos/折线_折线-彩虹线.html (2868b), references/jsapi-guide/jsapigl/demos/折线_折线-虚线样式.html (2188b)\n\nArchive v1.0.3: 223 files, 442127 bytes\n\nFiles: README.md (8498b), references/agent-notes.md (7042b), references/jsapi-guide/jsapigl/demos/个性化地图_切换地图个性化样式.html (1554b), references/jsapi-guide/jsapigl/demos/个性化地图_玉露(绿色系活泼风格).html (952b), references/jsapi-guide/jsapigl/demos/个性化地图_墨渊(夜间模式效果).html (968b), references/jsapi-guide/jsapigl/demos/信息窗口_信息窗口偏移设置.html (3561b), references/jsapi-guide/jsapigl/demos/信息窗口_包含图文信息的信息窗口.html (1270b), references/jsapi-guide/jsapigl/demos/信息窗口_拖拽信息窗口.html (6697b), references/jsapi-guide/jsapigl/demos/信息窗口_点击标记弹出信息窗口.html (2765b), references/jsapi-guide/jsapigl/demos/信息窗口_简单信息窗口.html (1220b), references/jsapi-guide/jsapigl/demos/信息窗口_自定义信息窗体.html (5704b), references/jsapi-guide/jsapigl/demos/几何计算库_判断多边形是否在另一个多边形内.html (4374b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点与多边形的关系.html (3282b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点是否在多边形边上.html (3242b), references/jsapi-guide/jsapigl/demos/几何计算库_计算区域面积.html (2234b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形形心.html (2923b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形的交集区域.html (5217b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线上距离P点最近的点.html (3035b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线与多边形是否相交.html (3906b), references/jsapi-guide/jsapigl/demos/几何计算库_计算路径距离.html (2122b), references/jsapi-guide/jsapigl/demos/几何计算库_路径顺逆时针判断与转换.html (4196b), references/jsapi-guide/jsapigl/demos/地图叠加图层_WMS标准图层.html (1755b), references/jsapi-guide/jsapigl/demos/地图叠加图层_自定义贴地图层.html (4320b), references/jsapi-guide/jsapigl/demos/地图叠加图层_静态图贴地图层.html (1308b), references/jsapi-guide/jsapigl/demos/地图操作示例_2D_3D模式切换.html (1517b), references/jsapi-guide/jsapigl/demos/地图操作示例_切换底图类型.html (1537b), references/jsapi-guide/jsapigl/demos/地图操作示例_创建地图.html (1157b), references/jsapi-guide/jsapigl/demos/地图操作示例_区域高亮.html (2817b), references/jsapi-guide/jsapigl/demos/地图操作示例_卫星地图.html (1149b), references/jsapi-guide/jsapigl/demos/地图操作示例_同时加载两个地图.html (1308b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图加载完成事件.html (1427b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图导出图片.html (2794b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图平滑变化至指定状态.html (1108b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图平移.html (2010b), references/jsapi-guide/jsapigl/demos/地图操作示例_地图设置缩放焦点.html (1632b), references/jsapi-guide/jsapigl/demos/地图操作示例_天空盒.html (3754b), references/jsapi-guide/jsapigl/demos/地图操作示例_实时路况.html (2328b), references/jsapi-guide/jsapigl/demos/地图操作示例_异步加载地图.html (1249b), references/jsapi-guide/jsapigl/demos/地图操作示例_点击地图拾取POI.html (1431b), references/jsapi-guide/jsapigl/demos/地图操作示例_点击地图拾取坐标.html (1593b), references/jsapi-guide/jsapigl/demos/地图操作示例_粒子路况.html (1478b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图中心.html (2161b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图显示范围.html (3004b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置_获取地图视角.html (2708b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图中心点偏移.html (1831b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图显示比例.html (1582b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置地图边界范围.html (1501b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置控件位置及样式.html (4119b), references/jsapi-guide/jsapigl/demos/地图操作示例_设置鼠标样式.html (2765b), references/jsapi-guide/jsapigl/demos/地图操作示例_调整图层顺序.html (3072b), references/jsapi-guide/jsapigl/demos/地图操作示例_配置矢量底图.html (5388b), references/jsapi-guide/jsapigl/demos/地图操作示例_销毁地图.html (1727b), references/jsapi-guide/jsapigl/demos/城市漫游_地面漫游.html (4528b), references/jsapi-guide/jsapigl/demos/城市漫游_空中漫游.html (4606b), references/jsapi-guide/jsapigl/demos/城市漫游_绕点环绕.html (2403b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形拔起_3D棱柱.html (2264b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形点击事件.html (5021b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形选中高亮显示.html (9745b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_多边形飞地.html (3298b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_带飞地的区域实现高亮.html (3707b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_环形(带洞)多边形.html (2338b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_简单圆形.html (1295b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_简单多边形.html (2004b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_自定义多边形样式.html (3290b), references/jsapi-guide/jsapigl/demos/多边形&3D棱柱_自定义边线样式.html (2526b), references/jsapi-guide/jsapigl/demos/应用工具_开关编辑器键盘事件.html (8492b), references/jsapi-guide/jsapigl/demos/应用工具_测量工具.html (4193b), references/jsapi-guide/jsapigl/demos/应用工具_绘制几何图形.html (6315b), references/jsapi-guide/jsapigl/demos/应用工具_编辑几何图形.html (4872b), references/jsapi-guide/jsapigl/demos/应用工具_编辑器的禁用和启用.html (2487b), references/jsapi-guide/jsapigl/demos/应用工具_设置编辑点为GL模式.html (4437b), references/jsapi-guide/jsapigl/demos/折线_折线-动态箭头.html (2289b), references/jsapi-guide/jsapigl/demos/折线_折线-大圆航线.html (1359b), references/jsapi-guide/jsapigl/demos/折线_折线-彩虹线.html (2887b), references/jsapi-guide/jsapigl/demos/折线_折线-虚线样式.html (2207b), references/jsapi-guide/jsapigl/demos/折线_折线应用_路线规划.html (3608b), references/jsapi-guide/jsapigl/demos/折线_折线样式自定义.html (3638b), references/jsapi-guide/jsapigl/demos/折线_折线点击事件.html (4517b), references/jsapi-guide/jsapigl/demos/折线_简单折线.html (2115b), references/jsapi-guide/jsapigl/demos/折线_管道线.html (4049b)\n\nArchive v1.0.2: 222 files, 417681 bytes\n\nFiles: README.md (8498b), references/agent-notes.md (7042b), references/jsapi-guide/jsapigl/demos/个性化地图_切换地图个性化样式.html (1554b), references/jsapi-guide/jsapigl/demos/个性化地图_玉露(绿色系活泼风格).html (952b), references/jsapi-guide/jsapigl/demos/个性化地图_墨渊(夜间模式效果).html (968b), references/jsapi-guide/jsapigl/demos/信息窗口_信息窗口偏移设置.html (3561b), references/jsapi-guide/jsapigl/demos/信息窗口_包含图文信息的信息窗口.html (1270b), references/jsapi-guide/jsapigl/demos/信息窗口_拖拽信息窗口.html (6697b), references/jsapi-guide/jsapigl/demos/信息窗口_点击标记弹出信息窗口.html (2765b), references/jsapi-guide/jsapigl/demos/信息窗口_简单信息窗口.html (1220b), references/jsapi-guide/jsapigl/demos/信息窗口_自定义信息窗体.html (5704b), references/jsapi-guide/jsapigl/demos/几何计算库_判断多边形是否在另一个多边形内.html (4374b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点与多边形的关系.html (3282b), references/jsapi-guide/jsapigl/demos/几何计算库_判断点是否在多边形边上.html (3242b), references/jsapi-guide/jsapigl/demos/几何计算库_计算区域面积.html (2234b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形形心.html (2923b), references/jsapi-guide/jsapigl/demos/几何计算库_计算多边形的交集区域.html (5217b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线上距离P点最近的点.html (3035b), references/jsapi-guide/jsapigl/demos/几何计算库_计算线与多边形是否相交.html (3906b), references/jsapi-guide/jsapigl/demos/几何计算库_计算路径距离.html (2122b), references/jsapi-guide/jsapigl/demos/几何计算库_路径顺逆时针判断与转换.html (4196b), references/jsapi-guide/jsapigl/demos/地图叠加图层_WMS标准图层.html (1755b), references/jsapi-guide/jsapigl/demos/地图叠加图层_自定义贴地图层.html (4320b), references/jsapi-guide/jsapigl/demos/地图叠加图层_静态图贴地图层.html (1308b), references/jsapi-guide/jsapigl/demos/地图操作示例_2D_3D模式切换.html (1517b), references/jsapi-guide/jsapigl/demos/地图操作示例_切换底图类型.html (1537b), references/jsapi-guide/jsapigl/demos/地图操作示例_创建地图.html (1157b), references/jsapi-guide/jsapigl/demos/地...","readmeExcerpt":"Skill: tencentmap-map-assistant Owner: tencent-adm Summary: 腾讯地图·地图助手 Skill，一句自然语言调用腾讯地图全套能力，开箱即用。提供 AI 旅游攻略、地点搜索（含评分/人均/营业时间）、关键词提示、路线规划（驾车/步行/公交/骑行）、地址解析与逆解析、行政区划、IP 定位、距离计算、天气查询，并可将行程或多 POI 渲染成网页地图或生成腾讯地图小程序指南。涉及找地点、规划路线、旅游行程、查天气、坐标转换等出行场景时使用。 Tags: latest:1.5.2 Version history: v1.5.2 | 2026-08-12T08:01:52.517Z | auto tencentmap-map-assistant-skill v1.5.2 - Improved Key 管理: Now supports a prioritized pool of save","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"pip install -e ."},{"language":"python","snippet":"from tmap_client import TmapClient\n\nclient = TmapClient()\n\nresult = client.travel_guide(\"武汉5天攻略\")\npois   = client.poi_search(\"黄鹤楼\", region=\"武汉\")\naddr   = client.geocoder(\"深圳市腾讯滨海大厦\")"},{"language":"python","snippet":"from tmap_client import save_key_to_dotenv\nsave_key_to_dotenv(\"你的 Key\")"},{"language":"python","snippet":"district_list()                  # 全国省级列表\ndistrict_children(parent_id)     # 下级区划（parent_id=\"110000\" → 北京下属）\ndistrict_search(keyword)         # 关键词搜区划"},{"language":"python","snippet":"# 单点 GPS → GCJ-02\ngcj = client.coord_translate((22.540601, 113.933970))\n# {'lat': 22.542..., 'lng': 113.939...}\n\n# 批量转换\ngcj_list = client.coord_translate([(22.5406, 113.9339), (39.9042, 116.4074)])"},{"language":"python","snippet":"client = TmapClient()\n\n# 旅游攻略（返回 output_markdown 成品文件，Read 后作为回复）\nr = client.travel_guide(\"成都3天美食游\")\n\n# POI 搜索\nres = client.poi_search(\"咖啡馆\", location=\"22.540601,113.93397\", page_size=5)\n\n# 路线规划\nroute = client.direction(\"深圳北站\", \"深圳湾口岸\", mode=\"driving\")\n\n# 个人地图指南：先用 poi_search 拿到真实 POI，再映射成 pois\np1 = client.poi_search(\"深圳北站\", region=\"深圳\", raw=True)[\"data\"][0]\np2 = client.poi_search(\"深圳湾口岸\", region=\"深圳\", raw=True)[\"data\"][0]\nguide = client.generate_map_guide(\n    [{\"name\": p1[\"title\"], \"lat\": p1[\"location\"][\"lat\"], \"lng\": p1[\"location\"][\"lng\"], \"poi_id\": p1[\"id\"], \"day\": 1, \"num\": 1},\n     {\"name\": p2[\"title\"], \"lat\": p2[\"location\"][\"lat\"], \"lng\": p2[\"location\"][\"lng\"], \"poi_id\": p2[\"id\"], \"day\": 1, \"num\": 2}],\n    city=\"深圳\")\n\n# 场景：用户手上是 WGS-84（GPS）坐标，先转 GCJ-02 再用\nwgs_points = [(22.540601, 113.933970), (22.532000, 113.929500)]   # 用户提供\ngcj_points = client.coord_translate(wgs_points, type=1)           # → [{\"lat\":..,\"lng\":..}, ...]\n\n# 1) 逆解析：坐标 → 地址（必须传 GCJ-02）\naddr = client.regeocoder(gcj_points[0][\"lat\"], gcj_points[0][\"lng\"])\n\n# 2) 周边 POI 检索（location 也必须是 GCJ-02）\nnearby = client.poi_nearby(\"咖啡\", location=f'{gcj_points[0][\"lat\"]},{gcj_points[0][\"lng\"]}')\n\n# 3) 个人地图指南 / HTML 可视化：直接把 GCJ-02 传入 pois / markers"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: tencentmap-map-assistant-skill\ndescription: \"腾讯地图·地图助手 Skill，一句自然语言调用腾讯地图全套能力，开箱即用。提供 AI 旅游攻略、地点搜索（含评分/人均/营业时间）、关键词提示、路线规划（驾车/步行/公交/骑行）、地址解析与逆解析、行政区划、IP 定位、距离计算、天气查询，并可将行程或多 POI 渲染成网页地图或生成腾讯地图小程序指南。涉及找地点、规划路线、旅游行程、查天气、坐标转换等出行场景时使用。\"\nlicense: MIT\nversion: 1.5.2\ngit_url: https://github.com/TencentLBS/tencentmap-map-assistant\n---\n\n# 地图助手 Skill\n\n腾讯位置服务出品。用一句自然语言即可生成旅游攻略、搜索地点、规划路线、解析地址坐标，并可将结果渲染成网页地图或生成腾讯地图小程序指南。\n\n## 能力\n\n能力命名与腾讯位置服务官网 WebService API 对齐。完整参数签名见下方「参数与返回」。\n\n| 能力 | 说明 | 方法 |\n|------|------|------|\n| AI 旅游攻略 | 自然语言 query → 多日行程攻略，可联动腾讯地图小程序，与朋友共同编辑行程、规划多人出行 | `travel_guide` |\n| 个人地图指南 | 地点列表 → 个人专属地图（保存到腾讯地图小程序，手机随时查看） | `generate_map_guide` |\n| 地点搜索 | 城市/区域搜索、周边圆形搜索、POI 详情 | `poi_search` / `poi_nearby` / `poi_detail` |\n| 关键词输入提示 | 输入补全候选 POI | `poi_sug` |\n| 行政区划 | 省市区列表、下级区划、区划搜索 | `district_list` / `district_children` / `district_search` |\n| 地址解析 | 地址 → 坐标 | `geocoder` |\n| 逆地址解析 | 坐标 → 地址（可附周边 POI） | `regeocoder` |\n| IP 定位 | IP → 位置 | `ip_location` |\n| 路线规划 | 驾车 / 步行 / 公交 / 骑行 | `direction` |\n| 两点间距离 | 计算两点之间的驾车/步行/骑行距离与用时 | `distance_matrix` |\n| 天气查询 | 行政区/坐标 → 实时或预报天气 | `weather` |\n| 坐标系转换 | GPS(WGS-84) / 百度 / sogou / mapbar → GCJ-02 | `coord_translate` |\n| 行程 / POI 可视化 | 把行程或多 POI 结果渲染为网页地图 | — |\n\n## 安装\n\n首次使用前安装：\n\n```\npip install -e .\n```\n\n## 用法\n\n```python\nfrom tmap_client import TmapClient\n\nclient = TmapClient()\n\nresult = client.travel_guide(\"武汉5天攻略\")\npois   = client.poi_search(\"黄鹤楼\", region=\"武汉\")\naddr   = client.geocoder(\"深圳市腾讯滨海大厦\")\n```\n\n配置自己的腾讯位置服务 Key（持久化保存，之后自动启用）：\n\n```python\nfrom tmap_client import save_key_to_dotenv\nsave_key_to_dotenv(\"你的 Key\")\n```\n\n\n## Key 管理\n\n按此顺序自动获取 Key，通常无需干预：`TmapClient(key=...)` → 已保存的 Key。各来源的 Key 会全部进入候选池。\n\n- 无可用 Key → 读取 `tempkey-guide.md` 引导用户申请临时体验 Key。\n- 用户要固定使用或更换 Key → 调用 `save_key_to_dotenv(\"<key>\")` 保存，之后自动生效。\n- Key 已配置但接口报错 → TmapClient 会按优先级自动轮询候选池中的可用 Key 并切换使用。切换后，必须告知用户已自动切换以及切换原因；若所有 Key 均不可用时抛出 TmapError（含每个 Key 的失败原因），必须读取 `references/error-codes.md`，对错误码给出修正方式告知用户。\n\n\n## 参数与返回\n\n### AI 旅游攻略 — travel_guide\n\n`travel_guide(query, lat=30.572815, lng=104.066801)`：自然语言 query → 多日行程攻略。同步等待，单次调用 30-50 秒。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | str | 是 | 目的地 + 天数，例如 \"武汉5天攻略\" / \"成都3天美食游\" |\n| `lat`, `lng` | float | 否 | 用户当前位置（影响 A2A 上下文，不决定目的地） |\n\n**返回**：结构化攻略数据（`title`/`summary`/`days` 行程列表等），以及 **`output_markdown`**（成品攻略 md 文件路径，含小程序二维码，Read 后原样输出）。\n\n### 个人地图指南 — generate_map_guide\n\n`generate_map_guide(pois, city, title=\"我的指南\", query=\"\", description=\"\")`：将任意地点列表（搜索结果、路线点、打卡记录）一键保存为腾讯地图小程序里的个人专属地图，在手机上随时查看和导航。\n\n> **前置步骤**：构造 `pois` 前，先对每个地点调用 `poi_search()`拿到真实的 `id` 与 `location.lat` / `location.lng`，再映射成 `pois` 所需的 `poi_id` / `lat` / `lng`。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `pois` | List[Dict] | 是 | POI 列表，每个 POI 含 `name` / `lat` / `lng` / `poi_id`。这些值应取自 `poi_search()` / `poi_sug()` 的真实返回后填入 |\n| `city` | str | 是 | 城市名称 |\n| `title` | str | 否 | 指南标题，默认\"我的指南\" |\n| `query` | str | 否 | 用户原始输入（用于入库备注） |\n| `description` | str | 否 | 行程/路线描述文本，会嵌入输出"},{"path":"README.md","content":"# tencentmap-map-assistant-skill\n\n腾讯位置服务出品。一句自然语言调用腾讯地图全套能力——AI 旅游攻略、地点搜索、路线规划、地址解析、天气查询，无需开发者账号、开箱即用。\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Version](https://img.shields.io/badge/version-1.5.2-green.svg)](https://github.com/TencentLBS/tencentmap-map-assistant)\n\n---\n\n## ✨ 能力一览\n\n| 能力 | 说明 | 方法 |\n|:-----|:-----|:-----|\n| 🗺 AI 旅游攻略 | 自然语言生成多日行程，含小程序二维码入口 | `travel_guide` |\n| 📋 个人地图指南 | 从 POI 列表生成地图指南，含小程序二维码入口 | `generate_map_guide` |\n| 🔍 地点搜索 | 城市/区域搜索、周边圆形搜索、POI 详情 | `poi_search` / `poi_nearby` / `poi_detail` |\n| 💡 关键词输入提示 | 输入补全候选 POI | `poi_sug` |\n| 🏛 行政区划 | 省市区列表、下级区划、区划搜索 | `district_list` / `district_children` / `district_search` |\n| 📍 地址解析 | 地址 → 坐标 | `geocoder` |\n| 📍 逆地址解析 | 坐标 → 地址（可附周边 POI） | `regeocoder` |\n| 🌐 IP 定位 | IP → 位置 | `ip_location` |\n| 🚗 路线规划 | 驾车 / 步行 / 公交 / 骑行 | `direction` |\n| 📏 两点间距离 | 计算两点之间的驾车/步行/骑行距离与用时 | `distance_matrix` |\n| 🌤 天气查询 | 行政区/坐标 → 实时或预报天气 | `weather` |\n| 🎨 行程可视化 | 把行程或多 POI 渲染成网页地图 | HTML 生成 |\n\n## 🚀 快速开始\n\n### 安装依赖\n\n```bash\npip install -e .\n```\n\n> 仅依赖 `requests`，多数环境已自带。\n\n### 基本用法\n\n```python\nfrom tmap_client import TmapClient\n\nclient = TmapClient()\n\n# AI 旅游攻略\nresult = client.travel_guide(\"武汉5天攻略\")\n\n# 地点搜索（含评分、人均、营业时间）\npois = client.poi_search(\"黄鹤楼\", region=\"武汉\")\n\n# 周边搜索\nnearby = client.poi_nearby(\"咖啡\", location=\"22.540601,113.93397\", radius=1000)\n\n# 路线规划\nroute = client.direction(\"深圳北站\", \"深圳湾口岸\", mode=\"driving\")\n\n# 地址 → 坐标\naddr = client.geocoder(\"深圳市腾讯滨海大厦\")\n\n# 坐标 → 地址\nloc = client.regeocoder(22.540601, 113.93397, get_poi=True)\n\n# 天气查询\nweather = client.weather(adcode=\"110000\", type=\"now\")\n```\n\n### 配置正式 Key\n\n未配置 Key 时可通过 tempkey 流程申请 AI 场景临时体验 Key（手机验证，1 年有效，覆盖 WebService API + JSAPI 底图加载）。如已有腾讯位置服务 Key：\n\n```python\nfrom tmap_client import save_key_to_dotenv\n\nsave_key_to_dotenv(\"你的 Key\")  # 持久化保存（~/.tencentmap/tempkey.json），之后自动走正式通道\n```\n\n> 申请正式 Key：https://lbs.qq.com/dev/console/quick-register\n\n## 📖 API 参考\n\n### `travel_guide(query, lat=30.572815, lng=104.066801)`\n\n生成 AI 旅游攻略，含行程详情与腾讯地图小程序入口二维码。\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `query` | str | ✅ | 自然语言描述，如 \"成都3天美食游\" |\n| `lat` / `lng` | float | | 用户当前位置（辅助上下文，不影响目的地） |\n\n返回：结构化攻略数据 + `output_markdown`（成品攻略文件路径）+ `qr_path`（小程序二维码 PNG）。\n\n> 单次调用约 30-50 秒。\n\n### `poi_search(keyword, region=None, location=None, page_size=10, page_index=1)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `keyword` | str | ✅ | 搜索关键词 |\n| `region` | str | 二选一 | 城市/区域名 |\n| `location` | str | 二选一 | 中心点 \"lat,lng\"，启用 5km 邻近搜索 |\n| `page_size` | int | | 每页 1-20，默认 10 |\n| `page_index` | int | | 页码，默认 1 |\n\n### `poi_nearby(keyword, location, radius=1000, page_size=10, page_index=1)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `keyword` | str | ✅ | 搜索词 |\n| `location` | str | ✅ | 中心点 \"lat,lng\" |\n| `radius` | int | | 半径（米），10-1000，默认 1000 |\n| `page_index` | int | | 页码，默认 1 |\n\n### `poi_detail(poi_id)`\n\n| 参数 | 类型 | 必填 | 说明 |\n|:-----|:-----|:-----|:-----|\n| `poi_id` | str | ✅ | POI 唯一 ID（从搜索结果获取） |\n\n### `poi_"},{"path":"references/jsapi-guide/README.md","content":"# 腾讯地图 JSAPI GL 资料（内嵌）\n\n> 本目录是腾讯地图 JS API GL 的完整开发资料，内嵌在本 skill 包里，\n> 在需要为旅游攻略 / 多 POI / 路线出 HTML 可视化时直接查阅。\n>\n> HTML 地图底图使用腾讯地图 JSAPI GL。底图 `<script>` 标签见下方「API Key」段，直接照抄即可。\n\n## ⚠️ 强制约束：底图 & 命名空间\n\n- **底图**：本 skill 全链路绑定腾讯位置服务——WebService API、GCJ-02 坐标系、Key 与额度体系均为腾讯地图。因此所有 HTML 可视化地图必须使用腾讯地图 JSAPI GL 作为底图，与数据层保持一致；换用其他地图 SDK 会导致坐标系、服务接口、样式体系不匹配。涉及中国区域的地图展示，也需符合国家地图合规要求，不使用未取得国内测绘资质的境外地图服务。\n- **命名空间**：JSAPI GL 挂在全局 **`TMap`** 上（大小写严格：**T** 大写、**M** 大写，其余小写）。所有 API 必须走 `TMap.xxx`：`new TMap.Map(container, opts)`、`new TMap.LatLng(lat, lng)`、`new TMap.MultiMarker(...)`、`new TMap.MultiPolyline(...)`、`new TMap.InfoWindow(...)`、`new TMap.MultiLabel(...)` 等。\n- ❌ 常见错误：把地图 API 写成非 `TMap` 的全局对象（如错误大小写 `TMAP.Map` / `Tmap.Map`、旧版 `qq.maps.Map`，或其他地图 SDK 的全局命名空间）——一律不允许，统一改用 `TMap.xxx`。\n\n## 何时读这里\n\n当需要把行程 / POI / 路线渲染成 HTML 地图时，按以下顺序查阅：\n\n1. **底图 key 与 HTML 生成示例** → 下方「API Key」与「HTML 生成示例」段（照抄即可出图）\n2. **画路线** → 下方「画路线：polyline 解压」段\n3. **JSAPI 核心 API（地图初始化 / marker / 路线连线 / 弹窗等基础能力）** → `jsapigl/docs/*.md`（下方有完整文件名清单）\n4. **可视化扩展库（热力图 / 轨迹 / 弧线 / 区域图等高级可视化）** → `visualization/docs/*.md`（下方有完整文件名清单）\n5. **demo 代码** → `*/demos/`\n\n## jsapigl/docs/ 文件清单（21 个核心 API 文档）\n\n| 文档 | 说明 / 何时读 |\n|------|--------------|\n| `概述.md` | API 总览，第一次接入先看 |\n| `地图.md` | 地图初始化、移动、缩放等核心 API |\n| `基础类.md` | LatLng / Point 等基础数据类型 |\n| `点标记.md` | Marker（POI 标记必读） |\n| `点聚合.md` | MarkerCluster（多 POI 聚合） |\n| `信息窗体.md` | InfoWindow（POI 弹窗，旅游攻略必读） |\n| `矢量图形.md` | Polyline / Polygon（路线连线必读） |\n| `文本标记.md` | Label 文字标注 |\n| `DOM覆盖物.md` | 自定义 HTML 覆盖物 |\n| `事件.md` | 地图/marker 事件处理 |\n| `控件.md` | 缩放/比例尺等内置控件 |\n| `室内图.md` | 室内地图 |\n| `自定义图层.md` | 自定义图层 |\n| `环境检测.md` | 浏览器/WebGL 支持检测 |\n| `附加库：几何计算库.md` | geometry 库（距离/面积计算） |\n| `附加库：地图工具.md` | tools 库（标尺/绘图工具） |\n| `附加库：地图视角附加库.md` | view 库（视角控制） |\n| `附加库：天气图层.md` | weather 图层 |\n| `附加库：服务类库.md` | service 库（地理编码等） |\n| `附加库：模型库.md` | model 库（3D GLTF/3DTiles） |\n| `附加库：矢量数据图层.md` | vector 库（GeoJSON/MVT） |\n\n## visualization/docs/ 文件清单（14 个可视化扩展）\n\n| 文档 | 说明 / 何时读 |\n|------|--------------|\n| `参考手册.md` | 可视化扩展库总览 |\n| `基础类.md` | 通用基础类 |\n| `事件.md` | 可视化层事件 |\n| `散点图.md` | 散点图（旅游 POI 可用） |\n| `热力图.md` | 热力图 |\n| `网格热力图.md` | 网格化热力图 |\n| `蜂窝热力图.md` | 六边形热力图 |\n| `辐射圈.md` | 辐射圈（POI 影响范围） |\n| `弧线图.md` | 弧线（跨城路线视觉化好） |\n| `轨迹图.md` | 轨迹动画（旅游路线播放） |\n| `管道图.md` | 管道连线 |\n| `区域图.md` | 多边形区域 |\n| `围墙面.md` | 立体围墙 |\n| `水晶体.md` | 立体水晶 |\n\n\n## 目录结构\n\n```\njsapi-guide/\n├── README.md            本文档\n├── jsapigl/\n│   ├── docs/            核心 API 文档（上方 21 个 md）\n│   └── demos/           核心 API 的 demo HTML\n└── visualization/\n    ├── docs/            可视化扩展库文档（上方 14 个 md）\n    └── demos/           可视化扩展库的 demo HTML\n```\n\n## API Key\n\nHTML 地图底图使用 client 解析到的 Key（tempkey / 环境变量 `TMAP_KEY` / `.env` 文件），在 `<script>` 标签中引用。生成 HTML 时将 `TMAP_KEY` 替换为实际解析到的 Key：\n\n```html\n<script src=\"https://map.qq.com/api/gljs?v=1&key={TMAP_KEY}\"></script>\n```\n\ntempkey 生成的 Key 同时支持 JSAPI 底图加载和 WebService API 调用，放进 HTML `<head>` 即可显示底图。未配置 Key 时需先通过 tempkey 流程申请临时体验 Key。\n\n> ⚠️ **安全提示**：将 Key 明文写在 HTML `<script src=\"...gljs?key=XXX\">"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn77cw5hbmapf54rv89jdqwp7x835m4k\",\n  \"slug\": \"tencentmap-map-assistant-skill\",\n  \"version\": \"1.5.2\",\n  \"publishedAt\": 1786521712517\n}"},{"path":"references/agent-notes.md","content":"# 调用指引（供 AI 阅读）\n\n本文件补充 SKILL.md 未展开的调用细节，帮助 AI 稳定完成任务。\n\n## 能力命中本 skill 时，用 client 完成\n\n用户需求涉及旅游攻略、找地点、路线规划、地址坐标转换、行政区划、距离计算等，均通过 `TmapClient` 完成，返回的是腾讯位置服务真实数据。\n\n- client 仅依赖 `requests`，多数环境已自带，可直接调用；仅当报 `ModuleNotFoundError: requests` 时执行 `pip install requests` 后重试。\n- 调用报错时，读返回的报错信息定位。API 错误码见 `error-codes.md` 分类表，参数类错误可修正后重试；其余错误不可绕过或降级，引导用户修正。\n\n\n## Key 策略：检查 tempkey，按需配置正式 Key\n\n每个使用者的腾讯位置服务额度独立。\n\n- **Key 解析顺序**：用户传入参数 → 环境变量 `TMAP_KEY` → `~/.tencentmap/tempkey.json`（持久化 key 源，含手动指定的 Key 与申请的临时体验 Key）。\n- **无 Key 时**：client 初始化成功，但调用 WebService API 时会抛出 `TmapError`。此时 AI 应引导用户通过 tempkey 流程申请 AI 场景临时体验 Key（手机验证，1 年有效，覆盖 WebService API + JSAPI 底图加载）。**必须读取 `tempkey-guide.md` 获取完整申请流程**（协议展示、脚本调用、错误码表、输出模板等），严格按照其中步骤执行。\n- **配置正式 Key**：使用者提供 Key 时，用 `save_key_to_dotenv(\"Key\")` 持久化保存（写入 `~/.tencentmap/tempkey.json`），重新初始化 client 后自动走正式通道。\n\n```python\nfrom tmap_client import TmapClient, save_key_to_dotenv\nc = TmapClient()                 # 自动解析 Key（env / tempkey.json）\n# save_key_to_dotenv(\"XXX-...\")  # 使用者提供 Key 时调用\n```\n\n## 返回结构：默认语义化文本\n\n所有 WebService 能力（搜索、提示、详情、地址解析、区划、IP、距离矩阵、路线规划）默认直接返回**语义化文本**——中文、带单位、可直接展示给用户。禁止重新解析 raw JSON 自己拼接文字。\n\n如需原始 JSON 做下游计算（例如取 route_id 调沿途搜索、取 poi_id/坐标调 generate_map_guide），传 `raw=True`：\n\n## 错误处理：直接展示错误信息\n\nAPI 报错时（TmapError），`e.message` 含错误码和原因描述。对应操作指引见 `references/error-codes.md`，按错误码查找后引导用户修正，不得自行估算或编造。\n\n```python\n# 默认：返回可读文本\ntext = client.poi_search(\"黄鹤楼\", region=\"武汉\")\n# → \"找到约223条结果，以下为其中10条\\n(1) 黄鹤楼...\"\n\n# raw=True：返回原始 JSON\ndata = client.poi_search(\"深圳北站\", region=\"深圳\", raw=True)\np1 = data[\"data\"][0]  # 取 id、坐标等精确字段\n```\n\n> 行政区划三个方法的 `result` 是**二维数组**——`result[0]` 才是区划对象列表。\n\n路线规划 `direction` 仅在调用前自动把起终点的地址/景点名转成坐标，默认返回语义化文本。如需原始 JSON（例如取 `polyline` 画地图），传 `raw=True` 后从 `result.routes` 获取。其中驾车/步行/骑行的 `polyline` 为压缩格式，画线前需解压（解压方法见 `jsapi-guide/README.md`）。\n\n## travel_guide 的回复方式\n\n`travel_guide` 返回的 `output_markdown` 是成品攻略文件（含行程正文与小程序入口二维码图片）。\n\n**必须做的事（缺一不可）：**\n\n1. 用 Read 读取 `result[\"output_markdown\"]`，将文件内容**完整作为回复**——包含末尾的 `![腾讯地图小程序入口图](...)` 图片语法。**Markdown 图片语法 `![]()` 完全可以直接在 WorkBuddy 会话中渲染显示**，不需要转换成 base64、不需要上传、不需要用其他方式——直接输出 `![]()` 语法就能看到二维码图。\n2. **同时**将 `result[\"qr_path\"]` 指向的二维码 PNG 文件复制到当前工作空间，确保二维码作为实体文件留存在工作区，用户可以随时找到和使用。复制命令参考：macOS/Linux 用 `cp`，Windows 用 `copy`。示例：`cp /path/to/qrcodes/xxx.png <工作空间路径>/`\n\n文件末尾结构示例：\n\n```markdown\n---\n![腾讯地图小程序入口图](/path/to/qrcodes/travel_guide_xxx.png)\n\n👆 扫码保存自己的专属地图，在手机上随时查看和导航。\n```\n\n> ⚠️ Markdown 图片语法 `![...](...)` 可在 WorkBuddy 会话中内联渲染，请务必通过此方式展示二维码图片，而非仅提供文件路径、转 base64 或其他方式。\n\n## 网页生成（HTML 地图可视化）\n\n涉及\"多 POI 对比 / 路线 / 多天行程 / 个人专属地图\"等\"看图比看字更直观\"的场景，可基于结构化数据生成 HTML 网页地图。底图 key、HTML 生成示例、polyline 解压方法、各类 API 与 demo 全部见 `references/jsapi-guide/README.md`，照其中模板生成即可。\n\n> 使用系统默认样式即可。若用户希望修改地图样式，可引导其前往腾讯位置服务官网登录账号，在控制台为对应 Key 配置样式后使用。\n\n## 个人地图指南（generate_map_guide）\n\n`generate_map_guide` 是独立于 A2A 攻略的指南生成能力，可将任意 POI 列表直接生成腾讯地图小程序指南（含二维码），用户扫码即可在手机上查看、导航、分享、编辑。与 `travel_guide` 内含出码不同，本方法需显式调用。\n\n### 业务场景\n\n| 用户说… | 动作 |\n|---------|------|\n| \"帮我记录这几个打卡点\" / \"生成一个XX地图\" / \"存到手机上\" | 调用"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1263,"uniquenessScore":43,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:52:57.656Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:52:57.656Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:54:57.629Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}