react-phone-apps/.blueprint/modules/floor-map.md
lanrtop 3dbc6f0ff5 refactor: 标记点序号显示、布局叠加方式及照片选择器重构
- 标记点角标从物品数量改为按楼层顺序编号,角标背景色跟随标记颜色
- FoldableLayout 改为绝对定位叠加布局,移除 LayoutAnimation(解决 Android 地图渲染空白及卡顿)
- PhotoPicker 拆分为拍照/选图两个独立按钮;选图改用 expo-document-picker 绕过三星 Photo Picker 崩溃问题
- AndroidManifest 移除手动 FileProvider 声明(改由 Expo 插件自动注入)
- 同步更新蓝图文档:新增 category-management 模块、补全各模块已完成任务卡

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 02:17:34 +09:00

3.8 KiB
Raw Blame History

id name area status
floor-map 楼层地图与标记点管理 rn-app done

概述

以真实 SVG 楼层平面图为底图,支持捏合缩放、单指平移、长按添加标记点、拖拽移动标记点。支持 1F/2F/3F/楼顶四个楼层。SVG 内嵌图片通过构建脚本提取,分层以原生 Image 渲染,保证清晰度和旋转精度。

任务卡

SVG 地图渲染(多层架构)

  • status: done
  • complexity: M
  • files: apps/property-survey/src/features/map/FloorMap.tsx, apps/property-survey/src/features/map/floorMaps.generated.ts, apps/property-survey/scripts/generate-maps.js
  • acceptance: 三层渲染:① 底图 JPEG原生 Imagefrom imageUri② SVG 矢量路径SvgXmloverdraw 预渲染提升缩放清晰度,动态计算安全 overdraw 倍数避免 Android Canvas OOM③ 用户嵌入图片(原生 Image从 SVG 提取并按 SVG matrix/rotate 变换还原坐标和旋转角)

捏合缩放 + 单指平移手势

  • status: done
  • complexity: M
  • files: apps/property-survey/src/features/map/FloorMap.tsx
  • acceptance: 使用 react-native-gesture-handler Gesture APIPinch 手势控制缩放MIN_SCALE=1, MAX_SCALE=5Pan 手势minPointers:1, maxPointers:1控制平移双指和单指通过 Gesture.Race 互斥;使用 react-native-reanimated SharedValue 实现原生线程动画

长按添加标记点

  • status: done
  • complexity: M
  • files: apps/property-survey/src/features/map/FloorMap.tsx
  • acceptance: LongPress 手势minDuration:500ms触点坐标反算缩放/平移变换得到地图相对坐标0~1调用 insertMarker 写入数据库;与双指手势通过 Gesture.Race 互斥

标记点图标组件

  • status: done
  • complexity: M
  • files: apps/property-survey/src/features/map/MapMarker.tsx
  • depends: floor-map
  • acceptance: 按相对坐标绝对定位;已有物品的标记点显示彩色图钉 + 数量角标(颜色来自 marker.color选中状态有缩放高亮支持拖拽移动Pan 手势,拖拽结束调用 onDragEnd

楼层标记点数据加载与标记列表

  • status: done
  • complexity: S
  • files: apps/property-survey/src/features/map/MarkerList.tsx
  • depends: floor-map
  • acceptance: 楼层切换或 refreshKey 变化时重新查询;左侧边栏展示当前楼层所有标记点卡片(标签、物品列表含确认状态图标);删除标记点时弹确认对话框含级联删除提示

SVG 地图生成脚本

  • status: done
  • complexity: M
  • files: scripts/generate-maps.js, apps/property-survey/img/1101-1104.svg
  • acceptance: 读取 4 个 SVG 文件;提取背景 JPEGimageUri+ 用户嵌入图片embeddedImages含 cx/cy/width/height/angleDeg/opacity从 svgXml 中去除所有 image 元素及 Inkscape 私有命名空间;生成 floorMaps.generated.ts TypeScript 文件

决策记录

  • SVG 三层渲染架构SvgXml 无法可靠渲染带 rotate/matrix transform 的 <image> 元素(坐标偏移、旋转不准)。改为构建时提取:① 背景 JPEG 用原生 Image 渲染(性能好);② 矢量路径用 SvgXml 渲染(保留矢量清晰度);③ 用户嵌入图片用原生 Image 渲染(精确还原旋转和位置)。
  • SVG overdraw 预渲染SvgXml 在 RN 中被光栅化为固定分辨率纹理,缩放时模糊。通过以 N 倍宽高渲染再 scale(1/N) 缩回,在 Android Canvas 安全内存上限内最大化预渲染分辨率。N 值由 calcSafeOverdraw() 根据 PixelRatio.get() 动态计算,避免高 DPI 设备 OOM。
  • 嵌入图片坐标还原SVG matrix(a,b,c,d,e,f) 变换的图片中心点计算公式:cx = a*(ox+W/2) + c*(oy+H/2) + e,旋转角 angleDeg = atan2(b,a) * 180/π。RN 中 Image 的 transform: rotate 以元素自身中心为锚点,与 SVG transform 语义一致,无需额外偏移修正。