Compare commits

..

522 Commits

Author SHA1 Message Date
1eef357079 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-12-07 14:18:06 +08:00
qiji4215
517d5a884c 1、修改物理车道数编码2、修复车道中心面断面问题3、修复中央隔离带按通行方向左右显示4、修复设施分离按通行方向左右显示5、更新可变线限速样式 2023-12-06 17:21:46 +08:00
qiji4215
3fc43af5bf 1、增加照片记录功能2、增加便签语音及照片功能3、修复便签保存后绘制画布没有消失问题 2023-12-05 17:24:22 +08:00
qiji4215
b906ec83d2 修改设施分离渲染样式 2023-12-04 19:09:29 +08:00
qiji4215
27cbd1a9cf 调整车道边界类型渲染样式 2023-12-04 15:01:03 +08:00
e5df2c0785 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-12-04 11:02:46 +08:00
fb85eebc87 fix: 修改测试定位位置 2023-12-04 11:02:21 +08:00
qiji4215
57538774fe 调整中央隔离带渲染错误 2023-12-01 18:41:54 +08:00
qiji4215
21605c8bbd merge code 2023-12-01 18:20:00 +08:00
qiji4215
1032187dab Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS into origin 2023-12-01 17:59:04 +08:00
qiji4215
2f513c8b43 增加物理车道数渲染及屏蔽物理车道数道路属性 2023-12-01 17:55:13 +08:00
squallzhjch
273fc3d327 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-12-01 16:43:50 +08:00
squallzhjch
8dfd95dff4 修改车信存储 2023-12-01 16:43:25 +08:00
qiji4215
1d0611b7e9 修改车道类型不渲染2、修复列表连续下载失败 2023-12-01 14:32:53 +08:00
qiji4215
edaf8b8784 1、增加简要标题内容定义2、增加全封闭渲染3、修改路口内交通岛编码为3028 2023-11-28 17:29:14 +08:00
qiji4215
55fc6e8d80 增加道路边界类型详情显示 2023-11-28 15:53:52 +08:00
qiji4215
acd086c255 merge code 2023-11-28 15:27:59 +08:00
qiji4215
a93fe8695f 增加对象类要素导入及渲染业务 2023-11-28 14:47:39 +08:00
unknown
4a67fb1026 修改动态资源适配 2023-11-28 09:51:18 +08:00
qiji4215
32d3d1a76f merge code 2023-11-28 09:22:10 +08:00
fa4cf3d251 fix: 合并代码 2023-11-27 15:11:57 +08:00
69849fee98 fix: 修改vtm子模块的git地址 2023-11-27 15:10:48 +08:00
qiji4215
559f55f498 要素样式优化 2023-11-27 09:36:28 +08:00
qiji4215
37a8a4fac8 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-11-24 16:22:11 +08:00
0e96ab1ee2 合并代码 2023-11-24 16:19:33 +08:00
qiji4215
6563a41389 更新图标资源 2023-11-24 13:40:32 +08:00
1ebe58a2a9 feat: symbol添加背景、前景、内容显示区域设置 2023-11-24 09:30:59 +08:00
qiji4215
231d7c429d 更新图标资源 2023-11-24 09:26:35 +08:00
qiji4215
167cbdc4d3 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-11-22 09:54:47 +08:00
qiji4215
1043946c0b 调整杆状障碍物图标资源 2023-11-22 09:54:07 +08:00
squallzhjch
b5afd6fd2b Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt
	collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java
	vtm
2023-11-21 17:40:52 +08:00
squallzhjch
2b506941b6 修改语音播报 2023-11-21 17:34:55 +08:00
2e0712ed2b fix: 修改车信导入功能 2023-11-21 17:06:24 +08:00
qiji4215
796ced9243 提交代码,修复交通标牌不显示,增加车道、道路边界类型杆状障碍物渲染 2023-11-21 17:05:35 +08:00
5fbeb45e5a fix: 合并代码 2023-11-17 09:28:02 +08:00
89b862a0cd feat: 动态marker配置支持多图标设置 2023-11-17 09:24:53 +08:00
qiji4215
3de8ce6a39 调整图标样式 2023-11-16 11:09:08 +08:00
qiji4215
2c571bf9ce 1.增加要素聚合显示数字业务2.调整部分渲染样式 2023-11-15 16:37:44 +08:00
squallzhjch
eaeef833ae Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt
	collect-library/src/main/java/com/navinfo/collect/library/enums/DataCodeEnum.kt
	vtm
2023-11-10 15:17:37 +08:00
squallzhjch
bd024342d2 注释掉测试代码 2023-11-10 15:15:30 +08:00
qiji4215
b123fa543f 修改交通标牌为同点位聚合 2023-11-09 17:25:25 +08:00
qiji4215
e4aff19599 增加交通标牌同点位坐标转换 2023-11-09 16:14:31 +08:00
qiji4215
e7985f195c Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-11-09 15:15:08 +08:00
qiji4215
791fe30bf4 修改车信解析错误并增加主点位捕捉业务 2023-11-09 15:13:22 +08:00
35301e4c48 fix: 修改动态marker显示错乱的问题 2023-11-08 15:50:17 +08:00
c1f4774b43 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-11-07 14:27:18 +08:00
squallzhjch
c2e2d33025 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
2023-11-06 16:33:56 +08:00
squallzhjch
763fef952e 增加车信按车道编辑,自动生成问题描述功能 2023-11-06 16:21:46 +08:00
5ad883d543 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-11-03 17:48:24 +08:00
8fea0fb041 fix: 增加marker外边框,调查渲染稀疏问题 2023-11-03 17:48:12 +08:00
qiji4215
21ebf3900c Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-11-03 17:22:56 +08:00
qiji4215
00c37a8996 增加安装进度处理 2023-11-03 17:21:22 +08:00
92181c5ab4 fix: 合并代码 2023-11-03 15:31:34 +08:00
5df2ba7cd0 feat: 增加车道类型渲染 2023-11-03 15:28:28 +08:00
qiji4215
0f97c08b44 优化数据安装效率,更换第三方库 2023-10-31 15:02:21 +08:00
qiji4215
584eea6928 优化数据安装性能,更换阿里Json库 2023-10-30 16:40:27 +08:00
qiji4215
707f3b8961 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-10-30 10:42:05 +08:00
qiji4215
323298334a merge code 2023-10-30 10:41:48 +08:00
squallzhjch
ffba871e3c 数据库增加索引 2023-10-30 10:36:47 +08:00
qiji4215
db2ecd45be Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt
	app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt
2023-10-30 10:34:42 +08:00
qiji4215
1dc4e807cc 优化数据安装效率,更换压缩库及不进行车道中心线转化面业务 2023-10-30 10:31:10 +08:00
squallzhjch
1c5a8f542b 修改多线程安装 2023-10-27 17:24:56 +08:00
squallzhjch
d6acc030f2 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/assets/omdb_config.json
	app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt
	app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt
2023-10-27 14:49:47 +08:00
squallzhjch
43523d09b4 修改多线程安装 2023-10-27 14:18:38 +08:00
qiji4215
b40a9e2ebb merge codew 2023-10-27 14:05:59 +08:00
qiji4215
f03d8037d2 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/assets/omdb_config.json
	app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt
2023-10-26 15:02:34 +08:00
qiji4215
d3398ae755 增加轨迹多层显示 2023-10-26 14:58:43 +08:00
77482329fa Merge branch 'dev' 2023-10-26 14:48:41 +08:00
squallzhjch
459970d01b 修改多线程安装 2023-10-26 14:28:58 +08:00
squallzhjch
ed116d2acd 修改查询语句 2023-10-26 10:04:20 +08:00
261812b870 fix: 修改测试定位位置 2023-10-26 09:52:47 +08:00
squallzhjch
15bfad1357 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/assets/omdb_config.json
	app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt
	app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt
	vtm
2023-10-26 09:45:16 +08:00
qiji4215
40d07cc329 修改任务新增link刷新列表崩溃问题 2023-10-26 09:43:40 +08:00
squallzhjch
1b5da9e536 优化数据库查询
1、去掉了RenderEntity表的主键
2、去掉了ReferenceEntity表的主键和 与RenderEntity表的关联外键
3、去掉了上面两个表的set,map集合改为int,String基础字段
4、对properties字段进行了压缩
5、将properties表中的linkpid字段移到RenderEntity中
6、查询语句修改
2023-10-26 09:18:02 +08:00
squallzhjch
c7122376cf 优化数据库查询 2023-10-25 10:17:16 +08:00
qiji4215
9bc68b52fa Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-10-25 09:23:18 +08:00
14ae6a695d Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-10-25 09:22:06 +08:00
e9c1190637 feat: 增加立交类型 2023-10-25 09:21:49 +08:00
qiji4215
172d84f8c2 增加轨迹日志信息 2023-10-24 17:53:46 +08:00
8c49ac7bc8 增加车道类型、车道点限速渲染导入 2023-10-24 11:03:57 +08:00
squallzhjch
9cf39d476c Merge branch 'navinfo-20231018'
# Conflicts:
#	app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt
#	app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt
#	collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java
2023-10-20 16:38:53 +08:00
squallzhjch
51c44f00b1 优化数据库查询 2023-10-20 16:30:27 +08:00
00515cfe37 feat: 引入通行车辆类型Lane类型数据,增加对应渲染原则 2023-10-19 16:30:38 +08:00
squallzhjch
129c48f11d 优化数据库查询 2023-10-19 14:47:15 +08:00
7a99a9d0fb fix: 将数据的linkPid提到外边 2023-10-19 09:56:42 +08:00
qiji4215
884ec8a583 merge code 2023-10-18 14:13:55 +08:00
qiji4215
6c29e7f6c7 merge coee 2023-10-17 09:32:47 +08:00
squallzhjch
202e2b3a8e 修改路径规划失败提示 2023-10-17 09:18:25 +08:00
qiji4215
576c66c19d 增加相机状态显示 2023-10-16 19:25:06 +08:00
qiji4215
3bf5db5d55 增加物理车道组业务 2023-10-16 09:22:53 +08:00
qiji4215
998906dcb8 增加施工要素过滤条件 2023-10-14 10:41:00 +08:00
qiji4215
9ff0cb2aa2 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileSource.java
	vtm
2023-10-14 09:58:34 +08:00
dbf4108979 fix: 合并代码 2023-10-13 17:40:51 +08:00
ab873e86af fix: 修改18级overzoom模式,解决部分情况下渲染出错的问题 2023-10-13 17:39:53 +08:00
qiji4215
4957115122 merge code 2023-10-13 17:34:36 +08:00
squallzhjch
7c5a1763fe 修改轨迹回放功能 2023-10-13 17:34:02 +08:00
squallzhjch
06993b6a22 修改轨迹回放功能 2023-10-13 17:33:53 +08:00
squallzhjch
b69f4fc9c6 修改桥 小分类问题
修改 匝道问题
修改数据上传字段改动问题
增加轨迹回放功能
2023-10-13 15:08:26 +08:00
qiji4215
fe8790440c Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-10-11 14:28:09 +08:00
qiji4215
f0c6e633eb 过滤掉车道边界类型无偏移数据,且无offset为0的数据不参与捕捉业务 2023-10-11 14:26:56 +08:00
squallzhjch
f1c6773713 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-10-11 14:14:33 +08:00
squallzhjch
f3ed4f3f72 修改数据上传 2023-10-11 14:13:51 +08:00
qiji4215
0ae4a00346 增加车道边界偏移量计算原则 2023-10-11 13:38:36 +08:00
squallzhjch
887ee7f2e4 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-10-09 14:22:54 +08:00
squallzhjch
e44fc0eeb5 增加定位测试 2023-10-09 14:22:43 +08:00
squallzhjch
c23b6e1c7d 增加定位测试 2023-10-09 14:22:36 +08:00
qiji4215
673d8b900d Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-10-09 14:21:32 +08:00
qiji4215
92ae4af99e merge code 2023-10-09 14:18:31 +08:00
b2d7b8af47 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-10-09 11:07:50 +08:00
9db5e0c4b1 fix: 修改车信渲染位置错误的问题 2023-10-09 11:07:30 +08:00
squallzhjch
eb97cb57b3 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-10-09 10:45:40 +08:00
squallzhjch
fc92cebe4a 增加导流区详情展示
修改数据查询接口
修改数据上传状态动态变化
2023-10-09 10:44:42 +08:00
qiji4215
0fce93ecc9 merge code 2023-10-09 09:58:51 +08:00
b04142fd5d fix: 合并代码 2023-09-28 14:32:03 +08:00
fb789814d3 fix: 修改箭头图标内边距,部分解决出现异形形状时贴图不完全的问题 2023-09-28 14:31:17 +08:00
qiji4215
0627f1917f 修改渲染样式 2023-09-28 10:59:33 +08:00
qiji4215
7c0375c211 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-28 10:20:33 +08:00
qiji4215
c101490242 merge code 2023-09-28 10:16:00 +08:00
f81e01309d Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-28 10:13:10 +08:00
squallzhjch
ecb4cd2f1c Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-28 10:12:38 +08:00
dffd44da0d fix: 修改最大级别为20级 2023-09-28 10:12:37 +08:00
squallzhjch
a92dc071d2 增加符号详情 2023-09-28 10:12:21 +08:00
qiji4215
37de10fe89 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-27 16:21:25 +08:00
qiji4215
7b603e6af3 增加道路边界类型路牙、护栏渲染 2023-09-27 16:20:58 +08:00
squallzhjch
9a4b4d2f58 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-27 14:49:22 +08:00
squallzhjch
4a84dcc9fb 优化UI 2023-09-27 14:48:49 +08:00
squallzhjch
51b021ba59 增加上方障碍物,符号,路口内交通岛 详情 2023-09-27 11:00:25 +08:00
4f9af9c218 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-27 09:38:02 +08:00
a2245f8e7c fix: 修改上方障碍物渲染样式 2023-09-27 09:37:30 +08:00
qiji4215
4c18381125 修改多点列表点击显示问题 2023-09-26 17:46:14 +08:00
qiji4215
1187be699b Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
2023-09-26 17:23:38 +08:00
qiji4215
3471ac9b93 增加列表连续点击后只保留最近一条数据 2023-09-26 17:18:17 +08:00
squallzhjch
b7192a50e4 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-26 17:15:41 +08:00
squallzhjch
1a87a5ca34 修改多点列表点击功能
增加导航设置
2023-09-26 17:15:18 +08:00
qiji4215
b4724f205e 1、修改车道中心面样式,解决缺口问题2、修改道路边界类型间隔与车道类型一致 2023-09-26 16:32:05 +08:00
qiji4215
1f34a8f306 增加车道中心线扩充面业务 2023-09-26 16:14:30 +08:00
0f5c9bfb8d feat: 增加路口内交通岛、上方障碍物的渲染,修改符号、文字颜色 2023-09-25 14:56:02 +08:00
qiji4215
4b91feca22 增加车道边界类型实线渲染样式2.修复数据无法上传问题 2023-09-25 14:37:51 +08:00
squallzhjch
c9f084d289 调试道路施工 2023-09-21 20:47:10 +08:00
squallzhjch
705779f631 增加条件线限速的展示 2023-09-21 16:18:59 +08:00
qiji4215
e37d7bc38f Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-21 16:14:43 +08:00
qiji4215
575540a03b 1、增加要素线捕捉开关2、增加图层开关与要素捕捉联动3、个人中心增加Marker显隐开关4、修复道路属性不显示道路种别问题 2023-09-21 16:14:29 +08:00
qiji4215
ab27048d54 1、增加要素线捕捉开关2、增加图层开关与要素捕捉联动3、个人中心增加Marker显隐开关4、修复道路属性不显示道路种别问题 2023-09-21 16:13:46 +08:00
0c416fec0d Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-21 15:50:50 +08:00
79b86da93c fix: 增加友盟异常统计功能 2023-09-21 15:50:32 +08:00
2292fbc6d8 fix: 修改可变点限速不显示的问题 2023-09-21 15:05:54 +08:00
squallzhjch
781f7d5a52 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-21 10:12:21 +08:00
squallzhjch
af3cd2b464 修改线选择的预警要素距离显示 2023-09-21 10:12:03 +08:00
qiji4215
028fda54b5 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/util/SignUtil.kt
2023-09-21 10:01:21 +08:00
78766de39c fix: 合并代码 2023-09-21 09:57:07 +08:00
qiji4215
121a8cf39c mergecode 2023-09-21 09:55:14 +08:00
squallzhjch
4aac9d1675 修改线选择的预警要素距离显示 2023-09-21 09:46:25 +08:00
squallzhjch
f775267612 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-20 16:21:40 +08:00
squallzhjch
7d29ce2309 路线选择时,要素距离计算 2023-09-20 16:21:26 +08:00
ecdd28898e fix: 合并代码 2023-09-20 15:36:10 +08:00
3dc346f29d feat: symbol增加y方向的偏移选项 2023-09-20 15:35:14 +08:00
qiji4215
2eb8528f98 增加任务错误数据容错2.增加交通标牌详情显示 2023-09-20 15:32:57 +08:00
2b574da6d4 fix: 面纹理优化,根据实际长度设置纹理重复repeat次数 2023-09-20 13:41:16 +08:00
squallzhjch
427e36bb8a Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	vtm
2023-09-20 09:59:34 +08:00
squallzhjch
607d4c290a 预警信息导航功能 2023-09-20 09:42:53 +08:00
qiji4215
03c778c1ec Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-19 16:34:33 +08:00
qiji4215
5320caac69 1、增加任务列表定位2、地图初始化显示底部工具栏3、修改道路形态标题 2023-09-19 16:33:42 +08:00
0bacea8259 feat: 交通标牌2D化渲染 2023-09-19 16:19:33 +08:00
18c36b179e fix: 合并代码 2023-09-19 15:07:46 +08:00
ad95095433 fix: 道路标牌预处理增加获取中心点坐标 2023-09-19 15:05:03 +08:00
10e8f32070 fix: 修改文字渲染,不显示边框 2023-09-19 15:03:52 +08:00
baf223dc39 fix: 修改文字对象渲染,支持按数据颜色渲染 2023-09-19 14:09:57 +08:00
qiji4215
0d9b6e90ac 修复已知bug及优化部分要素渲染效果 2023-09-19 11:22:18 +08:00
qiji4215
633f254b2a merge code 2023-09-18 17:37:32 +08:00
qiji4215
95ca4cb9ff 修改路牙样式,增加对话窗体内容复制功能 2023-09-18 11:04:35 +08:00
squallzhjch
923475b199 修改崩溃问题 2023-09-15 16:16:36 +08:00
qiji4215
934ece1df4 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-15 16:15:53 +08:00
qiji4215
7999d6f8de merge code 2023-09-15 16:15:32 +08:00
qiji4215
25583f6240 修改配置文件,解决大数据量无法下载 2023-09-15 15:37:52 +08:00
093842cbbb fix: 修改任务切换时label图层的marker继续显示的问题 2023-09-15 14:35:30 +08:00
squallzhjch
d78423b039 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
2023-09-15 13:37:15 +08:00
squallzhjch
95f2209cc6 开发路径导航功能 2023-09-15 13:31:37 +08:00
qiji4215
fbdaeb3939 增加全要素捕捉开关及属性信息显示窗体展示 2023-09-14 17:49:39 +08:00
qiji4215
c3d9ed5a2f 对数据插入进行优化重构 2023-09-13 17:53:12 +08:00
qiji4215
de0a1e3223 merge code 2023-09-13 10:49:56 +08:00
qiji4215
a8d88a2ada Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-13 10:22:01 +08:00
qiji4215
fbf2be815f 修改自动定位逻辑 2023-09-13 10:21:17 +08:00
963c84a7d0 fix: 解决冲突 2023-09-13 10:19:44 +08:00
qiji4215
f40f1a1881 增加10S自动定位及指北模式 2023-09-12 17:18:01 +08:00
qiji4215
3caaa57e20 增加地图要素捕捉过滤业务 2023-09-12 11:15:47 +08:00
qiji4215
33d17eea0d 修复冲突 2023-09-11 17:17:32 +08:00
qiji4215
c61599bcc8 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	vtm
2023-09-11 17:13:53 +08:00
qiji4215
5e957c30a9 增加原则设置要素捕捉条件 2023-09-11 16:59:20 +08:00
squallzhjch
e5ebe64e0b 路径绑定测试 2023-09-11 16:15:08 +08:00
qiji4215
30822c7937 修改realm事物存储逻辑,解决OOM问题 2023-09-11 15:59:56 +08:00
squallzhjch
85c9677739 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt
	vtm
2023-09-11 15:16:31 +08:00
squallzhjch
8230e44f83 代码冲突 2023-09-11 15:14:28 +08:00
70b820a358 fix: 修改最高级别下线数据出现幽灵渲染的问题 2023-09-08 17:20:39 +08:00
408d98ddea fix: 修改主点偏移与参考图标不匹配的问题 2023-09-07 17:28:09 +08:00
bcc11946a1 fix: 修改电子眼渲染图标 2023-09-07 14:52:01 +08:00
27b8be2cb1 fix: 修改电子眼图标 2023-09-07 14:26:21 +08:00
qiji4215
dbe81f5bde Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-06 09:32:13 +08:00
ab266bce3e fix: 修改realm插入大量数据OOM问题 2023-09-06 09:31:07 +08:00
qiji4215
6c4eab70a0 merge code 2023-09-06 09:09:23 +08:00
qiji4215
8328876ec8 调整种别渲染线宽 2023-09-05 17:53:50 +08:00
b1e5e30880 fix: 修改数据安装事务提交机制 2023-09-05 16:58:46 +08:00
qiji4215
edf98fe624 merge code 2023-09-05 16:58:34 +08:00
cfa1041f7e Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-09-05 16:02:08 +08:00
ebd70520e4 feat: 修改同点位marker避让时未参考angle角度的问题 2023-09-05 15:59:09 +08:00
1aba0b513d fix: 修改电子眼类型配置错误 2023-09-05 15:58:13 +08:00
0b2b5bfe7d fix: 修改车信渲染配置为动态类型 2023-09-05 15:25:27 +08:00
squallzhjch
0f29f32906 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-05 14:08:33 +08:00
squallzhjch
1206c0d61c 修改交限渲染 2023-09-05 14:07:49 +08:00
qiji4215
4230bbd3d0 merge code 2023-09-05 14:07:11 +08:00
qiji4215
ef13f9a926 merge code 2023-09-05 12:26:21 +08:00
squallzhjch
128c45f90c Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-05 09:19:01 +08:00
squallzhjch
1b5df15491 修改收费站详情 2023-09-05 09:18:24 +08:00
qiji4215
ba063003dd merge code 2023-09-05 09:16:44 +08:00
qiji4215
6d0880b3a9 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-04 10:23:17 +08:00
9a486bde52 fix: 合并代码 2023-09-04 10:22:45 +08:00
d0301aac95 fix: 杆状物要素增加导入时过滤流程 2023-09-04 10:20:43 +08:00
qiji4215
827fe1bf77 merge code 2023-09-04 10:20:41 +08:00
qiji4215
8f9dc82353 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-01 18:00:36 +08:00
squallzhjch
34977af660 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-09-01 17:21:18 +08:00
squallzhjch
5ffb0e68e8 增加收费站的预警信息
增加文字,停止位置,危险信息的详情和预警
2023-09-01 17:20:46 +08:00
qiji4215
624460d546 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-01 14:51:52 +08:00
1762b8d165 fix: 修改箭头对象渲染方向及颜色 2023-09-01 14:51:12 +08:00
qiji4215
b04a8bef8c 修改箭头颜色 2023-09-01 14:51:07 +08:00
qiji4215
d01fb35541 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-09-01 14:27:30 +08:00
qiji4215
2e2d6718f1 merge code 2023-09-01 14:27:12 +08:00
0f2bc264d3 fix: 合并代码 2023-09-01 14:25:56 +08:00
af294bbf50 fix: 修改杆状物渲染为图标样式 2023-09-01 14:24:22 +08:00
qiji4215
a7f9422d9d merge code 2023-09-01 13:32:27 +08:00
8a1d36b117 fix: 完善人行道对象面纹理图片 2023-09-01 10:34:58 +08:00
qiji4215
94c9b8fd4f 增加要素是否捕捉控制参数 2023-09-01 10:26:45 +08:00
qiji4215
8fe236922e Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	vtm
2023-08-31 16:46:15 +08:00
squallzhjch
e4aa29ea32 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-08-31 15:33:15 +08:00
squallzhjch
2d3e725119 增加任务列表下拉刷新功能
增加警示信息的预警面板和详情面板
2023-08-31 15:32:33 +08:00
qiji4215
87190c90ae Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-31 15:20:04 +08:00
qiji4215
6fe9e50b2c merge code 2023-08-31 15:19:44 +08:00
aad0197f5c fix: 优化人行横道和文字渲染样式 2023-08-31 15:06:05 +08:00
qiji4215
45341a9747 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-31 10:38:00 +08:00
qiji4215
31f9358415 merge code 2023-08-31 10:37:16 +08:00
squallzhjch
f5e6a87b9b Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/http/taskupload/TaskUploadScope.kt
	vtm
2023-08-30 14:47:00 +08:00
squallzhjch
9fed02564c 时间区间算法,车道施工,道路施工 2023-08-30 14:45:58 +08:00
4fc6b0cd5b fix: 合并代码 2023-08-30 14:20:04 +08:00
817009953c feat: 增加文字object的渲染 2023-08-30 11:05:56 +08:00
qiji4215
4c53144549 增加人行横道渲染 2023-08-30 11:04:51 +08:00
qiji4215
bfbf89d7e5 merge code 2023-08-28 09:30:15 +08:00
qiji4215
3b951ab9fb Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-25 17:42:02 +08:00
qiji4215
7994ae611a merge code 2023-08-25 17:41:16 +08:00
squallzhjch
6447bbb8d5 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-25 17:35:45 +08:00
30ae2d18d4 fix: 修改桥数据渲染起终点图标按线样式渲染的问题 2023-08-25 17:35:41 +08:00
squallzhjch
bccb235521 时间区间算法 2023-08-25 17:35:35 +08:00
qiji4215
d346dc1d4c merge code 2023-08-25 17:24:30 +08:00
qiji4215
12a1d22651 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-08-25 15:54:38 +08:00
qiji4215
554452ddc9 merge code 2023-08-25 15:42:13 +08:00
f6c52e649a fix: 合并代码 2023-08-25 14:46:54 +08:00
29e78f78f4 fix: 更换车信图标 2023-08-25 14:46:13 +08:00
squallzhjch
31074e8e71 开发道路施工 2023-08-25 14:23:17 +08:00
squallzhjch
7c533faad2 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-08-25 09:28:23 +08:00
squallzhjch
f4495ea202 修改bug 2023-08-25 09:28:04 +08:00
5a9cbd09e6 feat: 增加警示信息图标渲染 2023-08-24 14:27:31 +08:00
squallzhjch
5b2fcbddd9 修改bug 2023-08-24 10:14:07 +08:00
d92a75e2b5 fix: 合并代码 2023-08-23 14:46:29 +08:00
b05c1f9038 fix: 修改电子眼图标渲染 2023-08-23 14:45:05 +08:00
qiji4215
207c61184d 增加非避让属性设置 2023-08-23 14:18:11 +08:00
qiji4215
7e297dbb73 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-08-23 14:11:40 +08:00
qiji4215
5614f513f7 增加道路施工/车道施工渲染业务 2023-08-23 14:08:09 +08:00
e30e824a1b fix: 合并代码 2023-08-23 14:00:54 +08:00
d05222e65f feat: 增加marker支持压盖 2023-08-23 13:57:17 +08:00
qiji4215
9ba310428f 增加道路施工及车道施工 2023-08-22 17:44:37 +08:00
b3bb83032b fix: omdb_config增加是否引入3D Z轴数据参数,默认不引入,如果引入,数据按照3D样式渲染 2023-08-22 13:54:14 +08:00
qiji4215
f43dce5ae2 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-22 11:20:37 +08:00
qiji4215
a310df91e1 增加铁路道口渲染业务 2023-08-22 11:19:45 +08:00
squallzhjch
13c2d55159 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-22 10:09:42 +08:00
squallzhjch
06f77dd1cd 修改数据库查询bug导致交限数据不渲染 2023-08-22 10:09:19 +08:00
qiji4215
7abb32610a 更换图标,修复部分问题 2023-08-22 08:52:53 +08:00
qiji4215
05bd11419d Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-21 10:07:12 +08:00
qiji4215
130b3ff7ad merge code 2023-08-21 10:04:43 +08:00
df2524244f fix: 合并代码 2023-08-18 16:19:09 +08:00
521324fd6e fix: 面纹理渲染修改 2023-08-18 16:17:11 +08:00
qiji4215
75a99929b0 merge code 2023-08-17 17:51:29 +08:00
squallzhjch
95b0dd540f Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-17 17:38:10 +08:00
squallzhjch
31991ebe00 增加多点列表 2023-08-17 17:37:49 +08:00
qiji4215
b53aa520d4 修改道路形态code不对问题 2023-08-17 17:35:06 +08:00
squallzhjch
53e5154c36 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-17 10:10:09 +08:00
squallzhjch
d1040b65ba 修改主页布局 2023-08-17 10:09:31 +08:00
qiji4215
ac17e764ea Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/assets/omdb_config.json
2023-08-17 10:07:06 +08:00
qiji4215
9fe1847f60 merge code 2023-08-17 10:04:48 +08:00
qiji4215
27d21f341f 1.增加护栏渲染2.增加路牙渲染 2023-08-17 09:32:58 +08:00
471e869ad9 fix: 修改vtm配置 2023-08-16 16:52:11 +08:00
58dfe64227 feat: 增加道路形态图层分组 2023-08-16 16:49:38 +08:00
squallzhjch
51b9a398a4 增加道路属性,道路形态展示 2023-08-16 16:43:48 +08:00
qiji4215
0f8f36ea8c 修改车道边界类型渲染效果 2023-08-16 16:31:49 +08:00
f388f7c986 fix: 合并冲突 2023-08-16 13:54:33 +08:00
5f6d363bb8 fix: 添加导流区纹理 2023-08-16 13:52:55 +08:00
squallzhjch
f9b5c8a1d1 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
2023-08-16 13:43:45 +08:00
qiji4215
a0c9dadbd8 merge code 2023-08-16 13:33:34 +08:00
squallzhjch
b17ff18c67 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	collect-library/src/main/java/com/navinfo/collect/library/enum/DataCodeEnum.kt
2023-08-16 11:25:02 +08:00
qiji4215
015733451b 增加草图任务id及重构部分数据库读取业务 2023-08-16 11:24:56 +08:00
squallzhjch
2431fc3bdd 增加道路属性,跨线立交,匝道,上下线分离,隧道,环岛的道路属性展示 2023-08-16 11:22:07 +08:00
qiji4215
7abf0e9e15 merge code 2023-08-15 17:17:45 +08:00
29f6ba22bc Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-15 16:16:15 +08:00
697a80b6c9 fix: 增加导流区渲染样式 2023-08-15 16:16:06 +08:00
qiji4215
04d8922c90 merge code 2023-08-15 16:15:07 +08:00
qiji4215
de86fb57fb 增加SA/PA渲染原则 2023-08-15 14:16:00 +08:00
60eed7d9ca fix: 合并代码 2023-08-15 10:49:55 +08:00
8ba68d19f8 fix: 去除log 2023-08-15 10:49:17 +08:00
qiji4215
5fa01313b4 增加道路形态渲染业务 2023-08-15 10:45:59 +08:00
squallzhjch
f7843baabe Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	app/src/main/java/com/navinfo/omqs/ui/widget/SignUtil.kt
	vtm
2023-08-15 09:52:48 +08:00
squallzhjch
8fba6764bb 增加全封闭,匝道内容显示 2023-08-15 09:47:55 +08:00
qiji4215
4fe231cf02 增加数据过滤 2023-08-14 18:19:26 +08:00
qiji4215
85e863c7b4 merge code 2023-08-14 17:08:47 +08:00
qiji4215
63d36c3e1d Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-14 14:41:18 +08:00
qiji4215
08283761e0 修改数据类型增加PA/SA要素编码处理 2023-08-14 14:18:19 +08:00
squallzhjch
dc4c6daf2e 增加坐标复制和测量结果复制功能 2023-08-11 17:24:56 +08:00
qiji4215
f100578627 merge code 2023-08-11 16:18:16 +08:00
qiji4215
1b2c149c43 merge code 2023-08-11 15:35:14 +08:00
squallzhjch
4417201497 恢复代码 2023-08-11 15:32:22 +08:00
squallzhjch
3dd4daa11e 优化UI 2023-08-11 14:51:37 +08:00
squallzhjch
212193dc26 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java
	collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java
	vtm
2023-08-11 14:30:42 +08:00
squallzhjch
595cc42b3f 优化UI 2023-08-11 14:29:18 +08:00
squallzhjch
00e197f264 优化UI 2023-08-11 14:28:55 +08:00
qiji4215
dfcc1ca0e7 merge code 2023-08-11 14:20:26 +08:00
qiji4215
dcca1d50ea merge code 2023-08-11 10:27:35 +08:00
qiji4215
215aad041e Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java
	vtm
2023-08-11 10:05:35 +08:00
qiji4215
061aca96ab merge code 2023-08-11 09:49:45 +08:00
squallzhjch
54b30d5db5 修改测量工具的联动功能
修改崩溃bug
2023-08-10 14:02:52 +08:00
qiji4215
311823cc6a merge code 2023-08-10 13:49:59 +08:00
qiji4215
8d7c6036f1 merge code 2023-08-10 13:43:36 +08:00
qiji4215
af4baf80b5 增加路口要素按任务link渲染 2023-08-10 13:37:39 +08:00
squallzhjch
6bed16f470 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-08-10 11:18:40 +08:00
squallzhjch
4baa137ad6 重构测量工具代码,修改代码逻辑和展现形式。
增加面积,角度测量
修改地图渲染面会崩溃的问题
2023-08-10 11:18:14 +08:00
qiji4215
96316fe1bb Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-08-10 10:56:52 +08:00
qiji4215
57ccf8584b 1.增加搜索相关功能业务2.解决下载omdb后不及时渲染问题3.增加按任务及link关联渲染业务4.接口中增加按任务查询条件 2023-08-10 10:51:22 +08:00
d11dd5e806 fix: 适配面纹理及文字类型 2023-08-09 17:20:57 +08:00
4b7ccbc3b4 fix: 合并代码 2023-08-08 16:00:11 +08:00
9bc3560647 feat: 普通marker支持动态配置 2023-08-08 15:55:09 +08:00
958e94ea1e feat: 面数据增加自适应纹理 2023-08-08 15:29:44 +08:00
qiji4215
1765b8801b 增加要素按任务关联LinkPid进行渲染业务 2023-08-04 15:50:42 +08:00
qiji4215
8a8a48fbb5 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java
2023-08-04 10:15:17 +08:00
squallzhjch
8578ea0afd Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-04 10:11:55 +08:00
squallzhjch
8f3bd1926a 增加要素捕捉功能,
增加测量功能
2023-08-04 10:11:29 +08:00
qiji4215
19c8fd3cf3 1.增加按任务linkpid进行数据显示业务2.增加桥要素渲染 2023-08-04 10:10:46 +08:00
0462a1682e fix: 合并editormarker样式配置 2023-08-01 17:15:40 +08:00
a500d3ffea fix: 解决冲突 2023-08-01 16:30:08 +08:00
09b3dd2f43 fix: 适配3D渲染 2023-08-01 16:26:33 +08:00
c2d47afed7 fix: 修改symbol要素在限制层级下依然显示的问题 2023-08-01 16:01:39 +08:00
qiji4215
c54cbae676 修改问题记录上传无效问题 2023-08-01 15:36:56 +08:00
5d0ce1e4ce Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-08-01 09:54:23 +08:00
4806168274 fix: 修改渲染样式 2023-08-01 09:54:11 +08:00
qiji4215
34ee4a0101 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-07-28 17:06:44 +08:00
qiji4215
3c8bf307a2 修改渲染策略 2023-07-28 11:04:42 +08:00
squallzhjch
5266cbb4b1 修改编辑评测数据编辑时切换任务关闭 右侧面板 2023-07-28 10:03:38 +08:00
qiji4215
0979cc7caf Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-07-28 09:41:21 +08:00
qiji4215
0b7b262540 调整资源 2023-07-28 09:40:31 +08:00
squallzhjch
485c2b4b79 修改离线地图下载的按钮状态
修改详细信息面板快捷进入新增数据界面
2023-07-27 17:15:51 +08:00
qiji4215
1d258c4b8e 修改已知问题2.调整渲染图层策略及样式 2023-07-27 16:35:15 +08:00
1188e470bb fix: 解析omdb高程数据-道路标牌和杆状物 2023-07-27 15:53:24 +08:00
squallzhjch
b9e3e4766e Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-07-27 11:16:49 +08:00
squallzhjch
2b4b2645a6 修改任务下载 2023-07-27 11:16:36 +08:00
qiji4215
53ae5ab043 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-07-26 18:37:54 +08:00
qiji4215
27e812c49f 调整渲染级别 2023-07-26 18:37:35 +08:00
squallzhjch
01bc6ac7fc 修改登录逻辑和数据访问顺序
增加任务和作业数据统计
2023-07-26 17:08:45 +08:00
7ad3fcbbb4 fix: 合并代码 2023-07-26 15:29:13 +08:00
1a19dc1cfa feat: 杆状物、交通面板3D化测试 2023-07-26 14:45:16 +08:00
squallzhjch
e1b0e45157 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt
	app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt
	vtm
2023-07-26 10:53:01 +08:00
squallzhjch
e69b6fca03 修改任务下载按钮刷新不及时问题 2023-07-26 10:49:23 +08:00
qiji4215
43bd63a397 渲染表增加任务id和显示缩放级别控制 2023-07-26 10:21:50 +08:00
squallzhjch
7a268f43e0 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-07-25 10:37:28 +08:00
squallzhjch
33cc1dc243 修改任务下载刷新不及时 2023-07-25 10:37:06 +08:00
qiji4215
17524bbabb Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
2023-07-24 14:30:12 +08:00
qiji4215
b92110c785 修改渲染策略 2023-07-24 14:28:49 +08:00
squallzhjch
5806fbf5ac 增加非空判断 2023-07-21 15:50:44 +08:00
qiji4215
7df7cf1345 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-07-21 15:40:32 +08:00
squallzhjch
19876f8275 修改冲突 2023-07-21 15:39:44 +08:00
squallzhjch
6c386505d6 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt
	collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt
2023-07-21 15:30:20 +08:00
squallzhjch
2bb7203539 评测数据增加任务id
评测数据根据所选任务显隐
修改评测link和评测数据的联动维护
2023-07-21 15:11:21 +08:00
qiji4215
04f157c036 修改测评问题人记录错误2.调整车道边界类型渲染原则 2023-07-21 15:10:28 +08:00
qiji4215
c83ed1b97e 完善室内整理功能 2023-07-20 16:01:42 +08:00
qiji4215
0848ee491b 增加登录缓存校验 2023-07-20 10:48:38 +08:00
qiji4215
392fb91215 增加自动定位开关 2023-07-19 17:46:50 +08:00
qiji4215
58f5329a75 增加相机自动重新连接功能 2023-07-19 17:40:44 +08:00
qiji4215
45de9982fc 增加室内整理工具反向控制 2023-07-19 17:01:02 +08:00
qiji4215
063927653a 增加室内整理工具反向控制业务 2023-07-18 18:00:31 +08:00
qiji4215
0378378dec 修改定位无效问题 2023-07-18 17:08:07 +08:00
qiji4215
53275472f4 解决代码冲突 2023-07-18 15:56:21 +08:00
qiji4215
44d1473a4a Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt
2023-07-18 15:54:06 +08:00
qiji4215
78bd363372 重构轨迹回放业务 2023-07-18 15:45:11 +08:00
squallzhjch
4ef07f470d 修改点击聚合marker崩溃问题 2023-07-18 15:13:01 +08:00
squallzhjch
71948187c3 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
2023-07-18 10:58:21 +08:00
3f173aa86f 面数据增加纹理 2023-07-18 10:56:21 +08:00
squallzhjch
45e3e3ca0d 修改地图卡顿
修改新增link线型编辑
2023-07-18 10:49:56 +08:00
qiji4215
dfbea188ea merge code 2023-07-18 10:43:41 +08:00
qiji4215
07c0103de1 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt
2023-07-18 10:12:41 +08:00
qiji4215
694ad106d7 修复地图卡顿问题 2023-07-18 10:11:34 +08:00
qiji4215
6210f41b69 增加室内整理工具更新信息逻辑 2023-07-17 14:49:21 +08:00
squallzhjch
e3695fb6cb 解决代码冲突 2023-07-14 16:45:31 +08:00
qiji4215
1253cc10be Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-07-14 16:42:15 +08:00
squallzhjch
eea7cb6fdf 解决代码冲突 2023-07-14 16:41:39 +08:00
qiji4215
3883c934fc merge code 2023-07-14 16:40:14 +08:00
squallzhjch
1be2b00bf2 解决代码冲突 2023-07-14 16:33:09 +08:00
squallzhjch
3fb89ca470 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt
2023-07-14 16:32:39 +08:00
squallzhjch
1412f7106a 增加评测link功能 2023-07-14 16:28:19 +08:00
qiji4215
4fa9df8e3c merge code 2023-07-14 14:25:44 +08:00
qiji4215
c8ac5c9582 1、适配上传接口2、代码融合 2023-07-14 14:20:34 +08:00
qiji4215
c3f299222a Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt
	collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt
2023-07-14 11:07:57 +08:00
qiji4215
108c6daa2f merge code 2023-07-14 10:54:02 +08:00
squallzhjch
be2d0389cf 增加评测link功能 2023-07-13 17:43:38 +08:00
squallzhjch
43b62f9947 增加评测link功能 2023-07-13 16:36:43 +08:00
qiji4215
7ebdfc93ff 增加轨迹存储 2023-07-13 16:00:19 +08:00
qiji4215
d1f7129549 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt
2023-07-13 14:16:51 +08:00
squallzhjch
23a3490c20 增加评测link功能 2023-07-13 14:09:58 +08:00
qiji4215
29a90b5555 更换隧道起终点坐标 2023-07-12 13:55:05 +08:00
qiji4215
3c5c1c3220 增加车道边界类型渲染2.增加地图级别联动底部工具栏调整位置 2023-07-12 10:47:53 +08:00
qiji4215
c8c7c4d4ce Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-07-07 18:06:38 +08:00
qiji4215
b505bdc044 增加隧道渲染原则 2023-07-07 18:06:19 +08:00
squallzhjch
ae44b848e2 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-07-07 13:55:31 +08:00
squallzhjch
07d3165813 增加便签功能 2023-07-07 13:54:08 +08:00
qiji4215
7c57a451f1 修改车道面为车道中心线并在辅助表中存储 2023-07-05 14:09:45 +08:00
13089fe6f2 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-07-05 10:13:51 +08:00
df3a32a07d feat: 增加车信图标及渲染配置 2023-07-05 10:13:24 +08:00
qiji4215
e3a78aeb77 增加任务无mark校验及关闭业务 2023-07-04 10:08:47 +08:00
qiji4215
5e32c7ac8e 增加版本号显示 2023-06-30 17:45:33 +08:00
qiji4215
39a3835de4 增加任务缓存处理,保留已上传最近3个月数据及未上传任务 2023-06-30 17:00:02 +08:00
c1616ed744 feat: 添加车信测试图标 2023-06-30 15:35:05 +08:00
squallzhjch
d84356415c 增加多媒体照片 2023-06-30 14:31:51 +08:00
squallzhjch
f415ded353 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-06-29 17:23:12 +08:00
squallzhjch
c00592f6d5 统一地图图标渲染尺寸
优化提前显示面板,详细信息面板
增加多媒体照片
2023-06-29 17:22:40 +08:00
qiji4215
827e6b31b8 1、问题记录增加要素编码存储2.回传问题增加未测评判断业务 2023-06-29 17:16:36 +08:00
qiji4215
b9d85640aa Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-06-28 11:14:12 +08:00
qiji4215
f6b4c7543a 1、修改问题描述2、修改定位适配较低系统 2023-06-28 11:13:03 +08:00
squallzhjch
2fe71fe94f Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
2023-06-27 16:13:50 +08:00
squallzhjch
6921e4c0b0 增加车信提前看板显示
调整条件限速,常规限速提前看板,详细看板
调整道路名详细信息
2023-06-27 16:11:11 +08:00
8551ce43a7 fix: 完善路口和电子眼渲染样式 2023-06-26 14:56:29 +08:00
qiji4215
2c9c20e913 merge code 2023-06-26 14:45:39 +08:00
qiji4215
02b65eedf2 merge code 2023-06-26 14:24:46 +08:00
qiji4215
fb08f42848 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/Constant.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt
2023-06-26 14:18:48 +08:00
qiji4215
97ad787f51 1、增加室内整理工具布局2、封装定时业务类 2023-06-26 14:12:38 +08:00
qiji4215
d3fc05adad 增加室内整理工具更新接口 2023-06-25 17:50:23 +08:00
3d4d6c13a7 fix: 注释无用渲染样式 2023-06-25 17:12:02 +08:00
e9af1785f8 fix: 修改普通交限入库规则,首尾相接数据不入库 2023-06-25 16:49:25 +08:00
qiji4215
a970ca1992 增加室内整理工具扫描业务 2023-06-25 16:44:40 +08:00
a5e964efbb feat: 增加路口渲染 2023-06-25 10:11:24 +08:00
qiji4215
d0b85d649a 封装二维码扫描业务 2023-06-21 17:51:49 +08:00
squallzhjch
fd2c5d0358 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/assets/omdb_config.json
2023-06-21 10:21:50 +08:00
squallzhjch
7b4229d756 增加道路名显示和详细信息功能 2023-06-21 10:10:21 +08:00
f6346acb89 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-06-20 14:30:30 +08:00
ac6e3d577a fix: 增加道路面渲染 2023-06-20 14:30:07 +08:00
squallzhjch
1fe90ccf26 增加提示项 2023-06-16 17:16:20 +08:00
squallzhjch
236f422fa1 修改冲突代码 2023-06-16 15:29:01 +08:00
squallzhjch
89c7fd4585 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	collect-library/src/main/assets/editormarker.xml
	vtm
2023-06-16 15:24:02 +08:00
squallzhjch
083a6fd57a 调整离线地图UI,任务列表UI,个人中心UI 2023-06-16 15:16:10 +08:00
dee79fd63a fix: 合并冲突 2023-06-16 13:49:20 +08:00
23eaaf5aec fix: 修改测试按钮跳转位置 2023-06-15 10:23:11 +08:00
squallzhjch
6cd9bab9e1 调整中控联动UI 2023-06-14 14:42:34 +08:00
qiji4215
d5fbeec02b merge code 2023-06-14 14:29:13 +08:00
qiji4215
94467f21a1 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
2023-06-14 14:23:08 +08:00
qiji4215
4e98a5745c 1.优化部分页面2.修复Task无link数据地图及控制业务无效问题 2023-06-14 14:20:37 +08:00
squallzhjch
876d5bef44 调整中控联动UI 2023-06-14 14:06:13 +08:00
squallzhjch
46fa06d1a8 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/AndroidManifest.xml
	app/src/main/java/com/navinfo/omqs/ui/fragment/console/ConsoleFragment.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/layermanager/LayerManagerFragment.kt
2023-06-14 13:51:43 +08:00
squallzhjch
e352a34ef9 调整中控联动UI 2023-06-14 13:47:49 +08:00
79659e78fb fix: 面渲染测试 2023-06-13 17:48:48 +08:00
qiji4215
e0b6d687f6 1.修改布局允许水平旋转2.修复主页访问图层管理崩溃问题3.扩充轨迹字段 2023-06-13 17:00:02 +08:00
qiji4215
4884db93fc merge code 2023-06-09 19:10:55 +08:00
qiji4215
43e554b344 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-06-09 16:59:31 +08:00
qiji4215
4614ef4db8 merge code 2023-06-09 16:59:10 +08:00
squallzhjch
4ddabe7a94 增加中控页面 2023-06-09 16:58:08 +08:00
squallzhjch
5665638120 增加中控页面 2023-06-09 13:38:40 +08:00
qiji4215
8310f4b7e7 重构离线地图页面 2023-06-08 11:07:15 +08:00
qiji4215
999052507a 重构网络返回对象2.对应服务上报问题接口变更 2023-06-08 10:48:44 +08:00
02a65100c8 fix: 修改车道边线数据导入时的选取原则 2023-06-05 15:59:56 +08:00
qiji4215
0d3b16503a Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-06-05 10:01:36 +08:00
qiji4215
e42ba1909c merge code 2023-06-05 10:00:46 +08:00
squallzhjch
c6bf940dc4 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	vtm
2023-06-02 14:20:18 +08:00
squallzhjch
e4f28405dc 解决冲突 2023-06-02 14:18:49 +08:00
squallzhjch
ebc4ddf5a9 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	app/src/main/res/layout/adapter_sign.xml
2023-06-02 14:17:05 +08:00
肖岩
c643f2e08d Merge branch 'master' into 'master'
增加车道边线渲染

See merge request CollectVehicle/OneMapQS!2
2023-06-02 14:16:45 +08:00
3d4b9ce78d fix: 合并代码 2023-06-02 14:16:30 +08:00
squallzhjch
d68e7bd768 调整UI 2023-06-02 14:12:25 +08:00
qiji4215
5f953aa816 1.解决新增问题后点击获取数据无效2.预警面板增加快速问题记录 2023-06-02 13:57:50 +08:00
c237ccb928 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-06-02 10:06:30 +08:00
6a77e69ed7 feat: 增加车道边线渲染 2023-06-02 10:05:53 +08:00
qiji4215
6cc0a20aa6 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-06-01 10:18:19 +08:00
qiji4215
02cf95b83d merge code 2023-06-01 10:18:00 +08:00
squallzhjch
b8015a8b20 调整任务列表的UI,
增加任务列表和道路link的筛选功能
调整问题原因面板的UI
增加经纬度定位功能
2023-05-31 15:47:38 +08:00
qiji4215
7a7eb61401 merge code 2023-05-30 14:00:32 +08:00
qiji4215
7fb8af31b5 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-05-26 17:51:13 +08:00
squallzhjch
e9735ee4d8 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-05-26 17:45:56 +08:00
squallzhjch
8d6bb8c6e8 修改普通交限的道路渲染 2023-05-26 17:45:36 +08:00
qiji4215
5ff8509c95 merge code 2023-05-26 17:35:15 +08:00
squallzhjch
75a6d56471 调整看板 2023-05-26 17:23:47 +08:00
qiji4215
591b9cd579 merge code 2023-05-26 15:32:47 +08:00
c2416ab709 fix: 修改submodule配置 2023-05-26 15:24:03 +08:00
61165ff9f0 fix: 合并代码 2023-05-26 15:22:33 +08:00
90897174ac fix: 修改渲染样式 2023-05-26 15:18:23 +08:00
squallzhjch
d5d251c85e Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-05-26 15:16:19 +08:00
squallzhjch
dae344afc2 调整看板 2023-05-26 15:16:09 +08:00
qiji4215
64eb25d5d4 mergecode 2023-05-26 15:08:09 +08:00
qiji4215
8988661bed Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-05-26 14:54:05 +08:00
f2891d6d2f fix: 修改submodule的仓库地址 2023-05-26 14:53:27 +08:00
squallzhjch
c94eb5654d Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-05-26 14:01:49 +08:00
squallzhjch
10ec7a1e04 增加经纬度定位功能 2023-05-26 14:01:36 +08:00
qiji4215
f99517b386 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-05-26 13:56:32 +08:00
549031e8a8 Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-05-26 13:47:39 +08:00
22f52429f4 fix: 修改普通交限的显示 2023-05-26 13:46:32 +08:00
squallzhjch
59bc0f544b 调整UI
调整道路属性面板
2023-05-26 10:51:36 +08:00
qiji4215
46268b3549 增加点击事件返回联动 2023-05-26 10:51:24 +08:00
qiji4215
d1aab7aabb Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-05-26 10:24:12 +08:00
qiji4215
3c0fe6b1b1 merge code 2023-05-26 10:24:00 +08:00
squallzhjch
b6bbcad634 调整UI
调整道路属性面板
2023-05-26 10:06:58 +08:00
qiji4215
e86b0696b6 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/res/layout/text_item_select.xml
2023-05-26 09:59:24 +08:00
12e9fd1a2a feat: 增加交限和交通灯的渲染图标 2023-05-25 15:10:40 +08:00
80b8b60556 fix: 修改数据导入 2023-05-24 17:12:34 +08:00
squallzhjch
4e997b8632 调整UI
调整道路属性面板
2023-05-24 15:57:52 +08:00
4d579d87c4 fix: 增加右偏功能,增加角度计算功能 2023-05-24 14:04:11 +08:00
f160f1dd00 fix: 修改git忽略文件 2023-05-23 15:44:41 +08:00
squallzhjch
d89ad95a17 调整UI
增加道路属性面板
2023-05-23 14:03:36 +08:00
squallzhjch
6d0f36068d Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS 2023-05-23 09:48:21 +08:00
squallzhjch
dc6b4b91e5 调整UI
增加道路属性面板
2023-05-23 09:48:07 +08:00
qiji4215
6af2479dbd Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-05-19 17:25:10 +08:00
qiji4215
24f58b7872 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS 2023-05-19 17:14:12 +08:00
qiji4215
2807b2f689 增加登录接口和问题回传接口变更 2023-05-19 17:12:19 +08:00
qiji4215
c42045ba45 Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
 Conflicts:
	app/src/main/res/layout/fragment_evaluation_result.xml
2023-05-19 09:28:50 +08:00
qiji4215
4ec107b359 merge code 2023-05-19 09:27:11 +08:00
qiji4215
e6c2c3f76d 增加删除确认窗体2增加返回箭头 2023-05-11 16:36:35 +08:00
1031 changed files with 75942 additions and 4487 deletions

4
.gitignore vendored
View File

@@ -12,6 +12,4 @@
/build
/captures
.externalNativeBuild
.cxx
local.properties
/vtm/
.cxx

3
.gitmodules vendored
View File

@@ -1,3 +1,4 @@
[submodule "vtm"]
path = vtm
url = git@github.com:mapsforge/vtm.git
url = git@gitee.com:navinfo-mobile/vtm.git
branch = navinfo

View File

@@ -6,21 +6,27 @@ plugins {
id 'kotlin-parcelize' // 序列化
id 'androidx.navigation.safeargs.kotlin'//Safe Args传递数据
}
//定义时间
def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
android {
namespace 'com.navinfo.omqs'
compileSdk 33
defaultConfig {
applicationId "com.navinfo.omqs"
// applicationId "com.navinfo.omqs"
minSdk 21
targetSdk 21
versionCode 1
versionName "1.0"
versionName "1.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "armeabi", "mips"
abiFilters "arm64-v8a", "armeabi-v7a", "armeabi", "mips"
}
}
@@ -71,9 +77,9 @@ android {
}
dependencies {
api project(':collect-library')
implementation project(path: ':vtm-android')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
@@ -101,6 +107,7 @@ dependencies {
// implementation 'javax.xml.stream:stax-api:1.0-2'
// implementation 'com.bea.xml.stream:com.bea.xml.stream:1.0.0'
implementation 'commons-io:commons-io:2.11.0'
implementation 'com.alibaba:fastjson:1.2.73'
// 读取spatialite文件
implementation 'com.github.sevar83:android-spatialite:2.0.1'
@@ -109,6 +116,32 @@ dependencies {
//kotlin反射
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.0"
implementation "org.jetbrains.kotlin:kotlin-reflect:1.7.0"
implementation 'com.permissionx.guolindev:permissionx:1.4.0'
def camerax_version = "1.1.0-alpha04"
// The following line is optional, as the core library is included indirectly by camera-camera2
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
// If you want to additionally use the CameraX Lifecycle library
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
// If you want to additionally use the CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha24"
implementation 'com.google.mlkit:barcode-scanning:16.1.1'
//图片加载
implementation 'com.github.bumptech.glide:glide:4.15.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'
// implementation "io.realm:realm-kotlin-extensions:6.1.0"
//带侧滑的自定义列表
implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
// 友盟统计SDK
implementation 'com.umeng.umsdk:common:9.4.7'// 必选
implementation 'com.umeng.umsdk:asms:1.4.1'// 必选
implementation 'com.umeng.umsdk:apm:1.5.2' // U-APM包依赖(必选)
}
//允许引用生成的代码
kapt {

View File

@@ -1,24 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="3"
android:versionName="1.4"
package="com.navinfo.omqs">
<!-- 这个权限用于相机权限-->
<uses-feature android:name="android.hardware.camera.any" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- 用于访问wifi网络信息wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 这个权限用于获取wifi的获取权限wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 访问网络,网络定位需要上网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- 访问网络,网络定位需要上网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许访问振动设备 -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 允许使用PowerManager的 WakeLocks保持进程在休眠时从屏幕消失 -->
@@ -29,7 +36,13 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 读取缓存数据 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 音频权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--闹钟和提醒-->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!--android:largeHeap="true" 大内存 128M -->
<application
android:name=".OMQSApplication"
@@ -46,7 +59,6 @@
android:name=".ui.activity.login.LoginActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="landscape"
android:theme="@style/Theme.OMQualityInspection">
<intent-filter>
@@ -54,14 +66,32 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="um.650bece7b2f6fa00ba573c7a" />
</intent-filter>
</activity>
<activity
android:name=".ui.activity.map.MainActivity"
android:exported="false"
android:launchMode="singleTask"
android:screenOrientation="landscape"
android:exported="false"
android:theme="@style/Theme.OMQualityInspection" />
<activity
android:name=".ui.activity.scan.QrCodeActivity"
android:theme="@style/Theme.OMQualityInspection"
android:screenOrientation="portrait" />
<activity
android:name=".ui.activity.scan.QRCodeResultActivity"
android:theme="@style/Theme.OMQualityInspection"
android:screenOrientation="portrait" />
<meta-data
android:name="ScopedStorage"
android:value="true" />

View File

@@ -1,88 +1,897 @@
{
"tableMap" : {
"2001": {
"table": "OMDB_RD_LINK",
"code": 2001,
"name": "道路线"
},
"2008": {
"table": "OMDB_RD_LINK_KIND",
"code": 2008,
"name": "道路种别"
},
"2010": {
"table": "OMDB_LINK_DIRECT",
"code": 2010,
"name": "道路方向"
},
"4002": {
"table": "OMDB_SPEEDLIMIT",
"code": 4002,
"name": "常规点限速",
"transformer": [
{
"k": "maxSpeed",
"v": "0",
"klib": "maxSpeed",
"vlib": "限"
}
]
},
"4003":{
"table": "OMDB_SPEEDLIMIT_COND",
"code": 4003,
"name": "条件点限速",
"transformer": [
{
"k": "maxSpeed",
"v": "0|",
"klib": "maxSpeed",
"vlib": "限"
}
]
},
"4004":{
"table": "OMDB_SPEEDLIMIT_VAR",
"code": 4004,
"name": "可变点限速",
"transformer": [
{
"k": "location",
"v": "1",
"klib": "location",
"vlib": "左"
},
{
"k": "location",
"v": "2",
"klib": "locationlib",
"vlib": "右"
},
{
"k": "location",
"v": "3",
"klib": "location",
"vlib": "上"
}
]
},
"5001":{
"table": "OMDB_LANE_LINK_LG",
"code": 5001,
"name": "车道中心线"
},
"2041":{
"table": "OMDB_LANE_NUM",
"code": 2041,
"name": "车道数",
"transformer": [
{
"k": "laneS2e",
"v": "~",
"klib": "left_00",
"vlib": "laneNumLeft00()"
}
]
}
}
}
[
{
"tableGroupName": "普通图层",
"tableMap": {
"1007": {
"table": "OMDB_NODE_FORM",
"code": 1007,
"name": "点形态",
"existSubCode": true,
"checkLinkId": false,
"zoomMin": 15,
"zoomMax": 20
},
"1007_PA": {
"table": "OMDB_NODE_PA",
"code": 1007,
"name": "点形态PA",
"existSubCode": true,
"checkLinkId": false,
"zoomMin": 15,
"zoomMax": 20
},
"1012": {
"table": "OMDB_CHECKPOINT",
"code": 1012,
"name": "检查点",
"catch": true,
"zoomMin": 15,
"zoomMax": 20
},
"2001": {
"table": "OMDB_RD_LINK",
"code": 2001,
"name": "道路线",
"zoomMin": 15,
"zoomMax": 17,
"catch": true,
"checkLinkId": false
},
"2002": {
"table": "OMDB_RD_LINK_FUNCTION_CLASS",
"code": 2002,
"name": "道路功能等级",
"zoomMin": 15,
"zoomMax": 17
},
"2008": {
"table": "OMDB_RD_LINK_KIND",
"code": 2008,
"name": "道路种别",
"zoomMin": 15,
"zoomMax": 17,
"catch": false,
"checkLinkId": false
},
"2010": {
"table": "OMDB_LINK_DIRECT",
"code": 2010,
"name": "道路方向",
"zoomMin": 15,
"zoomMax": 17,
"checkLinkId": false
},
"2011": {
"table": "OMDB_LINK_NAME",
"code": 2011,
"name": "道路名",
"zoomMin": 15,
"zoomMax": 17,
"checkLinkId": false,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateRoadName()"
}
]
},
"2013": {
"table": "OMDB_LANE_MARK_BOUNDARYTYPE",
"code": 2013,
"name": "车道边界类型",
"zoomMin": 18,
"zoomMax": 20,
"isDependOnOtherTable": true,
"checkLinkId": false,
"filterData": true,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "unpackingLaneBoundary()"
}
]
},
"2017": {
"table": "OMDB_LINK_CONSTRUCTION",
"code": 2017,
"name": "道路施工",
"catch": true,
"checkLinkId": true,
"zoomMin": 15,
"zoomMax": 17
},
"2019": {
"table": "OMDB_LINK_SPEEDLIMIT",
"code": 2019,
"name": "常规线限速",
"zoomMin": 15,
"zoomMax": 17,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine()"
}
]
},
"2020": {
"table": "OMDB_LINK_SPEEDLIMIT_COND",
"code": 2020,
"name": "条件线限速",
"zoomMin": 15,
"zoomMax": 17,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine()"
}
]
},
"2021": {
"table": "OMDB_LINK_SPEEDLIMIT_VAR",
"code": 2021,
"name": "可变线限速",
"zoomMin": 15,
"zoomMax": 17
},
"2070": {
"table": "OMDB_LINK_SEPARATION",
"code": 2070,
"name": "设施分离",
"zoomMin": 18,
"zoomMax": 20,
"filterData": true,
"catch": true
},
"2071": {
"table": "OMDB_LINK_MEDIAN",
"code": 2071,
"name": "中央隔离带",
"zoomMin": 18,
"zoomMax": 20,
"isDependOnOtherTable": true,
"filterData": true,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateLinkMedianToPolygon()"
}
]
},
"2083": {
"table": "OMDB_RDBOUND_BOUNDARYTYPE",
"code": 2083,
"name": "道路边界类型",
"checkLinkId": true,
"filterData": true,
"zoomMin": 18,
"zoomMax": 20,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "dengfenLineString()"
}
]
},
"2090": {
"table": "OMDB_LANE_CONSTRUCTION",
"code": 2090,
"name": "车道施工",
"existSubCode": true,
"catch": true,
"zoomMin": 18,
"zoomMax": 20
},
"2092": {
"table": "OMDB_LANE_TYPE_ACCESS",
"code": 2092,
"name": "车道类型",
"catch": true,
"isDependOnOtherTable": false,
"zoomMin": 18,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "filterLaneTypeAccess()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateLaneTypeAccessS2ERefPoint()"
}
]
},
"2201": {
"table": "OMDB_BRIDGE",
"code": 2201,
"name": "桥",
"catch": true,
"existSubCode": true,
"isDependOnOtherTable": false,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferencePoint(bridgeType,OMDB_BRIDGE)"
}
]
},
"2202": {
"table": "OMDB_TUNNEL",
"code": 2202,
"name": "隧道",
"zoomMin": 15,
"zoomMax": 20,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferencePoint()"
}
]
},
"2617": {
"table": "OMDB_PHY_LANENUM",
"code": 2617,
"name": "物理车道数",
"zoomMin": 15,
"zoomMax": 18,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generatePhyName()"
}
]
},
"2638": {
"table": "OMDB_LANE_ACCESS",
"code": 2638,
"name": "通行车辆类型Lane",
"zoomMin": 15,
"zoomMax": 20,
"catch": true,
"filterData": false,
"checkLinkId": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateLaneAccessType()"
}
]
},
"3001": {
"table": "OMDB_OBJECT_OH_STRUCT",
"code": 3001,
"name": "上方障碍物",
"zoomMin": 15,
"zoomMax": 20,
"catch": true,
"checkLinkId": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "getPolygonCenterPoint()"
}
]
},
"3002": {
"table": "OMDB_OBJECT_TEXT",
"code": 3002,
"name": "文字",
"zoomMin": 18,
"zoomMax": 20,
"catch": true,
"checkLinkId": true,
"transformer": []
},
"3003": {
"table": "OMDB_OBJECT_SYMBOL",
"code": 3003,
"name": "符号",
"checkLinkId": true,
"zoomMin": 18,
"zoomMax": 20,
"catch": true,
"transformer": []
},
"3004": {
"table": "OMDB_OBJECT_ARROW",
"code": 3004,
"name": "箭头",
"checkLinkId": true,
"zoomMin": 18,
"zoomMax": 20,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "obtainDynamicSrc('assets:omdb/arrowDirection/','.svg','arrowClass')"
}
]
},
"3005": {
"table": "OMDB_TRAFFIC_SIGN",
"code": 3005,
"name": "交通标牌",
"zoomMin": 17,
"zoomMax": 20,
"is3D": true,
"catch": true,
"checkLinkId": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "obtainTrafficSignCenterPoint()"
}
]
},
"3006": {
"table": "OMDB_POLE",
"code": 3006,
"name": "杆状物",
"is3D": true,
"catch": true,
"filterData": true,
"zoomMin": 18,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "normalizationPoleHeight()"
}
]
},
"3007": {
"table": "OMDB_OBJECT_WARNING_AREA",
"code": 3007,
"name": "警示区",
"checkLinkId": true,
"filterData": true,
"zoomMin": 18,
"catch": true,
"zoomMax": 20
},
"3009": {
"table": "OMDB_OBJECT_BARRIER",
"code": 3009,
"name": "护栏",
"checkLinkId": true,
"filterData": true,
"zoomMin": 18,
"catch": true,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateMulToLine()"
}
]
},
"3010": {
"table": "OMDB_OBJECT_WALL",
"code": 3010,
"name": "平行墙",
"checkLinkId": true,
"filterData": true,
"zoomMin": 18,
"catch": true,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateMulToLine()"
}
]
},
"3012": {
"table": "OMDB_FILL_AREA",
"code": 3012,
"name": "导流区",
"catch": true,
"checkLinkId": true,
"zoomMin": 18,
"zoomMax": 20
},
"3014": {
"table": "OMDB_CROSS_WALK",
"code": 3014,
"name": "人行横道",
"catch": true,
"checkLinkId": true,
"zoomMin": 18,
"zoomMax": 20
},
"3016": {
"table": "OMDB_OBJECT_STOPLOCATION",
"code": 3016,
"name": "停止位置",
"checkLinkId": true,
"filterData": true,
"zoomMin": 18,
"catch": true,
"zoomMax": 20
},
"3019": {
"table": "OMDB_OBJECT_CURB",
"code": 3019,
"name": "路牙",
"checkLinkId": true,
"filterData": true,
"zoomMin": 18,
"catch": true,
"zoomMax": 20
},
"3028": {
"table": "OMDB_OBJECT_REFUGE_ISLAND",
"code": 3028,
"name": "路口内交通岛",
"catch": true,
"checkLinkId": true,
"zoomMin": 18,
"zoomMax": 20
},
"4001": {
"table": "OMDB_INTERSECTION",
"code": 4001,
"name": "路口",
"zoomMin": 15,
"isDependOnOtherTable": false,
"zoomMax": 17,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateIntersectionReference()"
}
]
},
"4002": {
"table": "OMDB_SPEEDLIMIT",
"code": 4002,
"name": "常规点限速",
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "maxSpeed",
"v": "0",
"klib": "maxSpeed",
"vlib": "限"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "createSpeedLimitText()"
}
]
},
"4003": {
"table": "OMDB_SPEEDLIMIT_COND",
"code": 4003,
"name": "条件点限速",
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "maxSpeed",
"v": "0|",
"klib": "maxSpeed",
"vlib": "限"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "createSpeedLimitText()"
}
]
},
"4004": {
"table": "OMDB_SPEEDLIMIT_VAR",
"code": 4004,
"name": "可变点限速",
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "location",
"v": "1",
"klib": "ref",
"vlib": "左"
},
{
"k": "location",
"v": "2",
"klib": "ref",
"vlib": "右"
},
{
"k": "location",
"v": "3",
"klib": "ref",
"vlib": "上"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "createSpeedLimitText()"
}
]
},
"4005": {
"table": "OMDB_LANE_SPEEDLIMIT",
"code": 4005,
"name": "车道点限速",
"zoomMin": 18,
"zoomMax": 20,
"filterData": true,
"checkLinkId": false,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "obtainLaneSpeedLimitName()"
}
]
},
"4006": {
"table": "OMDB_RESTRICTION",
"code": 4006,
"name": "普通交限",
"zoomMin": 15,
"zoomMax": 17,
"filterData": true,
"isDependOnOtherTable": true,
"catch": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "checkCircleRoad()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateBack()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine()"
}
]
},
"4009": {
"table": "OMDB_WARNINGSIGN",
"code": 4009,
"name": "警示信息",
"catch": true,
"isDependOnOtherTable": false,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine('',3)"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "obtainReferenceDynamicSrc('assets:omdb/appendix/1105_','_0.svg','typeCode')"
}
]
},
"4010": {
"table": "OMDB_ELECTRONICEYE",
"code": 4010,
"name": "电子眼",
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine('',3)"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateElectronName()"
}
]
},
"4016": {
"table": "OMDB_ZLEVEL",
"code": 4016,
"name": "立交",
"zoomMin": 15,
"zoomMax": 20,
"filterData": true,
"catch": true,
"checkLinkId": true,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "obtainZLevelReference()"
}
]
},
"4022": {
"table": "OMDB_TRAFFICLIGHT",
"code": 4022,
"name": "交通灯",
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
]
},
"4023": {
"table": "OMDB_TOLLGATE",
"code": 4023,
"name": "收费站",
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
]
},
"4601": {
"table": "OMDB_LANEINFO",
"code": 4601,
"name": "车信",
"catch": true,
"isDependOnOtherTable": false,
"checkLinkId": true,
"zoomMin": 15,
"zoomMax": 17,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "translateRight(direct=3)"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "unpackingLaneInfo()"
},
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferenceLine()"
}
]
},
"5001": {
"table": "OMDB_LANE_LINK_LG",
"code": 5001,
"name": "车道中心线",
"catch": false,
"isDependOnOtherTable": false,
"checkLinkId": true,
"zoomMin": 18,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateAddWidthLine()"
}
]
}
}
},
{
"tableGroupName": "道路形态",
"tableMap": {
"2004": {
"table": "OMDB_LINK_ATTRIBUTE",
"code": 2004,
"name": "道路属性",
"existSubCode": true,
"catch": true,
"zoomMin": 15,
"zoomMax": 20,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateRoadText()"
}
]
},
"2022": {
"table": "OMDB_CON_ACCESS",
"code": 2022,
"name": "全封闭",
"zoomMin": 15,
"zoomMax": 17
},
"2037": {
"table": "OMDB_RAMP",
"code": 2037,
"name": "匝道",
"existSubCode": true,
"zoomMin": 15,
"zoomMax": 17
},
"2040": {
"table": "OMDB_MULTI_DIGITIZED",
"code": 2040,
"name": "上下线分离",
"zoomMin": 15,
"zoomMax": 17
},
"2204": {
"table": "OMDB_ROUNDABOUT",
"code": 2204,
"name": "环岛",
"catch": true,
"zoomMin": 15,
"zoomMax": 17,
"transformer": [
]
},
"2205": {
"table": "OMDB_LINK_FORM1",
"code": 2205,
"name": "道路形态1",
"existSubCode": true,
"zoomMin": 15,
"zoomMax": 17
},
"2206": {
"table": "OMDB_LINK_FORM2",
"code": 2206,
"existSubCode": true,
"name": "道路形态2",
"zoomMin": 15,
"zoomMax": 17
}
}
}
]

View File

@@ -1,5 +1,10 @@
package com.navinfo.omqs
import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.bean.ImportConfig
import io.realm.RealmConfiguration
import java.io.File
class Constant {
companion object {
/**
@@ -22,6 +27,11 @@ class Constant {
*/
lateinit var USER_ID: String
/**
* 当前用户名称
*/
lateinit var USER_REAL_NAME: String
//数据版本
lateinit var VERSION_ID: String
@@ -30,6 +40,44 @@ class Constant {
*/
lateinit var USER_DATA_PATH: String
/**
* 用户数据安装标识
*/
var INSTALL_DATA: Boolean = false
/**
* 轨迹渲染个数统计
*/
var TRACE_COUNT : Int = 0
var TRACE_COUNT_TIME : Int = 9
var TRACE_COUNT_MORE_TIME : Int = 24
/**
* 当前安装任务
*/
lateinit var installTaskid: String
/**
* 密码
*/
val PASSWORD = "encryp".encodeToByteArray().copyInto(ByteArray(64))
/**
* 当前安装的任务文件
*/
lateinit var currentInstallTaskFolder: File
lateinit var currentInstallTaskConfig: RealmConfiguration
/**
* 当前选择的任务
*/
lateinit var currentSelectTaskFolder: File
lateinit var currentSelectTaskConfig: RealmConfiguration
/**
* 用户附件数据目录
*/
@@ -45,8 +93,54 @@ class Constant {
*/
lateinit var DOWNLOAD_PATH: String
/**
* 日志目录
*/
lateinit var USER_DATA_LOG_PATH: String
/**
* 图层管理对应的配置
* */
var LAYER_CONFIG_LIST: List<ImportConfig>? = null
/**
* 室内整理工具IP
*/
var INDOOR_IP: String = ""
const val DEBUG = true
/**
* 是否自动定位
*/
var AUTO_LOCATION = false
/**
* 地图视角是否锁定
*/
var MapRotateEnable = false
/**
* Marker显隐
*/
var MapMarkerCloseEnable = false
/**
* 轨迹显隐
*/
var MapTraceCloseEnable = false
/**
* 是否开启线捕捉
*/
var MapCatchLine = false
/**
* 全要素捕捉
*/
var CATCH_ALL = false
var IS_VIDEO_SPEED by kotlin.properties.Delegates.notNull<Boolean>()
const val message_status_late = "预约,待发送"
@@ -75,11 +169,30 @@ class Constant {
const val SELECT_TAKEPHOTO_OR_RECORD = "select_takephoto_or_record"
const val OMDB_CONFIG = "omdb_config.json"
const val OTHER_CONFIG = "other.config"
// const val OTHER_CONFIG = "other_config.json"
val OMDB_LAYER_VISIBLE_LIST: MutableList<String> = mutableListOf() // 记录OMDB数据显示的图层名称列表
const val EVENT_LAYER_MANAGER_CHANGE = "EVENT_LAYER_MANAGER_CHANGE" // 图层管理中的配置修改
const val SELECT_TASK_ID = "select_task_id" //选中的任务ID
const val SHARED_SYNC_TASK_LINK_ID = "shared_sync_task_link_id"//利用shared通知任务页面更新
/**
* 偏离距离 单位:米
*/
const val NAVI_DEVIATION_DISTANCE = "navi_deviation_distance"
/**
* 偏离次数上限
*/
const val NAVI_DEVIATION_COUNT = "navi_deviation_count"
/**
* 最远显示距离 米
*/
const val NAVI_FARTHEST_DISPLAY_DISTANCE = "navi_farthest_display_distance"
}

View File

@@ -1,9 +1,16 @@
package com.navinfo.omqs
import android.app.Activity
import android.app.Application
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.view.Surface
import android.view.WindowManager
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.ui.manager.TakePhotoManager
import com.navinfo.omqs.util.CMLog
import com.navinfo.omqs.util.NetUtils
import com.umeng.commonsdk.UMConfigure
import dagger.hilt.android.HiltAndroidApp
import org.videolan.vlc.Util
import java.security.MessageDigest
@@ -14,8 +21,11 @@ class OMQSApplication : Application() {
super.onCreate()
FileManager.initRootDir(this)
Util.getInstance().init(applicationContext)
CMLog.getInstance().init(applicationContext)
NetUtils.getInstance().init(this)
TakePhotoManager.getInstance().init(this, 1)
// 初始化友盟统计
UMConfigure.preInit(this,"650bece7b2f6fa00ba573c7a","native")
}
private fun getKey(inputString: String): String {
@@ -23,5 +33,4 @@ class OMQSApplication : Application() {
val hashBytes = messageDigest.digest(inputString.toByteArray())
return hashBytes.joinToString("") { "%02x".format(it) };
}
}

View File

@@ -12,7 +12,7 @@ data class EvaluationInfo(
val linkPid: String = "",//Link号
@SerializedName("linkStatus")
val linkStatus: String = "",//Link状态
val linkStatus: Int = 0,//Link状态 0未测评 1已测评 2原库新增 3现场新增
@SerializedName("markId")
val markId: String = "",//Link状态
@@ -23,11 +23,14 @@ data class EvaluationInfo(
@SerializedName("markGeometry")
val markGeometry: String = "",//MARK_几何坐标
@SerializedName("linkGeometry")
val linkGeometry: String = "",//link_几何坐标
@SerializedName("featureName")
val featureName: String = "",//问题类型
@SerializedName("problemType")
val problemType: String = "",//问题现象
val problemType: Int = 0,//问题现象 0错误 1多余 2遗漏 服务字段定义为Integer使用包装类对应无值情况为空
@SerializedName("problemPhenomenon")
val problemPhenomenon: String = "",//问题现象
@@ -38,8 +41,8 @@ data class EvaluationInfo(
@SerializedName("problemLink")
val problemLink: String = "",//问题环节
@SerializedName("problemReason")
val problemReason: String = "",//问题原因
@SerializedName("preliminaryAnalysis")
val preliminaryAnalysis: String = "",//初步分析
@SerializedName("evaluatorName")
val evaluatorName: String = "",//测评人名称
@@ -48,6 +51,24 @@ data class EvaluationInfo(
val evaluationDate: String = "",//测评日期(yyyy-mm-dd)
@SerializedName("evaluationWay")
val evaluationWay: String = "现场测评"//测评方式
val evaluationWay: Int = 2,//测评方式 1生产测评 2现场测评 服务字段定义为Integer使用包装类对应无值情况为空
@SerializedName("roadClassifcation")
val roadClassifcation: Int = 1,//道路种别
@SerializedName("roadFunctionGrade")
val roadFunctionGrade: Int = 1,//道路功能等级
@SerializedName("noEvaluationreason")
val noEvaluationreason: String = "",//未测评原因
@SerializedName("linkLength")
val linkLength: Double = 0.0,//link长度(m 保留3位小数)
@SerializedName("dataLevel")
val dataLevel: Int = 1,//数据级别
@SerializedName("linstringLength")
val linstringLength: Double = 0.0,//错误要素长度m
) : Parcelable

View File

@@ -1,24 +1,39 @@
package com.navinfo.omqs.bean
import android.util.Log
import com.google.gson.annotations.Expose
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.db.ImportPreProcess
import io.realm.Realm
import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.declaredMemberFunctions
class ImportConfig {
@Expose
var tableMap: MutableMap<String, TableInfo> = mutableMapOf()
val tableGroupName: String = "OMDB数据"
var checked : Boolean = true
val preProcess: ImportPreProcess = ImportPreProcess()
fun transformProperties(renderEntity: RenderEntity): RenderEntity {
@Expose
val tableGroupName: String = "OMDB数据"
@Expose
var checked: Boolean = true
val preProcess: ImportPreProcess = ImportPreProcess()
fun transformProperties(renderEntity: RenderEntity, realm: Realm?): RenderEntity? {
preProcess.realm = realm
val transformList = tableMap[renderEntity.code.toString()]?.transformer
if (transformList.isNullOrEmpty()) {
return renderEntity
}
if(renderEntity.code==DataCodeEnum.OMDB_LANEINFO.code){
Log.e("车信","====车信")
}
for (transform in transformList) {
// 开始执行转换
val key:String = transform.k
val key: String = transform.k
val value = transform.v
val keylib = transform.klib
val valuelib = transform.vlib
@@ -27,32 +42,91 @@ class ImportConfig {
continue
}
// 如果key和value都为空说明当前数据需要增加一个新字段
if (key.isNullOrEmpty()&&value.isNullOrEmpty()&&!renderEntity.properties.containsKey(keylib)) {
if (key.isNullOrEmpty() && value.isNullOrEmpty() && !renderEntity.properties.containsKey(
keylib
)
) {
renderEntity.properties[keylib] = valuelib
continue
}
// 开始解析key和value并对数据进行匹配
m@ for (k in processKeyOrValue(key)) {
for (v in processKeyOrValue(value)) {
if ("~" == v &&renderEntity.properties.containsKey(k)) { // ~符可以匹配任意元素
if (valuelib.endsWith("()")) { // 以()结尾说明该value配置是一个function需要通过反射调用指定方法
val method = preProcess::class.declaredMemberFunctions.first { it.name == valuelib.replace("()", "") }
method.call(preProcess, renderEntity)
} else {
renderEntity.properties[keylib] = valuelib
if (renderEntity.properties.containsKey(k)) { // json配置的key可以匹配到数据
for (v in processKeyOrValue(value)) {
if ("~" == v) { // ~符可以匹配任意元素
if (valuelib.endsWith(")")) { // 以()结尾说明该value配置是一个function需要通过反射调用指定方法
// 获取方法名
val methodName = valuelib.substringBefore("(")
// 获取参数
val params: List<String> =
valuelib.substringAfter("(").substringBefore(")").split(",")
.filter { it.isNotEmpty() }.map { it.trim() }
val method =
preProcess::class.members.filter { it.name == methodName }
.first() as KFunction<*>
val methodParams = method.parameters
val callByParams = mutableMapOf<KParameter, Any>(
methodParams[0] to preProcess,
methodParams[1] to renderEntity,
)
for ((index, value) in params.withIndex()) {
// 前2个参数确定为对象本身和RenderEntity因此自定义参数从index+2开始设置
if (methodParams.size > index + 2) {
callByParams[methodParams[index + 2]] =
value.replace("'", "")
}
}
when (val result =
method.callBy(callByParams)) { // 如果方法返回的数据类型是boolean且返回为false则该数据不处理
is Boolean ->
if (!result) {
return null
}
}
} else {
renderEntity.properties[keylib] = valuelib
}
break@m
} else if (renderEntity.properties[k] == v) { // 完全匹配
if (valuelib.endsWith(")")) { // 以()结尾说明该value配置是一个function需要通过反射调用指定方法
// 获取方法名
val methodName = valuelib.substringBefore("(")
// 获取参数
val params: List<String> =
valuelib.substringAfter("(").substringBefore(")").split(",")
.filter { it.isNotEmpty() }.map { it.trim() }
val method =
preProcess::class.members.filter { it.name == methodName }
.first() as KFunction<*>
val methodParams = method.parameters
val callByParams = mutableMapOf<KParameter, Any>(
methodParams[0] to preProcess,
methodParams[1] to renderEntity
)
for ((index, value) in params.withIndex()) {
// 前2个参数确定为对象本身和RenderEntity因此自定义参数从index+2开始设置
if (methodParams.size > index + 2) {
callByParams[methodParams[index + 2]] = value
}
}
when (val result = method.callBy(callByParams)) {
is Boolean ->
if (!result) {
return null
}
}
} else {
renderEntity.properties[keylib] = valuelib
}
break@m
}
break@m
} else if (renderEntity.properties[k] == v) {
if (valuelib.endsWith("()")) { // 以()结尾说明该value配置是一个function需要通过反射调用指定方法
val method = preProcess::class.declaredMemberFunctions.first { it.name == valuelib.replace("()", "") }
method.call(preProcess, renderEntity)
} else {
renderEntity.properties[keylib] = valuelib
}
break@m
}
}
}
}
preProcess.realm = null
return renderEntity
}
@@ -68,9 +142,18 @@ class ImportConfig {
class TableInfo {
val table: String = ""
val code: Int = 0
val zoomMin: Int = 16
val zoomMax: Int = 21
val checkLinkId: Boolean = true//是否需要校验linkid
val filterData: Boolean = false//是否需要过滤数据
val existSubCode: Boolean = false//是否存在子编码
val isDependOnOtherTable = false//是否依赖其他表
val catch: Boolean =
false//是否需要捕捉 // 需要根据丹丹提供的捕捉原则进行设置参考文档W行设置条件https://navinfo.feishu.cn/sheets/shtcnfsxKZhekU26ezBcHgl7aWh?sheet=BZd6yM
val name: String = ""
var checked : Boolean = true
var checked: Boolean = true
var transformer: MutableList<Transform> = mutableListOf()
var is3D: Boolean = false // 是否支持3D默认情况下都不支持3D在数据导入阶段会自动抹去Z轴高程信息
}
class Transform {

View File

@@ -0,0 +1,11 @@
package com.navinfo.omqs.bean
data class IndoorConnectionInfoBean(
var username: String = "",
var uname: String = "",
var userid: String = "",
var token: String = "",
var baseurl: String = "",
var plate: String = "",
var platform: String = "Android",
)

View File

@@ -1,6 +1,6 @@
package com.navinfo.omqs.bean
data class LoginUserBean(
var username: String = "",
var password: String = ""
var userCode: String = "",
var passWord: String = ""
)

View File

@@ -0,0 +1,51 @@
package com.navinfo.omqs.bean
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.utils.GeometryTools
import org.oscim.core.GeoPoint
data class NaviRoute(
//我是整条路径中的第几段路径
var indexInPath: Int = -1,
//link id
val linkId: String,
//起点id
var sNode: String = "",
//终点id
var eNode: String = "",
//方向
var direct: Int = 0,
//道路名称
var name: RenderEntity? = null,
//路段总长
var length: Double = 0.0,
//当前link在整段路径中的起点
var startIndexInPath: Int = -1,
//当前link在整段路径中的终点
var endIndexIntPath: Int = -1,
var itemList: MutableList<NaviRouteItem>? = null,
//种别
var kind: String = "",
//除导航退出线外的其他拓扑link
var otherTopologyLinks: MutableList<String> = mutableListOf(),
//线限速
var speedLimit: String = "0"
) {
var pointList: MutableList<GeoPoint> = mutableListOf()
get() {
return field
}
set(value) {
length = GeometryTools.getDistance(value)
field = value
}
}
data class NaviRouteItem(
var index: Int,
val data: RenderEntity,
val linkId: String,
var distance: Int = -1,
var voiceText: String = "",
var isVoicePlayed: Boolean = false
)

View File

@@ -0,0 +1,6 @@
package com.navinfo.omqs.bean
data class QRCodeBean(
var errcode: Int = -1,
var errmsg: String = ""
)

View File

@@ -0,0 +1,49 @@
package com.navinfo.omqs.bean
data class RoadNameBean(
/**
* 道路名称
*/
val name: String = "",
/**
* 0 普通
* 1 立交桥名(连接路)
* 2 立交桥名 (主路)
* 3 风景线路
* 5 隧道
* 6 虚拟名称
*/
val type: Int = 0,
/**
* 1 不论“名称分类”是官方名别名还是曾用名都统一从1开始递增
* 2 若取第一官方名时,需判断“名称”分类 [nameClass]=="官方名",且[seqNum] 最小的
*/
val seqNum: Int = 1,
/**
* 1 官方名
* 2 别名
* 3 曾用名
*/
val nameClass: Int = 1,
) {
fun getNameClassStr(): String {
when (nameClass) {
1 -> return "官方名"
2 -> return "别名"
3 -> return "曾用名"
}
return ""
}
fun getTypeStr(): String {
when (type) {
0 -> return "普通"
1 -> return "立交桥名(连接路)"
2 -> return "立交桥名(主路)"
3 -> return "风景线路"
5 -> return "隧道"
6 -> return "虚拟名称"
}
return ""
}
}

View File

@@ -0,0 +1,26 @@
package com.navinfo.omqs.bean
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Entity(tableName = "ScWarningCode")
@Parcelize
data class ScWarningCodeBean(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
/**
* code
* 编码
*/
@ColumnInfo("CODE")
val code: String = "",
/**
* 描述
*/
@ColumnInfo("DESCRIBE")
val describe: String = "",
) : Parcelable

View File

@@ -1,26 +1,27 @@
package com.navinfo.omqs.bean
import android.os.Parcelable
import com.navinfo.collect.library.data.entity.RenderEntity
import kotlinx.parcelize.Parcelize
@Parcelize
data class SignBean(
//图标ID
val iconId: Int,
var iconId: Int = 0,
//定位点到目标距离
val distance: Int = 0,
//图表中的问题
var distance: Int = 0,
//左上图标中的文字
val iconText: String = "",
//绑定的要素id
val elementId: String = "",
//绑定的linkid
val linkId: String,
//坐标
val geometry: String,
//底部文字
val bottomText: String,
//名称
val name: String,
//是否要展示详细信息
val isMoreInfo: Boolean = false,
//底部右侧文字
val bottomRightText: String,
//要素code类型
val elementCode: Int
val bottomRightText: String = "",
//捕捉数据
val renderEntity: RenderEntity,
//道路信息排序用的字段
val index: Int = 0
) : Parcelable

View File

@@ -0,0 +1,8 @@
package com.navinfo.omqs.bean
data class SysUserBean(
var userName: String = "",
var passWord: String = "",
var userCode: String = "",
var roleId: Int = 0,
)

View File

@@ -0,0 +1,8 @@
package com.navinfo.omqs.bean
data class TraceVideoBean(
var userid: String = "",
var playMode: String = "",
var time: String = "",
var command: String = "",
)

View File

@@ -0,0 +1,43 @@
package com.navinfo.omqs.db
class Code2NameMap {
val electronEyeKindMap = mapOf(
1 to "超高",
2 to "超低",
3 to "移动",
4 to "可变",
5 to "分车道",
6 to "分车种",
7 to "车灯",
8 to "占车道",
9 to "过路口",
10 to "闯红灯",
11 to "路况",
12 to "单行",
13 to "非机动",
14 to "出入口",
15 to "公交",
16 to "禁转",
17 to "掉头",
18 to "应急",
19 to "标线",
20 to "区间S",
21 to "区间E",
22 to "停车",
23 to "尾号",
24 to "环保",
25 to "安全带",
26 to "手机",
27 to "行人",
28 to "禁令",
29 to "鸣笛",
30 to "年检",
31 to "尾气",
32 to "ETC",
33 to "专用",
34 to "标线",
35 to "违章",
36 to "卡车",
37 to "限时长",
)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
package com.navinfo.omqs.db
class ImportPreCacheData {
}

File diff suppressed because it is too large Load Diff

View File

@@ -3,25 +3,32 @@ package com.navinfo.omqs.db
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.navinfo.collect.library.data.entity.HadLinkDvoBean
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.GeometryToolsKt
import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.Constant
import io.realm.Realm
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import io.realm.RealmModel
import io.realm.RealmQuery
import org.locationtech.jts.geom.*
import org.locationtech.jts.operation.buffer.BufferOp
import org.oscim.core.GeoPoint
import org.oscim.core.MercatorProjection
import javax.inject.Inject
import kotlin.reflect.jvm.jvmName
import kotlin.streams.toList
class RealmOperateHelper() {
@Inject
lateinit var niMapController: NIMapController
private var isUpdate: Boolean = false
/**
* 根据当前点位查询匹配的Link数据
* @param point 点位经纬度信息
@@ -31,79 +38,216 @@ class RealmOperateHelper() {
* */
@RequiresApi(Build.VERSION_CODES.N)
suspend fun queryLink(
realm: Realm,
point: GeoPoint,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE,
sort: Boolean = true
): MutableList<RenderEntity> {
val result = mutableListOf<RenderEntity>()
withContext(Dispatchers.IO) {
val polygon = getPolygonFromPoint(
GeometryTools.createPoint(point.longitude, point.latitude),
buffer,
bufferType
)
// 根据polygon查询相交的tile号
val tileXSet = mutableSetOf<Int>()
tileXSet.toString()
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
val tileYSet = mutableSetOf<Int>()
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
val polygon = getPolygonFromPoint(
GeometryTools.createPoint(point.longitude, point.latitude),
buffer,
bufferType
)
// 根据polygon查询相交的tile号
val tileXSet = mutableSetOf<Int>()
// 对tileXSet和tileYSet查询最大最小值
val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null)
val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null)
val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null)
val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null)
// 查询realm中对应tile号的数据
val realm = Realm.getDefaultInstance()
val realmList = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RD_LINK")
.and()
.rawPredicate("tileX>=$xStart and tileX<=$xEnd and tileY>=$yStart and tileY<=$yEnd")
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
val tileYSet = mutableSetOf<Int>()
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
// 对tileXSet和tileYSet查询最大最小值
val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null)
val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null)
val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null)
val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null)
// 查询realm中对应tile号的数据
// val realm = getSelectTaskRealmInstance()
val sql =
" ((tileXMin <= $xStart and tileXMax >= $xStart) or (tileXMin <=$xEnd and tileXMax >=$xStart)) and ((tileYMin <= $yStart and tileYMax >= $yStart) or (tileYMin <=$yEnd and tileYMin >=$yStart))"
val realmList =
getSelectTaskRealmTools(realm, RenderEntity::class.java, false)
.equalTo("table", DataCodeEnum.OMDB_LINK_DIRECT.name)
.rawPredicate(sql)
.findAll()
// 将获取到的数据和查询的polygon做相交只返回相交的数据
val dataList = realm.copyFromRealm(realmList)
val queryResult = dataList?.stream()?.filter {
polygon.intersects(it.wkt)
}?.toList()
// 将获取到的数据和查询的polygon做相交只返回相交的数据
val dataList = realm.copyFromRealm(realmList)
// realm.close()
queryResult?.let {
if (sort) {
result.addAll(
sortRenderEntity(
GeometryTools.createPoint(
point.longitude,
point.latitude
) , it
)
val queryResult = dataList?.stream()?.filter {
polygon.intersects(it.wkt)
}?.toList()
queryResult?.let {
if (sort) {
result.addAll(
sortRenderEntity(
GeometryTools.createPoint(
point.longitude,
point.latitude
), it
)
} else {
result.addAll(it)
}
)
} else {
result.addAll(it)
}
}
return result
}
/**
* 根据当前点位查询匹配的Link数据
* @param point 点位经纬度信息
* @param buffer 点位的外扩距离
* @param bufferType 点位外扩距离的单位: 米-Meter像素-PIXEL
* @param sort 是否需要排序
* */
@RequiresApi(Build.VERSION_CODES.N)
suspend fun queryLine(
point: GeoPoint,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE,
table: String,
sort: Boolean = true
): MutableList<RenderEntity> {
val result = mutableListOf<RenderEntity>()
val polygon = getPolygonFromPoint(
GeometryTools.createPoint(point.longitude, point.latitude),
buffer,
bufferType
)
// 根据polygon查询相交的tile号
val tileXSet = mutableSetOf<Int>()
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
val tileYSet = mutableSetOf<Int>()
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
// 对tileXSet和tileYSet查询最大最小值
val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null)
val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null)
val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null)
val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null)
// 查询realm中对应tile号的数据
val realm = getSelectTaskRealmInstance()
val sql =
" ((tileXMin <= $xStart and tileXMax >= $xStart) or (tileXMin <=$xEnd and tileXMax >=$xStart)) and ((tileYMin <= $yStart and tileYMax >= $yStart) or (tileYMin <=$yEnd and tileYMin >=$yStart))"
val realmList = getSelectTaskRealmTools(realm, RenderEntity::class.java, true)
.equalTo("table", table)
.rawPredicate(sql)
.findAll()
// 将获取到的数据和查询的polygon做相交只返回相交的数据
val dataList = realm.copyFromRealm(realmList)
val queryResult = dataList?.stream()?.filter {
polygon.intersects(it.wkt)
}?.toList()
queryResult?.let {
if (sort) {
result.addAll(
sortRenderEntity(
GeometryTools.createPoint(
point.longitude,
point.latitude
), it
)
)
} else {
result.addAll(it)
}
}
realm.close()
return result
}
suspend fun captureTaskLink(
point: GeoPoint,
taskId: Int,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE,
): HadLinkDvoBean? {
val polygon = getPolygonFromPoint(
GeometryTools.createPoint(point.longitude, point.latitude),
buffer,
bufferType
)
val realm = getRealmDefaultInstance()
try {
val realmList =
realm.where(HadLinkDvoBean::class.java).equalTo("taskId", taskId).findAll()
var linkBean: HadLinkDvoBean? = null
var nearLast: Double = 99999.99
for (link in realmList) {
if (polygon.intersects(GeometryTools.createGeometry(link.geometry))) {
val near = GeometryTools.createGeometry(link.geometry).distance(GeometryTools.createGeometry(point))
if (near < nearLast) {
nearLast = near
linkBean = link
}
}
}
if (linkBean != null)
return realm.copyFromRealm(linkBean)
} catch (e: Exception) {
} finally {
realm.close()
}
return null
}
suspend fun queryLink(linkPid: String): RenderEntity? {
var link: RenderEntity? = null
withContext(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val realmR = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RD_LINK")
.and()
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.findFirst()
if (realmR != null) {
link = realm.copyFromRealm(realmR)
}
val realm = getSelectTaskRealmInstance()
val realmR =
realm.where(RenderEntity::class.java).equalTo("table", "OMDB_RD_LINK_KIND")
.equalTo("linkPid", linkPid).findFirst()
if (realmR != null) {
link = realm.copyFromRealm(realmR)
}
realm.close()
return link
}
/**
* 根据markid查询获取对应数据
* @param markId
* */
suspend fun queryQcRecordBean(markId: String): QsRecordBean? {
var qsRecordBean: QsRecordBean? = null
val realm = getRealmDefaultInstance()
val realmR = getRealmTools(QsRecordBean::class.java)
.equalTo("table", "QsRecordBean").equalTo("id", markId).findFirst()
if (realmR != null) {
qsRecordBean = realm.copyFromRealm(realmR)
}
realm.close()
return qsRecordBean
}
suspend fun queryLinkToMutableRenderEntityList(
realm: Realm,
linkPid: String
): MutableList<RenderEntity>? {
val resultList = mutableListOf<RenderEntity>()
// val realm = getSelectTaskRealmInstance()
val realmR = getSelectTaskRealmTools(realm, RenderEntity::class.java, true)
.equalTo("linkPid", linkPid).findAll()
val dataList = realm.copyFromRealm(realmR)
dataList.forEach {
resultList.add(it)
}
// realm.close()
return resultList
}
/**
* 根据当前点位查询匹配的除Link外的其他要素数据
* @param point 点位经纬度信息
@@ -116,41 +260,64 @@ class RealmOperateHelper() {
point: Point,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE,
catchAll: Boolean = true,
sort: Boolean = true
): MutableList<RenderEntity> {
val result = mutableListOf<RenderEntity>()
withContext(Dispatchers.IO) {
val polygon = getPolygonFromPoint(point, buffer, bufferType)
// 根据polygon查询相交的tile号
val tileXSet = mutableSetOf<Int>()
tileXSet.toString()
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
val tileYSet = mutableSetOf<Int>()
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
val polygon = getPolygonFromPoint(point, buffer, bufferType)
// 对tileXSet和tileYSet查询最大最小值
val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null)
val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null)
val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null)
val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null)
niMapController.lineHandler.showLine(polygon.toText())
// 根据polygon查询相交的tile号
val tileXSet = mutableSetOf<Int>()
tileXSet.toString()
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
val tileYSet = mutableSetOf<Int>()
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
// 对tileXSet和tileYSet查询最大最小值
val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null)
val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null)
val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null)
val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null)
val realm = getSelectTaskRealmInstance()
var realmList = mutableListOf<RenderEntity>()
val sql =
" ((tileXMin <= $xStart and tileXMax >= $xStart) or (tileXMin <=$xEnd and tileXMax >=$xStart)) and ((tileYMin <= $yStart and tileYMax >= $yStart) or (tileYMin <=$yEnd and tileYMin >=$yStart))"
val realmQuery = getSelectTaskRealmTools(realm, RenderEntity::class.java, false)
.rawPredicate(sql)
// 筛选不显示的数据
if (catchAll) {
// 查询realm中对应tile号的数据
val realmList = Realm.getDefaultInstance().where(RenderEntity::class.java)
.notEqualTo("table", "OMDB_RD_LINK")
.and()
.rawPredicate("tileX>=$xStart and tileX<=$xEnd and tileY>=$yStart and tileY<=$yEnd")
.findAll()
// 将获取到的数据和查询的polygon做相交只返回相交的数据
val queryResult = realmList?.stream()?.filter {
polygon.intersects(it.wkt)
}?.toList()
queryResult?.let {
result.addAll(queryResult)
}
if (sort) {
result.clear()
result.addAll(sortRenderEntity(point, result))
realmList = realmQuery.findAll()
} else {
// 查询realm中对应tile号的数据
if (Constant.CATCH_ALL) {
realmList = realmQuery.findAll()
} else {
realmList = realmQuery.greaterThan("catchEnable", 0).findAll()
}
}
// 将获取到的数据和查询的polygon做相交只返回相交的数据
val queryResult = realmList?.stream()?.filter {
if (Constant.MapCatchLine) {
Log.e("qj",it.code+"捕捉要素编码"+it.enable+"==="+it.catchEnable)
polygon.intersects(it.wkt) && it.wkt?.geometryType?.uppercase()
.equals("LINESTRING") || it.wkt?.geometryType?.uppercase().equals("POLYGON")
} else {
polygon.intersects(it.wkt) && it.wkt?.geometryType?.uppercase()
.equals("POINT") || it.wkt?.geometryType?.uppercase().equals("POLYGON")
}
}?.toList()
queryResult?.let {
if (sort) {
result.addAll(sortRenderEntity(point, realm.copyFromRealm(it)))
} else {
result.addAll(realm.copyFromRealm(it))
}
}
realm.close()
return result
}
@@ -161,17 +328,13 @@ class RealmOperateHelper() {
* @param bufferType 点位外扩距离的单位: 米-Meter像素-PIXEL
* @param sort 是否需要排序
* */
suspend fun queryLinkByLinkPid(linkPid: String): MutableList<RenderEntity> {
suspend fun queryLinkByLinkPid(realm: Realm, linkPid: String): MutableList<RenderEntity> {
val result = mutableListOf<RenderEntity>()
withContext(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val realmList = realm.where(RenderEntity::class.java)
.notEqualTo("table", "OMDB_RD_LINK")
.and()
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.findAll()
result.addAll(realm.copyFromRealm(realmList))
}
val realmList = getSelectTaskRealmTools(realm, RenderEntity::class.java, false)
.notEqualTo("table", DataCodeEnum.OMDB_RD_LINK.name)
.equalTo("linkPid", linkPid)
.findAll()
result.addAll(realm.copyFromRealm(realmList))
return result
}
@@ -184,8 +347,7 @@ class RealmOperateHelper() {
@RequiresApi(Build.VERSION_CODES.N)
fun sortRenderEntity(point: Point, unSortList: List<RenderEntity>): List<RenderEntity> {
val sortList = unSortList.stream().sorted { renderEntity, renderEntity2 ->
val near = point.distance(renderEntity.wkt) - point.distance(renderEntity2.wkt)
if (near < 0) -1 else 1
point.distance(renderEntity.wkt).compareTo(point.distance(renderEntity2.wkt))
}.toList()
return sortList
}
@@ -242,6 +404,75 @@ class RealmOperateHelper() {
Log.d("queryLink", wkt.toString())
return wkt
}
/**
* 默认的数据库,用于存储任务、作业数据
* @param clazz 查询表
* @param enableSql
* */
fun <E : RealmModel> getRealmTools(clazz: Class<E>): RealmQuery<E> {
return getRealmDefaultInstance().where(clazz)
}
fun getRealmDefaultInstance(): Realm {
val realm = Realm.getDefaultInstance()
if (isUpdate) {
Log.e("jingo", "数据库更新")
if (realm.isInTransaction) {
realm.cancelTransaction()
Log.e("jingo", "数据库正在事物,需要退出当前事物")
}
realm.refresh()
isUpdate = false;
}
return realm
}
fun <E : RealmModel> getSelectTaskRealmTools(
realm: Realm,
clazz: Class<E>,
enableSql: Boolean
): RealmQuery<E> {
val realmQuery = realm.where(clazz)
if (MapParamUtils.getDataLayerEnum() != null) {
if (enableSql) {
val sql =
" enable${MapParamUtils.getDataLayerEnum().sql}"
realm.where(clazz).rawPredicate(sql)
}
}
if (clazz.name == RenderEntity::class.jvmName) {
// 筛选不显示的数据
if (com.navinfo.collect.library.system.Constant.HAD_LAYER_INVISIABLE_ARRAY != null && com.navinfo.collect.library.system.Constant.HAD_LAYER_INVISIABLE_ARRAY.isNotEmpty()) {
realmQuery.beginGroup()
for (type in com.navinfo.collect.library.system.Constant.HAD_LAYER_INVISIABLE_ARRAY) {
realmQuery.notEqualTo("table", type)
}
realmQuery.endGroup()
}
}
return realmQuery
}
fun getSelectTaskRealmInstance(): Realm {
val realm = Realm.getInstance(Constant.currentSelectTaskConfig)
if (isUpdate) {
Log.e("jingo", "数据库更新")
if (realm.isInTransaction) {
realm.cancelTransaction()
Log.e("jingo", "数据库正在事物,需要退出当前事物")
}
realm.refresh()
isUpdate = false;
}
return realm
}
fun updateRealmDefaultInstance() {
isUpdate = true
}
}
enum class BUFFER_TYPE(val index: Int) {
@@ -257,5 +488,5 @@ enum class BUFFER_TYPE(val index: Int) {
}
}
private val DEFAULT_BUFFER: Double = 15.0
private const val DEFAULT_BUFFER: Double = 15.0
private val DEFAULT_BUFFER_TYPE = BUFFER_TYPE.METER

View File

@@ -6,17 +6,20 @@ import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
import com.navinfo.omqs.bean.ScWarningCodeBean
import com.navinfo.omqs.db.dao.OfflineMapDao
import com.navinfo.omqs.db.dao.ScProblemTypeDao
import com.navinfo.omqs.db.dao.ScRootCauseAnalysisDao
import com.navinfo.omqs.db.dao.ScWarningCodeDao
@Database(
entities = [OfflineMapCityBean::class, ScProblemTypeBean::class, ScRootCauseAnalysisBean::class],
version = 1,
entities = [OfflineMapCityBean::class, ScProblemTypeBean::class, ScRootCauseAnalysisBean::class, ScWarningCodeBean::class],
version = 2,
exportSchema = false
)
abstract class RoomAppDatabase : RoomDatabase() {
abstract fun getOfflineMapDao(): OfflineMapDao
abstract fun getScProblemTypeDao(): ScProblemTypeDao
abstract fun getScRootCauseAnalysisDao(): ScRootCauseAnalysisDao
abstract fun getScWarningCodeDao(): ScWarningCodeDao
}

View File

@@ -30,11 +30,11 @@ interface ScProblemTypeDao {
/**
* 获取问题分类,并去重
*/
@Query("select DISTINCT CLASS_TYPE from ScProblemType order by CLASS_TYPE")
suspend fun findClassTypeList(): List<String>?
@Query("select * from ScProblemType group by CLASS_TYPE")
suspend fun findClassTypeList(): List<ScProblemTypeBean>?
@Query("select DISTINCT CLASS_TYPE from ScProblemType where ELEMENT_CODE=:code")
suspend fun findClassTypeByCode(code: Int): String?
suspend fun findClassTypeByCode(code: String): String?
/**
* 获取问题类型,并去重

View File

@@ -0,0 +1,32 @@
package com.navinfo.omqs.db.dao
import androidx.room.*
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScWarningCodeBean
@Dao
interface ScWarningCodeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertList(list: List<ScWarningCodeBean>)
@Query("delete from ScWarningCode")
suspend fun deleteAll()
/**
* 更新整个数据库表,由于没有
*/
@Transaction
suspend fun insertOrUpdateList(list: List<ScWarningCodeBean>) {
//先删除
deleteAll()
//后插入
insertList(list)
}
@Query("select DESCRIBE from ScWarningCode where CODE=:code")
suspend fun findScWarningDescribe(code: String): String?
}

View File

@@ -0,0 +1,6 @@
package com.navinfo.omqs.db.deep
data class LinkList(
var featureType: Int = -1,
var linkPid: String = ""
)

View File

@@ -44,9 +44,10 @@ class ActivityModule {
fun providesTaskListDownloadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
importFactory: ImportOMDBHiltFactory,
mapController: NIMapController
mapController: NIMapController,
realmOperateHelper: RealmOperateHelper,
): TaskDownloadManager =
TaskDownloadManager(importFactory, networkServiceAPI, mapController)
TaskDownloadManager(importFactory, networkServiceAPI, mapController, realmOperateHelper)
/**
* 注入任务下载
@@ -55,8 +56,9 @@ class ActivityModule {
@Provides
fun providesTaskListUploadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
realmOperateHelper: RealmOperateHelper,
): TaskUploadManager =
TaskUploadManager(networkServiceAPI)
TaskUploadManager(networkServiceAPI, realmOperateHelper)
/**
* 实验失败这样创建viewmodel不会在activity销毁的时候同时销毁

View File

@@ -1,6 +1,8 @@
package com.navinfo.omqs.hilt
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.room.Room
import com.google.gson.Gson
@@ -25,7 +27,6 @@ import io.realm.Realm
import kotlinx.coroutines.*
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
@@ -38,6 +39,7 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
class GlobalModule {
@Singleton
@Provides
fun provideApplication(@ApplicationContext application: Application): OMQSApplication {
@@ -152,18 +154,10 @@ class GlobalModule {
)
}
// /**
// * realm 注册
// */
// @Provides
// @Singleton
// fun provideRealmService(context: Application): RealmCoroutineScope {
// return RealmCoroutineScope(context)
// }
@Singleton
@Provides
fun provideRealmDefaultInstance(): Realm {
return Realm.getDefaultInstance()
fun provideSharedPreferences(context: Application): SharedPreferences {
return context.getSharedPreferences("Shared" + Constant.USER_ID, Context.MODE_PRIVATE)
}
}

View File

@@ -1,6 +1,6 @@
package com.navinfo.omqs.http
class DefaultTaskResponse<T> {
class DefaultResponse<T> {
var success: Boolean = false
var msg: String = ""
var obj: T? = null

View File

@@ -31,8 +31,8 @@ package com.navinfo.omqs.http
sealed class NetResult<out R> {
data class Success<out T>(val data: T?) : NetResult<T>()
data class Failure(val code: Int, val msg: String) : NetResult<Nothing>()
data class Error(val exception: Exception) : NetResult<Nothing>()
data class Failure<T>(val code: Int, val msg: String) : NetResult<Nothing>()
data class Error<T>(val exception: Exception) : NetResult<Nothing>()
object Loading : NetResult<Nothing>()
/**
@@ -42,8 +42,8 @@ sealed class NetResult<out R> {
override fun toString(): String {
return when (this) {
is Success<*> -> "网络访问成功返回正确结果Success[data=$data]"
is Failure -> "网络访问成功返回错误结果Failure[$msg]"
is Error -> "网络访问出错 Error[exception=$exception]"
is Failure<*> -> "网络访问成功返回错误结果Failure[$msg]"
is Error<*> -> "网络访问出错 Error[exception=$exception]"
is Loading -> "网络访问中 Loading"
}
}

View File

@@ -2,6 +2,11 @@ package com.navinfo.omqs.http
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import com.navinfo.omqs.bean.TraceVideoBean
/**
@@ -11,9 +16,30 @@ interface NetworkService {
/**
* 获取离线地图城市列表
*/
suspend fun getOfflineMapCityList():NetResult<List<OfflineMapCityBean>>
suspend fun getOfflineMapCityList(): NetResult<List<OfflineMapCityBean>>
/**
* 获取任务列表
*/
suspend fun getTaskList(evaluatorNo:String): NetResult<DefaultTaskResponse<List<TaskBean>>>
suspend fun getTaskList(evaluatorNo: String): NetResult<DefaultResponse<List<TaskBean>>>
/**
* 登录接口
*/
suspend fun loginUser(loginUserBean: LoginUserBean): NetResult<DefaultResponse<SysUserBean>>
/**
* 连接室内整理工具
*/
suspend fun connectIndoorTools(url: String): NetResult<QRCodeBean>
/**
* 更新用户信息
*/
suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult<QRCodeBean>
/**
* 设置轨迹对应的视频
*/
suspend fun sendServerCommand(url: String,traceVideoBean: TraceVideoBean): NetResult<QRCodeBean>
}

View File

@@ -2,8 +2,15 @@ package com.navinfo.omqs.http
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import com.navinfo.omqs.bean.TraceVideoBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.ResponseBody
import retrofit2.Response
import javax.inject.Inject
/**
@@ -24,17 +31,17 @@ class NetworkServiceImpl @Inject constructor(
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure(result.code(), result.message())
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure(result.code(), result.message())
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error(e)
NetResult.Error<Any>(e)
}
}
override suspend fun getTaskList(evaluatorNo: String): NetResult<DefaultTaskResponse<List<TaskBean>>> =
override suspend fun getTaskList(evaluatorNo: String): NetResult<DefaultResponse<List<TaskBean>>> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
@@ -43,13 +50,106 @@ class NetworkServiceImpl @Inject constructor(
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure(result.code(), result.message())
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure(result.code(), result.message())
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error(e)
NetResult.Error<Any>(e)
}
}
override suspend fun loginUser(loginUserBean: LoginUserBean): NetResult<DefaultResponse<SysUserBean>> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
val result = netApi.retrofitLoginUser(loginUserBean)
if (result.isSuccessful) {
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error<Any>(e)
}
}
override suspend fun connectIndoorTools(url: String): NetResult<QRCodeBean> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
val result = netApi.retrofitConnectIndoorTools(url = url)
if (result.isSuccessful) {
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error<Any>(e)
}
}
override suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult<QRCodeBean> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
val map: MutableMap<String, String> = HashMap()
map["username"] = indoorConnectionInfoBean.username
map["uname"] = indoorConnectionInfoBean.uname
map["userid"] = indoorConnectionInfoBean.userid
map["plate"] = indoorConnectionInfoBean.plate
map["token"] = indoorConnectionInfoBean.token
map["baseurl"] = indoorConnectionInfoBean.baseurl
map["platform"] = indoorConnectionInfoBean.platform
val result = netApi.retrofitUpdateServerInfo(url,map)
if (result.isSuccessful) {
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error<Any>(e)
}
}
override suspend fun sendServerCommand(
url: String,
traceVideoBean: TraceVideoBean
): NetResult<QRCodeBean> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
val map: MutableMap<String, String> = HashMap()
map["userid"] = traceVideoBean.userid
map["playMode"] = traceVideoBean.playMode
map["time"] = traceVideoBean.time
val result = netApi.retrofitUpdateServerInfo(url,map)
if (result.isSuccessful) {
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error<Any>(e)
}
}
}

View File

@@ -3,6 +3,10 @@ package com.navinfo.omqs.http
import com.navinfo.omqs.bean.EvaluationInfo
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.*
@@ -40,6 +44,13 @@ interface RetrofitNetworkServiceAPI {
@GET("/drdc/MapDownload/maplist")
suspend fun retrofitGetOfflineMapCityList(): Response<List<OfflineMapCityBean>>
/**
* 登录接口
*/
@Headers("Content-Type: application/json")
@POST("/devcp/loginUser")
suspend fun retrofitLoginUser(@Body loginUserBean: LoginUserBean): Response<DefaultResponse<SysUserBean>>
/**
* 下载文件
*/
@@ -53,11 +64,27 @@ interface RetrofitNetworkServiceAPI {
@GET("/devcp/getEvaluationTask?evaluatType=2")
suspend fun retrofitGetTaskList(
@Query("evaluatorNo") evaluatorNo: String,
): Response<DefaultTaskResponse<List<TaskBean>>>
): Response<DefaultResponse<List<TaskBean>>>
/**
* 连接室内整理工具
*/
@Streaming
@GET
suspend fun retrofitConnectIndoorTools(@Url url: String): Response<QRCodeBean>
/**
* 登录接口
*/
@FormUrlEncoded
@POST
suspend fun retrofitUpdateServerInfo(@Url url: String,@FieldMap map: Map<String,String>): Response<QRCodeBean>
@Headers("Content-Type: application/json")
@POST("/devcp/uploadSceneProblem")
suspend fun postRequest(@Body listEvaluationInfo: List<EvaluationInfo>?): Response<ResponseBody>
suspend fun postRequest(@Body listEvaluationInfo: List<EvaluationInfo>?): Response<DefaultResponse<*>>
/**
* @FormUrlEncoded 请求格式注解请求实体是一个From表单每个键值对需要使用@Field注解

View File

@@ -79,7 +79,6 @@ class OfflineMapDownloadManager(
}
launchNext(id)
}
}
/**

View File

@@ -34,7 +34,7 @@ class OfflineMapDownloadScope(
/**
* 管理观察者,同时只有一个就行了
*/
private val observer = Observer<Any> {}
// private val observer = Observer<Any> {}
// private var lifecycleOwner: LifecycleOwner? = null
/**
@@ -58,7 +58,13 @@ class OfflineMapDownloadScope(
*/
fun pause() {
downloadJob?.cancel("pause")
change(FileDownloadStatus.PAUSE)
launch {
if (cityBean.fileSize == 0L) {
change(FileDownloadStatus.NONE)
} else {
change(FileDownloadStatus.PAUSE)
}
}
}
/**
@@ -99,7 +105,6 @@ class OfflineMapDownloadScope(
* 添加下载任务观察者
*/
fun observer(owner: LifecycleOwner, ob: Observer<OfflineMapCityBean>) {
removeObserver()
// this.lifecycleOwner = owner
downloadData.observe(owner, ob)
}
@@ -149,19 +154,23 @@ class OfflineMapDownloadScope(
}
}
Log.e("jingo", "文件下载完成 ${cityBean.currentSize} == ${cityBean.fileSize}")
if (cityBean.currentSize == cityBean.fileSize) {
val res =
fileTemp.renameTo(File("${Constant.OFFLINE_MAP_PATH}${cityBean.fileName}"))
Log.e("jingo", "文件下载完成 修改文件 $res")
change(FileDownloadStatus.DONE)
withContext(Dispatchers.Main) {
downloadManager.mapController.layerManagerHandler.loadBaseMap()
try {
withContext(Dispatchers.Main) {
downloadManager.mapController.layerManagerHandler.loadBaseMap()
}
} catch (e: Throwable) {
Log.e("jingo", "下载离线地图 load map ${e.message}")
}
} else {
change(FileDownloadStatus.PAUSE)
}
} catch (e: Throwable) {
Log.e("jingo", "下载离线地图 ${e.message}")
change(FileDownloadStatus.ERROR)
} finally {
inputStream?.close()
@@ -169,11 +178,15 @@ class OfflineMapDownloadScope(
}
}
fun removeObserver() {
downloadData.observeForever(observer)
// lifecycleOwner?.let {
downloadData.removeObserver(observer)
// null
// downloadData.observeForever(observer)
//// lifecycleOwner?.let {
// downloadData.removeObserver(observer)
//// null
//// }
// if (lifecycleOwner != null) {
// downloadData.removeObservers(lifecycleOwner!!)
// }
}
}

View File

@@ -1,10 +1,12 @@
package com.navinfo.omqs.http.taskdownload
import android.content.Context
import android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import java.util.concurrent.ConcurrentHashMap
@@ -17,7 +19,8 @@ import java.util.concurrent.ConcurrentHashMap
class TaskDownloadManager constructor(
val importFactory: ImportOMDBHiltFactory,
val netApi: RetrofitNetworkServiceAPI,
val mapController:NIMapController
val mapController: NIMapController,
val realmOperateHelper: RealmOperateHelper,
) {
lateinit var context: Context
@@ -41,6 +44,7 @@ class TaskDownloadManager constructor(
ConcurrentHashMap<Int, TaskDownloadScope>()
}
fun init(context: Context) {
this.context = context
}
@@ -81,6 +85,12 @@ class TaskDownloadManager constructor(
* 只有等待中的任务和正在下载中的任务才可以进行暂停操作
*/
fun pause(id: Int) {
if (scopeMap.containsKey(id)) {
val downloadScope = scopeMap[id]
downloadScope?.let {
downloadScope.pause()
}
}
if (taskScopeMap.containsKey(id)) {
val downloadScope = taskScopeMap[id]
downloadScope?.let {
@@ -103,7 +113,7 @@ class TaskDownloadManager constructor(
fun addTask(taskBean: TaskBean) {
if (!scopeMap.containsKey(taskBean.id)) {
scopeMap[taskBean.id] = TaskDownloadScope( this, taskBean)
scopeMap[taskBean.id] = TaskDownloadScope(this, realmOperateHelper, taskBean)
}
}

View File

@@ -1,16 +1,25 @@
package com.navinfo.omqs.http.taskdownload
import android.os.Handler
import android.os.Message
import android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.navinfo.omqs.Constant
import androidx.lifecycle.viewmodel.viewModelFactory
import com.blankj.utilcode.util.MapUtils
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.Constant
import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.db.MultiPathsCallback
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
import com.navinfo.omqs.util.DateTimeUtil
import io.realm.Realm
import kotlinx.coroutines.*
import org.oscim.android.theme.AssetsRenderTheme
import java.io.File
import java.io.IOException
import java.io.InputStream
@@ -18,9 +27,10 @@ import java.io.RandomAccessFile
class TaskDownloadScope(
private val downloadManager: TaskDownloadManager,
val taskBean: TaskBean,
private val realmOperateHelper: RealmOperateHelper,
var taskBean: TaskBean,
) :
CoroutineScope by CoroutineScope(Dispatchers.IO + CoroutineName("OfflineMapDownLoad")) {
CoroutineScope by CoroutineScope(Dispatchers.IO + CoroutineName("TaskMapDownLoad")) {
/**
*下载任务,用来取消的
@@ -30,8 +40,8 @@ class TaskDownloadScope(
/**
* 管理观察者,同时只有一个就行了
*/
private val observer = Observer<Any> {}
// private var lifecycleOwner: LifecycleOwner? = null
// private val observer = Observer<Any> {}
private var lifecycleOwner: LifecycleOwner? = null
/**
*通知UI更新
@@ -44,7 +54,7 @@ class TaskDownloadScope(
//改进的代码
fun start() {
launch{
launch {
change(FileDownloadStatus.WAITING)
}
downloadManager.launchScope(this@TaskDownloadScope)
@@ -56,8 +66,12 @@ class TaskDownloadScope(
*/
fun pause() {
downloadJob?.cancel("pause")
launch{
change(FileDownloadStatus.PAUSE)
launch {
if (taskBean.fileSize == 0L) {
change(FileDownloadStatus.NONE)
} else {
change(FileDownloadStatus.PAUSE)
}
}
}
@@ -70,7 +84,7 @@ class TaskDownloadScope(
downloadJob = launch() {
FileManager.checkOMDBFileInfo(taskBean)
if (taskBean.status == FileDownloadStatus.IMPORT) {
importData()
importData(task = taskBean)
} else {
download()
}
@@ -91,15 +105,34 @@ class TaskDownloadScope(
* @param status [OfflineMapCityBean.Status]
*/
private suspend fun change(status: Int, message: String = "") {
if (taskBean.status != status || status == FileDownloadStatus.LOADING || status == FileDownloadStatus.IMPORTING) {
taskBean.status = status
taskBean.message = message
//赋值时间,用于查询过滤
taskBean.operationTime = DateTimeUtil.getNowDate().time
downloadData.postValue(taskBean)
if (status != FileDownloadStatus.LOADING && status != FileDownloadStatus.IMPORTING) {
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
it.copyToRealmOrUpdate(taskBean)
val realm = realmOperateHelper.getRealmDefaultInstance()
// Log.e("jingo", "数据下载更新状态 原${}")
realm.executeTransaction { r ->
// realm.insertOrUpdate(taskBean)
val newTask =
realm.where(TaskBean::class.java).equalTo("id", taskBean.id).findFirst()
newTask?.let {
it.syncStatus = taskBean.syncStatus
it.status = taskBean.status
it.errMsg = taskBean.errMsg
//赋值时间,用于查询过滤
it.operationTime = taskBean.operationTime
Log.e("jingo","文件下载1状态 ${it.status}")
r.copyToRealmOrUpdate(it)
taskBean = realm.copyFromRealm(it)
Log.e("jingo","文件下载2状态 ${taskBean.status}")
}
}
realm.refresh()
realm.close()
}
}
}
@@ -108,15 +141,16 @@ class TaskDownloadScope(
* 添加下载任务观察者
*/
fun observer(owner: LifecycleOwner, ob: Observer<TaskBean>) {
removeObserver()
// this.lifecycleOwner = owner
this.lifecycleOwner = owner
downloadData.observe(owner, ob)
}
/**
* 导入数据
*/
private suspend fun importData(file: File? = null) {
private suspend fun importData(file: File? = null, task: TaskBean? = null) {
try {
Log.e("jingo", "importData SSS")
change(FileDownloadStatus.IMPORTING)
@@ -127,21 +161,61 @@ class TaskDownloadScope(
downloadManager.context,
fileNew
)
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile).collect {
Log.e("jingo", "数据安装 $it")
if (it == "finish") {
change(FileDownloadStatus.DONE)
withContext(Dispatchers.Main) {
downloadManager.mapController.mMapView.updateMap(true)
}
} else {
change(FileDownloadStatus.IMPORTING, it)
}
if (task != null) {
importOMDBHelper.importOmdbZipFile(
importOMDBHelper.omdbFile,
task,
this,
object : MultiPathsCallback<String> {
override fun onProgress(value: Int) {
// Log.e("jingo", "安装====$value")
}
override fun onError(t: Throwable) {
}
override fun onComplete() {
taskBean.status = FileDownloadStatus.DONE
downloadData.postValue(taskBean)
//移除当前任务,进行下一个任务下载逻辑
downloadManager.launchNext(taskBean.id)
//任务与当前一致,需要更新渲染图层
if (MapParamUtils.getTaskId() == taskBean.id) {
downloadManager.mapController.layerManagerHandler.updateOMDBVectorTileLayer()
}
val realm = realmOperateHelper.getRealmDefaultInstance()
realm.executeTransaction { r ->
val newTask =
realm.where(TaskBean::class.java).equalTo("id", taskBean.id)
.findFirst()
newTask?.let {
it.syncStatus = taskBean.syncStatus
it.status = taskBean.status
it.errMsg = taskBean.errMsg
//赋值时间,用于查询过滤
it.operationTime = taskBean.operationTime
Log.e("jingo","文件下载安装1状态 ${it.status}")
r.copyToRealmOrUpdate(it)
taskBean = realm.copyFromRealm(it)
Log.e("jingo","文件下载安装2状态 ${taskBean.status}")
}
}
realm.refresh()
realm.close()
}
override fun onResult(value: String) {
taskBean.status = FileDownloadStatus.IMPORTING
taskBean.message = value
downloadData.postValue(taskBean)
}
})
}
} catch (e: Exception) {
Log.e("jingo", "数据安装失败 ${e.toString()}")
change(FileDownloadStatus.ERROR)
}finally {
} finally {
}
@@ -167,10 +241,14 @@ class TaskDownloadScope(
val fileTemp =
File("${Constant.DOWNLOAD_PATH}${taskBean.evaluationTaskName}_${taskBean.dataVersion}.zip")
val startPosition = taskBean.currentSize
var startPosition = taskBean.currentSize
if (fileTemp.length() > taskBean.fileSize && taskBean.fileSize > 0) {
fileTemp.delete()
fileTemp.createNewFile()
startPosition = 0
}
if (fileTemp.length() > 0 && taskBean.fileSize > 0 && fileTemp.length() == taskBean.fileSize) {
importData(fileTemp)
importData(fileTemp, taskBean)
return
}
@@ -184,7 +262,6 @@ class TaskDownloadScope(
responseBody ?: throw IOException("jingo ResponseBody is null")
if (startPosition == 0L) {
taskBean.fileSize = responseBody.contentLength()
Log.e("jingo", "当前文件大小 ${taskBean.fileSize}")
}
change(FileDownloadStatus.LOADING)
//写入文件
@@ -212,7 +289,7 @@ class TaskDownloadScope(
randomAccessFile?.close()
inputStream = null
randomAccessFile = null
importData()
importData(task = taskBean)
} else {
change(FileDownloadStatus.PAUSE)
}
@@ -226,10 +303,13 @@ class TaskDownloadScope(
}
fun removeObserver() {
downloadData.observeForever(observer)
// lifecycleOwner?.let {
downloadData.removeObserver(observer)
// null
// }
// downloadData.observeForever(observer)
//// lifecycleOwner?.let {
// downloadData.removeObserver(observer)
//// null
//// }
if (lifecycleOwner != null) {
downloadData.removeObservers(lifecycleOwner!!)
}
}
}

View File

@@ -4,6 +4,7 @@ import android.content.Context
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import java.util.concurrent.ConcurrentHashMap
@@ -13,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap
class TaskUploadManager constructor(
val netApi: RetrofitNetworkServiceAPI,
val realmOperateHelper: RealmOperateHelper,
) {
lateinit var context: Context
@@ -84,7 +86,7 @@ class TaskUploadManager constructor(
fun addTask(taskBean: TaskBean) {
if (!scopeMap.containsKey(taskBean.id)) {
scopeMap[taskBean.id] = TaskUploadScope( this, taskBean)
scopeMap[taskBean.id] = TaskUploadScope(this, realmOperateHelper, taskBean)
}
}

View File

@@ -2,6 +2,7 @@ package com.navinfo.omqs.http.taskupload
import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
@@ -9,14 +10,21 @@ import androidx.lifecycle.Observer
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.omqs.bean.EvaluationInfo
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.bean.SysUserBean
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.http.DefaultResponse
import com.navinfo.omqs.tools.FileManager.Companion.FileUploadStatus
import com.navinfo.omqs.util.DateTimeUtil
import com.navinfo.omqs.util.FileUtils
import io.realm.Realm
import kotlinx.coroutines.*
import java.util.*
class TaskUploadScope(
private val uploadManager: TaskUploadManager,
val taskBean: TaskBean,
private val realmOperateHelper: RealmOperateHelper,
var taskBean: TaskBean,
) :
CoroutineScope by CoroutineScope(Dispatchers.IO + CoroutineName("OfflineMapUpLoad")) {
@@ -66,18 +74,36 @@ class TaskUploadScope(
* @param status [OfflineMapCityBean.Status]
*/
private fun change(status: Int, message: String = "") {
if (taskBean.syncStatus != status) {
taskBean.syncStatus = status
uploadData.postValue(taskBean)
//同步中不进行状态记录,只做界面变更显示
if(status!=FileUploadStatus.UPLOADING){
launch {
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
it.copyToRealmOrUpdate(taskBean)
launch {
if (taskBean.syncStatus != status) {
taskBean.syncStatus = status
taskBean.errMsg = message
//赋值时间,用于查询过滤
taskBean.operationTime = DateTimeUtil.getNowDate().time
//同步中不进行状态记录,只做界面变更显示
if (status != FileUploadStatus.UPLOADING) {
val realm = realmOperateHelper.getRealmDefaultInstance()
Log.e(
"jingo",
"数据上传更新状态change status:${status} 任务link数量${taskBean.hadLinkDvoList.size}"
)
realm.executeTransaction { r ->
val newTask =
realm.where(TaskBean::class.java).equalTo("id", taskBean.id).findFirst()
newTask?.let {
it.syncStatus = taskBean.syncStatus
it.errMsg = taskBean.errMsg
//赋值时间,用于查询过滤
it.operationTime = taskBean.operationTime
Log.e("jingo","数据安装状态 ${it.status}")
r.copyToRealmOrUpdate(it)
taskBean = realm.copyFromRealm(it)
}
}
realm.close()
}
}
uploadData.postValue(taskBean)
}
}
@@ -107,51 +133,145 @@ class TaskUploadScope(
return
}
val realm = Realm.getDefaultInstance()
val realm = realmOperateHelper.getRealmDefaultInstance()
realm.refresh()
val bodyList: MutableList<EvaluationInfo> = ArrayList()
if (taskBean.syncStatus == FileUploadStatus.WAITING){
if (taskBean.syncStatus == FileUploadStatus.WAITING) {
change(FileUploadStatus.UPLOADING)
}
Log.e("jingo", "上传link数量1 ${taskBean.hadLinkDvoList.size}")
val newTaskBean =
realm.where(TaskBean::class.java).equalTo("id", taskBean.id).findFirst()
if (newTaskBean != null) {
Log.e("jingo", "上传link数量2 ${newTaskBean.hadLinkDvoList.size}")
taskBean = realm.copyFromRealm(newTaskBean)
}
taskBean.hadLinkDvoList.forEach { hadLinkDvoBean ->
val objects = realm.where(QsRecordBean::class.java)
.equalTo("linkId", /*"84207223282277331"*/hadLinkDvoBean.linkPid).findAll()
if (objects != null&&objects.size>0) {
val copyList = realm.copyFromRealm(objects)
copyList.forEach {
val evaluationInfo = EvaluationInfo(
evaluationTaskId = taskBean.id.toString(),
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"
linkStatus = "已测评",
markId = hadLinkDvoBean.mesh,//"20065597"
trackPhotoNumber = "",
markGeometry = it.geometry,
featureName = it.classType,
problemType = it.problemType,
problemPhenomenon = it.phenomenon,
problemDesc = it.description,
problemLink = it.problemLink,
problemReason = it.cause,
evaluatorName = it.checkUserId,
evaluationDate = it.checkTime,
evaluationWay = "现场测评"
)
for (hadLinkDvoBean in taskBean.hadLinkDvoList) {
Log.e("jingo", "数据上传遍历开始0${hadLinkDvoBean.linkPid}")
val linkStatus = 1
//存在原因标记未测评
if (hadLinkDvoBean.reason.isNotEmpty()) {
bodyList.add(evaluationInfo)
//未测评
val linkStatus = 0
val evaluationInfo = EvaluationInfo(
evaluationTaskId = taskBean.id.toString(),
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"
linkStatus = linkStatus,
markId = UUID.randomUUID().toString(),//"20065597"
trackPhotoNumber = "",
markGeometry = "",
linkGeometry = "",
featureName = "",
problemType = 0,
problemPhenomenon = "",
problemDesc = "",
problemLink = "",
preliminaryAnalysis = "",
evaluatorName = "",
evaluationDate = "",
evaluationWay = 2,
roadClassifcation = 1,
roadFunctionGrade = 0,
noEvaluationreason = hadLinkDvoBean.reason,
linkLength = 0.0,
dataLevel = 0,
linstringLength = 0.0,
)
bodyList.add(evaluationInfo)
} else {
val linkStatus = hadLinkDvoBean.linkStatus
var s: String = "%.3f".format(hadLinkDvoBean.length)//保留一位小数(且支持四舍五入)
val objects = realm.where(QsRecordBean::class.java)
.equalTo("linkId", /*"84207223282277331"*/hadLinkDvoBean.linkPid).and()
.equalTo("taskId", taskBean.id).findAll()
if (objects != null && objects.size > 0) {
val copyList = realm.copyFromRealm(objects)
for (it in copyList) {
val problemType = when (it.problemType) {
// "错误" -> {
// 0
// }
"多余" -> {
1
}
"遗漏" -> {
2
}
else -> {
0
}
}
var roadClassifcation = 0
var roadFunctionGrade = 0
var dataLevel = 0
if (hadLinkDvoBean.linkInfo != null) {
roadClassifcation = hadLinkDvoBean.linkInfo!!.kind
roadFunctionGrade = hadLinkDvoBean.linkInfo!!.functionLevel
dataLevel = hadLinkDvoBean.linkInfo!!.dataLevel
}
var linkGeometry = ""
if(linkStatus == 3)
linkGeometry = hadLinkDvoBean.geometry
val evaluationWay = 2
val evaluationInfo = EvaluationInfo(
evaluationTaskId = taskBean.id.toString(),
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"
linkStatus = linkStatus,
markId = it.id,
trackPhotoNumber = "",
markGeometry = it.geometry,
linkGeometry = linkGeometry,
featureName = it.classCode,
problemType = problemType,
problemPhenomenon = it.phenomenon,
problemDesc = it.description,
problemLink = it.problemLink,
preliminaryAnalysis = it.cause,
evaluatorName = it.checkUserId,
evaluationDate = it.checkTime,
evaluationWay = evaluationWay,
roadClassifcation = roadClassifcation,
roadFunctionGrade = roadFunctionGrade,
noEvaluationreason = "",
linkLength = s.toDouble(),
dataLevel = dataLevel,
linstringLength = 0.0,
)
bodyList.add(evaluationInfo)
}
}
}
}
realm.close()
Log.e("jingo", "数据上传条数 ${bodyList.size}")
if (bodyList.size > 0) {
if(bodyList.size>0){
val result = uploadManager.netApi.postRequest(bodyList)// .enqueue(object :
// Callback<ResponseBody> {
if (result.isSuccessful) {
if (result.code() == 200) {
// taskBean.syncStatus = FileUploadStatus.DONE
// handle the response
change(FileUploadStatus.DONE)
if (result.code() == 200 && result.body() != null) {
val defaultUserResponse = result.body() as DefaultResponse<*>
if (defaultUserResponse.success) {
change(FileUploadStatus.DONE, "上传成功")
} else {
change(FileUploadStatus.ERROR, "${defaultUserResponse.msg}")
Log.e("jingo", "数据上传出错 ${defaultUserResponse.msg}")
}
} else {
// handle the failure
change(FileUploadStatus.ERROR)
@@ -159,14 +279,13 @@ class TaskUploadScope(
} else {
change(FileUploadStatus.ERROR)
}
}else{
change(FileUploadStatus.NONE)
} else {
change(FileUploadStatus.NONE, "无可上传数据")
}
} catch (e: Throwable) {
change(FileUploadStatus.ERROR)
Log.e("jingo", "数据上传出错 ${e.message}")
} finally {
}
}

View File

@@ -0,0 +1,131 @@
package com.navinfo.omqs.server
import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.SystemClock
/**
* date:2023/6/18
* author:qj
* description:定时器
*/
class TimeTask<T : TimeTask.Task?>(context: Context, actionName: String, task: T) {
private var mContext: Context?
private val mActionName: String
private var mReceiver: TimeTaskReceiver? = null
private val mTask: T?
companion object {
private var mPendingIntent: PendingIntent? = null
}
init {
mContext = context
mActionName = actionName
mTask = task
initReceiver(context, actionName)
}
fun startLooperTask() {
if (null != mTask) {
mTask.exeTask()
configureAlarmManager(mTask.period())
}
}
fun stopLooperTask() {
cancelAlarmManager()
}
fun onClose() {
mContext!!.unregisterReceiver(mReceiver)
mContext = null
}
@SuppressLint("ObsoleteSdkInt")
private fun configureAlarmManager(time: Long) {
val manager = mContext!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val pendIntent = pendingIntent
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
manager.setExactAndAllowWhileIdle(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + time,
pendIntent
)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT -> {
manager.setExact(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + time,
pendIntent
)
}
else -> {
manager[AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + time] = pendIntent
}
}
}
@get:SuppressLint("UnspecifiedImmutableFlag")
private val pendingIntent: PendingIntent?
get() {
if (mPendingIntent == null) {
val requestCode = 0
val intent = Intent()
intent.action = mActionName
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
mPendingIntent = PendingIntent.getBroadcast(
mContext, requestCode, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
)
}
else -> {
mPendingIntent = PendingIntent.getBroadcast(
mContext,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
}
}
return mPendingIntent
}
private fun cancelAlarmManager() {
val manager = mContext!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
manager.cancel(pendingIntent)
}
private fun initReceiver(context: Context, actionName: String) {
mReceiver = TimeTaskReceiver()
val intentFilter = IntentFilter()
intentFilter.addAction(actionName)
context.registerReceiver(mReceiver, intentFilter)
}
internal inner class TimeTaskReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
startLooperTask()
}
}
interface Task {
fun period(): Long {
// 默认时间5S
return 5000L
}
fun exeTask()
}
}

View File

@@ -28,6 +28,7 @@ class FileManager {
const val ERROR = 2 //错误
const val WAITING = 3 //等待中
const val UPLOADING = 4 //同步中
const val NOUPLOAD = 5 //无能上传
}
//初始化数据文件夹

View File

@@ -6,39 +6,33 @@ import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.ImportConfig
import com.navinfo.omqs.tools.LayerConfigUtils.Companion.gson
import java.io.File
class LayerConfigUtils {
companion object {
private val omdbConfigFile = File("${Constant.USER_DATA_PATH}", Constant.OMDB_CONFIG)
private val otherConfigFile = File("${Constant.USER_DATA_PATH}", Constant.OTHER_CONFIG)
private val gson = Gson()
fun getLayerConfigList(): List<ImportConfig> {
// 首先读取Shared文件如果存在则直接返回否则读取config文件
return SPStaticUtils.getString(Constant.EVENT_LAYER_MANAGER_CHANGE, null).let {
if (it != null) {
val result: List<ImportConfig> =
gson.fromJson(it, object : TypeToken<List<ImportConfig>>() {}.type)
result
} else {
LayerConfigUtils.getLayerConfigListFromAssetsFile()
}
// 首先读取全局变量的数据如果存在则直接返回否则读取config文件
if (Constant.LAYER_CONFIG_LIST == null) {
Constant.LAYER_CONFIG_LIST = getLayerConfigListFromAssetsFile()
}
return Constant.LAYER_CONFIG_LIST!!
}
private fun getLayerConfigListFromAssetsFile(): List<ImportConfig> {
val resultList = mutableListOf<ImportConfig>()
if (omdbConfigFile.exists()) {
val omdbConfiStr = FileIOUtils.readFile2String(omdbConfigFile)
val omdbConfig = gson.fromJson<ImportConfig>(omdbConfiStr, ImportConfig::class.java)
resultList.add(omdbConfig)
}
if (otherConfigFile.exists()) {
val otherConfiStr = FileIOUtils.readFile2String(otherConfigFile)
val otherConfig =
gson.fromJson<ImportConfig>(otherConfiStr, ImportConfig::class.java)
resultList.add(otherConfig)
val type = object : TypeToken<List<ImportConfig>>() {}.type
return try {
val result = gson.fromJson<List<ImportConfig>>(omdbConfiStr, type)
result ?: resultList
} catch (e: Exception) {
resultList
}
}
return resultList
}

View File

@@ -13,7 +13,12 @@ class MetadataUtils {
object ScRootCauseAnalysisTitle {
const val TITLE_PROBLEM_LINK = "问题环节"
const val TITLE_PROBLEM_CAUSE = "初步问题原因"
const val TITLE_PROBLEM_CAUSE = "初步分析"
}
object ScWarningCodeTitle{
const val TITLE_CODE = "编码"
const val TITLE_DESCRIBE = "描述"
}
}
}

View File

@@ -1,9 +1,7 @@
package com.navinfo.omqs.ui.activity
import android.app.Dialog
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.os.PersistableBundle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.R
@@ -15,10 +13,15 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
open class BaseActivity : AppCompatActivity() {
private var loadingDialog: AlertDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE//横屏
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
super.onCreate(savedInstanceState)
}
override fun onResume() {
super.onResume()
}
/**
* 显示loading dialog
*/

View File

@@ -37,7 +37,8 @@ public class CheckPermissionsActivity extends BaseActivity {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
};
private static final int PERMISSON_REQUESTCODE = 0;
@@ -53,6 +54,7 @@ public class CheckPermissionsActivity extends BaseActivity {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
BACKGROUND_LOCATION_PERMISSION
};
}

View File

@@ -13,8 +13,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityLoginBinding
import com.navinfo.omqs.ui.activity.CheckPermissionsActivity
import com.navinfo.omqs.ui.activity.PermissionsActivity
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.umeng.commonsdk.UMConfigure
import dagger.hilt.android.AndroidEntryPoint
/**
@@ -34,7 +34,14 @@ class LoginActivity : CheckPermissionsActivity() {
binding.lifecycleOwner = this
binding.activity = this
initView()
Log.e("jingo", getScreenParams())
// Log.e("jingo", getScreenParams())
UMConfigure.init(
this,
"650bece7b2f6fa00ba573c7a",
"native",
UMConfigure.DEVICE_TYPE_PHONE,
""
)
}
private fun getScreenParams(): String {
@@ -73,40 +80,54 @@ class LoginActivity : CheckPermissionsActivity() {
LoginStatus.LOGIN_STATUS_NET_LOADING -> {
loginDialog("验证用户信息...")
}
LoginStatus.LOGIN_STATUS_FOLDER_INIT -> {
loginDialog("检查本地数据...")
}
LoginStatus.LOGIN_STATUS_FOLDER_FAILURE -> {
Toast.makeText(this, "文件夹初始化失败", Toast.LENGTH_SHORT).show()
loginDialog?.dismiss()
loginDialog = null
}
LoginStatus.LOGIN_STATUS_NET_FAILURE -> {
Toast.makeText(this, "网络访问失败", Toast.LENGTH_SHORT).show()
loginDialog?.dismiss()
loginDialog = null
}
LoginStatus.LOGIN_STATUS_SUCCESS -> {
loginDialog?.dismiss()
loginDialog = null
//Toast.makeText(this, "插入成功", Toast.LENGTH_SHORT).show()
val intent = Intent(this@LoginActivity, MainActivity::class.java)
startActivity(intent)
finish()
}
LoginStatus.LOGIN_STATUS_CANCEL -> {
loginDialog?.dismiss()
loginDialog = null
}
LoginStatus.LOGIN_STATUS_NET_OFFLINE_MAP -> {
loginDialog("检查离线地图...")
}
LoginStatus.LOGIN_STATUS_NET_GET_TASK_LIST -> {
loginDialog("获取任务列表...")
}
else -> {}
}
}
private fun initView() {
//登录校验,初始化成功
viewModel.loginStatus.observe(this, loginObserve)
viewModel.lastLoginUserInfo(this)
}
/**
@@ -114,6 +135,7 @@ class LoginActivity : CheckPermissionsActivity() {
*/
private fun loginDialog(message: String) {
if (loginDialog == null) {
Log.e("jingo", "登录dialog显示")
loginDialog = MaterialAlertDialogBuilder(
this, com.google.android.material.R.style.MaterialAlertDialog_Material3
).setTitle("登录").setMessage(message).show()

View File

@@ -1,6 +1,7 @@
package com.navinfo.omqs.ui.activity.login
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import android.view.View
import android.widget.Toast
@@ -8,16 +9,21 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.ResourceUtils
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.db.MyRealmModule
import com.navinfo.omqs.bean.SysUserBean
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.DefaultResponse
import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.util.DateTimeUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmMigration
import io.realm.RealmSchema
import kotlinx.coroutines.*
import java.io.File
import java.io.IOException
@@ -34,6 +40,11 @@ enum class LoginStatus {
*/
LOGIN_STATUS_NET_OFFLINE_MAP,
/**
* 访问任务列表
*/
LOGIN_STATUS_NET_GET_TASK_LIST,
/**
* 初始化文件夹
*/
@@ -71,18 +82,27 @@ class LoginViewModel @Inject constructor(
//是不是登录成功
val loginStatus: MutableLiveData<LoginStatus> = MutableLiveData()
var jobLogin: Job? = null;
var jobLogin: Job? = null
var sharedPreferences: SharedPreferences? = null
init {
loginUser.value = LoginUserBean(username = "admin", password = "123456")
}
fun lastLoginUserInfo(context: Context){
sharedPreferences =
context.getSharedPreferences("USER_SHAREDPREFERENCES", Context.MODE_PRIVATE)
val userNameCache = sharedPreferences?.getString("userName", "lixiaoming00427")
val passwordCache = sharedPreferences?.getString("passWord", "123456")
loginUser.value = LoginUserBean(userCode = "$userNameCache", passWord = "$passwordCache")
}
/**
* 处理注册按钮
*/
fun onClick(view: View) {
loginUser.value!!.username = "admin2"
loginUser.value!!.userCode = "admin2"
loginUser.value = loginUser.value
}
@@ -96,10 +116,29 @@ class LoginViewModel @Inject constructor(
if (password.isEmpty()) {
Toast.makeText(context, "请输入密码", Toast.LENGTH_SHORT).show()
}
sharedPreferences =
context.getSharedPreferences("USER_SHAREDPREFERENCES", Context.MODE_PRIVATE)
val userNameCache = sharedPreferences?.getString("userName", null)
val passwordCache = sharedPreferences?.getString("passWord", null)
val userCodeCache = sharedPreferences?.getString("userCode", null)
val userRealName = sharedPreferences?.getString("userRealName", null)
//增加缓存记录,不用每次连接网络登录
if (userNameCache != null && passwordCache != null && userCodeCache != null && userRealName != null) {
if (userNameCache == userName && passwordCache == password) {
viewModelScope.launch(Dispatchers.IO) {
createUserFolder(context, userCodeCache, userRealName)
// getOfflineCityList(context)
// loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
}
// return
}
}
//不指定IO会在主线程里运行
jobLogin = viewModelScope.launch(Dispatchers.IO) {
//Log.e("qj", "computeline==${GeometryTools.computeLine(0.003,0.003,"LINESTRING(116.2730063860964 40.09052257957624 36.75, 116.27376497186042 40.090072453495395 38.34, 116.27413076766412 40.089855289361786 39.01, 116.27417239035157 40.08983061650492 39.15, 116.27466896728139 40.089535645040385 39.99, 116.2751211296483 40.089267551829636 40.67, 116.27545352868347 40.089070581974944 40.98, 116.27589660200627 40.088807594767246 41.28, 116.27604819769634 40.088718103405185 41.34, 116.27667570485863 40.08834486145473 41.43, 116.2770275412774 40.08813642434714 41.36, 116.27745673745146 40.087882150865546 41.14, 116.27778797172138 40.08768490714857 40.89, 116.2781675465249 40.087459905560266 40.45, 116.2783819045443 40.087332076220086 40.02, 116.27880692426884 40.0870801193608 39.32, 116.27943180930261 40.08670963506418 38.04, 116.27977508323622 40.08650562397605 37.39, 116.28016410016664 40.08627485623695 36.77, 116.28057924586821 40.0860283164225 36.29)")}")
loginCheck(context, userName, password)
}
}
/**
@@ -111,18 +150,85 @@ class LoginViewModel @Inject constructor(
// withContext(Dispatchers.IO) {
//网络访问
loginStatus.postValue(LoginStatus.LOGIN_STATUS_NET_LOADING)
//假装网络访问等待2秒
delay(1000)
//文件夹初始化
try {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
createUserFolder(context, "02911")
} catch (e: IOException) {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
var userCode = "99999";
var userRealName = "";
//登录访问
when (val result = networkService.loginUser(LoginUserBean(userName, password))) {
is NetResult.Success<*> -> {
if (result.data != null) {
try {
val defaultUserResponse = result.data as DefaultResponse<SysUserBean>
if (defaultUserResponse.success) {
if (defaultUserResponse.obj == null || defaultUserResponse.obj!!.userCode == null) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"服务返回用户Code信息错误",
Toast.LENGTH_SHORT
)
.show()
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
return
} else {
userCode = defaultUserResponse.obj?.userCode.toString()
userRealName = defaultUserResponse.obj?.userName.toString()
folderInit(
context = context,
userName = userName,
password = password,
userCode = userCode,
userRealName = userRealName
)
getOfflineCityList(context)
}
} else {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${defaultUserResponse.msg}",
Toast.LENGTH_SHORT
)
.show()
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
return
}
} catch (e: IOException) {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
}
}
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
.show()
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
return
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
.show()
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
return
}
else -> {}
}
//假装解压文件等
delay(1000)
}
/**
* 获取离线地图
*/
private suspend fun getOfflineCityList(context: Context) {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_NET_OFFLINE_MAP)
when (val result = networkService.getOfflineMapCityList()) {
is NetResult.Success -> {
@@ -133,58 +239,186 @@ class LoginViewModel @Inject constructor(
}
roomAppDatabase.getOfflineMapDao().insertOrUpdate(result.data)
}
getTaskList(context)
}
is NetResult.Error -> {
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
.show()
}
getTaskList(context)
}
is NetResult.Failure -> {
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
.show()
}
getTaskList(context)
}
is NetResult.Loading -> {}
else -> {}
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
}
/**
* 获取任务列表
*/
private suspend fun getTaskList(context: Context) {
//每天主动请求一次,其他情况列表内自己手动请求
val questToday = sharedPreferences?.getBoolean(DateTimeUtil.getYYYYMMDDDate()+"getTaskList",false)
if(!questToday!!){
loginStatus.postValue(LoginStatus.LOGIN_STATUS_NET_GET_TASK_LIST)
Log.e("qj","获取任务请求开始==")
when (val result = networkService.getTaskList(Constant.USER_ID)) {
is NetResult.Success -> {
if (result.data != null) {
Log.e("qj","获取任务返回成功==")
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
result.data.obj?.let { list ->
for (index in list.indices) {
var inSertData = true
val task = list[index]
val item = realm.where(TaskBean::class.java).equalTo(
"id", task.id
).findFirst()
if (item != null) {
task.fileSize = item.fileSize
task.status = item.status
task.currentSize = item.currentSize
//增加mesh==null兼容性处理
for (hadLink in item.hadLinkDvoList) {
if(hadLink.mesh==null){
hadLink.mesh = ""
}
}
task.hadLinkDvoList = item.hadLinkDvoList
task.syncStatus = item.syncStatus
//已上传后不在更新操作时间
if (task.syncStatus != FileManager.Companion.FileUploadStatus.DONE) {
//赋值时间,用于查询过滤
task.operationTime = DateTimeUtil.getNowDate().time
}else{
continue
}
} else {
for (hadLink in task.hadLinkDvoList) {
if(hadLink.geometry==null){
inSertData = false
}else if(hadLink.mesh==null){
hadLink.mesh = ""
}else{
hadLink.taskId = task.id
}
Log.e("qj","mesh==${hadLink.mesh}")
}
//赋值时间,用于查询过滤
task.operationTime = DateTimeUtil.getNowDate().time
}
Log.e("qj","task==${task.id}")
if(inSertData){
realm.copyToRealmOrUpdate(task)
}
}
}
}
realm.close()
//增加当天请求过标识
sharedPreferences?.edit()
?.putBoolean(DateTimeUtil.getYYYYMMDDDate()+"getTaskList",true)
Log.e("qj","获取任务结束==")
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
.show()
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
.show()
}
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
}
is NetResult.Loading -> {}
}
}else{
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
}
}
/**
* 初始化文件夹
*/
private fun folderInit(
context: Context,
userName: String,
password: String,
userCode: String,
userRealName: String
) {
//文件夹初始化
try {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
sharedPreferences?.edit()?.putString("userName", userName)?.commit()
sharedPreferences?.edit()?.putString("passWord", password)?.commit()
sharedPreferences?.edit()?.putString("userCode", userCode)?.commit()
sharedPreferences?.edit()?.putString("userRealName", userRealName)?.commit()
createUserFolder(context, userCode, userRealName)
} catch (e: IOException) {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
}
}
/**
* 创建用户目录
*/
private fun createUserFolder(context: Context, userId: String) {
private fun createUserFolder(context: Context, userId: String, userRealName: String) {
Constant.IS_VIDEO_SPEED = false
Constant.USER_ID = userId
Constant.USER_REAL_NAME = userRealName
Constant.VERSION_ID = userId
Constant.USER_DATA_PATH = Constant.DATA_PATH + Constant.USER_ID + "/" + Constant.VERSION_ID
Constant.USER_DATA_ATTACHEMNT_PATH = Constant.USER_DATA_PATH + "/attachment/"
Constant.USER_DATA_LOG_PATH = Constant.USER_DATA_PATH + "/log/"
// 在SD卡创建用户目录解压资源等
val userFolder = File(Constant.USER_DATA_PATH)
if (!userFolder.exists()) userFolder.mkdirs()
//创建附件目录
val userAttachmentFolder = File(Constant.USER_DATA_ATTACHEMNT_PATH)
if (!userAttachmentFolder.exists()) userAttachmentFolder.mkdirs()
val userLogFolder = File(Constant.USER_DATA_LOG_PATH)
if (!userLogFolder.exists()) userLogFolder.mkdirs()
// 初始化Realm
Realm.init(context.applicationContext)
val password = "encryp".encodeToByteArray().copyInto(ByteArray(64))
// 656e6372797000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Log.d("OMQSApplication", "密码是: ${byteArrayToHexString(password)}")
val config = RealmConfiguration.Builder()
.directory(userFolder)
.name("OMQS.realm")
.encryptionKey(password)
// .modules(Realm.getDefaultModule(), MyRealmModule())
.schemaVersion(1)
.encryptionKey(Constant.PASSWORD)
// .allowQueriesOnUiThread(true)
.schemaVersion(3)
// .migration(migration)
.build()
Realm.setDefaultConfiguration(config)
// 拷贝配置文件到用户目录下
val omdbConfigFile = File(userFolder.absolutePath, Constant.OMDB_CONFIG);
if (!omdbConfigFile.exists()) {
ResourceUtils.copyFileFromAssets(Constant.OMDB_CONFIG, omdbConfigFile.absolutePath)
}
ResourceUtils.copyFileFromAssets(Constant.OMDB_CONFIG, omdbConfigFile.absolutePath)
}
/**
@@ -205,4 +439,17 @@ class LoginViewModel @Inject constructor(
private fun byteArrayToHexString(byteArray: ByteArray): String {
return byteArray.joinToString("") { "%02x".format(it) }
}
val migration : RealmMigration = RealmMigration {
realm, oldVersion, newVersion -> {
if (oldVersion == 2L && newVersion == 3L) {
// DynamicRealm exposes an editable schema
val schema: RealmSchema = realm.schema
if (!schema.get("RenderEntity")!!.hasField("linkPid")) {
schema.get("RenderEntity")
?.addField("linkPid", String::class.java)
}
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
package com.navinfo.omqs.ui.activity.map
enum class SearchEnum {
LINK,LOCATION,MARK
}

View File

@@ -1,34 +1,233 @@
package com.navinfo.omqs.ui.activity.map
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.BitmapDrawable
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.databinding.AdapterSignBinding
import com.navinfo.omqs.databinding.AdapterSignLaneinfoBinding
import com.navinfo.omqs.databinding.AdapterSignTollgateBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
import com.navinfo.omqs.util.SignUtil
import org.oscim.android.canvas.AndroidSvgBitmap
class SignAdapter(private var itemListener: ((Int, SignBean) -> Unit?)? = null) :
interface OnSignAdapterClickListener {
fun onItemClick(signBean: SignBean)
fun onMoreInfoClick(selectTag: String, tag: String, signBean: SignBean)
fun onErrorClick(signBean: SignBean)
}
data class LaneInfoItem(var id: Int, var type: Int)
class SignAdapter(private var listener: OnSignAdapterClickListener?) :
BaseRecyclerViewAdapter<SignBean>() {
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_sign
/**
* 选中的详细信息按钮的tag标签
*/
private var selectMoreInfoTag: String = ""
override fun getItemViewType(position: Int): Int {
if (data.isNotEmpty() && data[position].renderEntity.code == DataCodeEnum.OMDB_LANEINFO.code) {
return 4601
}else if (data.isNotEmpty() && data[position].renderEntity.code == DataCodeEnum.OMDB_CLM_LANEINFO.code) {
return 4602
} else if (data.isNotEmpty() && data[position].renderEntity.code == DataCodeEnum.OMDB_TOLLGATE.code) {
return 4023
}
return 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterSignBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
return when (viewType) {
4601 -> {
val viewBinding =
AdapterSignLaneinfoBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
BaseViewHolder(viewBinding)
}
4023 -> {
val viewBinding = AdapterSignTollgateBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
BaseViewHolder(viewBinding)
}
else -> {
val viewBinding =
AdapterSignBinding.inflate(LayoutInflater.from(parent.context), parent, false)
BaseViewHolder(viewBinding)
}
}
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as AdapterSignBinding
val context = holder.viewBinding.root.context
val item = data[position]
bd.signMainIcon.background = holder.viewBinding.root.context.getDrawable(item.iconId)
bd.signMainIcon.text = item.iconText
bd.signBottomText.text = item.bottomText
bd.signBottomRightText.text = item.bottomRightText
bd.root.setOnClickListener {
itemListener?.invoke(position, item)
when (holder.viewBinding) {
is AdapterSignBinding -> {
val bd = holder.viewBinding
if (item.iconId != 0) {
bd.signMainIconBg.visibility = View.VISIBLE
if (item.renderEntity.code == DataCodeEnum.OMDB_WARNINGSIGN.code) {
try {
var typeCode = "${item.iconId}"
while (typeCode.length < 5) {
typeCode = "0${typeCode}"
}
val input =
holder.viewBinding.root.context.assets.open("omdb/appendix/1105_${typeCode}_0.svg")
if (input != null) {
val bitmap =
AndroidSvgBitmap.getResourceBitmap(
input,
1.0f,
60.0f,
60,
60,
100
)
input.close()
val drawable = BitmapDrawable(
holder.viewBinding.root.context.resources,
bitmap
)
bd.signMainIconBg.setImageDrawable(drawable)
}
} catch (e: Exception) {
Log.e("jingo", "警示信息没有${item.iconId} 这个SVG")
}
} else {
bd.signMainIconBg.setImageResource(item.iconId)
}
}else{
bd.signMainIconBg.visibility = View.INVISIBLE
}
bd.signMainIcon.text = item.iconText
bd.signBottomText.text = item.name
//点击错误按钮
bd.signMainFastError.setOnClickListener {
listener?.onErrorClick(item)
}
bd.signBottomRightText.text = item.bottomRightText
if (item.isMoreInfo) {
bd.signMainInfo.visibility = View.VISIBLE
bd.signMainInfo.setOnClickListener {
listener?.onMoreInfoClick(selectMoreInfoTag, holder.tag, item)
selectMoreInfoTag = holder.tag
}
} else {
bd.signMainInfo.visibility = View.GONE
}
bd.signDistanceText.text = "${item.distance}"
bd.signSecondIcon.text = ""
if (item.renderEntity.code == DataCodeEnum.OMDB_SPEEDLIMIT.code) {
val minSpeed = SignUtil.getSpeedLimitMinText(item.renderEntity)
if (minSpeed != "0") {
bd.signSecondIcon.text = minSpeed
}
}
bd.signMainBg.setOnClickListener {
listener?.onItemClick(item)
}
}
is AdapterSignLaneinfoBinding -> {
val bd = holder.viewBinding
bd.signMoreIconsLayout.removeAllViews()
bd.signBottomText.text = item.name
bd.signBottomRightText.text = "${item.distance}"
val list = SignUtil.getLineInfoIcons(item.renderEntity)
val lineViewS = View(context)
lineViewS.layoutParams = ViewGroup.LayoutParams(24, 80)
lineViewS.background = context.getDrawable(R.drawable.shape_vertical_dashed_line)
bd.signMoreIconsLayout.addView(lineViewS, lineViewS.layoutParams)
for (i in list.indices) {
val laneInfo = list[i]
val imageView = ImageView(context)
val drawable = context.getDrawable(laneInfo.id)
var color = when (laneInfo.type) {
1 -> bd.root.resources.getColor(R.color.lane_info_1)
2 -> bd.root.resources.getColor(R.color.lane_info_2)
else -> bd.root.resources.getColor(R.color.white)
}
// 创建 PorterDuffColorFilter 对象
val colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
// 将 PorterDuffColorFilter 设置给 Drawable
drawable!!.colorFilter = colorFilter
// 将 Drawable 设置给 ImageView
imageView.background = drawable
// 将 ImageView 的颜色设置为红色
imageView.setColorFilter(color, PorterDuff.Mode.SRC_IN)
imageView.layoutParams = ViewGroup.LayoutParams(35, 100)
bd.signMoreIconsLayout.addView(imageView, imageView.layoutParams)
if (i < list.size - 1) {
val lineView = View(context)
lineView.layoutParams = ViewGroup.LayoutParams(24, 80)
lineView.background =
context.getDrawable(R.drawable.shape_vertical_dashed_line)
bd.signMoreIconsLayout.addView(lineView, lineView.layoutParams)
}
}
val lineViewE = View(context)
lineViewE.layoutParams = ViewGroup.LayoutParams(24, 80)
lineViewE.background = context.getDrawable(R.drawable.shape_vertical_dashed_line)
bd.signMoreIconsLayout.addView(lineViewE, lineViewE.layoutParams)
bd.root.setOnClickListener {
listener?.onItemClick(item)
}
}
is AdapterSignTollgateBinding -> {
val bd = holder.viewBinding
if (item.iconId != 0) {
bd.signMainIconBg.setImageResource(item.iconId)
}
bd.signBottomText.text = item.name
//点击错误按钮
bd.signMainFastError.setOnClickListener {
listener?.onErrorClick(item)
}
bd.signBottomRightText.text = item.bottomRightText
if (item.isMoreInfo) {
bd.signMainInfo.visibility = View.VISIBLE
bd.signMainInfo.setOnClickListener {
listener?.onMoreInfoClick(selectMoreInfoTag, holder.tag, item)
selectMoreInfoTag = holder.tag
}
} else {
bd.signMainInfo.visibility = View.GONE
}
bd.signMainBg.setOnClickListener {
listener?.onItemClick(item)
}
}
}
holder.tag = item.name + position
}
// override fun refreshData(newData: List<SignBean>) {
// super.refreshData(newData)
//// ?这是要干嘛 for (i in newData.indices) {
//// if (selectMoreInfoTag == newData[i].name + i) {
//// return
//// }
//// }
// }
}

View File

@@ -0,0 +1,606 @@
package com.navinfo.omqs.ui.activity.map
import android.app.Service
import android.content.Intent
import android.content.SharedPreferences
import android.os.Binder
import android.os.Handler
import android.os.IBinder
import android.os.Message
import android.text.TextUtils
import android.util.Log
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.Constant
import com.navinfo.omqs.util.DateTimeUtil
import org.json.JSONObject
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.io.Serializable
import java.net.Socket
import java.util.Collections
import kotlin.math.abs
enum class IndoorToolsCommand {
PLAY,
SELECT_POINT,
INDEXING,
NEXT,
REWIND,
STOP
}
enum class IndoorToolsResp{
/**
* 信息更新轨迹成功
*/
QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS,
/**
* 信息更新轨迹失败
*/
QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE,
}
/**
* @author qj
* @version V1.0
* @Date 2018/4/18.
* @Description: 轨迹反向控制服务
*/
class SocketServer(
private val mapController: NIMapController,
private val traceDataBase: TraceDataBase,
private val sharedPreferences: SharedPreferences
) : Service() {
//类标识
private val TAG = "SocketServer"
//线程池
private val threadConnect = ThreadLocal<Socket>()
//读的线程
private var tRecv: RecvThread? = null
//解析线程
private var tParse: ParseThread? = null
//输出流
private var outStr: OutputStream? = null
//输入流
private var inStr: InputStream? = null
//状态
var connectstatus = false
//socket
private var client: Socket? = null
//接收缓存
private val sData = ByteArray(512)
//反馈接口
private var mListener: OnConnectSinsListener? = null
//服务
private val mBinder: MyBinder = MyBinder()
//接收集合
private val mTaskList = Collections.synchronizedList(ArrayList<String>())
//连接线程
private var connectThread: Thread? = null
//缓存ip
private var lastIp = ""
private val mHandler: Handler = object : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
0x11 -> if (mListener != null) {
if (msg.obj != null && msg.obj is NiLocation) {
mListener!!.onReceiveLocation(msg.obj as NiLocation)
} else {
mListener!!.onReceiveLocation(null)
}
}
0x22 -> //索引定位中
if (mListener != null) {
mListener!!.onIndexing()
}
0x33 -> if (mListener != null) {
mListener!!.onConnect(true)
}
0x44 -> if (mListener != null) {
mListener!!.onConnect(false)
}
0x55 -> if (mListener != null) {
mListener!!.onPlay()
}
0x66 -> if (mListener != null) {
mListener!!.onStop()
}
0x99 -> if (mListener != null) {
mListener!!.onParseEnd()
}
0x999 -> if (mListener != null) {
mListener!!.onConnect(false)
disconnect()
}
}
}
}
override fun onCreate() {
super.onCreate()
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
return mBinder
}
inner class MyBinder : Binder() {
// 返回Activity所关联的Service对象这样在Activity里就可调用Service里的一些公用方法 和公用属性
val service: SocketServer
get() =// 返回Activity所关联的Service对象这样在Activity里就可调用Service里的一些公用方法 和公用属性
this@SocketServer
}
/**
* 启动sock连接
*
* @param ip
* @param listener 结果回调
*/
fun connect(ip: String, listener: OnConnectSinsListener?) {
if (connectThread != null && connectThread!!.isAlive && TextUtils.equals(lastIp, ip)) {
return
}
mListener = listener
lastIp = ip
connectThread = object : Thread() {
override fun run() {
try {
client = threadConnect.get()
if (client == null) {
client = Socket(ip, 8010)
client!!.soTimeout = 3000000
client!!.keepAlive = true
threadConnect.set(client)
}
outStr = client!!.getOutputStream()
inStr = client!!.getInputStream()
if (tRecv != null) {
tRecv!!.cancel()
}
tRecv = RecvThread()
val thread = Thread(tRecv)
thread.start()
//解析线程
if (tParse != null) {
tParse!!.cancel()
}
tParse = ParseThread()
val parsethread = Thread(tParse)
parsethread.start()
//socket启动成功
val msg = Message()
msg.what = 0x33
mHandler.sendMessage(msg)
if (!connectstatus) {
connectstatus = true // 更改连接状态
}
} catch (e: Exception) {
e.printStackTrace()
//启动失败
val msg = Message()
msg.what = 0x44
mHandler.sendMessage(msg)
}
}
}
(connectThread as Thread).start()
}
/**
* sock是否启动
*
* @return true 启动 false停止
*/
val isStart: Boolean
get() = if (connectThread != null && connectThread!!.isAlive) {
true
} else false
/**
* 销毁连接
*/
fun disconnect() {
try {
//销毁线程
if (tRecv != null) {
tRecv!!.cancel()
}
//销毁线程
if (tParse != null) {
tParse!!.cancel()
}
} catch (e: Exception) {
}
try {
if (outStr != null) outStr!!.close()
if (inStr != null) inStr!!.close()
if (client != null) client!!.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
/**
* 解析接收到得线程
*/
private inner class ParseThread : Runnable {
private var runFlag = true
//轨迹时间buffer
private val traceTimeBuffer = 1500
private var timeIndex = 0
fun cancel() {
runFlag = false
}
override fun run() {
try {
while (runFlag) {
if (mTaskList.size > 0) {
timeIndex = mTaskList.size - 1
val result = parseResult(mTaskList[timeIndex])
var resultNiLocation: NiLocation? = null
var index: Int = -1
if (result != null) {
when (result.type) {
1 -> {
//先暂停播放
val msg = Message()
msg.what = 0x22
mHandler.sendMessage(msg)
val currentTime: Long = DateTimeUtil.getTimePointSSS(
result.data
)
val currentTimeStr: String = DateTimeUtil.TimePointSSSToTime(
result.data
)
Log.e(TAG, "反向"+result.data)
val startTime = currentTime - traceTimeBuffer
val endTme = currentTime + traceTimeBuffer
//转换为数据库时间
val startTimeStr: String =
DateTimeUtil.getDateSimpleTime(startTime)
//转换为数据库时间
val endTimeStr: String =
DateTimeUtil.getDateSimpleTime(endTme)
if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(
endTimeStr
)
) {
Log.e(TAG, "getTraceData开始")
val list: List<NiLocation>? = getTrackList(startTimeStr, endTimeStr, currentTimeStr)
Log.e(TAG, "getTraceData结束")
if (list != null && list.size > 0) {
var disTime: Long = 0
//只有一个点不进行判断直接返回结果
if (list.size == 1) {
resultNiLocation = list[0]
} else {
//遍历集合取最近时间的轨迹点
b@ for (nilocation in list) {
if (!TextUtils.isEmpty(nilocation.time)) {
//只获取到秒的常量
val time: Long =
nilocation.timeStamp.toLong()
val disTimeTemp = abs(time - currentTime)
//如果时间相同直接返回该点
if (disTimeTemp == 0L) {
resultNiLocation = nilocation
break@b
} else {
//第一次不对比,取当前值
if (disTime == 0L) {
disTime = disTimeTemp
resultNiLocation = nilocation
} else {
//前一个差值大于当前差值则取当前相对小的值
if (disTime - disTimeTemp > 0) {
disTime = disTimeTemp
resultNiLocation = nilocation
}
}
}
}
}
}
}
}
val msg1 = Message()
msg1.what = 0x11
msg1.obj = resultNiLocation
if (resultNiLocation != null) {
Log.e(TAG, "反向app"+resultNiLocation.time)
}
mHandler.sendMessage(msg1)
}
2 -> {
val msg4 = Message()
msg4.what = 0x55
mHandler.sendMessage(msg4)
}
3 -> {
val msg5 = Message()
msg5.what = 0x66
mHandler.sendMessage(msg5)
}
}
}
//解析时索引与集合索引对比,如果不相同代表有新命令,需要继续解析最后一条,否则清空集合不在解析
try {
if (timeIndex == mTaskList.size - 1) {
mTaskList.clear()
}
} catch (e: Exception) {
}
val msg2 = Message()
msg2.what = 0x99
mHandler.sendMessage(msg2)
}
}
Thread.sleep(10)
} catch (e: Exception) {
e.printStackTrace()
val msg = Message()
msg.what = 0x99
mHandler.sendMessage(msg)
}
}
}
/**
* 获取轨迹数据
*
* @param startTimeStr 起始时间
* @param endTimeStr 结束时间
* @param currentTimeStr 当前点时间,如果存在便直接获取一个点
* @return list 数据集合
*/
private fun getTrackList(
startTimeStr: String,
endTimeStr: String,
currentTimeStr: String
): List<NiLocation>? {
if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(endTimeStr)) {
var startTime: Long = 0
var endTime: Long = 0
try {
startTime = startTimeStr.toLong()
endTime = endTimeStr.toLong()
} catch (e: java.lang.Exception) {
}
if (startTime != 0L && endTime != 0L) {
val id = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1)
val list: MutableList<NiLocation> = traceDataBase.niLocationDao.findToTaskIdAll(id.toString())
if (list.size > 0) return list
}
}
return null
}
/**
* 接收管道数据
*/
private inner class RecvThread : Runnable {
private var runFlag = true
fun cancel() {
runFlag = false
}
override fun run() {
var rlRead: Int
try {
while (runFlag) {
var line: String = ""
if (!isServerClose) {
rlRead = inStr!!.read(sData) //对方断开返回-1
if (rlRead > 0) {
Log.e(TAG, sData.toString() + "")
line = String(sData, 0, rlRead)
mTaskList.add(line)
} else {
connectFaild("连接断开")
}
} else {
connectFaild("连接断开")
}
}
Thread.sleep(10)
} catch (e: IOException) {
connectFaild(e.toString())
e.printStackTrace()
}
}
}
/**
* 连接失败
* @param e 原因
*/
private fun connectFaild(e: String) {
val msg2 = Message()
msg2.what = 0x999
mHandler.sendMessage(msg2)
}
/**
* 判断是否断开连接断开返回true,没有返回false
* @return
*/
val isServerClose: Boolean
get() {
return try {
client!!.sendUrgentData(0) //发送1个字节的紧急数据默认情况下服务器端没有开启紧急数据处理不影响正常通信
false
} catch (se: Exception) {
true
}
}
/**
* 停止接收管道数据
*/
fun stop() {
Log.e(TAG, "stop!")
connectstatus = false
if (tRecv != null) {
tRecv!!.cancel()
}
if (tParse != null) {
tParse!!.cancel()
}
}
/**
* 开始接收管道数据
*/
fun start() {
Log.e(TAG, "start!")
if (tRecv != null) {
tRecv!!.cancel()
}
tRecv = RecvThread()
val thread = Thread(tRecv)
thread.start()
//解析线程
if (tParse != null) {
tParse!!.cancel()
}
tParse = ParseThread()
val parsethread = Thread(tParse)
parsethread.start()
}
fun setTraceMap() {
}
/**
* 轨迹反向控制回调接口
*/
interface OnConnectSinsListener {
/**
* 连接状态
*
* @param success true 连接成功 false 连接失败
*/
fun onConnect(success: Boolean)
/**
* 索引中
*/
fun onIndexing()
/**
* 暂停
*/
fun onStop()
/**
* 播放
*/
fun onPlay()
/**
* 结束完成
*/
fun onParseEnd()
/**
* 轨迹点
*
* @param mNiLocation
*/
fun onReceiveLocation(mNiLocation: NiLocation?)
}
/**
* 解析返回值
*
* @return 时间信息
*/
private fun parseResult(data: String): Result? {
var data = data
if (!TextUtils.isEmpty(data)) {
try {
data = data.replace("\n".toRegex(), "")
val json = JSONObject(data)
val type = json.optInt("type")
val mResult: Result = Result()
mResult.type = type
if (type == 1) {
mResult.data = json.optString("data", "")
}
return mResult
} catch (e: Exception) {
}
}
return null
}
//结果类对象
internal inner class Result : Serializable {
var type = 0
var data: String? = null
}
}

View File

@@ -0,0 +1,72 @@
package com.navinfo.omqs.ui.activity.map
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.databinding.AdapterTopSignBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class TopSignAdapter(private var itemListener: ((Int, SignBean) -> Unit?)? = null) :
BaseRecyclerViewAdapter<SignBean>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterTopSignBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as AdapterTopSignBinding
val item = data[position]
if (item.iconId != 0)
bd.topSignText.background = holder.viewBinding.root.context.getDrawable(item.iconId)
when (item.renderEntity.code) {
DataCodeEnum.OMDB_CON_ACCESS.code,
DataCodeEnum.OMDB_MULTI_DIGITIZED.code,
DataCodeEnum.OMDB_TUNNEL.code,
DataCodeEnum.OMDB_ROUNDABOUT.code,
DataCodeEnum.OMDB_VIADUCT.code,
-> bd.topSignName.text = "形态"
else -> bd.topSignName.text = item.name
}
bd.topSignText.text = item.iconText
if (data.size == 1) {
bd.topSignLeftLine.visibility = View.GONE
bd.topSignRightLine.visibility = View.GONE
bd.topSignName.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_top_bg)
bd.topSignText.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_bottom_bg)
} else if (position == 0) {
bd.topSignLeftLine.visibility = View.GONE
bd.topSignRightLine.visibility = View.VISIBLE
bd.topSignName.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_left_top_bg)
bd.topSignText.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_left_bottom_bg)
} else if (position == data.size - 1) {
bd.topSignLeftLine.visibility = View.VISIBLE
bd.topSignRightLine.visibility = View.GONE
bd.topSignName.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_right_top_bg)
bd.topSignText.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_right_bottom_bg)
} else {
bd.topSignLeftLine.visibility = View.VISIBLE
bd.topSignRightLine.visibility = View.VISIBLE
bd.topSignName.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_middle_top_bg)
bd.topSignText.background =
holder.viewBinding.root.context.getDrawable(R.drawable.shape_road_info_middle_bottom_bg)
}
bd.root.setOnClickListener {
itemListener?.invoke(position, item)
}
}
}

View File

@@ -0,0 +1,259 @@
package com.navinfo.omqs.ui.activity.scan
import android.content.Context
import android.text.TextUtils
import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import javax.inject.Inject
enum class QrCodeStatus {
/**
* 网络访问失败
*/
QR_CODE_STATUS_NET_FAILURE,
/**
* 成功
*/
QR_CODE_STATUS_SUCCESS,
/**
* 信息更新成功
*/
QR_CODE_STATUS_SERVER_INFO_SUCCESS,
}
@HiltViewModel
class QrCodeViewModel @Inject constructor(
private val networkService: NetworkService
) : ViewModel() {
//用户信息
val qrCodeBean: MutableLiveData<QRCodeBean> = MutableLiveData()
//是不是连接成功
val qrCodeStatus: MutableLiveData<QrCodeStatus> = MutableLiveData()
init {
qrCodeBean.value = QRCodeBean()
}
/**
* 扫一扫按钮
*/
fun connect(context: Context, ips: String) {
if (TextUtils.isEmpty(ips)) {
Toast.makeText(context, "获取ip失败", Toast.LENGTH_LONG).show()
return
}
val ipArray = ips.split(";".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
//测试代码
//final String[] ipArray = new String[]{"172.21.2.137"};
if (ipArray.isEmpty()) {
Toast.makeText(context, "获取ip失败", Toast.LENGTH_SHORT).show()
return
}
ipArray.forEach { ip ->
if (!TextUtils.isEmpty(ip)) {
viewModelScope.launch(Dispatchers.Default) {
val ipTemp: String = ip
val url = "http://$ipTemp:8080/sensor/service/keepalive"
when (val result = networkService.connectIndoorTools(url)) {
is NetResult.Success<*> -> {
if (result.data != null) {
try {
val defaultUserResponse = result.data as QRCodeBean
if (defaultUserResponse.errcode == 0) {
Constant.INDOOR_IP = ipTemp
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_SUCCESS)
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"连接室内整理工具成功。",
Toast.LENGTH_LONG
).show()
}
updateServerInfo(context)
} else {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${defaultUserResponse.errmsg}",
Toast.LENGTH_SHORT
)
.show()
}
}
} catch (e: IOException) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.exception.message}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.code}:${result.msg}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
else -> {}
}
}
}
}
}
/**
* 扫一扫按钮
*/
fun updateServerInfo(context: Context) {
if (TextUtils.isEmpty(Constant.INDOOR_IP)) {
Toast.makeText(context, "获取ip失败", Toast.LENGTH_LONG).show()
return
}
viewModelScope.launch(Dispatchers.Default) {
val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/connection"
val indoorConnectionInfoBean = IndoorConnectionInfoBean(
Constant.USER_ID,
Constant.USER_ID,
Constant.USER_ID,
"eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2ODk2MjI5MjQsInVzZXJJZCI6IjEwNCIsImlhdCI6MTY4OTU3MjUyNCwidXNlcm5hbWUiOiJ3ZWl3ZWlsaW4wMDEwNCJ9.9WUqOhme8Yi_2xRBKMMe0ihb_yR1uwTqWTdZfZ7dMtE",
"http://fastmap.navinfo.com/onemap",
Constant.USER_ID,
"Android"
)
when (val result = networkService.updateServerInfo(
url = url,
indoorConnectionInfoBean = indoorConnectionInfoBean
)) {
is NetResult.Success<*> -> {
if (result.data != null) {
try {
val defaultUserResponse = result.data as QRCodeBean
if (defaultUserResponse.errcode == 0) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"信息更新成功。",
Toast.LENGTH_LONG
).show()
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_SERVER_INFO_SUCCESS)
}
} else {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${defaultUserResponse.errmsg}",
Toast.LENGTH_SHORT
)
.show()
}
}
} catch (e: IOException) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.exception.message}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.code}:${result.msg}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
else -> {}
}
}
}
override fun onCleared() {
super.onCleared()
}
}

View File

@@ -0,0 +1,147 @@
package com.navinfo.omqs.ui.activity.scan
import android.annotation.SuppressLint
import android.graphics.Rect
import android.graphics.RectF
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.camera.core.ImageCapture
import androidx.camera.view.LifecycleCameraController
import androidx.databinding.DataBindingUtil
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityQrCodeBinding
import com.navinfo.omqs.ui.activity.BaseActivity
import com.navinfo.omqs.ui.listener.QRCodeAnalyser
import dagger.hilt.android.AndroidEntryPoint
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import androidx.lifecycle.Observer
import com.navinfo.omqs.ui.activity.login.LoginStatus
/**
* date:2023/6/18
* author:qj
* description:二维码扫描
*/
@AndroidEntryPoint
class QrCodeActivity : BaseActivity() {
private lateinit var binding: ActivityQrCodeBinding
private lateinit var lifecycleCameraController: LifecycleCameraController
private lateinit var cameraExecutor: ExecutorService
private val viewModel by viewModels<QrCodeViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_qr_code)
binding.qrCodeModel = viewModel
binding.lifecycleOwner = this
binding.activity = this
initView()
initController()
}
private fun initView() {
//登录校验,初始化成功
viewModel.qrCodeStatus.observe(this, qrCodeObserve)
}
/*
* 监听扫描结果
* */
private val qrCodeObserve = Observer<QrCodeStatus> {
when (it) {
QrCodeStatus.QR_CODE_STATUS_SUCCESS -> {
finish()
}
QrCodeStatus.QR_CODE_STATUS_NET_FAILURE -> {
}
QrCodeStatus.QR_CODE_STATUS_SERVER_INFO_SUCCESS -> {
}
}
}
@SuppressLint("ClickableViewAccessibility", "UnsafeOptInUsageError")
private fun initController() {
cameraExecutor = Executors.newSingleThreadExecutor()
lifecycleCameraController = LifecycleCameraController(this)
lifecycleCameraController.bindToLifecycle(this)
lifecycleCameraController.imageCaptureFlashMode = ImageCapture.FLASH_MODE_AUTO
lifecycleCameraController.setImageAnalysisAnalyzer(
cameraExecutor,
QRCodeAnalyser { barcodes, imageWidth, imageHeight ->
if (barcodes.isEmpty()) {
return@QRCodeAnalyser
}
initScale(imageWidth, imageHeight)
val list = ArrayList<RectF>()
val strList = ArrayList<String>()
barcodes.forEach { barcode ->
barcode.boundingBox?.let { rect ->
val translateRect = translateRect(rect)
list.add(translateRect)
Log.e(
"ztzt", "left${translateRect.left} +" +
" top${translateRect.top} + right${translateRect.right}" +
" + bottom${translateRect.bottom}"
)
Log.e("ztzt", "barcode.rawValue${barcode.rawValue}")
strList.add(barcode.rawValue ?: "No Value")
}
}
judgeIntent(strList)
binding.scanView.setRectList(list)
})
binding.previewView.controller = lifecycleCameraController
}
fun judgeIntent(list: ArrayList<String>) {
val sb = StringBuilder()
list.forEach {
sb.append(it)
sb.append("\n")
}
intentToResult(sb.toString())
}
private fun intentToResult(result: String) {
Log.e("qj", "QRCodeActivity === $result")
viewModel.connect(this, result)
/* val intent = Intent(this, QRCodeResultActivity::class.java)
intent.putExtra(QRCodeResultActivity.RESULT_KEY, result)
startActivity(intent)
finish()*/
}
private var scaleX = 0f
private var scaleY = 0f
private fun translateX(x: Float): Float = x * scaleX
private fun translateY(y: Float): Float = y * scaleY
//将扫描的矩形换算为当前屏幕大小
private fun translateRect(rect: Rect) = RectF(
translateX(rect.left.toFloat()),
translateY(rect.top.toFloat()),
translateX(rect.right.toFloat()),
translateY(rect.bottom.toFloat())
)
//初始化缩放比例
private fun initScale(imageWidth: Int, imageHeight: Int) {
Log.e("ztzt", "imageWidth${imageWidth} + imageHeight${imageHeight}")
scaleY = binding.scanView.height.toFloat() / imageWidth.toFloat()
scaleX = binding.scanView.width.toFloat() / imageHeight.toFloat()
Log.e("ztzt", "scaleX${scaleX} + scaleY${scaleY}")
}
}

View File

@@ -0,0 +1,30 @@
package com.navinfo.omqs.ui.activity.scan
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.navinfo.omqs.databinding.ActivityResultBinding
/**
* date:2021/6/18
* author:zhangteng
* description:
*/
class QRCodeResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityResultBinding
companion object {
const val RESULT_KEY = "result_key";
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityResultBinding.inflate(layoutInflater)
setContentView(binding.root)
val intent = intent
binding.text.text = intent.getStringExtra(RESULT_KEY)
binding.button.setOnClickListener {
finish()
}
}
}

View File

@@ -676,6 +676,7 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
//当前为连接时启动已有的状态
if (connectstate) {
mOneBtConnect.setPressed(true);
mOneBtConnect.setBackgroundResource(R.drawable.shape_btn_red_disconnect_bg);
@@ -709,10 +710,10 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
* 更新相机状态资源
*/
public void updateCameraResources(int statusType, int indexClentCamera) {
int resId = R.id.main_activity_camera;
int resId = R.id.main_activity_status_camera;
if (indexClentCamera == 2)
resId = R.id.main_activity_camera2;
resId = R.id.main_activity_status_camera;
Drawable drawable = context.getResources().getDrawable(R.drawable.icon_page_video_a0);
@@ -769,10 +770,10 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
}
public void updateCameraBackgroundResources(int drawable, int indexClentCamera) {
int resId = R.id.main_activity_camera;
int resId = R.id.main_activity_status_camera;
if (indexClentCamera == 2)
resId = R.id.main_activity_camera2;
resId = R.id.main_activity_status_camera;
ImageView ivStatus = (ImageView) findViewById(resId);
@@ -1525,7 +1526,7 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
}
//连接
private void connection(HostBean hostBean) {
public void connection(HostBean hostBean) {
if (hostBean != null) {
SensorParams params = new SensorParams();
@@ -1546,9 +1547,9 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
private int getResId() {
if (getmDeviceNum() == 2)
return R.id.main_activity_camera2;
return R.id.main_activity_status_camera;
return R.id.main_activity_camera;
return R.id.main_activity_status_camera;
}
public ShareUtil getmShareUtil() {

View File

@@ -0,0 +1,70 @@
package com.navinfo.omqs.ui.dialog
import android.app.Dialog
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.DatePicker
import android.widget.TextView
import android.widget.TimePicker
import androidx.annotation.RequiresApi
import com.navinfo.omqs.R
import java.text.SimpleDateFormat
interface OnTimeDialogListener {
fun selectTime(milliseconds: Long)
}
class TimeDialog(context: Context, val listener: OnTimeDialogListener) : Dialog(context),
View.OnClickListener {
private lateinit var dataPicker: DatePicker
private lateinit var timePicker: TimePicker
private var timeText = ""
override fun onCreate(savedInstanceState: Bundle?) {
val customFrame = View.inflate(context, R.layout.dialog_time_layout, null)
dataPicker = customFrame.findViewById(R.id.time_dialog_data_picker)
timePicker = customFrame.findViewById(R.id.time_dialog_time_picker)
customFrame.findViewById<TextView>(R.id.time_dialog_ok).setOnClickListener(this)
customFrame.findViewById<TextView>(R.id.time_dialog_cancel).setOnClickListener(this)
setContentView(customFrame)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onClick(v: View) {
when (v.id) {
R.id.time_dialog_ok -> {
val month = if (dataPicker.month > 8) {
"${dataPicker.month + 1}"
} else {
"0${dataPicker.month + 1}"
}
val hour = if(timePicker.hour < 10){
"0${timePicker.hour}"
}else{
"${timePicker.hour}"
}
val minute = if(timePicker.minute<10){
"0${timePicker.minute}"
}else{
"${timePicker.minute}"
}
val time =
"${dataPicker.year}${month}${dataPicker.dayOfMonth}${hour}${minute}00"
Log.e("jingo", "选择的时间 $time")
val sdf = SimpleDateFormat("yyyyMMddHHmmss")
listener.selectTime(sdf.parse(time).time)
dismiss()
}
R.id.time_dialog_cancel -> {
dismiss()
}
}
}
}

View File

@@ -1,15 +1,14 @@
package com.navinfo.omqs.ui.fragment
import android.os.Bundle
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
abstract class BaseFragment : Fragment() {
private var loadingDialog: AlertDialog? = null
// override fun onCreateView(
// inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
// ): View {
@@ -49,9 +48,26 @@ abstract class BaseFragment : Fragment() {
// savedInstanceState: Bundle?
// ): View
fun onBackPressed(): Boolean{
findNavController().navigateUp()
open fun onBackPressed(): Boolean{
// findNavController().navigateUp()
return true
}
/**
* 显示loading dialog
*/
fun showLoadingDialog(message: String) {
loadingDialog?.dismiss()
loadingDialog = MaterialAlertDialogBuilder(
this.requireContext(), R.style.MaterialAlertDialog_Material3_Animation).setMessage(message).setCancelable(false).show()
}
/**
* 隐藏loading dialog
* */
fun hideLoadingDialog() {
loadingDialog?.dismiss()
loadingDialog = null
}
}

View File

@@ -0,0 +1,318 @@
package com.navinfo.omqs.ui.fragment.console
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.transition.AutoTransition
import androidx.transition.Scene
import androidx.transition.TransitionManager
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentConsoleBinding
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.fragment.layermanager.LayerManagerFragment
import com.navinfo.omqs.ui.fragment.navi.NaviSettingFragment
import com.navinfo.omqs.ui.fragment.personalcenter.PersonalCenterFragment
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ConsoleFragment : BaseFragment(), OnClickListener {
private var _binding: FragmentConsoleBinding? = null
private val binding get() = _binding!!
private var sceneFlag = true
private val aTransition = AutoTransition()
private val bTransition = AutoTransition()
private var mFragment: Fragment? = null
private val fragmentId = R.id.console_fragment
private val viewModel by viewModels<ConsoleViewModel>()
// 创建a场景
private val aScene by lazy {
Scene.getSceneForLayout(
binding.consoleRoot, R.layout.console_on, requireContext()
)
}
// 创建b场景
private val bScene by lazy {
Scene.getSceneForLayout(
binding.consoleRoot, R.layout.console_off, requireContext()
)
}
// private val mTransitionAManager: TransitionManager by lazy {
// TransitionInflater.from(this)
// .inflateTransitionManager(R.transition.transitionmanager_console, binding.consoleRoot)
// }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentConsoleBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
aTransition.addListener(object : androidx.transition.Transition.TransitionListener {
override fun onTransitionStart(transition: androidx.transition.Transition) {
sceneFlag = true
if (mFragment != null) {
childFragmentManager.beginTransaction().remove(mFragment!!).commit()
mFragment = null
}
}
override fun onTransitionEnd(transition: androidx.transition.Transition) {
initOnClickListener()
initLiveData()
}
override fun onTransitionCancel(transition: androidx.transition.Transition) {
}
override fun onTransitionPause(transition: androidx.transition.Transition) {
}
override fun onTransitionResume(transition: androidx.transition.Transition) {
}
})
bTransition.addListener(object : androidx.transition.Transition.TransitionListener {
override fun onTransitionStart(transition: androidx.transition.Transition) {
sceneFlag = false
if (mFragment != null) {
childFragmentManager.beginTransaction().replace(fragmentId, mFragment!!)
.commit()
}
}
override fun onTransitionEnd(transition: androidx.transition.Transition) {
initOnClickListener()
initLiveData()
}
override fun onTransitionCancel(transition: androidx.transition.Transition) {
}
override fun onTransitionPause(transition: androidx.transition.Transition) {
}
override fun onTransitionResume(transition: androidx.transition.Transition) {
}
})
initOnClickListener()
initLiveData()
}
private fun initLiveData(){
/**
* 任务数量统计
*/
viewModel.liveDataTaskCount.observe(viewLifecycleOwner) {
binding.consoleRoot.findViewById<TextView>(R.id.console_task_count_text).text =
"${it}"
}
/**
* 评测数据数量统计
*/
viewModel.liveDataEvaluationResultCount.observe(viewLifecycleOwner) {
binding.consoleRoot.findViewById<TextView>(R.id.console_evaluation_count_text).text =
"${it}"
}
}
/**
* 设置点击事件
*/
private fun initOnClickListener() {
/**
* 地图按钮
*/
binding.consoleRoot.findViewById<View>(R.id.console_map_icon_bg)?.setOnClickListener(
this
)
binding.consoleRoot.findViewById<View>(R.id.console_map_bg)?.setOnClickListener(this)
/**
* 离线地图按钮
*/
binding.consoleRoot.findViewById<View>(R.id.console_offline_map_icon_bg)
?.setOnClickListener(this)
binding.consoleRoot.findViewById<View>(R.id.console_offline_map_bg)
?.setOnClickListener(this)
/**
* 图层设置按钮
*/
binding.consoleRoot.findViewById<View>(R.id.console_layer_setting_icon_bg)
?.setOnClickListener(this)
binding.consoleRoot.findViewById<View>(R.id.console_layer_setting_bg)
?.setOnClickListener(this)
/**
* 个人中心
*/
binding.consoleRoot.findViewById<View>(R.id.console_personal_center_icon_bg)
?.setOnClickListener(this)
binding.consoleRoot.findViewById<View>(R.id.console_personal_center_bg)
?.setOnClickListener(this)
/**
* 测评结果列表
*/
binding.consoleRoot.findViewById<View>(R.id.console_evaluation_icon_bg)
?.setOnClickListener(this)
binding.consoleRoot.findViewById<View>(R.id.console_evaluation_bg)?.setOnClickListener(this)
/**
* 评测任务
*/
binding.consoleRoot.findViewById<View>(R.id.console_task_bg)?.setOnClickListener(this)
binding.consoleRoot.findViewById<View>(R.id.console_task_icon_bg)?.setOnClickListener(this)
/**
* 路径规划
*/
binding.consoleRoot.findViewById<View>(R.id.console_route_bg)?.setOnClickListener(this)
binding.consoleRoot.findViewById<View>(R.id.console_route_icon_bg)?.setOnClickListener(this)
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
override fun onClick(v: View?) {
v?.let {
when (it.id) {
/**
* 地图点击事件
*/
R.id.console_map_bg, R.id.console_map_icon_bg -> {
activity?.let { a ->
a.supportFragmentManager.beginTransaction().remove(this).commit()
}
}
/**
* 离线地图点击
*/
R.id.console_offline_map_icon_bg, R.id.console_offline_map_bg -> {
activity?.let { a ->
a.supportFragmentManager.beginTransaction().remove(this).commit()
(a as MainActivity).onClickOfflineMapFragment()
}
}
/**
* 个人中心点击
*/
R.id.console_personal_center_bg, R.id.console_personal_center_icon_bg -> {
if (sceneFlag) {
mFragment = PersonalCenterFragment {
if (it) {
activity?.let { a ->
a.supportFragmentManager.beginTransaction().remove(this)
.commit()
(a as MainActivity).showIndoorDataLayout()
}
} else {
TransitionManager.go(aScene, aTransition)
}
}
sceneFlag = false
TransitionManager.go(bScene, bTransition)
} else {
if (mFragment !is PersonalCenterFragment) {
mFragment = PersonalCenterFragment {
if (it) {
activity?.let { a ->
a.supportFragmentManager.beginTransaction().remove(this)
.commit()
(a as MainActivity).showIndoorDataLayout()
}
} else {
TransitionManager.go(aScene, aTransition)
}
}
childFragmentManager.beginTransaction().replace(fragmentId, mFragment!!)
.commit()
}
return
}
}
/**
* 图层设置
*/
R.id.console_layer_setting_bg, R.id.console_layer_setting_icon_bg -> {
if (sceneFlag) {
mFragment = LayerManagerFragment {
TransitionManager.go(aScene, aTransition)
}
sceneFlag = false
TransitionManager.go(bScene, bTransition)
} else {
if (mFragment !is LayerManagerFragment) {
mFragment = LayerManagerFragment {
TransitionManager.go(aScene, aTransition)
}
childFragmentManager.beginTransaction().replace(fragmentId, mFragment!!)
.commit()
}
return
}
}
/**
* 测评结果列表
*/
R.id.console_evaluation_icon_bg, R.id.console_evaluation_bg -> {
activity?.let { a ->
a.supportFragmentManager.beginTransaction().remove(this).commit()
(a as MainActivity).onClickResFragment()
}
}
/**
* 任务列表
*/
R.id.console_task_icon_bg, R.id.console_task_bg -> {
activity?.let { a ->
a.supportFragmentManager.beginTransaction().remove(this).commit()
(a as MainActivity).onClickTaskFragment()
}
}
/**
* 路径规划
*/
R.id.console_route_bg, R.id.console_route_icon_bg -> {
// Toast.makeText(requireContext(), "功能开发中", Toast.LENGTH_SHORT).show()
if (sceneFlag) {
mFragment = NaviSettingFragment {
TransitionManager.go(aScene, aTransition)
}
sceneFlag = false
TransitionManager.go(bScene, bTransition)
} else {
if (mFragment !is NaviSettingFragment) {
mFragment = NaviSettingFragment {
TransitionManager.go(aScene, aTransition)
}
childFragmentManager.beginTransaction().replace(fragmentId, mFragment!!)
.commit()
}
return
}
}
else -> {}
}
}
}
}

View File

@@ -0,0 +1,46 @@
package com.navinfo.omqs.ui.fragment.console
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.util.DateTimeUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class ConsoleViewModel @Inject constructor(
private val realmOperateHelper: RealmOperateHelper
) : ViewModel() {
/**
* 当前任务量统计
*/
val liveDataTaskCount = MutableLiveData(0)
/**
* 作业数据统计
*/
val liveDataEvaluationResultCount = MutableLiveData(0)
init {
viewModelScope.launch {
val realm = realmOperateHelper.getRealmDefaultInstance()
val nowTime: Long = DateTimeUtil.getNowDate().time
val beginNowTime: Long = nowTime - 90 * 3600 * 24 * 1000L
val syncUpload: Int = FileManager.Companion.FileUploadStatus.DONE
val count =
realm.where(TaskBean::class.java).notEqualTo("syncStatus", syncUpload).or()
.between("operationTime", beginNowTime, nowTime)
.equalTo("syncStatus", syncUpload).count()
liveDataTaskCount.postValue(count.toInt())
val count2 = realm.where(QsRecordBean::class.java).count()
liveDataEvaluationResultCount.postValue(count2.toInt())
realm.close()
}
}
}

View File

@@ -5,13 +5,17 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentEmptyBinding
import com.navinfo.omqs.ui.activity.map.MainActivity
class EmptyFragment :Fragment(){
class EmptyFragment : Fragment() {
private var _binding: FragmentEmptyBinding? = null
private var currentDestinationLabel = ""
private val binding get() = _binding!!
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
@@ -25,6 +29,33 @@ class EmptyFragment :Fragment(){
super.onViewCreated(view, savedInstanceState)
}
override fun onStart() {
super.onStart()
val currentDestination = findNavController().currentDestination
currentDestination?.let {
//有右侧面板的时候
currentDestinationLabel = it.label.toString()
if (it.label == "右侧空页面") {
(activity as MainActivity).setRightSwitchButtonVisibility(View.GONE)
(activity as MainActivity).setTopMenuButtonVisibility(View.VISIBLE)
} else if (it.label == "中间空页面") {
(activity as MainActivity).setRightButtonsVisible(View.VISIBLE)
}
}
}
override fun onStop() {
super.onStop()
//没有有右侧面板的时候
if (currentDestinationLabel == "右侧空页面") {
(activity as MainActivity).setRightSwitchButtonVisibility(View.VISIBLE)
(activity as MainActivity).setTopMenuButtonVisibility(View.GONE)
} else if (currentDestinationLabel == "中间空页面") {
(activity as MainActivity).setRightButtonsVisible(View.GONE)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null

View File

@@ -1,34 +1,71 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.*
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.databinding.DataBindingUtil
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.databinding.FragmentEvaluationResultBinding
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.other.shareViewModels
import dagger.hilt.android.AndroidEntryPoint
import androidx.navigation.findNavController
/**
* 评测结果页面
*/
@AndroidEntryPoint
class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
private lateinit var binding: FragmentEvaluationResultBinding
private var mCameraLauncher: ActivityResultLauncher<Intent>? = null
/**
* 和[PhenomenonFragment],[ProblemLinkFragment],[EvaluationResultFragment]共用同一个viewModel
*/
private val viewModel by shareViewModels<EvaluationResultViewModel>("QsRecode")
private val pictureAdapter by lazy {
PictureAdapter()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mCameraLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// 处理相机返回的结果
val extras = result.data!!.extras
val imageBitmap: Bitmap? = extras!!["data"] as Bitmap?
// 在这里处理图片数据
if (imageBitmap != null)
viewModel.savePhoto(imageBitmap)
}
}
}
// private val args:EmptyFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@@ -36,189 +73,190 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
binding =
DataBindingUtil.inflate(inflater, R.layout.fragment_evaluation_result, container, false)
binding.fragment = this
val layoutManager = LinearLayoutManager(context)
binding.viewModel = viewModel
binding.lifecycleOwner = this
return binding.root
}
@RequiresApi(Build.VERSION_CODES.N)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能
binding.evaluationVoiceRecyclerview.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(context)
binding.evaluationVoiceRecyclerview.layoutManager = layoutManager
/**
* 监听左侧栏的点击事件
*/
val adapter = SoundtListAdapter { _, view ->
val adapter = SoundtListAdapter { _, _ ->
}
binding.evaluationDescription.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
viewModel.description = s.toString()
}
})
binding.evaluationVoiceRecyclerview.adapter = adapter
viewModel.listDataChatMsgEntityList.observe(viewLifecycleOwner) {
adapter.refreshData(it)
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//监听是否退出当前页面
viewModel.liveDataFinish.observe(viewLifecycleOwner) {
onBackPressed()
}
//返回按钮点击
binding.evaluationBar.setOnClickListener() {
onBackPressed()
binding.evaluationBar.setOnClickListener {
it.isEnabled = false
val mDialog = FirstDialog(context)
mDialog.setTitle("提示?")
mDialog.setMessage("是否退出,请确认!")
mDialog.setPositiveButton(
"确定"
) { _, _ ->
mDialog.dismiss()
onBackPressed()
}
mDialog.setNegativeButton("取消") { _, _ ->
mDialog.dismiss()
it.isEnabled = true
}
mDialog.show()
}
//测距按钮
binding.evaluationBarMeasuring.setOnClickListener {
(activity as MainActivity).measuringToolOn()
}
//保存事件
binding.evaluationBarSave.setOnClickListener() {
binding.evaluationBarSave.setOnClickListener {
viewModel.saveData()
}
//删除事件
binding.evaluationBarDelete.setOnClickListener() {
viewModel.deleteData()
binding.evaluationBarDelete.setOnClickListener {
viewModel.deleteData(requireContext())
}
/**
* 照片view
*/
binding.evaluationPictureViewpager.adapter = pictureAdapter
//照片左右选择键点击监听
binding.evaluationPictureLeft.setOnClickListener(this)
binding.evaluationPictureRight.setOnClickListener(this)
binding.evaluationCamera.setOnClickListener(this)
//设置照片偏移量
val viewPager = binding.evaluationPictureViewpager
val vto = viewPager.viewTreeObserver
vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
val width = viewPager.width
// 处理View宽度
// 在回调完成后需要将监听器从View树中移除以避免重复调用
viewPager.viewTreeObserver.removeOnGlobalLayoutListener(this)
binding.evaluationVoice.setOnTouchListener(object : View.OnTouchListener {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
Log.e("qj", event?.action.toString())
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
voiceOnTouchStart()//Do Something
Log.e("qj", "voiceOnTouchStart")
}
MotionEvent.ACTION_UP -> {
voiceOnTouchStop()//Do Something
Log.e("qj", "voiceOnTouchStop")
}
}
return v?.onTouchEvent(event) ?: true
val recyclerView = viewPager.getChildAt(0) as RecyclerView
recyclerView.setPadding(0, 0, width / 2 - 30, 0)
recyclerView.clipToPadding = false
}
})
binding.evaluationVoice.setOnTouchListener { _, event ->
Log.e("qj", event?.action.toString())
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
voiceOnTouchStart()//Do Something
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE -> {
voiceOnTouchStop()//Do Something
}
}
true
}
/**
* 读取元数据
*/
// val id = args.qsId
var id: String = ""
var id = ""
var signBean: SignBean? = null
var filePath: String = ""
var autoSave = false
var filePath = ""
arguments?.let {
id = it.getString("QsId", "")
filePath = it.getString("filePath", "")
try {
signBean = it.getParcelable("SignBean")
} catch (e: java.lang.Exception) {
autoSave = it.getBoolean("AutoSave")
//高亮数据几何
signBean?.let { it1 -> viewModel.show(it1.renderEntity) }
} catch (_: java.lang.Exception) {
}
}
if (id == null || id.isEmpty()) {
if (id.isEmpty()) {
viewModel.initNewData(signBean, filePath)
//增加监听,联动列表自动保存
viewModel.liveDataRightTypeList.observe(viewLifecycleOwner) {
if (autoSave) {
viewModel.saveData()
}
}
} else {
viewModel.initData(id)
}
// //监听大分类数据变化
// viewModel.liveDataClassTypeList.observe(viewLifecycleOwner) {
// if (it == null || it.isEmpty()) {
// Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
// } else {
// binding.evaluationClassType.adapter =
// ArrayAdapter(requireContext(), R.layout.text_item_select, it)
// }
// }
//
// viewModel.liveDataProblemTypeList.observe(viewLifecycleOwner){
// if (it == null || it.isEmpty()) {
// Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
// }else{
// binding.evaluationProblemType.adapter =
// ArrayAdapter(requireContext(), R.layout.text_item_select, it)
// }
// }
// //选择问题分类的回调
// binding.evaluationClassType.onItemSelectedListener =
// object : AdapterView.OnItemSelectedListener {
// override fun onItemSelected(
// parent: AdapterView<*>?, view: View?, position: Int, id: Long
// ) {
// viewModel.getProblemTypeList(position)
// }
//
// override fun onNothingSelected(parent: AdapterView<*>?) {}
// }
// /**
// * 监听联动选择的内容
// */
// viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) {
// binding.evaluationClassTabLayout.let { tabLayout ->
// tabLayout.removeAllTabs()
// val fragmentList = mutableListOf<Fragment>()
// for (item in it) {
// val tab = tabLayout.newTab()
// tab.text = item
// tabLayout.addTab(tab)
// fragmentList.add(PhenomenonFragment(viewModel.currentClassType, item))
// }
// phenomenonFragmentAdapter =
// activity?.let { a -> EvaluationResultAdapter(a, fragmentList) }
// binding.evaluationViewpager.adapter = phenomenonFragmentAdapter
//
// TabLayoutMediator(
// binding.evaluationClassTabLayout,
// binding.evaluationViewpager
// ) { tab, position ->
// tab.text = it[position]
// }.attach()
// updateHeight(0)
// }
//
// }
/**
* 车信编辑备注
*/
viewModel.liveDataLanInfoChange.observe(viewLifecycleOwner) {
binding.evaluationDescription.setText(it)
}
/**
* 照片view
*/
viewModel.liveDataPictureList.observe(viewLifecycleOwner){
pictureAdapter.refreshData(it)
}
viewModel.listDataChatMsgEntityList.observe(viewLifecycleOwner) {
adapter.refreshData(it)
}
//监听是否退出当前页面
viewModel.liveDataFinish.observe(viewLifecycleOwner) {
onBackPressed()
}
//监听要提示的信息
viewModel.liveDataToastMessage.observe(viewLifecycleOwner) {
Toast.makeText(requireContext(), it, Toast.LENGTH_SHORT).show()
}
viewModel.liveDataQsRecordBean.observe(viewLifecycleOwner) {
binding.evaluationId.text = it.id
binding.evaluationProblemType.text = it.problemType
if(it.classCode == DataCodeEnum.OMDB_LANEINFO.code) {
when (it.problemType) {
"遗漏", "错误" -> {
activity?.run {
findNavController(R.id.main_activity_middle_fragment).navigate(R.id.LineInfoEditFragment)
}
}
}
}
}
// binding.evaluationViewpager.registerOnPageChangeCallback(object :
// ViewPager2.OnPageChangeCallback() {
// override fun onPageSelected(position: Int) {
// super.onPageSelected(position)
// updateHeight(position)
// }
// })
}
// private fun updateHeight(position: Int) {
// phenomenonFragmentAdapter?.let {
// if (it.fragmentList.size > position) {
// val fragment: Fragment = it.fragmentList[position]
// if (fragment.view != null) {
// val viewWidth = View.MeasureSpec.makeMeasureSpec(
// fragment.requireView().width, View.MeasureSpec.EXACTLY
// )
// val viewHeight =
// View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
// fragment.requireView().measure(viewWidth, viewHeight)
// binding.evaluationViewpager.let { viewpager ->
// if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) {
// //必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效...
// val layoutParams: ViewGroup.LayoutParams =
// viewpager.layoutParams
// layoutParams.height = fragment.requireView().measuredHeight
// viewpager.layoutParams = layoutParams
// }
// }
//
// }
// }
// }
//
// }
override fun onDestroyView() {
activity?.run {
findNavController(R.id.main_activity_middle_fragment).navigateUp()
(this as MainActivity).measuringToolOff()
}
super.onDestroyView()
}
@@ -229,13 +267,32 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
override fun onClick(v: View?) {
v?.let {
when (v.id) {
//照片左侧按钮
R.id.evaluation_picture_left -> {
val currentItem = binding.evaluationPictureViewpager.currentItem
if (currentItem > 0) {
binding.evaluationPictureViewpager.currentItem = currentItem - 1
} else {
return
}
}
//照片右侧按钮
R.id.evaluation_picture_right -> {
val currentItem = binding.evaluationPictureViewpager.currentItem
if (currentItem < pictureAdapter.data.size - 1) {
binding.evaluationPictureViewpager.currentItem = currentItem + 1
} else {
return
}
}
//上三项,打开面板
R.id.evaluation_class_type, R.id.evaluation_problem_type, R.id.evaluation_phenomenon -> {
activity?.run {
val controller = findNavController(R.id.main_activity_middle_fragment)
controller.currentDestination?.let {
//如果之前页面是空fragment直接打开面板
if (it.id == R.id.EmptyFragment) {
if (it.id == R.id.MiddleEmptyFragment) {
findNavController(
R.id.main_activity_middle_fragment
).navigate(R.id.PhenomenonFragment)
@@ -258,7 +315,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
val controller = findNavController(R.id.main_activity_middle_fragment)
controller.currentDestination?.let {
//如果之前页面是空fragment直接打开面板
if (it.id == R.id.EmptyFragment) {
if (it.id == R.id.MiddleEmptyFragment) {
findNavController(
R.id.main_activity_middle_fragment
).navigate(R.id.ProblemLinkFragment)
@@ -276,20 +333,43 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
}
}
else -> {}
R.id.evaluation_camera -> {
takePhoto()
}
else -> {
return
}
}
}
}
fun voiceOnTouchStart() {
viewModel!!.startSoundMetter(requireActivity(), binding.evaluationVoice)
private fun voiceOnTouchStart() {
viewModel.startSoundMetter(requireActivity(), binding.evaluationVoice)
}
@RequiresApi(Build.VERSION_CODES.Q)
fun voiceOnTouchStop() {
private fun voiceOnTouchStop() {
Log.e("qj", "voiceOnTouchStop====${Constant.IS_VIDEO_SPEED}")
if (Constant.IS_VIDEO_SPEED) {
viewModel!!.stopSoundMeter()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
viewModel.stopSoundMeter()
}
}
}
override fun onBackPressed(): Boolean {
findNavController().navigateUp()
return true
}
private fun takePhoto() {
try {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(requireActivity().packageManager) != null) {
mCameraLauncher!!.launch(takePictureIntent)
}
} catch (e: Exception) {
Log.d("TTTT", e.toString())
}
}
}

View File

@@ -0,0 +1,333 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ImageView
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentLineInfoEditBinding
import com.navinfo.omqs.ui.activity.map.LaneInfoItem
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.other.shareViewModels
class LaneInfoEditFragment : BaseFragment() {
private var _binding: FragmentLineInfoEditBinding? = null
private val binding get() = _binding!!
private val viewModel by shareViewModels<EvaluationResultViewModel>("QsRecode")
/**
* 车道类型
*/
private var laneType = 0
private var selectView: ImageView? = null
private lateinit var laneInfoItemsAdapter: LaneInfoItemsAdapter
private lateinit var laneInfoItemsAdapter2: LaneInfoItems2Adapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentLineInfoEditBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.laneInfoList.observe(viewLifecycleOwner){
initLaneInfo(it)
viewModel.laneInfoList.removeObservers(viewLifecycleOwner)
}
initFLowLayout()
binding.laneInfoBackspace.setOnClickListener {
if (binding.laneInfoTopContainer.childCount < 4) {
binding.laneInfoTopContainer.removeAllViews()
} else {
binding.laneInfoTopContainer.removeViewAt(binding.laneInfoTopContainer.childCount - 1)
val view =
binding.laneInfoTopContainer.getChildAt(binding.laneInfoTopContainer.childCount - 1)
binding.laneInfoTopContainer.removeView(view)
if (view == selectView) {
selectView = null
}
}
viewModel.backspaceLaneInfo()
}
binding.laneInfoRadio1.setOnClickListener {
laneType = 0
laneInfoItemsAdapter.setType(laneType)
}
binding.laneInfoRadio2.setOnClickListener {
laneType = 1
laneInfoItemsAdapter.setType(laneType)
}
binding.laneInfoRadio3.setOnClickListener {
laneType = 2
laneInfoItemsAdapter.setType(laneType)
}
}
private fun initFLowLayout() {
val itemList: MutableList<Int> = mutableListOf()
itemList.add(R.drawable.laneinfo_1)
itemList.add(R.drawable.laneinfo_2)
itemList.add(R.drawable.laneinfo_3)
itemList.add(R.drawable.laneinfo_5)
itemList.add(R.drawable.laneinfo_6)
itemList.add(R.drawable.laneinfo_4)
itemList.add(R.drawable.laneinfo_7)
itemList.add(R.drawable.laneinfo_1_2)
itemList.add(R.drawable.laneinfo_1_5)
itemList.add(R.drawable.laneinfo_2_5)
itemList.add(R.drawable.laneinfo_2_6)
itemList.add(R.drawable.laneinfo_1_3)
itemList.add(R.drawable.laneinfo_1_6)
itemList.add(R.drawable.laneinfo_3_5)
itemList.add(R.drawable.laneinfo_3_6)
itemList.add(R.drawable.laneinfo_2_3)
itemList.add(R.drawable.laneinfo_5_6)
itemList.add(R.drawable.laneinfo_1_4)
itemList.add(R.drawable.laneinfo_4_5)
itemList.add(R.drawable.laneinfo_2_4)
itemList.add(R.drawable.laneinfo_3_4)
itemList.add(R.drawable.laneinfo_4_6)
itemList.add(R.drawable.laneinfo_1_7)
itemList.add(R.drawable.laneinfo_1_2_3)
itemList.add(R.drawable.laneinfo_1_2_4)
itemList.add(R.drawable.laneinfo_1_2_5)
itemList.add(R.drawable.laneinfo_1_2_6)
itemList.add(R.drawable.laneinfo_1_3_4)
itemList.add(R.drawable.laneinfo_1_3_5)
itemList.add(R.drawable.laneinfo_1_3_6)
itemList.add(R.drawable.laneinfo_2_3_4)
itemList.add(R.drawable.laneinfo_0)
laneInfoItemsAdapter = LaneInfoItemsAdapter(itemList)
binding.laneInfoGridview.adapter = laneInfoItemsAdapter
binding.laneInfoGridview.onItemClickListener =
AdapterView.OnItemClickListener { parent, view, position, id ->
val resId = laneInfoItemsAdapter.getItem(position) as Int
//如果选中了一个view
if (selectView != null) {
val drawable = requireContext().getDrawable(resId)
val color = when (laneType) {
1 -> requireContext().resources.getColor(R.color.lane_info_1)
2 -> requireContext().resources.getColor(R.color.lane_info_2)
else -> requireContext().resources.getColor(R.color.white)
}
// 创建 PorterDuffColorFilter 对象
val colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
// 将 PorterDuffColorFilter 设置给 Drawable
drawable!!.colorFilter = colorFilter
selectView!!.scaleType = ImageView.ScaleType.FIT_XY
selectView!!.setColorFilter(color, PorterDuff.Mode.SRC_IN)
selectView!!.setImageDrawable(drawable)
viewModel.updateLaneInfo(selectView!!.tag as Int, resId, laneType)
} else {
//如果一条车道都没有,左侧先加一条虚线
if (binding.laneInfoTopContainer.childCount == 0) {
val lineViewS = View(context)
lineViewS.layoutParams = ViewGroup.LayoutParams(24, 110)
lineViewS.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
binding.laneInfoTopContainer.addView(lineViewS, lineViewS.layoutParams)
}
val imageView = ImageView(context)
val drawable =
requireContext().getDrawable(laneInfoItemsAdapter.getItem(position) as Int)
val color = when (laneType) {
1 -> requireContext().resources.getColor(R.color.lane_info_1)
2 -> requireContext().resources.getColor(R.color.lane_info_2)
else -> requireContext().resources.getColor(R.color.white)
}
// 创建 PorterDuffColorFilter 对象
val colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
// 将 PorterDuffColorFilter 设置给 Drawable
drawable!!.colorFilter = colorFilter
imageView.setColorFilter(color, PorterDuff.Mode.SRC_IN)
imageView.layoutParams = ViewGroup.LayoutParams(45, 100)
imageView.scaleType = ImageView.ScaleType.FIT_XY
imageView.setImageDrawable(drawable)
imageView.tag = viewModel.addLaneInfo(resId, laneType)
binding.laneInfoTopContainer.addView(imageView)
imageView.setOnClickListener {
selectView = if (selectView == it) {
selectView!!.setBackgroundColor(requireContext().resources.getColor(R.color.gray))
null
} else {
if (selectView != null) {
selectView!!.setBackgroundColor(
requireContext().resources.getColor(
R.color.gray
)
)
}
imageView.setBackgroundColor(requireContext().resources.getColor(R.color.lane_info_0))
it as ImageView
}
}
//右侧加虚线
val lineViewE = View(context)
lineViewE.layoutParams = ViewGroup.LayoutParams(24, 110)
lineViewE.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
binding.laneInfoTopContainer.addView(lineViewE)
}
}
val itemList2: MutableList<List<Int>> = mutableListOf()
itemList2.add(listOf(R.drawable.laneinfo_2, R.drawable.laneinfo_1, R.drawable.laneinfo_3))
itemList2.add(listOf(R.drawable.laneinfo_1_2, R.drawable.laneinfo_1, R.drawable.laneinfo_1_3))
itemList2.add(listOf(R.drawable.laneinfo_2, R.drawable.laneinfo_1, R.drawable.laneinfo_1_3))
itemList2.add(listOf(R.drawable.laneinfo_2_4, R.drawable.laneinfo_1, R.drawable.laneinfo_3))
itemList2.add(listOf(R.drawable.laneinfo_1_2, R.drawable.laneinfo_1, R.drawable.laneinfo_3))
itemList2.add(listOf(R.drawable.laneinfo_2_4, R.drawable.laneinfo_1, R.drawable.laneinfo_1_3))
itemList2.add(listOf(R.drawable.laneinfo_2, R.drawable.laneinfo_1, R.drawable.laneinfo_1, R.drawable.laneinfo_3))
itemList2.add(listOf(R.drawable.laneinfo_1_2, R.drawable.laneinfo_1, R.drawable.laneinfo_1, R.drawable.laneinfo_1_3))
itemList2.add(listOf(R.drawable.laneinfo_2, R.drawable.laneinfo_1, R.drawable.laneinfo_1, R.drawable.laneinfo_1_3))
itemList2.add(listOf(R.drawable.laneinfo_2_4, R.drawable.laneinfo_1, R.drawable.laneinfo_1, R.drawable.laneinfo_3))
itemList2.add(listOf(R.drawable.laneinfo_1_2, R.drawable.laneinfo_1, R.drawable.laneinfo_1, R.drawable.laneinfo_3))
itemList2.add(listOf(R.drawable.laneinfo_2_4, R.drawable.laneinfo_1, R.drawable.laneinfo_1, R.drawable.laneinfo_1_3))
laneInfoItemsAdapter2 = LaneInfoItems2Adapter(itemList2)
binding.laneInfoGridview2.adapter = laneInfoItemsAdapter2
binding.laneInfoGridview2.onItemClickListener =
AdapterView.OnItemClickListener { parent, view, position, id ->
val listIds = laneInfoItemsAdapter2.getItem(position) as List<Int>
//如果选中了一个view
if (selectView != null) {
selectView = null
}
binding.laneInfoTopContainer.removeAllViews()
viewModel.removeAllLaneInfo()
for (resId in listIds) {
val lineViewS = View(context)
lineViewS.layoutParams = ViewGroup.LayoutParams(24, 110)
lineViewS.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
binding.laneInfoTopContainer.addView(lineViewS, lineViewS.layoutParams)
val imageView = ImageView(context)
val drawable =
requireContext().getDrawable(resId)
val color = when (laneType) {
1 -> requireContext().resources.getColor(R.color.lane_info_1)
2 -> requireContext().resources.getColor(R.color.lane_info_2)
else -> requireContext().resources.getColor(R.color.white)
}
// 创建 PorterDuffColorFilter 对象
val colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
// 将 PorterDuffColorFilter 设置给 Drawable
drawable!!.colorFilter = colorFilter
imageView.setColorFilter(color, PorterDuff.Mode.SRC_IN)
imageView.layoutParams = ViewGroup.LayoutParams(45, 100)
imageView.scaleType = ImageView.ScaleType.FIT_XY
imageView.setImageDrawable(drawable)
imageView.tag = viewModel.addLaneInfo(resId, laneType)
binding.laneInfoTopContainer.addView(imageView)
imageView.setOnClickListener {
selectView = if (selectView == it) {
selectView!!.setBackgroundColor(requireContext().resources.getColor(R.color.gray))
null
} else {
if (selectView != null) {
selectView!!.setBackgroundColor(
requireContext().resources.getColor(
R.color.gray
)
)
}
imageView.setBackgroundColor(requireContext().resources.getColor(R.color.lane_info_0))
it as ImageView
}
}
}
//右侧加虚线
val lineViewE = View(context)
lineViewE.layoutParams = ViewGroup.LayoutParams(24, 110)
lineViewE.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
binding.laneInfoTopContainer.addView(lineViewE)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* 初始化车道信息
*/
private fun initLaneInfo(list:MutableList<LaneInfoItem>) {
val container = binding.laneInfoTopContainer
container.removeAllViews()
val lineViewS = View(context)
lineViewS.layoutParams = ViewGroup.LayoutParams(24, 110)
lineViewS.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
container.addView(lineViewS, lineViewS.layoutParams)
for (i in list.indices) {
val laneInfo = list[i]
val imageView = ImageView(context)
val drawable = requireContext().getDrawable(laneInfo.id)
val color = when (laneInfo.type) {
1 -> requireContext().resources.getColor(R.color.lane_info_1)
2 -> requireContext().resources.getColor(R.color.lane_info_2)
else -> requireContext().resources.getColor(R.color.white)
}
// 创建 PorterDuffColorFilter 对象
val colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
// 将 PorterDuffColorFilter 设置给 Drawable
drawable!!.colorFilter = colorFilter
// 将 Drawable 设置给 ImageView
imageView.scaleType = ImageView.ScaleType.FIT_XY
imageView.setColorFilter(color, PorterDuff.Mode.SRC_IN)
imageView.setImageDrawable(drawable)
// 将 ImageView 的颜色设置为红色
imageView.layoutParams = ViewGroup.LayoutParams(45, 100)
container.addView(imageView, imageView.layoutParams)
if (i < list.size - 1) {
val lineView = View(context)
lineView.layoutParams = ViewGroup.LayoutParams(24, 110)
lineView.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
container.addView(lineView, lineView.layoutParams)
}
imageView.tag = i
imageView.setOnClickListener {
selectView = if (selectView == it) {
selectView!!.setBackgroundColor(requireContext().resources.getColor(R.color.gray))
null
} else {
if (selectView != null) {
selectView!!.setBackgroundColor(requireContext().resources.getColor(R.color.gray))
}
imageView.setBackgroundColor(requireContext().resources.getColor(R.color.lane_info_0))
it as ImageView
}
}
}
val lineViewE = View(context)
lineViewE.layoutParams = ViewGroup.LayoutParams(24, 110)
lineViewE.background =
requireContext().getDrawable(R.drawable.shape_vertical_dashed_line)
container.addView(lineViewE, lineViewE.layoutParams)
}
}

View File

@@ -0,0 +1,107 @@
package com.navinfo.omqs.ui.fragment.evaluationresult;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.navinfo.omqs.R;
import com.navinfo.omqs.databinding.LaneinfoItemBinding;
import java.util.List;
/**
* 车信图标gridView
*/
public class LaneInfoItems2Adapter extends BaseAdapter {
List<List<Integer>> dataList;
//车道类型 0普通1附加车道2公交车道
private int type = 0;
LaneInfoItems2Adapter(List<List<Integer>> data) {
dataList = data;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LaneinfoItemBinding viewBinding =
LaneinfoItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
holder = new ViewHolder();
holder.layout = viewBinding.laneinfoItemLayout;
convertView = viewBinding.getRoot();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
List<Integer> list = dataList.get(position);
holder.layout.removeAllViews();
for (int i : list) {
View lineViewS = new View(parent.getContext());
lineViewS.setLayoutParams(new ViewGroup.LayoutParams(24, 90));
lineViewS.setBackground(parent.getContext().getDrawable(R.drawable.shape_vertical_dashed_line));
holder.layout.addView(lineViewS);
ImageView imageView = new ImageView(parent.getContext());
Drawable drawable = parent.getContext().getDrawable(i);
int color;
switch (type) {
case 1:
color = parent.getContext().getResources().getColor(R.color.lane_info_1);
break;
case 2:
color = parent.getContext().getResources().getColor(R.color.lane_info_2);
break;
default:
color = parent.getContext().getResources().getColor(R.color.white);
break;
}
// 创建 PorterDuffColorFilter 对象
PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
// 将 PorterDuffColorFilter 设置给 Drawable
drawable.setColorFilter(colorFilter);
imageView.setColorFilter(color, PorterDuff.Mode.SRC_IN);
imageView.setBackground(drawable);
imageView.setLayoutParams(new ViewGroup.LayoutParams(36, 80));
holder.layout.addView(imageView);
}
View lineViewS = new View(parent.getContext());
lineViewS.setLayoutParams(new ViewGroup.LayoutParams(24, 90));
lineViewS.setBackground(parent.getContext().getDrawable(R.drawable.shape_vertical_dashed_line));
holder.layout.addView(lineViewS);
return convertView;
}
private class ViewHolder {
LinearLayout layout;
}
public void setType(int type) {
if (type != this.type) {
this.type = type;
notifyDataSetChanged();
}
}
}

View File

@@ -0,0 +1,95 @@
package com.navinfo.omqs.ui.fragment.evaluationresult;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.navinfo.omqs.R;
import com.navinfo.omqs.databinding.LaneinfoItemBinding;
import com.navinfo.omqs.util.SignUtil;
import java.util.List;
/**
* 车信图标gridView
*/
public class LaneInfoItemsAdapter extends BaseAdapter {
List<Integer> dataList;
//车道类型 0普通1附加车道2公交车道
private int type = 0;
LaneInfoItemsAdapter(List<Integer> data) {
dataList = data;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LaneinfoItemBinding viewBinding =
LaneinfoItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
holder = new ViewHolder();
holder.layout = viewBinding.laneinfoItemLayout;
convertView = viewBinding.getRoot();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ImageView imageView = new ImageView(parent.getContext());
Drawable drawable = parent.getContext().getDrawable(dataList.get(position));
int color;
switch (type) {
case 1:
color = parent.getContext().getResources().getColor(R.color.lane_info_1);
break;
case 2:
color = parent.getContext().getResources().getColor(R.color.lane_info_2);
break;
default:
color = parent.getContext().getResources().getColor(R.color.white);
break;
}
// 创建 PorterDuffColorFilter 对象
PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
// 将 PorterDuffColorFilter 设置给 Drawable
drawable.setColorFilter(colorFilter);
imageView.setBackground(drawable);
holder.layout.removeAllViews();
holder.layout.addView(imageView);
return convertView;
}
private class ViewHolder {
LinearLayout layout;
}
public void setType(int type) {
if (type != this.type) {
this.type = type;
notifyDataSetChanged();
}
}
}

View File

@@ -1,21 +1,16 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Build
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.databinding.TextItemSelectBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
BaseRecyclerViewAdapter<String>() {
class LeftAdapter(private var itemListener: ((Int, ScProblemTypeBean) -> Unit?)? = null) :
BaseRecyclerViewAdapter<ScProblemTypeBean>() {
private var selectTitle = ""
override fun getItemViewRes(position: Int): Int {
return R.layout.text_item_select
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
@@ -23,37 +18,28 @@ class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
return BaseViewHolder(viewBinding)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as TextItemSelectBinding
val title = data[position]
bd.itemId.text = title
if (selectTitle == title) {
bd.itemId.setBackgroundResource(R.drawable.shape_rect_white_2dp_bg)
bd.itemId.setTextColor(holder.viewBinding.root.context.getColor(R.color.highFontColor))
} else {
bd.itemId.setBackgroundResource(R.drawable.shape_rect_white_2dp_bg)
bd.itemId.setTextColor(holder.viewBinding.root.context.getColor(R.color.black))
}
bd.itemId.text = title.classType
holder.viewBinding.root.isSelected = selectTitle == title.classType
bd.root.setOnClickListener {
if (selectTitle != title) {
selectTitle = title
if (selectTitle != title.classType) {
selectTitle = title.classType
notifyDataSetChanged()
}
itemListener?.invoke(position, title)
}
}
override fun refreshData(newData: List<String>) {
override fun refreshData(newData: List<ScProblemTypeBean>) {
data = newData
selectTitle = newData[0]
notifyDataSetChanged()
}
fun setRightTitle(title: String) {
fun setSelectTitle(title: String) {
if (title != selectTitle) {
selectTitle = title
notifyDataSetChanged()
}
}
}

View File

@@ -13,9 +13,6 @@ class MiddleAdapter(private var itemListener: ((Int, String) -> Unit?)? = null)
BaseRecyclerViewAdapter<String>() {
private var selectTitle = ""
override fun getItemViewRes(position: Int): Int {
return R.layout.text_item_select
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
@@ -23,7 +20,6 @@ class MiddleAdapter(private var itemListener: ((Int, String) -> Unit?)? = null)
return BaseViewHolder(viewBinding)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as TextItemSelectBinding
val title = data[position]
@@ -33,10 +29,10 @@ class MiddleAdapter(private var itemListener: ((Int, String) -> Unit?)? = null)
bd.itemLayout.layoutParams = layoutParams
if (selectTitle == title) {
bd.itemId.setBackgroundResource(R.drawable.shape_bg_blue_bg_4_radius)
bd.itemId.setTextColor(holder.viewBinding.root.context.getColor(R.color.white))
bd.itemId.setTextColor(holder.viewBinding.root.context.resources.getColor(R.color.white))
} else {
bd.itemId.setBackgroundResource(R.drawable.shape_rect_white_2dp_bg)
bd.itemId.setTextColor(holder.viewBinding.root.context.getColor(R.color.black))
bd.itemId.setTextColor(holder.viewBinding.root.context.resources.getColor(R.color.black))
}
bd.root.setOnClickListener {
if (selectTitle != title) {

View File

@@ -6,19 +6,26 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentPhenomenonBinding
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.other.shareViewModels
import dagger.hilt.android.AndroidEntryPoint
/**
* 问题现象页面
*/
@AndroidEntryPoint
class PhenomenonFragment :
BaseFragment() {
private var _binding: FragmentPhenomenonBinding? = null
private val binding get() = _binding!!
/**
* 和[PhenomenonFragment],[ProblemLinkFragment],[EvaluationResultFragment]共用同一个viewModel
*/
@@ -30,7 +37,6 @@ class PhenomenonFragment :
savedInstanceState: Bundle?
): View {
_binding = FragmentPhenomenonBinding.inflate(inflater, container, false)
Log.e("jingo", "PhenomenonFragment onCreateView ${hashCode()}")
return binding.root
}
@@ -50,6 +56,7 @@ class PhenomenonFragment :
binding.phenomenonLeftRecyclerview.adapter = leftAdapter
//左侧菜单查询结果监听
viewModel.liveDataLeftTypeList.observe(viewLifecycleOwner) {
leftAdapter.setSelectTitle(viewModel.liveDataQsRecordBean.value!!.classType)
leftAdapter.refreshData(it)
}
@@ -63,18 +70,20 @@ class PhenomenonFragment :
*/
val rightAdapter = RightGroupHeaderAdapter { _, bean ->
viewModel.setPhenomenonMiddleBean(bean)
if (activity != null) {
requireActivity().findNavController(R.id.main_activity_middle_fragment).navigateUp()
}
}
binding.phenomenonRightRecyclerview.adapter = rightAdapter
//右侧菜单增加组标题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.phenomenonRightRecyclerview.addItemDecoration(
RightGroupHeaderDecoration(
requireContext()
)
binding.phenomenonRightRecyclerview.addItemDecoration(
RightGroupHeaderDecoration(
requireContext()
)
}
)
//右侧菜单查询数据监听
viewModel.liveDataRightTypeList.observe(viewLifecycleOwner) {
rightAdapter.setSelectTitle(viewModel.liveDataQsRecordBean.value!!.phenomenon)
rightAdapter.refreshData(it)
}
@@ -106,15 +115,15 @@ class PhenomenonFragment :
})
//中间菜单
binding.phenomenonMiddleRecyclerview.setHasFixedSize(true)
binding.phenomenonMiddleRecyclerview.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
binding.phenomenonMiddleRecyclerview.adapter = middleAdapter
// //中间菜单
// binding.phenomenonMiddleRecyclerview.setHasFixedSize(true)
// binding.phenomenonMiddleRecyclerview.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
//
// binding.phenomenonMiddleRecyclerview.adapter = middleAdapter
//中间侧菜单查询结果监听
viewModel.liveDataMiddleTypeList.observe(viewLifecycleOwner) {
middleAdapter.refreshData(it)
}
// viewModel.liveDataMiddleTypeList.observe(viewLifecycleOwner) {
// middleAdapter.refreshData(it)
// }
// binding.phenomenonDrawer.setOnClickListener {
// when (binding.group.visibility) {
// View.INVISIBLE, View.GONE ->
@@ -130,10 +139,6 @@ class PhenomenonFragment :
override fun onDestroyView() {
super.onDestroyView()
_binding = null
Log.e("jingo", "PhenomenonFragment onDestroyView ${hashCode()}")
}
override fun onResume() {
super.onResume()
}
}

View File

@@ -0,0 +1,36 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterPictureBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
import com.navinfo.omqs.util.ImageTools
import java.io.File
class PictureAdapter : BaseRecyclerViewAdapter<String>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterPictureBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as AdapterPictureBinding
val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH)
if (!myAppDir.exists()) myAppDir.mkdirs() // 确保文件夹已创建
// 创建一个名为 fileName 的文件
val file = File(myAppDir, data[position])
if(file.exists()){
bd.showImage.setImageBitmap(ImageTools.zoomBitmap(Constant.USER_DATA_ATTACHEMNT_PATH+"/"+data[position],2))
}else{
bd.showImage.setBackgroundResource(R.drawable.icon_camera_img)
}
}
}

View File

@@ -1,17 +1,20 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentProblemLinkBinding
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.other.shareViewModels
/**
* 问题环节页面
*/
class ProblemLinkFragment : BaseFragment() {
private var _binding: FragmentProblemLinkBinding? = null
private val binding get() = _binding!!
@@ -28,7 +31,6 @@ class ProblemLinkFragment : BaseFragment() {
savedInstanceState: Bundle?
): View {
_binding = FragmentProblemLinkBinding.inflate(inflater, container, false)
Log.e("jingo", "linkFragment onCreateView ${hashCode()}")
return binding.root
}
@@ -43,18 +45,20 @@ class ProblemLinkFragment : BaseFragment() {
binding.linkRightRecyclerview.layoutManager = rightLayoutManager
val rightAdapter = RightGroupHeaderAdapter { _, bean ->
viewModel.setProblemLinkMiddleBean(bean)
if (activity != null) {
requireActivity().findNavController(R.id.main_activity_middle_fragment).navigateUp()
}
}
binding.linkRightRecyclerview.adapter = rightAdapter
//右侧菜单增加组标题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.linkRightRecyclerview.addItemDecoration(
RightGroupHeaderDecoration(
requireContext()
)
binding.linkRightRecyclerview.addItemDecoration(
RightGroupHeaderDecoration(
requireContext()
)
}
)
//右侧菜单查询数据监听
viewModel.liveDataRightTypeList.observe(viewLifecycleOwner) {
rightAdapter.setSelectTitle(viewModel.liveDataQsRecordBean.value!!.cause)
rightAdapter.refreshData(it)
}
@@ -75,22 +79,6 @@ class ProblemLinkFragment : BaseFragment() {
}
})
//中间菜单
binding.linkMiddleRecyclerview.setHasFixedSize(true)
binding.linkMiddleRecyclerview.layoutManager = LinearLayoutManager(requireContext())
binding.linkMiddleRecyclerview.adapter = middleAdapter
//中间侧菜单查询结果监听
viewModel.liveDataMiddleTypeList.observe(viewLifecycleOwner) {
middleAdapter.refreshData(it)
}
binding.linkDrawer.setOnClickListener {
when (binding.group.visibility) {
View.INVISIBLE, View.GONE ->
binding.group.visibility = View.VISIBLE
else ->
binding.group.visibility = View.GONE
}
}
viewModel.getProblemLinkList()
}
@@ -98,10 +86,5 @@ class ProblemLinkFragment : BaseFragment() {
override fun onDestroyView() {
super.onDestroyView()
_binding = null
Log.e("jingo", "linkFragment onDestroyView ${hashCode()}")
}
override fun onResume() {
super.onResume()
}
}

View File

@@ -3,27 +3,32 @@ package com.navinfo.omqs.ui.fragment.evaluationresult
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.TextItemSelectBinding
import com.navinfo.omqs.databinding.TextItemSelect2Binding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class RightGroupHeaderAdapter(private var itemListener: ((Int, RightBean) -> Unit?)? = null) :
BaseRecyclerViewAdapter<RightBean>() {
private var selectTitle = ""
private var groupTitleList = mutableListOf<String>()
override fun getItemViewRes(position: Int): Int {
return R.layout.text_item_select
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
TextItemSelect2Binding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as TextItemSelectBinding
bd.itemId.text = data[position].text
val bd = holder.viewBinding as TextItemSelect2Binding
val title = data[position].text
bd.itemId.text = title
holder.viewBinding.root.isSelected = selectTitle == title
bd.root.setOnClickListener {
if (selectTitle != title) {
selectTitle = title
notifyDataSetChanged()
}
itemListener?.invoke(position, data[position])
}
}
@@ -86,7 +91,6 @@ class RightGroupHeaderAdapter(private var itemListener: ((Int, RightBean) -> Uni
}
override fun refreshData(newData: List<RightBean>) {
super.refreshData(newData)
groupTitleList.clear()
for (item in newData) {
if (groupTitleList.size > 0) {
@@ -97,7 +101,15 @@ class RightGroupHeaderAdapter(private var itemListener: ((Int, RightBean) -> Uni
groupTitleList.add(item.title)
}
}
super.refreshData(newData)
}
/**
* 设置当前选中的哪条数据
*/
fun setSelectTitle(title: String) {
if (title != selectTitle) {
selectTitle = title
}
}
}

View File

@@ -5,9 +5,7 @@ import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.os.Build
import android.view.View
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
@@ -17,7 +15,6 @@ import com.navinfo.omqs.R
/**
* 自定义装饰器(实现分组+吸顶效果)
*/
@RequiresApi(Build.VERSION_CODES.M)
class RightGroupHeaderDecoration(context: Context) : ItemDecoration() {
//头部的高
private val mItemHeaderHeight: Int
@@ -35,12 +32,12 @@ class RightGroupHeaderDecoration(context: Context) : ItemDecoration() {
mTextPaddingLeft = dp2px(context, 6f)
mTextRect = Rect()
mItemHeaderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
mItemHeaderPaint.color = context.getColor(R.color.btn_bg_blue)
mItemHeaderPaint.color = context.resources.getColor(R.color.btn_bg_blue)
mTextPaint = Paint(Paint.ANTI_ALIAS_FLAG)
mTextPaint.textSize = 46f
mTextPaint.color = Color.WHITE
mLinePaint = Paint(Paint.ANTI_ALIAS_FLAG)
mLinePaint.color = Color.GRAY
mLinePaint.color = Color.WHITE
}
/**

View File

@@ -224,10 +224,6 @@ class SoundtListAdapter(
}
}
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_sound_list
}
}

View File

@@ -0,0 +1,47 @@
package com.navinfo.omqs.ui.fragment.itemlist
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.databinding.AdapterItemBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class ItemAdapter(private var itemListener: ((Int,Boolean, RenderEntity) -> Unit?)? = null,
) : BaseRecyclerViewAdapter<RenderEntity>() {
var selectPosition = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val binding = holder.viewBinding as AdapterItemBinding
var renderEntity = data[position]
binding.root.isSelected = selectPosition == position
binding.itemIndex.text = (position+1).toString()
binding.name.text = DataCodeEnum.findTableNameByCode(renderEntity.code)
binding.root.setOnClickListener {
if (selectPosition != position) {
notifyItemChanged(selectPosition)
selectPosition = position
notifyItemChanged(position)
}
if (itemListener != null) {
itemListener!!.invoke(position,false, renderEntity)
}
}
binding.root.setOnLongClickListener(View.OnLongClickListener {
if (itemListener != null) {
itemListener!!.invoke(position, true,renderEntity)
}
true
})
}
}

View File

@@ -0,0 +1,73 @@
package com.navinfo.omqs.ui.fragment.itemlist
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.gson.Gson
import com.navinfo.collect.library.data.entity.NoteBean
import com.navinfo.omqs.databinding.FragmentItemListBinding
import com.navinfo.omqs.ui.activity.map.MainViewModel
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.widget.RecycleViewDivider
import dagger.hilt.android.AndroidEntryPoint
import io.realm.Realm
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@AndroidEntryPoint
class ItemListFragment(private var backListener: ((ItemListFragment) -> Unit?)? = null) :
BaseFragment() {
private var _binding: FragmentItemListBinding? = null
private val binding get() = _binding!!
private val viewModel by activityViewModels<MainViewModel>()
private val adapter by lazy {
ItemAdapter { _,isLongClick, data ->
if(!isLongClick){
viewModel.showSignMoreInfo(data)
} else{
val mDialog = FirstDialog(context)
mDialog.setTitle("提示?")
val gson = Gson()
mDialog.setMessage(gson.toJson(data.properties))
mDialog.setPositiveButton(
"确定"
) { dialog, _ ->
dialog.dismiss()
}
mDialog.setNegativeButton("取消", null)
mDialog.setCancelVisibility(View.GONE)
mDialog.show()
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentItemListBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.itemListRecyclerview.layoutManager = LinearLayoutManager(requireContext())
binding.itemListRecyclerview.adapter = adapter
binding.itemListRecyclerview.addItemDecoration(
RecycleViewDivider(
requireContext(),
LinearLayoutManager.VERTICAL
)
)
viewModel.liveDataItemList.observe(viewLifecycleOwner) {
adapter.refreshData(it)
}
binding.taskBack.setOnClickListener {
backListener?.invoke(this)
}
}
}

View File

@@ -4,22 +4,17 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.blankj.utilcode.util.SPStaticUtils
import com.navinfo.omqs.Constant
import com.navinfo.omqs.databinding.FragmentEmptyBinding
import com.navinfo.omqs.databinding.FragmentLayerManagerBinding
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapCityListViewModel
class LayermanagerFragment : BaseFragment(){
class LayerManagerFragment(private var backListener: (() -> Unit?)? = null) : BaseFragment() {
private var _binding: FragmentLayerManagerBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<LayerManagerViewModel>()
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
@@ -30,12 +25,13 @@ class LayermanagerFragment : BaseFragment(){
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val adapter = LayerManagerExpandableListAdapter(requireContext(), viewModel.getLayerConfigList())
val adapter =
LayerManagerExpandableListAdapter(requireContext(), viewModel.getLayerConfigList())
binding.elvLayerManager.setAdapter(adapter)
// 默认显示第一个父项下的子类
binding.elvLayerManager.expandGroup(0)
binding.elvLayerManager.setGroupIndicator(null)
binding.elvLayerManager.setOnGroupClickListener { expandableListView, view, groupPosition, l ->
binding.elvLayerManager.setOnGroupClickListener { expandableListView, _, groupPosition, _ ->
if (expandableListView.isGroupExpanded(groupPosition)) {
binding.elvLayerManager.collapseGroup(groupPosition)
} else {
@@ -43,14 +39,19 @@ class LayermanagerFragment : BaseFragment(){
}
}
binding.imgBack.setOnClickListener {
findNavController().navigateUp()
binding.imgConfirm.setOnClickListener {
viewModel.saveLayerConfigList(requireContext(), adapter.parentItems)
}
binding.tvTitle.text = findNavController().currentDestination?.label
binding.imgBack.setOnClickListener {
backListener?.invoke()
}
binding.tvTitle.text = "图层管理"//findNavController().currentDestination?.label
binding.imgConfirm.setOnClickListener { // 用户点击确认,重新设置当前的图层显隐控制
viewModel.saveLayerConfigList(adapter.parentItems)
viewModel.saveLayerConfigList(requireContext(), adapter.parentItems)
backListener?.invoke()
}
}

View File

@@ -1,19 +1,20 @@
package com.navinfo.omqs.ui.fragment.layermanager
import android.content.Context
import android.widget.Toast
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.FileIOUtils
import com.blankj.utilcode.util.SPStaticUtils
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.ImportConfig
import com.navinfo.omqs.tools.LayerConfigUtils
import com.navinfo.omqs.util.FlowEventBus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import kotlinx.coroutines.withContext
class LayerManagerViewModel(): ViewModel() {
class LayerManagerViewModel() : ViewModel() {
private val gson = Gson()
fun getLayerConfigList(): List<ImportConfig> {
@@ -21,11 +22,15 @@ class LayerManagerViewModel(): ViewModel() {
return LayerConfigUtils.getLayerConfigList()
}
fun saveLayerConfigList(listData: List<ImportConfig>) {
SPStaticUtils.put(Constant.EVENT_LAYER_MANAGER_CHANGE, gson.toJson(listData))
fun saveLayerConfigList(context: Context, listData: List<ImportConfig>) {
Constant.LAYER_CONFIG_LIST = listData
// 发送新的配置数据
viewModelScope.launch {
FlowEventBus.post(Constant.EVENT_LAYER_MANAGER_CHANGE, listData)
withContext(Dispatchers.Main) {
Toast.makeText(context, "设置成功", Toast.LENGTH_SHORT)
.show()
}
}
}

View File

@@ -0,0 +1,59 @@
package com.navinfo.omqs.ui.fragment.navi
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import com.navinfo.omqs.Constant
import com.navinfo.omqs.databinding.FragmentNaviSettingBinding
import com.navinfo.omqs.ui.fragment.BaseFragment
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class NaviSettingFragment(private var backListener: (() -> Unit?)? = null) : BaseFragment() {
private var _binding: FragmentNaviSettingBinding? = null
@Inject
lateinit var sharedPreferences: SharedPreferences
private val binding get() = _binding!!
private val viewModel by viewModels<NaviSettingViewModel>()
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentNaviSettingBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.offCount.setValue(sharedPreferences.getInt(Constant.NAVI_DEVIATION_COUNT,3))
binding.offDistance.setValue(sharedPreferences.getInt(Constant.NAVI_DEVIATION_DISTANCE,15))
binding.tipsDistance.setValue(sharedPreferences.getInt(Constant.NAVI_FARTHEST_DISPLAY_DISTANCE,500))
binding.imgConfirm.setOnClickListener{
sharedPreferences.edit()
.putInt(Constant.NAVI_DEVIATION_DISTANCE,binding.offDistance.getValue())
.putInt(Constant.NAVI_DEVIATION_COUNT,binding.offCount.getValue())
.putInt(Constant.NAVI_FARTHEST_DISPLAY_DISTANCE,binding.tipsDistance.getValue())
.commit()
backListener?.invoke()
}
binding.imgBack.setOnClickListener {
backListener?.invoke()
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,6 @@
package com.navinfo.omqs.ui.fragment.navi
import androidx.lifecycle.ViewModel
class NaviSettingViewModel : ViewModel() {
}

View File

@@ -0,0 +1,152 @@
package com.navinfo.omqs.ui.fragment.note
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentCanvasBinding
import com.navinfo.omqs.databinding.FragmentNoteBinding
import com.navinfo.omqs.databinding.FragmentProblemLinkBinding
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.fragment.note.CanvasView.CanvasStyle
import com.navinfo.omqs.ui.fragment.note.CanvasView.OnCanvasChangeListener
import com.navinfo.omqs.ui.other.shareViewModels
/**
* @author zhjch
* @version V1.0
* @ClassName: CanvasFragment
* @Date 2016/5/10
* @Description: ${TODO}(绘制画布)
*/
class CanvasFragment : BaseFragment() {
/**
* 获取画布
*
* @return
*/
/**
* 画布
*/
private val canvasView by lazy { binding.canvasView }
/**
* 画笔线型
*/
private var mStyle = CanvasStyle.FREE_LINE
/**
* 画笔颜色
*/
private var mColor = -1
/**
* 画笔粗细
*/
private var width = 5
/**
* 画布回调接口
*/
private var listener: OnCanvasChangeListener? = null
private var _binding: FragmentCanvasBinding? = null
private val binding get() = _binding!!
private val viewModel by shareViewModels<NoteViewModel>("note")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentCanvasBinding.inflate(inflater, container, false)
viewModel.initCanvasView(canvasView)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
canvasView.setStyle(mStyle)
if (mColor == -1) {
mColor = resources.getColor(R.color.black)
}
canvasView.setPaintColor(mColor)
canvasView.setPaintWidth(width)
if (listener != null) {
canvasView.setOnCanvasChangeListener(listener)
}
// * 开关橡皮擦
// */
// viewModel.liveEraserData.observe(viewLifecycleOwner) {
// canvasView.setEraser(it)
// }
// /**
// * 清除
// */
// viewModel.liveClearData.observe(viewLifecycleOwner) {
// canvasView.removeAllPaint()
// }
// /**
// * 回退上一笔
// */
// viewModel.liveBackData.observe(viewLifecycleOwner) {
// canvasView.back()
// }
// /**
// * 撤销回退
// */
// viewModel.liveForward.observe(viewLifecycleOwner) {
// canvasView.forward()
// }
//
}
/**
* 将数据转化并绘制在画板上
*
* @param value
*/
fun setDrawPathList(value: MutableList<CanvasView.DrawPath>) {
if (value != null && value.isNotEmpty()) {
canvasView.setDrawPathList(value)
}
}
/**
* 设置草图画笔线型
*/
fun setStyle(style: CanvasStyle) {
mStyle = style
canvasView.setStyle(style)
}
/**
* 设置画笔颜色
*/
fun setPaintColor(color: Int) {
mColor = color
canvasView.setPaintColor(mColor)
}
/**
* 设置画笔粗细
*/
fun setPaintWidth(width: Int) {
this.width = width
canvasView.setPaintWidth(width)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,424 @@
package com.navinfo.omqs.ui.fragment.note
import android.graphics.Path
import android.graphics.Point
import android.graphics.Rect
import android.graphics.RectF
import android.text.TextUtils
import com.navinfo.collect.library.data.entity.NoteBean
import com.navinfo.collect.library.data.entity.SketchAttachContent
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.ui.fragment.note.CanvasView.CanvasStyle
import io.realm.RealmList
import org.locationtech.jts.geom.Coordinate
import org.oscim.backend.canvas.Color
import org.oscim.core.GeoPoint
import java.util.UUID
import kotlin.math.abs
import kotlin.math.cos
import kotlin.math.sin
/**
* @author zhjch
* @version V1.0
* @ClassName: CanvasViewHelper
* @Date 2016/5/16
* @Description: ${TODO}(用一句话描述该文件做什么)
*/
object CanvasViewHelper {
private const val mD2I = 3600000
fun createNoteBean(
controller: NIMapController,
mCurrentPaths: List<CanvasView.DrawPath>,
): NoteBean {
val noteBean = NoteBean(UUID.randomUUID().toString())
if (mCurrentPaths.isNotEmpty()) {
val list: RealmList<SketchAttachContent> = RealmList<SketchAttachContent>()
noteBean.list = list
for (index in mCurrentPaths.indices) {
val dp: CanvasView.DrawPath = mCurrentPaths[index]
val geo = SketchAttachContent(UUID.randomUUID().toString())
val pointList = dp.pointList ?: continue
if (dp.style === CanvasStyle.GREENLAND_LINE || dp.style === CanvasStyle.WATER_LINE || dp.style === CanvasStyle.PARKING_LINE) {
val geoPointList = mutableListOf<GeoPoint>()
for (i in pointList.indices) {
val point = pointList[i]
val geoPoint: GeoPoint = controller.viewportHandler.fromScreenPoint(
point
)
geoPointList.add(geoPoint)
if (index == 0 && i == 0) {
noteBean.guideGeometry =
GeometryTools.createGeometry(geoPoint).toText()
}
}
geo.style = createLineStyle(dp.style, dp.width, dp.color)
geo.geometry = GeometryTools.createPolygon(geoPointList).toText()
} else if (dp.style === CanvasStyle.CIRCULAR_POINT) {
val point = pointList[0]
val geoPoint: GeoPoint = controller.viewportHandler.fromScreenPoint(point)
geo.style = createLineStyle(dp.style, dp.width, dp.color)
geo.geometry = GeometryTools.createGeometry(geoPoint).toText()
noteBean.guideGeometry = geo.geometry
} else if (dp.style === CanvasStyle.ELLIPSE_LINE) {
dp.rect?.let {
val pointLT = Point(it.left, it.top)
val pointRB = Point(it.right, it.bottom)
val geoPointLT: GeoPoint =
controller.viewportHandler.fromScreenPoint(pointLT)
val geoPointRB: GeoPoint =
controller.viewportHandler.fromScreenPoint(pointRB)
val minX: Double
val maxX: Double
val minY: Double
val maxY: Double
if (geoPointLT.longitude < geoPointRB.longitude) {
minX = (geoPointLT.longitude * mD2I)
maxX = (geoPointRB.longitude * mD2I)
} else {
minX = (geoPointRB.longitude * mD2I)
maxX = (geoPointLT.longitude * mD2I)
}
if (geoPointLT.latitude < geoPointRB.latitude) {
minY = (geoPointLT.latitude * mD2I)
maxY = (geoPointRB.latitude * mD2I)
} else {
minY = (geoPointRB.latitude * mD2I)
maxY = (geoPointLT.latitude * mD2I)
}
val xR = (maxX - minX) / 2
val yR = (maxY - minY) / 2
var a = 0.0
var tempX = xR * cos(a) + xR + minX
val tempY = yR * sin(a) + yR + minY
val firstX = tempX
val geoPointList = mutableListOf<GeoPoint>()
geoPointList.add(GeoPoint(tempX / mD2I, tempY / mD2I))
var bLeft = false
var bRight = false
var zeng = 0.1
if (controller.mMapView.mapLevel >= 20) {
zeng = 0.2
}
while (!bLeft || !bRight) {
a += zeng
val x1 = (xR * cos(a) + xR + minX).toInt().toDouble()
val y1 = (yR * sin(a) + yR + minY).toInt().toDouble()
if (!bLeft && x1 > tempX) {
bLeft = true
}
if (!bRight && bLeft && x1 <= tempX) {
bRight = true
geoPointList.add(
GeoPoint(
firstX / mD2I,
tempY / mD2I
)
)
} else {
tempX = x1
geoPointList.add(GeoPoint(x1 / mD2I, y1 / mD2I))
}
}
if (index == 0) {
noteBean.guideGeometry =
GeometryTools.createGeometry(geoPointList[0]).toText()
}
geo.style = createLineStyle(dp.style, dp.width, dp.color)
geo.geometry = GeometryTools.createLineString(geoPointList).toText()
}
} else {
val geoPointList = mutableListOf<GeoPoint>()
for (i in pointList.indices) {
val point = pointList[i]
val geoPoint: GeoPoint =
controller.viewportHandler.fromScreenPoint(point)
geoPointList.add(geoPoint)
if (index == 0 && i == 0) {
noteBean.guideGeometry =
GeometryTools.createGeometry(geoPoint).toText()
}
}
geo.style = createLineStyle(dp.style, dp.width, dp.color)
geo.geometry = GeometryTools.createLineString(geoPointList).toText()
}
list.add(geo)
}
}
return noteBean
}
fun createDrawPaths(
controller: NIMapController,
att: NoteBean
): MutableList<CanvasView.DrawPath> {
val contents: List<SketchAttachContent> = att.list
val drawPaths: MutableList<CanvasView.DrawPath> = mutableListOf()
var width = 5
var canvasStyle = CanvasStyle.FREE_LINE
var color = Color.BLACK
for (geo in contents) {
var max_x = 0
var max_y = 0
var min_x = 0
var min_y = 0
val style = geo.style
if (!TextUtils.isEmpty(style) && style.length > 3) {
try {
if (style.startsWith("4")) {
canvasStyle = CanvasStyle.RAILWAY_LINE
} else if (style.startsWith("5")) {
if (style.contains("cde3ac")) {
canvasStyle = CanvasStyle.GREENLAND_LINE
} else if (style.contains("abcaff")) {
canvasStyle = CanvasStyle.WATER_LINE
} else if (style.contains("fffe98")) {
canvasStyle = CanvasStyle.PARKING_LINE
}
} else {
val s = style.substring(0, 1)
if (TextUtils.equals(s, "2")) {
canvasStyle = CanvasStyle.STRAIGHT_LINE
} else if (TextUtils.equals(s, "3")) {
canvasStyle = CanvasStyle.RECT_LINE
} else if (TextUtils.equals(s, "6")) {
canvasStyle = CanvasStyle.POLY_LINE
} else if (TextUtils.equals(s, "7")) {
canvasStyle = CanvasStyle.ELLIPSE_LINE
} else if (TextUtils.equals(s, "9")) {
canvasStyle = CanvasStyle.CIRCULAR_POINT
} else if (TextUtils.equals(s, "1")) {
canvasStyle = CanvasStyle.FREE_LINE
}
width = style.substring(1, 3).toInt()
var colorStr = style.substring(3, style.length)
if (colorStr.length == 6) {
colorStr = "ff$colorStr"
} else if (colorStr.length == 8) {
} else {
colorStr = "ff000000"
}
color = colorStr.toLong(16).toInt()
}
} catch (e: Exception) {
e.printStackTrace()
}
val path = Path()
val pointList: MutableList<Point> = ArrayList()
if (canvasStyle === CanvasStyle.GREENLAND_LINE || canvasStyle === CanvasStyle.WATER_LINE || canvasStyle === CanvasStyle.PARKING_LINE) {
// val polygonGeometry: PolygonGeometry = geo.geo as PolygonGeometry
// if (polygonGeometry != null) {
// val xyz: Array<Array<DoubleArray>> = polygonGeometry.getCoordinates()
// if (xyz != null && xyz.isNotEmpty() && xyz[0].size > 1) {
// var geoPoint: GeoPoint? = GeoPoint(xyz[0][0][0], xyz[0][0][1])
// val movePoint: Point = .geoToScreen(geoPoint)
// max_x = movePoint.x
// max_y = movePoint.y
// min_x = movePoint.x
// min_y = movePoint.y
// path.reset()
// path.moveTo(movePoint.x.toFloat(), movePoint.y.toFloat())
// pointList.add(Point(movePoint.x, movePoint.y))
// for (i in 1 until xyz[0].size) {
// val x_y = xyz[0][i]
// if (x_y != null) {
// geoPoint = GeoPoint(x_y[0], x_y[1])
// val point: Point = projection.geoToScreen(geoPoint)
// if (point.x > max_x) {
// max_x = point.x
// }
// if (point.x < min_x) {
// min_x = point.x
// }
// if (point.y > max_y) {
// max_y = point.y
// }
// if (point.y < min_y) {
// min_y = point.y
// }
// path.lineTo(point.x.toFloat(), point.y.toFloat())
// pointList.add(point)
// }
// }
// path.close()
// }
// }
// val drawPath =
// CanvasView.DrawPath(pointList[0], path, width, color, canvasStyle)
// val rect = Rect(min_x, min_y, max_x, max_y)
// drawPath.rect = rect
// drawPath.pointList = pointList
// drawPaths.add(drawPath)
} else if (canvasStyle === CanvasStyle.CIRCULAR_POINT) {
// val pointGeometry: PointGeometry = geo.geo as PointGeometry
// if (pointGeometry != null && pointGeometry.getCoordinates() != null) {
// val geoPoint: GeoPoint = GeoPoint(
// pointGeometry.getCoordinates().get(0),
// pointGeometry.getCoordinates().get(1)
// )
// val movePoint: Point = projection.geoToScreen(geoPoint)
// pointList.add(movePoint)
// val drawPath = DrawPath(movePoint, path, width, color, canvasStyle)
// val rect = Rect(
// movePoint.x - width - 20,
// movePoint.y - width - 20,
// movePoint.x + width + 20,
// movePoint.y + width + 20
// )
// drawPath.rect = rect
// drawPath.pointList = pointList
// drawPaths.add(drawPath)
// }
} else if (canvasStyle === CanvasStyle.ELLIPSE_LINE) {
// val lineGeometry = GeometryTools.createGeometry(geo.geometry)
// if (lineGeometry != null) {
// val xys: Array<out Coordinate> = lineGeometry.coordinates
// if (xys != null && xys.size > 1) {
// var geoPoint: GeoPoint? = GeoPoint(xys[0].y, xys[0].x)
// val movePoint: Point = projection.geoToScreen(geoPoint)
// max_x = movePoint.x
// max_y = movePoint.y
// min_x = movePoint.x
// min_y = movePoint.y
// path.reset()
// path.moveTo(movePoint.x.toFloat(), movePoint.y.toFloat())
// pointList.add(Point(movePoint.x, movePoint.y))
// for (i in 1 until xys.size) {
// val x_y = xys[i]
// geoPoint = GeoPoint(x_y[0], x_y[1])
// val point: Point = projection.geoToScreen(geoPoint)
// if (point.x > max_x) {
// max_x = point.x
// }
// if (point.x < min_x) {
// min_x = point.x
// }
// if (point.y > max_y) {
// max_y = point.y
// }
// if (point.y < min_y) {
// min_y = point.y
// }
// pointList.add(point)
// }
// path.addOval(
// RectF(
// min_x.toFloat(),
// min_y.toFloat(),
// max_x.toFloat(),
// max_y.toFloat()
// ), Path.Direction.CW
// )
// }
// }
// val drawPath =
// CanvasView.DrawPath(pointList[0], path, width, color, canvasStyle)
// val rect = Rect(min_x, min_y, max_x, max_y)
// drawPath.rect = rect
// drawPath.pointList = pointList
// drawPaths.add(drawPath)
} else {
val lineGeometry = GeometryTools.createGeometry(geo.geometry)
if (lineGeometry != null) {
val xys: Array<out Coordinate> = lineGeometry.coordinates
if (xys.size > 1) {
var geoPoint = GeoPoint(xys[0].y, xys[0].x)
val movePoint: Point =
controller.viewportHandler.toScreenPoint(geoPoint)
max_x = movePoint.x
max_y = movePoint.y
min_x = movePoint.x
min_y = movePoint.y
path.reset()
path.moveTo(movePoint.x.toFloat(), movePoint.y.toFloat())
pointList.add(Point(movePoint.x, movePoint.y))
for (i in 1 until xys.size) {
val x_y = xys[i]
geoPoint = GeoPoint(x_y.y, x_y.x)
val point: Point =
controller.viewportHandler.toScreenPoint(geoPoint)
if (point.x > max_x) {
max_x = point.x
}
if (point.x < min_x) {
min_x = point.x
}
if (point.y > max_y) {
max_y = point.y
}
if (point.y < min_y) {
min_y = point.y
}
if (canvasStyle === CanvasStyle.FREE_LINE) {
val dx = abs(point.x - movePoint.x).toFloat()
val dy = abs(point.y - movePoint.y).toFloat()
if (dx >= 4 || dy >= 4) {
path.quadTo(
movePoint.x.toFloat(),
movePoint.y.toFloat(),
((point.x + movePoint.x) / 2).toFloat(),
((point.y + movePoint.y) / 2).toFloat()
) //源代码是这样写的,可是我没有弄明白,为什么要这样?
movePoint.x = point.x
movePoint.y = point.y
}
} else {
path.lineTo(point.x.toFloat(), point.y.toFloat())
}
pointList.add(point)
}
}
}
val drawPath =
CanvasView.DrawPath(pointList[0], path, width, color, canvasStyle)
val rect = Rect(min_x, min_y, max_x, max_y)
drawPath.rect = rect
drawPath.pointList = pointList
drawPaths.add(drawPath)
}
}
}
return drawPaths
}
private fun createLineStyle(canvasStyle: CanvasStyle, width: Int, color: Int): String {
val style = StringBuilder()
if (canvasStyle === CanvasStyle.RAILWAY_LINE) {
return "4060070c004ffffff16"
} else if (canvasStyle === CanvasStyle.GREENLAND_LINE) {
return "50200b050cde3ac"
} else if (canvasStyle === CanvasStyle.WATER_LINE) {
return "50200b050abcaff"
} else if (canvasStyle === CanvasStyle.PARKING_LINE) {
return "502a6a6a6fffe98"
}
if (canvasStyle === CanvasStyle.STRAIGHT_LINE) {
style.append("2")
} else if (canvasStyle === CanvasStyle.RECT_LINE) {
style.append("3")
} else if (canvasStyle === CanvasStyle.POLY_LINE) {
style.append("6")
} else if (canvasStyle === CanvasStyle.ELLIPSE_LINE) {
style.append("7")
} else if (canvasStyle === CanvasStyle.CIRCULAR_POINT) {
style.append("9")
} else {
style.append("1")
}
if (width < 10) {
style.append("0")
}
style.append(width.toString())
try {
var colorString = Integer.toHexString(color).toString()
if (colorString.length == 8) {
colorString = TextUtils.substring(colorString, 2, 8)
}
style.append(colorString)
} catch (e: Exception) {
e.printStackTrace()
}
return style.toString()
}
}

View File

@@ -0,0 +1,298 @@
package com.navinfo.omqs.ui.fragment.note
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentNoteBinding
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.fragment.evaluationresult.EvaluationResultFragment
import com.navinfo.omqs.ui.fragment.evaluationresult.EvaluationResultViewModel
import com.navinfo.omqs.ui.fragment.evaluationresult.PhenomenonFragment
import com.navinfo.omqs.ui.fragment.evaluationresult.PictureAdapter
import com.navinfo.omqs.ui.fragment.evaluationresult.ProblemLinkFragment
import com.navinfo.omqs.ui.fragment.evaluationresult.SoundtListAdapter
import com.navinfo.omqs.ui.other.shareViewModels
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class NoteFragment : BaseFragment(), View.OnClickListener {
private var _binding: FragmentNoteBinding? = null
private val binding get() = _binding!!
private var mCameraLauncher: ActivityResultLauncher<Intent>? = null
private val viewModel by shareViewModels<NoteViewModel>("note")
private val pictureAdapter by lazy {
PictureAdapter()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mCameraLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// 处理相机返回的结果
val extras = result.data!!.extras
val imageBitmap: Bitmap? = extras!!["data"] as Bitmap?
// 在这里处理图片数据
if (imageBitmap != null)
viewModel.savePhoto(imageBitmap)
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentNoteBinding.inflate(inflater, container, false)
return binding.root
}
@RequiresApi(Build.VERSION_CODES.N)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
activity?.run {
findNavController(
R.id.main_activity_middle_fragment
).navigate(R.id.CanvasFragment)
}
//// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能
binding.noteVoiceRecyclerview.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(context)
binding.noteVoiceRecyclerview.layoutManager = layoutManager
binding.sketchEraser.setOnClickListener(this)
binding.sketchClear.setOnClickListener(this)
binding.sketchForward.setOnClickListener(this)
binding.sketchBack.setOnClickListener(this)
binding.noteBarSave.setOnClickListener(this)
binding.noteBarCancel.setOnClickListener(this)
binding.noteBarDelete.setOnClickListener(this)
binding.noteCamera.setOnClickListener(this)
binding.noteDescription.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
viewModel.noteBeanDescription = s.toString()
}
})
viewModel.liveDataNoteBean.observe(viewLifecycleOwner) {
binding.noteDescription.setText(it.description)
}
//监听要提示的信息
viewModel.liveDataToastMessage.observe(viewLifecycleOwner) {
Toast.makeText(requireContext(), it, Toast.LENGTH_SHORT).show()
}
/**
* 监听左侧栏的点击事件
*/
val adapter = SoundtListAdapter { _, _ ->
}
binding.noteVoiceRecyclerview.adapter = adapter
/**
* 照片view
*/
/**
* 照片view
*/
binding.notePictureViewpager.adapter = pictureAdapter
/**
* 数据操作结束
*/
viewModel.liveDataFinish.observe(viewLifecycleOwner) {
if (it)
onBackPressed()
}
/**
* 画布初始化完成
*/
viewModel.liveDataCanvasViewInitFinished.observe(viewLifecycleOwner) {
if (it)
arguments?.let { b ->
val id = b.getString("NoteId", "")
if (id.isNotEmpty()) {
viewModel.initData(id)
}
}
}
/**
* 音频view
*/
viewModel.listDataChatMsgEntityList.observe(viewLifecycleOwner) {
adapter.refreshData(it)
}
/**
* 照片view
*/
viewModel.liveDataPictureList.observe(viewLifecycleOwner){
pictureAdapter.refreshData(it)
}
//照片左右选择键点击监听
binding.notePictureLeft.setOnClickListener(this)
binding.notePictureRight.setOnClickListener(this)
binding.noteCamera.setOnClickListener(this)
//设置照片偏移量
val viewPager = binding.notePictureViewpager
val vto = viewPager.viewTreeObserver
vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
val width = viewPager.width
// 处理View宽度
// 在回调完成后需要将监听器从View树中移除以避免重复调用
viewPager.viewTreeObserver.removeOnGlobalLayoutListener(this)
val recyclerView = viewPager.getChildAt(0) as RecyclerView
recyclerView.setPadding(0, 0, width / 2 - 30, 0)
recyclerView.clipToPadding = false
}
})
binding.noteVoice.setOnTouchListener { _, event ->
Log.e("qj", event?.action.toString())
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
voiceOnTouchStart()//Do Something
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE -> {
voiceOnTouchStop()//Do Something
}
}
true
}
}
private fun voiceOnTouchStart() {
viewModel.startSoundMetter(requireActivity(), binding.noteVoice)
}
private fun voiceOnTouchStop() {
Log.e("qj", "voiceOnTouchStop====${Constant.IS_VIDEO_SPEED}")
if (Constant.IS_VIDEO_SPEED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
viewModel.stopSoundMeter()
}
}
}
private fun takePhoto() {
try {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(requireActivity().packageManager) != null) {
mCameraLauncher!!.launch(takePictureIntent)
}
} catch (e: Exception) {
Log.d("TTTT", e.toString())
}
}
override fun onDestroy() {
activity?.run {
val result = findNavController(R.id.main_activity_middle_fragment).navigateUp()
Log.e("qj","onStop===$result")
}
super.onDestroy()
}
override fun onClick(v: View) {
when (v) {
binding.notePictureLeft->{
val currentItem = binding.notePictureViewpager.currentItem
if (currentItem > 0) {
binding.notePictureViewpager.currentItem = currentItem - 1
} else {
return
}
}
binding.notePictureRight->{
val currentItem = binding.notePictureViewpager.currentItem
if (currentItem < pictureAdapter.data.size - 1) {
binding.notePictureViewpager.currentItem = currentItem + 1
} else {
return
}
}
binding.sketchEraser -> {
viewModel.onEraser()
binding.sketchEraser.isSelected = viewModel.isEraser
}
binding.sketchBack -> {
viewModel.onBack()
}
binding.sketchForward -> {
viewModel.onForward()
}
binding.sketchClear -> {
viewModel.onClear()
}
binding.noteBarSave -> {
viewModel.onSaveData()
}
binding.noteBarDelete -> {
viewModel.deleteData(requireContext())
}
binding.noteBarCancel -> {
//返回按钮点击
val mDialog = FirstDialog(context)
mDialog.setTitle("提示?")
mDialog.setMessage("是否退出,请确认!")
mDialog.setPositiveButton(
"确定"
) { _, _ ->
mDialog.dismiss()
onBackPressed()
}
mDialog.setNegativeButton("取消", null)
mDialog.show()
}
binding.noteCamera-> {
takePhoto()
}
}
}
override fun onBackPressed(): Boolean {
findNavController().navigateUp()
return true
}
}

View File

@@ -0,0 +1,391 @@
package com.navinfo.omqs.ui.fragment.note
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.PopupWindow
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.entity.AttachmentBean
import com.navinfo.collect.library.data.entity.NoteBean
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ChatMsgEntity
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.util.DateTimeUtil
import com.navinfo.omqs.util.SoundMeter
import com.navinfo.omqs.util.SpeakMode
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
import io.realm.RealmList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream
import java.util.ArrayList
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class NoteViewModel @Inject constructor(
private val mapController: NIMapController,
private val realmOperateHelper: RealmOperateHelper
) : ViewModel() {
lateinit var canvasView: CanvasView
/**
* 要保存的评测数据
*/
val liveDataNoteBean = MutableLiveData(NoteBean(id = UUID.randomUUID().toString()))
/**
* 语音列表
*/
val listDataChatMsgEntityList = MutableLiveData<MutableList<ChatMsgEntity>>()
/**
* 照片列表
*/
val liveDataPictureList = MutableLiveData<MutableList<String>>()
var isEraser = false
var noteBeanDescription = ""
//语音窗体
private var pop: PopupWindow? = null
private var mSpeakMode: SpeakMode? = null
var oldBean: NoteBean? = null
//录音图标
var volume: ImageView? = null
var mSoundMeter: SoundMeter? = null
/**
* toast信息
*/
val liveDataToastMessage = MutableLiveData<String>()
/**
* 处理结束关闭fragment
*/
val liveDataFinish = MutableLiveData(false)
/**
* 通知页面画布初始化完成
*/
val liveDataCanvasViewInitFinished = MutableLiveData(false)
fun initCanvasView(canvasView: CanvasView) {
this.canvasView = canvasView
liveDataCanvasViewInitFinished.value = true
}
/**
* 通知橡皮擦开关
*/
fun onEraser() {
isEraser = !isEraser
canvasView.setEraser(isEraser)
// liveEraserData.value = !liveEraserData.value!!
}
/**
* 通知清除
*/
fun onClear() {
canvasView.removeAllPaint()
// liveClearData.value = true
}
/**
* 通知回退
*/
fun onBack() {
canvasView.back()
// liveBackData.value = true
}
/**
* 通知撤销回退
*/
fun onForward() {
canvasView.forward()
// liveForward.value = true
}
/**
* 保存数据
*/
fun onSaveData() {
viewModelScope.launch(Dispatchers.IO) {
if (canvasView.paths != null && canvasView.paths!!.isNotEmpty()) {
var noteBean = CanvasViewHelper.createNoteBean(mapController, canvasView.paths!!)
liveDataNoteBean.value!!.taskId = MapParamUtils.getTaskId()
liveDataNoteBean.value!!.list = noteBean.list
liveDataNoteBean.value!!.description = noteBeanDescription
liveDataNoteBean.value!!.guideGeometry = noteBean.guideGeometry
val realm = realmOperateHelper.getRealmDefaultInstance()
realm.executeTransaction {
it.copyToRealmOrUpdate(liveDataNoteBean.value)
}
mapController.markerHandle.addOrUpdateNoteMark(liveDataNoteBean.value!!)
liveDataFinish.postValue(true)
realm.refresh()
realm.close()
}else{
liveDataToastMessage.postValue("请绘制内容!")
}
}
}
/**
* 删除数据
*/
fun deleteData(context: Context) {
if (liveDataNoteBean.value == null) {
liveDataFinish.postValue(true)
return
} else {
val mDialog = FirstDialog(context)
mDialog.setTitle("提示?")
mDialog.setMessage("是否删除标签,请确认!")
mDialog.setPositiveButton(
"确定"
) { dialog, _ ->
dialog.dismiss()
viewModelScope.launch(Dispatchers.IO) {
val realm = realmOperateHelper.getRealmDefaultInstance()
realm.executeTransaction {
val objects = it.where(NoteBean::class.java)
.equalTo("id", liveDataNoteBean.value!!.id).findFirst()
objects?.deleteFromRealm()
}
mapController.markerHandle.removeNoteMark(liveDataNoteBean.value!!)
liveDataFinish.postValue(true)
realm.close()
}
}
mDialog.setNegativeButton("取消", null)
mDialog.show()
}
}
/**
* 初始化数据
*/
@RequiresApi(Build.VERSION_CODES.N)
fun initData(id: String) {
viewModelScope.launch(Dispatchers.IO) {
val realm = realmOperateHelper.getRealmDefaultInstance()
realm.executeTransaction { it ->
val objects = it.where(NoteBean::class.java)
.equalTo("id", id).findFirst()
if(objects!=null){
oldBean = realm.copyFromRealm(objects)
oldBean?.let {
noteBeanDescription = it.description
liveDataNoteBean.postValue(it.copy())
val list = CanvasViewHelper.createDrawPaths(mapController, it)
canvasView.setDrawPathList(list)
liveDataNoteBean.value?.attachmentBeanList = it.attachmentBeanList
}
}
}
// 显示语音数据到界面
getChatMsgEntityList()
realm.close()
}
}
fun startSoundMetter(activity: Activity, v: View) {
if (mSpeakMode == null) {
mSpeakMode = SpeakMode(activity)
}
//语音识别动画
if (pop == null) {
pop = PopupWindow()
pop!!.width = ViewGroup.LayoutParams.MATCH_PARENT
pop!!.height = ViewGroup.LayoutParams.WRAP_CONTENT
pop!!.setBackgroundDrawable(BitmapDrawable())
val view =
View.inflate(activity as Context, R.layout.cv_card_voice_rcd_hint_window, null)
pop!!.contentView = view
volume = view.findViewById(R.id.volume)
}
pop!!.update()
Constant.IS_VIDEO_SPEED = true
//录音动画
if (pop != null) {
pop!!.showAtLocation(v, Gravity.CENTER, 0, 0)
}
volume!!.setBackgroundResource(R.drawable.pop_voice_img)
val animation = volume!!.background as AnimationDrawable
animation.start()
val name: String = DateTimeUtil.getTimeSSS().toString() + ".m4a"
if (mSoundMeter == null) {
mSoundMeter = SoundMeter()
}
mSoundMeter!!.setmListener(object : SoundMeter.OnSoundMeterListener {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onSuccess(filePath: String?) {
filePath?.let {
val file = File(it)
if (file.exists() && file.length() < 1600) {
ToastUtils.showLong("语音时间太短,无效!")
mSpeakMode!!.speakText("语音时间太短,无效")
stopSoundMeter()
return
}
}
mSpeakMode!!.speakText("结束录音")
addChatMsgEntity(filePath!!)
}
@RequiresApi(api = Build.VERSION_CODES.Q)
override fun onfaild(message: String?) {
ToastUtils.showLong("录制失败!")
mSpeakMode!!.speakText("录制失败")
stopSoundMeter()
}
})
mSoundMeter!!.start(Constant.USER_DATA_ATTACHEMNT_PATH + name)
ToastUtils.showLong("开始录音")
mSpeakMode!!.speakText("开始录音")
}
//停止语音录制
@RequiresApi(api = Build.VERSION_CODES.Q)
fun stopSoundMeter() {
//先重置标识,防止按钮抬起时触发语音结束
Constant.IS_VIDEO_SPEED = false
if (mSoundMeter != null && mSoundMeter!!.isStartSound) {
mSoundMeter!!.stop()
}
pop?.let {
if (it.isShowing) {
it.dismiss()
}
}
}
fun savePhoto(bitmap: Bitmap) {
viewModelScope.launch(Dispatchers.IO) {
// 创建一个名为 "MyApp" 的文件夹
val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH)
if (!myAppDir.exists()) myAppDir.mkdirs() // 确保文件夹已创建
// 创建一个名为 fileName 的文件
val file = File(myAppDir, "${UUID.randomUUID()}.png")
file.createNewFile() // 创建文件
// 将 Bitmap 压缩为 JPEG 格式,并将其写入文件中
val out = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
out.flush()
out.close()
val picList = mutableListOf<String>()
if (liveDataPictureList.value == null) {
picList.add(file.name)
} else {
picList.addAll(liveDataPictureList.value!!)
picList.add(file.name)
}
var attachmentList: RealmList<AttachmentBean> = RealmList()
//赋值处理
if (liveDataNoteBean.value?.attachmentBeanList?.isEmpty() == false) {
attachmentList = liveDataNoteBean.value?.attachmentBeanList!!
}
val attachmentBean = AttachmentBean()
attachmentBean.name = file.name!!
attachmentBean.type = 2
attachmentList.add(attachmentBean)
liveDataNoteBean.value?.attachmentBeanList = attachmentList
liveDataPictureList.postValue(picList)
}
}
/**
* 多媒体列表
*/
private suspend fun getChatMsgEntityList() {
val chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
val pictureList: MutableList<String> = ArrayList()
liveDataNoteBean.value?.attachmentBeanList?.forEach {
//1 录音
if (it.type == 1) {
val chatMsgEntity = ChatMsgEntity()
chatMsgEntity.name = it.name
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
chatMsgEntityList.add(chatMsgEntity)
}else if(it.type==2){
pictureList.add(it.name)
}
}
listDataChatMsgEntityList.postValue(chatMsgEntityList)
liveDataPictureList.postValue(pictureList)
}
fun addChatMsgEntity(filePath: String) {
if (filePath.isNotEmpty()) {
var chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
if (listDataChatMsgEntityList.value?.isEmpty() == false) {
chatMsgEntityList = listDataChatMsgEntityList.value!!
}
val chatMsgEntity = ChatMsgEntity()
chatMsgEntity.name = filePath.replace(Constant.USER_DATA_ATTACHEMNT_PATH, "").toString()
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
chatMsgEntityList.add(chatMsgEntity)
var attachmentList: RealmList<AttachmentBean> = RealmList()
//赋值处理
if (liveDataNoteBean.value?.attachmentBeanList?.isEmpty() == false) {
attachmentList = liveDataNoteBean.value?.attachmentBeanList!!
}
val attachmentBean = AttachmentBean()
attachmentBean.name = chatMsgEntity.name!!
attachmentBean.type = 1
attachmentList.add(attachmentBean)
liveDataNoteBean.value?.attachmentBeanList = attachmentList
listDataChatMsgEntityList.postValue(chatMsgEntityList)
}
}
}

View File

@@ -5,6 +5,7 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Observer
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding
@@ -14,6 +15,7 @@ import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
import com.navinfo.omqs.ui.other.OnLifecycleStateListener
import javax.inject.Inject
/**
@@ -34,15 +36,12 @@ class OfflineMapCityListAdapter(
val cityBean = data[it.tag as Int]
when (cityBean.status) {
FileDownloadStatus.NONE, FileDownloadStatus.UPDATE, FileDownloadStatus.PAUSE, FileDownloadStatus.ERROR -> {
Log.e("jingo", "开始下载 ${cityBean.status}")
downloadManager.start(cityBean.id)
}
FileDownloadStatus.LOADING, FileDownloadStatus.WAITING -> {
Log.e("jingo", "暂停 ${cityBean.status}")
downloadManager.pause(cityBean.id)
}
else -> {
Log.e("jingo", "暂停 ${cityBean.status}")
}
}
}
@@ -71,7 +70,26 @@ class OfflineMapCityListAdapter(
changeViews(binding, cityBean)
downloadManager.addTask(cityBean)
downloadManager.observer(cityBean.id, holder, DownloadObserver(cityBean.id, holder))
holder.addObserver(object : OnLifecycleStateListener {
override fun onState(tag: String, state: Lifecycle.State) {
when (state) {
Lifecycle.State.STARTED -> {
downloadManager.observer(
cityBean.id,
holder,
DownloadObserver(cityBean.id, holder)
)
}
Lifecycle.State.DESTROYED -> {
downloadManager.removeObserver(cityBean.id)
}
else -> {}
}
}
})
binding.offlineMapDownloadBtn.tag = position
binding.offlineMapDownloadBtn.setOnClickListener(downloadBtnClick)
binding.offlineMapCityName.text = cityBean.name
@@ -85,7 +103,6 @@ class OfflineMapCityListAdapter(
if (id == holder.tag) {
val binding: AdapterOfflineMapCityBinding =
holder.viewBinding as AdapterOfflineMapCityBinding
Log.e("jingo", "进度条更新 $id ${bean.id} ${holder.tag} ")
changeViews(binding, bean)
}
}
@@ -95,7 +112,6 @@ class OfflineMapCityListAdapter(
private fun changeViews(binding: AdapterOfflineMapCityBinding, cityBean: OfflineMapCityBean) {
Log.e("jingo", "changeViews ${cityBean.status}")
binding.offlineMapProgress.progress =
(cityBean.currentSize * 100 / cityBean.fileSize).toInt()
when (cityBean.status) {
@@ -136,10 +152,6 @@ class OfflineMapCityListAdapter(
}
}
}
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_offline_map_city
}
}

View File

@@ -51,6 +51,23 @@ class OfflineMapCityListFragment : Fragment() {
viewModel.cityListLiveData.observe(viewLifecycleOwner) {
adapter.refreshData(it)
}
}
override fun onStart() {
super.onStart()
}
override fun onStop() {
super.onStop()
}
override fun onPause() {
super.onPause()
}
override fun onResume() {
super.onResume()
viewModel.getCityList()
}

View File

@@ -13,7 +13,8 @@ import com.navinfo.omqs.ui.fragment.BaseFragment
/**
* 离线地图总页面
*/
class OfflineMapFragment : BaseFragment() {
class OfflineMapFragment(private var backListener: (() -> Unit?)? = null) :
BaseFragment() {
private var _binding: FragmentOfflineMapBinding? = null
@@ -48,7 +49,7 @@ class OfflineMapFragment : BaseFragment() {
//处理返回按钮
binding.offlineMapBack.setOnClickListener {
findNavController().popBackStack()
backListener?.invoke()
}
}

View File

@@ -54,6 +54,18 @@ class OfflineMapStateListFragment : Fragment() {
}
}
override fun onStart() {
super.onStart()
}
override fun onStop() {
super.onStop()
}
override fun onPause() {
super.onPause()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null

View File

@@ -29,12 +29,7 @@ class OfflineMapStateListViewModel @Inject constructor(
fun getCityList() {
viewModelScope.launch(Dispatchers.IO) {
val list = roomDatabase.getOfflineMapDao().getOfflineMapListWithOutNone()
if (cityListLiveData.value != null) {
if (cityListLiveData.value!!.size != list.size)
cityListLiveData.postValue(list)
}else{
cityListLiveData.postValue(list)
}
cityListLiveData.postValue(list)
}
}
}

View File

@@ -1,40 +1,63 @@
package com.navinfo.omqs.ui.fragment.personalcenter
import android.Manifest
import android.app.TimePickerDialog
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TimePicker
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.view.forEach
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.blankj.utilcode.util.UriUtils
import com.github.k1rakishou.fsaf.FileChooser
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.github.k1rakishou.fsaf.callback.FileChooserCallback
import com.google.android.material.internal.NavigationMenuItemView
import com.google.android.material.timepicker.MaterialTimePicker
import com.navinfo.collect.library.enums.DataLayerEnum
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
import com.navinfo.omqs.tools.CoroutineUtils
import com.navinfo.omqs.ui.activity.map.MainViewModel
import com.navinfo.omqs.ui.activity.scan.QrCodeActivity
import com.navinfo.omqs.ui.dialog.OnTimeDialogListener
import com.navinfo.omqs.ui.dialog.TimeDialog
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.permissionx.guolindev.PermissionX
import dagger.hilt.android.AndroidEntryPoint
import org.oscim.core.GeoPoint
import org.oscim.core.MapPosition
import org.oscim.utils.MinHeap.Item
import javax.inject.Inject
/**
* 个人中心
*/
@AndroidEntryPoint
class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks {
class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit?)? = null) :
BaseFragment(),
FSAFActivityCallbacks {
private var _binding: FragmentPersonalCenterBinding? = null
private val binding get() = _binding!!
private val fileChooser by lazy { FileChooser(requireContext()) }
private val viewModel by lazy { viewModels<PersonalCenterViewModel>().value }
private val viewMainModel by activityViewModels<MainViewModel>()
@Inject
lateinit var importOMDBHiltFactory: ImportOMDBHiltFactory
@@ -53,33 +76,36 @@ class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.root.setNavigationItemSelectedListener {
binding.root.setNavigationItemSelectedListener { it ->
when (it.itemId) {
R.id.personal_center_menu_offline_map ->
findNavController().navigate(R.id.OfflineMapFragment)
R.id.personal_center_menu_obtain_data -> { // 生成数据根据sqlite文件生成对应的zip文件
fileChooser.openChooseFileDialog(object : FileChooserCallback() {
override fun onCancel(reason: String) {
}
override fun onResult(uri: Uri) {
val file = UriUtils.uri2File(uri)
// 开始导入数据
// 656e6372797000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
CoroutineUtils.launchWithLoading(
requireContext(),
loadingMessage = "生成数据..."
) {
val importOMDBHelper: ImportOMDBHelper =
importOMDBHiltFactory.obtainImportOMDBHelper(
requireContext(),
file
)
viewModel.obtainOMDBZipData(importOMDBHelper)
}
}
})
}
// R.id.personal_center_menu_obtain_data -> { // 生成数据根据sqlite文件生成对应的zip文件
// fileChooser.openChooseFileDialog(object : FileChooserCallback() {
// override fun onCancel(reason: String) {
// }
//
// @RequiresApi(Build.VERSION_CODES.N)
// override fun onResult(uri: Uri) {
// val file = UriUtils.uri2File(uri)
// // 开始导入数据
// // 656e6372797000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// CoroutineUtils.launchWithLoading(
// requireContext(),
// loadingMessage = "生成数据..."
// ) {
// val importOMDBHelper: ImportOMDBHelper =
// importOMDBHiltFactory.obtainImportOMDBHelper(
// requireContext(),
// file
// )
// viewModel.obtainOMDBZipData(importOMDBHelper)
// }
// }
// })
// }
R.id.personal_center_menu_import_data -> { // 导入zip数据
fileChooser.openChooseFileDialog(object : FileChooserCallback() {
override fun onCancel(reason: String) {
@@ -96,6 +122,7 @@ class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks {
}
})
}
R.id.personal_center_menu_import_yuan_data -> {
// 用户选中导入数据,打开文件选择器,用户选择导入的数据文件目录
fileChooser.openChooseFileDialog(object : FileChooserCallback() {
@@ -107,30 +134,158 @@ class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks {
}
})
}
R.id.personal_center_menu_open_auto_location -> {
Constant.AUTO_LOCATION = !Constant.AUTO_LOCATION
if (Constant.AUTO_LOCATION) {
it.title = "关闭自动定位"
viewMainModel.startAutoLocationTimer()
} else {
it.title = "开启10S自动定位"
viewMainModel.cancelAutoLocation()
}
}
R.id.personal_center_menu_rotate_over_look -> {
niMapController.mMapView.vtmMap.eventLayer.enableTilt(Constant.MapRotateEnable)
niMapController.mMapView.vtmMap.eventLayer.enableRotation(Constant.MapRotateEnable)
Constant.MapRotateEnable = !Constant.MapRotateEnable
if (Constant.MapRotateEnable) {
val mapPosition: MapPosition =
niMapController.mMapView.vtmMap.getMapPosition()
mapPosition.setBearing(0f) // 锁定角度,自动将地图旋转到正北方向
niMapController.mMapView.vtmMap.mapPosition = mapPosition
it.title = "开启地图旋转及视角"
} else {
it.title = "锁定地图旋转及视角"
}
}
R.id.personal_center_menu_marker -> {
niMapController.mMapView.vtmMap.eventLayer.enableTilt(Constant.MapRotateEnable)
Constant.MapMarkerCloseEnable = !Constant.MapMarkerCloseEnable
//增加开关控制
niMapController.markerHandle.setQsRecordMarkEnable(!Constant.MapMarkerCloseEnable)
if (Constant.MapMarkerCloseEnable) {
it.title = "显示Marker"
} else {
it.title = "隐藏Marker"
}
}
R.id.personal_center_menu_trace -> {
Constant.MapTraceCloseEnable = !Constant.MapTraceCloseEnable
//增加开关控制
niMapController.markerHandle.setTraceMarkEnable(!Constant.MapTraceCloseEnable)
//增加开关控制
if (Constant.MapTraceCloseEnable) {
it.title = "显示轨迹"
} else {
it.title = "隐藏轨迹"
}
}
R.id.personal_center_menu_catch_all -> {
Constant.CATCH_ALL = !Constant.CATCH_ALL
if (Constant.CATCH_ALL) {
it.title = "关闭全要素捕捉"
} else {
it.title = "开启全要素捕捉"
}
}
R.id.personal_center_menu_test -> {
viewModel.readRealmData()
//116.25017070328308 40.061730653134696
// 定位到指定位置
niMapController.mMapView.vtmMap.animator()
.animateTo(GeoPoint(40.1012346774074730, 116.25571303257621))
// .animateTo(GeoPoint( 40.05108004733645, 116.29187746293708 ))
.animateTo(GeoPoint(39.88707004725549, 116.16390557370013))
}
R.id.personal_center_menu_task_list -> {
findNavController().navigate(R.id.TaskManagerFragment)
R.id.personal_center_menu_open_all_layer -> {
MapParamUtils.setDataLayerEnum(DataLayerEnum.SHOW_ALL_LAYERS)
niMapController.layerManagerHandler.updateOMDBVectorTileLayer()
viewModel.realmOperateHelper.updateRealmDefaultInstance()
}
R.id.personal_center_menu_qs_record_list -> {
findNavController().navigate(R.id.QsRecordListFragment)
R.id.personal_center_menu_close_hide_layer -> {
MapParamUtils.setDataLayerEnum(DataLayerEnum.ONLY_ENABLE_LAYERS)
niMapController.layerManagerHandler.updateOMDBVectorTileLayer()
viewModel.realmOperateHelper.updateRealmDefaultInstance()
}
R.id.personal_center_menu_layer_manager -> { // 图层管理
findNavController().navigate(R.id.QsLayerManagerFragment)
R.id.personal_center_menu_scan_qr_code -> {
//跳转二维码扫描界面
checkPermission()
}
R.id.personal_center_menu_scan_indoor_data -> {
indoorDataListener?.invoke(true)
}
//导航定位测试
R.id.personal_center_menu_location_test -> {
viewMainModel.stopNaviLocationTest()
val dialog = TimeDialog(
requireContext(),
object : OnTimeDialogListener {
override fun selectTime(milliseconds: Long) {
viewMainModel.setNaviLocationTestStartTime(milliseconds)
}
}
)
dialog.show()
}
}
true
}
viewModel.liveDataMessage.observe(viewLifecycleOwner) {
ToastUtils.showShort(it)
}
fileChooser.setCallbacks(this@PersonalCenterFragment)
binding.root.menu.forEach {
when (it.itemId) {
R.id.personal_center_menu_open_auto_location -> {
if (Constant.AUTO_LOCATION) {
it.title = "关闭自动定位"
} else {
it.title = "开启10S自动定位"
}
}
R.id.personal_center_menu_rotate_over_look -> {
if (Constant.MapRotateEnable) {
it.title = "开启地图旋转及视角"
} else {
it.title = "锁定地图旋转及视角"
}
}
R.id.personal_center_menu_catch_all -> {
if (Constant.CATCH_ALL) {
it.title = "关闭全要素捕捉"
} else {
it.title = "开启全要素捕捉"
}
}
R.id.personal_center_menu_marker -> {
if (Constant.MapMarkerCloseEnable) {
it.title = "显示Marker"
} else {
it.title = "隐藏Marker"
}
}
R.id.personal_center_menu_trace -> {
if (Constant.MapTraceCloseEnable) {
it.title = "显示轨迹"
} else {
it.title = "隐藏轨迹"
}
}
}
}
}
private fun intentTOQRCode() {
val intent = Intent(context, QrCodeActivity::class.java);
startActivity(intent)
}
override fun onDestroyView() {
@@ -146,4 +301,18 @@ class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks {
super.onActivityResult(requestCode, resultCode, data)
fileChooser.onActivityResult(requestCode, resultCode, data)
}
private fun checkPermission() {
PermissionX.init(this)
.permissions(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
.request { allGranted, _, deniedList ->
if (allGranted) {
//所有权限已经授权
Toast.makeText(context, "授权成功", Toast.LENGTH_LONG).show()
intentTOQRCode()
} else {
Toast.makeText(context, "拒绝权限: $deniedList", Toast.LENGTH_LONG).show()
}
}
}
}

View File

@@ -2,32 +2,24 @@ package com.navinfo.omqs.ui.fragment.personalcenter
import android.net.Uri
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.FileIOUtils
import com.blankj.utilcode.util.UriUtils
import com.blankj.utilcode.util.ZipUtils
import com.google.gson.Gson
import com.navinfo.collect.library.data.entity.*
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
import com.navinfo.omqs.bean.ScWarningCodeBean
import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.db.MultiPathsCallback
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.tools.MetadataUtils
import com.navinfo.omqs.tools.MetadataUtils.Companion.ScProblemTypeTitle
import com.navinfo.omqs.tools.MetadataUtils.Companion.ScRootCauseAnalysisTitle
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.apache.commons.io.input.BOMInputStream
import java.io.*
import java.nio.charset.Charset
import java.text.Normalizer
import java.util.*
import javax.inject.Inject
@@ -40,135 +32,158 @@ class PersonalCenterViewModel @Inject constructor(
val liveDataMessage = MutableLiveData<String>()
/**
* 导入OMDB数据
* */
suspend fun obtainOMDBZipData(importOMDBHelper: ImportOMDBHelper) {
Log.d("OMQSApplication", "开始生成数据")
// Realm.getDefaultInstance().beginTransaction()
val gson = Gson()
val hadLinkFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_LINK.txt")
val hadLinkKindFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_LINK_KIND.txt")
val hadLinkDirectFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_LINK_DIRECT.txt")
val hadSpeedLimitFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_SPEEDLIMIT.txt")
val hadSpeedLimitCondFile =
File(importOMDBHelper.omdbFile.parentFile, "HAD_SPEEDLIMIT_COND.txt")
val hadSpeedLimitVarFile =
File(importOMDBHelper.omdbFile.parentFile, "HAD_SPEEDLIMIT_VAR.txt")
for (tableName in listOf<String>(
"HAD_LINK", "HAD_SPEEDLIMIT", "HAD_SPEEDLIMIT_COND", "HAD_SPEEDLIMIT_VAR"
)/*listOf<String>("HAD_LINK")*/) {
importOMDBHelper.getOMDBTableData(tableName).collect {
for (map in it) {
if ("HAD_LINK" == tableName) {
// 根据HAD_Link生成json文件
val hadLink = HAD_LINK()
hadLink.LINK_PID = map["LINK_PID"].toString()
hadLink.MESH = map["MESH"].toString()
hadLink.S_NODE_PID = map["S_NODE_PID"].toString()
hadLink.E_NODE_PID = map["E_NODE_PID"].toString()
hadLink.GEOMETRY = map["GEOMETRY"].toString()
// 将该数据写入到对应的txt文件
FileIOUtils.writeFileFromString(
hadLinkFile, gson.toJson(hadLink) + "\r", true
)
val hadLinkDirect = HAD_LINK_DIRECT()
hadLinkDirect.LINK_PID = map["LINK_PID"].toString()
hadLinkDirect.MESH = map["MESH"].toString()
hadLinkDirect.DIRECT = map["DIRECT"].toString().toInt()
hadLinkDirect.GEOMETRY = map["GEOMETRY"].toString()
// 将该数据写入到对应的txt文件
FileIOUtils.writeFileFromString(
hadLinkDirectFile, gson.toJson(hadLinkDirect) + "\r", true
)
val hadLinkKind = HAD_LINK_KIND()
hadLinkKind.LINK_PID = map["LINK_PID"].toString()
hadLinkKind.MESH = map["MESH"].toString()
hadLinkKind.KIND = map["KIND"].toString().toInt()
hadLinkKind.GEOMETRY = map["GEOMETRY"].toString()
// 将该数据写入到对应的txt文件
FileIOUtils.writeFileFromString(
hadLinkKindFile, gson.toJson(hadLinkKind) + "\r", true
)
} else if ("HAD_SPEEDLIMIT" == tableName) {
val hadSpeedlimit = HAD_SPEEDLIMIT()
hadSpeedlimit.SPEED_ID = map["SPEED_ID"].toString()
hadSpeedlimit.MESH = map["MESH"].toString()
hadSpeedlimit.LINK_PID = map["LINK_PID"].toString()
hadSpeedlimit.GEOMETRY = map["GEOMETRY"].toString()
hadSpeedlimit.DIRECT = map["DIRECT"].toString().toInt()
hadSpeedlimit.SPEED_FLAG = map["SPEED_FLAG"].toString().toInt()
hadSpeedlimit.MAX_SPEED = map["MAX_SPEED"].toString().toInt()
hadSpeedlimit.MIN_SPEED = map["MIN_SPEED"].toString().toInt()
// 将该数据写入到对应的txt文件
FileIOUtils.writeFileFromString(
hadSpeedLimitFile, gson.toJson(hadSpeedlimit) + "\r", true
)
} else if ("HAD_SPEEDLIMIT_COND" == tableName) {
val hadSpeedlimitCond = HAD_SPEEDLIMIT_COND()
hadSpeedlimitCond.SPEED_COND_ID = map["SPEED_COND_ID"].toString()
hadSpeedlimitCond.MESH = map["MESH"].toString()
hadSpeedlimitCond.LINK_PID = map["LINK_PID"].toString()
hadSpeedlimitCond.GEOMETRY = map["GEOMETRY"].toString()
hadSpeedlimitCond.DIRECT = map["DIRECT"].toString().toInt()
hadSpeedlimitCond.SPEED_FLAG = map["SPEED_FLAG"].toString().toInt()
hadSpeedlimitCond.MAX_SPEED = map["MAX_SPEED"].toString().toInt()
hadSpeedlimitCond.SPEED_DEPENDENT =
map["SPEED_DEPENDENT"].toString().toInt()
hadSpeedlimitCond.VEHICLE_TYPE = map["VEHICLE_TYPE"].toString().toInt()
hadSpeedlimitCond.VALID_PERIOD = map["VALID_PERIOD"].toString()
// 将该数据写入到对应的txt文件
FileIOUtils.writeFileFromString(
hadSpeedLimitCondFile, gson.toJson(hadSpeedlimitCond) + "\r", true
)
} else if ("HAD_SPEEDLIMIT_VAR" == tableName) {
val hadSpeedlimitVar = HAD_SPEEDLIMIT_VAR()
hadSpeedlimitVar.SPEED_VAR_ID = map["SPEED_ID"].toString()
hadSpeedlimitVar.MESH = map["MESH"].toString()
hadSpeedlimitVar.LINK_PID = map["LINK_PID"].toString()
hadSpeedlimitVar.GEOMETRY = map["GEOMETRY"].toString()
hadSpeedlimitVar.DIRECT = map["DIRECT"].toString().toInt()
hadSpeedlimitVar.LOCATION = map["LOCATION"].toString()
// 将该数据写入到对应的txt文件
FileIOUtils.writeFileFromString(
hadSpeedLimitVarFile, gson.toJson(hadSpeedlimitVar) + "\r", true
)
}
// val properties = RealmDictionary<String?>()
// for (entry in map.entries) {
// properties.putIfAbsent(entry.key, entry.value.toString())
// /**
// * 导入OMDB数据
// * */
// @RequiresApi(Build.VERSION_CODES.N)
// suspend fun obtainOMDBZipData(importOMDBHelper: ImportOMDBHelper) {
// Log.d("OMQSApplication", "开始生成数据")
// val gson = Gson()
// val hadLinkFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_LINK.txt")
// val hadLinkKindFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_LINK_KIND.txt")
// val hadLinkDirectFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_LINK_DIRECT.txt")
// val hadSpeedLimitFile = File(importOMDBHelper.omdbFile.parentFile, "HAD_SPEEDLIMIT.txt")
// val hadSpeedLimitCondFile =
// File(importOMDBHelper.omdbFile.parentFile, "HAD_SPEEDLIMIT_COND.txt")
// val hadSpeedLimitVarFile =
// File(importOMDBHelper.omdbFile.parentFile, "HAD_SPEEDLIMIT_VAR.txt")
//
// for (tableName in listOf<String>(
// "HAD_LINK", "HAD_SPEEDLIMIT", "HAD_SPEEDLIMIT_COND", "HAD_SPEEDLIMIT_VAR"
// )/*listOf<String>("HAD_LINK")*/) {
// importOMDBHelper.getOMDBTableData(tableName).collect {
// for (map in it) {
// if ("HAD_LINK" == tableName) {
// // 根据HAD_Link生成json文件
// val hadLink = HAD_LINK()
// hadLink.LINK_PID = map["LINK_PID"].toString()
// hadLink.MESH = map["MESH"].toString()
// hadLink.S_NODE_PID = map["S_NODE_PID"].toString()
// hadLink.E_NODE_PID = map["E_NODE_PID"].toString()
// hadLink.GEOMETRY = map["GEOMETRY"].toString()
// // 将该数据写入到对应的txt文件
// FileIOUtils.writeFileFromString(
// hadLinkFile, gson.toJson(hadLink) + "\r", true
// )
//
// val hadLinkDirect = HAD_LINK_DIRECT()
// hadLinkDirect.LINK_PID = map["LINK_PID"].toString()
// hadLinkDirect.MESH = map["MESH"].toString()
// hadLinkDirect.DIRECT = map["DIRECT"].toString().toInt()
// hadLinkDirect.GEOMETRY = map["GEOMETRY"].toString()
// // 将该数据写入到对应的txt文件
// FileIOUtils.writeFileFromString(
// hadLinkDirectFile, gson.toJson(hadLinkDirect) + "\r", true
// )
//
// val hadLinkKind = HAD_LINK_KIND()
// hadLinkKind.LINK_PID = map["LINK_PID"].toString()
// hadLinkKind.MESH = map["MESH"].toString()
// hadLinkKind.KIND = map["KIND"].toString().toInt()
// hadLinkKind.GEOMETRY = map["GEOMETRY"].toString()
// // 将该数据写入到对应的txt文件
// FileIOUtils.writeFileFromString(
// hadLinkKindFile, gson.toJson(hadLinkKind) + "\r", true
// )
// } else if ("HAD_SPEEDLIMIT" == tableName) {
// val hadSpeedlimit = HAD_SPEEDLIMIT()
// hadSpeedlimit.SPEED_ID = map["SPEED_ID"].toString()
// hadSpeedlimit.MESH = map["MESH"].toString()
// hadSpeedlimit.LINK_PID = map["LINK_PID"].toString()
// hadSpeedlimit.GEOMETRY = map["GEOMETRY"].toString()
// hadSpeedlimit.DIRECT = map["DIRECT"].toString().toInt()
// hadSpeedlimit.SPEED_FLAG = map["SPEED_FLAG"].toString().toInt()
// hadSpeedlimit.MAX_SPEED = map["MAX_SPEED"].toString().toInt()
// hadSpeedlimit.MIN_SPEED = map["MIN_SPEED"].toString().toInt()
// // 将该数据写入到对应的txt文件
// FileIOUtils.writeFileFromString(
// hadSpeedLimitFile, gson.toJson(hadSpeedlimit) + "\r", true
// )
// } else if ("HAD_SPEEDLIMIT_COND" == tableName) {
// val hadSpeedlimitCond = HAD_SPEEDLIMIT_COND()
// hadSpeedlimitCond.SPEED_COND_ID = map["SPEED_COND_ID"].toString()
// hadSpeedlimitCond.MESH = map["MESH"].toString()
// hadSpeedlimitCond.LINK_PID = map["LINK_PID"].toString()
// hadSpeedlimitCond.GEOMETRY = map["GEOMETRY"].toString()
// hadSpeedlimitCond.DIRECT = map["DIRECT"].toString().toInt()
// hadSpeedlimitCond.SPEED_FLAG = map["SPEED_FLAG"].toString().toInt()
// hadSpeedlimitCond.MAX_SPEED = map["MAX_SPEED"].toString().toInt()
// hadSpeedlimitCond.SPEED_DEPENDENT =
// map["SPEED_DEPENDENT"].toString().toInt()
// hadSpeedlimitCond.VEHICLE_TYPE = map["VEHICLE_TYPE"].toString().toInt()
// hadSpeedlimitCond.VALID_PERIOD = map["VALID_PERIOD"].toString()
// // 将该数据写入到对应的txt文件
// FileIOUtils.writeFileFromString(
// hadSpeedLimitCondFile, gson.toJson(hadSpeedlimitCond) + "\r", true
// )
// } else if ("HAD_SPEEDLIMIT_VAR" == tableName) {
// val hadSpeedlimitVar = HAD_SPEEDLIMIT_VAR()
// hadSpeedlimitVar.SPEED_VAR_ID = map["SPEED_ID"].toString()
// hadSpeedlimitVar.MESH = map["MESH"].toString()
// hadSpeedlimitVar.LINK_PID = map["LINK_PID"].toString()
// hadSpeedlimitVar.GEOMETRY = map["GEOMETRY"].toString()
// hadSpeedlimitVar.DIRECT = map["DIRECT"].toString().toInt()
// hadSpeedlimitVar.LOCATION = map["LOCATION"].toString()
// // 将该数据写入到对应的txt文件
// FileIOUtils.writeFileFromString(
// hadSpeedLimitVarFile, gson.toJson(hadSpeedlimitVar) + "\r", true
// )
// }
// // 将读取到的sqlite数据插入到Realm中
// Realm.getDefaultInstance().insert(OMDBEntity(tableName, properties))
}
}
}
ZipUtils.zipFiles(
mutableListOf(
hadLinkFile,
hadLinkKindFile,
hadLinkDirectFile,
hadSpeedLimitFile,
hadSpeedLimitCondFile,
hadSpeedLimitVarFile
), File(importOMDBHelper.omdbFile.parentFile, "output.zip")
)
Log.d("OMQSApplication", "生成数据完成")
}
// }
// }
// }
// ZipUtils.zipFiles(
// mutableListOf(
// hadLinkFile,
// hadLinkKindFile,
// hadLinkDirectFile,
// hadSpeedLimitFile,
// hadSpeedLimitCondFile,
// hadSpeedLimitVarFile
// ), File(importOMDBHelper.omdbFile.parentFile, "output.zip")
// )
//
// Log.d("OMQSApplication", "生成数据完成")
// }
/**
* 导入OMDB数据
* */
fun importOMDBData(importOMDBHelper: ImportOMDBHelper) {
fun importOMDBData(importOMDBHelper: ImportOMDBHelper, task: TaskBean? = null) {
viewModelScope.launch(Dispatchers.IO) {
Log.d("OMQSApplication", "开始导入数据")
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile).collect {
Log.d("importOMDBData", it)
if (task != null) {
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task, this,object :MultiPathsCallback<String>{
override fun onProgress(value: Int) {
}
override fun onResult(value: String) {
}
override fun onError(t: Throwable) {
}
override fun onComplete() {
}
})
} else {
val newTask = TaskBean()
newTask.id = -1
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, newTask, this,object :MultiPathsCallback<String>{
override fun onProgress(value: Int) {
}
override fun onResult(value: String) {
}
override fun onError(t: Throwable) {
}
override fun onComplete() {
}
})
}
Log.d("OMQSApplication", "导入数据完成")
}
@@ -194,35 +209,45 @@ class PersonalCenterViewModel @Inject constructor(
var phenomenonIndex = -1
var problemLinkIndex = -1
var problemCauseIndex = -1
var warningCodeIndex = -1
var warningDescribeIndex = -1
val list = mutableListOf<ScProblemTypeBean>()
val list2 = mutableListOf<ScRootCauseAnalysisBean>()
val list3 = mutableListOf<ScWarningCodeBean>()
while (bufferedReader.readLine()?.also { line = it } != null) { // 处理 CSV 文件中的每一行数据
val data =
line!!.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (index == 0) {
for (i in data.indices) {
when (data[i]) {
ScProblemTypeTitle.TITLE_ELEMENT_TYPE -> {
MetadataUtils.Companion.ScProblemTypeTitle.TITLE_ELEMENT_TYPE -> {
elementTypeIndex = i
}
ScProblemTypeTitle.TITLE_ELEMENT_CODE -> {
MetadataUtils.Companion.ScProblemTypeTitle.TITLE_ELEMENT_CODE -> {
elementCodeIndex = i
}
ScProblemTypeTitle.TITLE_CLASS_TYPE -> {
MetadataUtils.Companion.ScProblemTypeTitle.TITLE_CLASS_TYPE -> {
classTypeIndex = i
}
ScProblemTypeTitle.TITLE_PROBLEM_TYPE -> {
MetadataUtils.Companion.ScProblemTypeTitle.TITLE_PROBLEM_TYPE -> {
problemTypeIndex = i
}
ScProblemTypeTitle.TITLE_PHENOMENON -> {
MetadataUtils.Companion.ScProblemTypeTitle.TITLE_PHENOMENON -> {
phenomenonIndex = i
}
ScRootCauseAnalysisTitle.TITLE_PROBLEM_LINK -> {
MetadataUtils.Companion.ScRootCauseAnalysisTitle.TITLE_PROBLEM_LINK -> {
problemLinkIndex = i
}
ScRootCauseAnalysisTitle.TITLE_PROBLEM_CAUSE -> {
MetadataUtils.Companion.ScRootCauseAnalysisTitle.TITLE_PROBLEM_CAUSE -> {
problemCauseIndex = i
}
MetadataUtils.Companion.ScWarningCodeTitle.TITLE_CODE -> {
warningCodeIndex = i
}
MetadataUtils.Companion.ScWarningCodeTitle.TITLE_DESCRIBE -> {
warningDescribeIndex = i
}
}
}
} else {
@@ -246,6 +271,12 @@ class PersonalCenterViewModel @Inject constructor(
problemCause = data[problemCauseIndex],
)
list2.add(bean)
} else if (warningDescribeIndex > -1 && warningCodeIndex > -1) {
val bean = ScWarningCodeBean(
code = data[warningCodeIndex],
describe = data[warningDescribeIndex]
)
list3.add(bean)
} else {
liveDataMessage.postValue("元数据表规格不正确,请仔细核对")
break
@@ -261,49 +292,14 @@ class PersonalCenterViewModel @Inject constructor(
liveDataMessage.postValue("元数据表导入成功")
roomAppDatabase.getScRootCauseAnalysisDao().insertOrUpdateList(list2)
}
if (list3.isNotEmpty()) {
liveDataMessage.postValue("标牌对照表导入成功")
roomAppDatabase.getScWarningCodeDao().insertList(list3)
}
bufferedReader.close()
inputStreamReader.close()
inputStream.close()
// val workbook = WorkbookFactory.create(inputStream)
// //获取所有sheet
// val sheet1 = workbook.getSheet("SC_PROBLEM_TYPE")
// sheet1?.let {
// val rowCount: Int = it.physicalNumberOfRows // 获取行数
// val list = mutableListOf<ScProblemTypeBean>()
// for (i in 1 until rowCount) {
// val row: Row = it.getRow(i) // 获取行
//// val cellCount: Int = row.physicalNumberOfCells // 获取列数
// val bean = ScProblemTypeBean(
// elementType = row.getCell(0).stringCellValue,
// elementCode = row.getCell(1).numericCellValue.toString(),
// classType = row.getCell(2).stringCellValue,
// problemType = row.getCell(3).stringCellValue,
// phenomenon = row.getCell(4).stringCellValue
// )
// list.add(bean)
// Log.e("jingo", bean.toString())
// }
// roomAppDatabase.getScProblemTypeDao().insertOrUpdateList(list)
// }
// val sheet2 = workbook.getSheet("SC_ROOT_CAUSE_ANALYSIS")
// sheet2?.let {
// val rowCount: Int = it.physicalNumberOfRows // 获取行数
// val list = mutableListOf<ScRootCauseAnalysisBean>()
// for (i in 1 until rowCount) {
// val row: Row = it.getRow(i) // 获取行
// val cellCount: Int = row.physicalNumberOfCells // 获取列数
// if (cellCount == 2) {
// val bean = ScRootCauseAnalysisBean()
// bean.problemLink = row.getCell(0).stringCellValue
// bean.problemCause = row.getCell(1).stringCellValue
// list.add(bean)
// Log.e("jingo", bean.toString())
// }
// }
// roomAppDatabase.getScRootCauseAnalysisDao().insertOrUpdateList(list)
// }
// workbook.close()
} catch (e: IOException) {
e.printStackTrace()
@@ -316,7 +312,9 @@ class PersonalCenterViewModel @Inject constructor(
fun readRealmData() {
viewModelScope.launch(Dispatchers.IO) {
// val result = realmOperateHelper.queryLink(GeometryTools.createPoint(115.685817,28.62759))
val result = realmOperateHelper.queryLinkByLinkPid("84206617008217069")
val realm = realmOperateHelper.getSelectTaskRealmInstance()
val result = realmOperateHelper.queryLinkByLinkPid(realm, "84206617008217069")
realm.close()
Log.d("xiaoyan", result.toString())
}
}

View File

@@ -58,9 +58,6 @@ class QsRecordListAdapter(
binding.qsRecordTime.text = qsRecordBean.checkTime
}
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_qs_record_list
}
// 提供set方法
fun setOnKotlinItemClickListener(itemClickListener: IKotlinItemClickListener) {

View File

@@ -16,7 +16,7 @@ import com.navinfo.omqs.ui.fragment.tasklist.QsRecordListAdapter
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class QsRecordListFragment : BaseFragment(){
class QsRecordListFragment(private var backListener: (() -> Unit?)? = null) : BaseFragment() {
private var _binding: FragmentQsRecordListBinding? = null
private val viewModel by viewModels<QsRecordListViewModel>()
private val binding get() = _binding!!
@@ -44,7 +44,7 @@ class QsRecordListFragment : BaseFragment(){
binding.qsRecyclerview.adapter = adapter
viewModel.liveDataQSList.observe(viewLifecycleOwner) {
adapter.refreshData(it)
binding.tvTitleCount.text = ""+adapter.data.size+""
binding.tvTitleCount.text = "" + adapter.data.size + ""
}
val itemDecoration = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
itemDecoration.setDrawable(resources.getDrawable(R.drawable.separator))
@@ -53,13 +53,13 @@ class QsRecordListFragment : BaseFragment(){
// itemClick
adapter.setOnKotlinItemClickListener(object : QsRecordListAdapter.IKotlinItemClickListener {
override fun onItemClickListener(position: Int) {
viewModel.onItemClickListener(activity as MainActivity,position)
findNavController().popBackStack()
viewModel.onItemClickListener(activity as MainActivity, position)
backListener?.invoke()
}
})
binding.imgBack.setOnClickListener{
findNavController().navigateUp()
binding.imgBack.setOnClickListener {
backListener?.invoke()
}
}

View File

@@ -1,6 +1,7 @@
package com.navinfo.omqs.ui.fragment.qsrecordlist
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import androidx.lifecycle.MutableLiveData
@@ -9,7 +10,9 @@ import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.ui.activity.map.MainActivity
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
@@ -19,16 +22,19 @@ import javax.inject.Inject
@HiltViewModel
class QsRecordListViewModel @Inject constructor(
private val sharedPreferences: SharedPreferences,
private val realmOperateHelper: RealmOperateHelper
) : ViewModel() {
val liveDataQSList = MutableLiveData<List<QsRecordBean>>()
fun getList(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
Log.e("jingo","realm hashCOde ${realm.hashCode()}")
val objects = realm.where(QsRecordBean::class.java).findAll()
val taskId = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1)
val realm = realmOperateHelper.getRealmDefaultInstance()
val objects = realm.where(QsRecordBean::class.java).equalTo("taskId",taskId).findAll()
liveDataQSList.postValue(realm.copyFromRealm(objects))
realm.close()
}
}

View File

@@ -0,0 +1,104 @@
package com.navinfo.omqs.ui.fragment.signMoreInfo
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterLaneBoundaryBinding
import com.navinfo.omqs.databinding.AdapterTwoItemBinding
import com.navinfo.omqs.ui.other.BaseViewHolder
import com.navinfo.omqs.ui.other.anim.ExpandableViewHoldersUtil
import com.navinfo.omqs.ui.other.anim.ExpandableViewHoldersUtil.Expandable
data class LaneBoundaryItem(
val title: String, val text: String?, val itemList: MutableList<TwoItemAdapterItem>?
)
class LaneBoundaryAdapter : RecyclerView.Adapter<ViewHolder>() {
private val keepOne: ExpandableViewHoldersUtil.KeepOneH<ExpandViewHolder> =
ExpandableViewHoldersUtil.KeepOneH()
private var dataList = mutableListOf<LaneBoundaryItem>()
class ExpandViewHolder(
val viewBinding: AdapterLaneBoundaryBinding,
private val keepOne: ExpandableViewHoldersUtil.KeepOneH<ExpandViewHolder>
) : ViewHolder(viewBinding.root),
View.OnClickListener, Expandable {
init {
viewBinding.root.setOnClickListener(this)
}
fun bind(pos: Int, laneBoundaryItem: LaneBoundaryItem) {
viewBinding.contactName.text = laneBoundaryItem.title
if (laneBoundaryItem.itemList != null) {
viewBinding.infos.removeAllViews()
for (item in laneBoundaryItem.itemList) {
var view = LayoutInflater.from(viewBinding.root.context)
.inflate(R.layout.adapter_two_item, null, false)
view.findViewById<TextView>(R.id.title).text = item.title
view.findViewById<TextView>(R.id.text).text = item.text
viewBinding.infos.addView(view)
}
}
keepOne.bind(this, pos)
}
override fun onClick(v: View) {
keepOne.toggle(this,viewBinding.expandIcon)
}
override val expandView: View
get() = viewBinding.infos
}
override
fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return if (viewType == 1) {
val viewBinding = AdapterLaneBoundaryBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
ExpandViewHolder(viewBinding, keepOne)
} else {
val viewBinding =
AdapterTwoItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
BaseViewHolder(viewBinding)
}
}
override fun getItemCount(): Int {
return dataList.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (holder is ExpandViewHolder) {
holder.bind(position, dataList[position])
} else if (holder is BaseViewHolder) {
val binding: AdapterTwoItemBinding = holder.viewBinding as AdapterTwoItemBinding
val item = dataList[position]
binding.title.text = item.title
binding.text.text = item.text
}
}
override fun getItemViewType(position: Int): Int {
return if (dataList[position].itemList != null) 1
else 0
}
fun refreshData(list: List<LaneBoundaryItem>) {
dataList.clear()
dataList.addAll(list)
notifyDataSetChanged()
}
}

View File

@@ -0,0 +1,27 @@
package com.navinfo.omqs.ui.fragment.signMoreInfo
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.RoadNameBean
import com.navinfo.omqs.databinding.AdapterRoadNameBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class RoadNameInfoAdapter : BaseRecyclerViewAdapter<RoadNameBean>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterRoadNameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val binding: AdapterRoadNameBinding =
holder.viewBinding as AdapterRoadNameBinding
val bean = data[position]
binding.title.text = bean.getNameClassStr()
binding.name.text = bean.name
binding.type.text = bean.getTypeStr()
}
}

View File

@@ -0,0 +1,149 @@
package com.navinfo.omqs.ui.fragment.signMoreInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.databinding.FragmentSignInfoBinding
import com.navinfo.omqs.ui.activity.map.MainViewModel
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.util.SignUtil
class SignMoreInfoFragment : BaseFragment() {
private var _binding: FragmentSignInfoBinding? = null
private val binding get() = _binding!!
private val viewModel by activityViewModels<MainViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentSignInfoBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val layoutManager = LinearLayoutManager(context)
//// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能
binding.signInfoRecyclerview.setHasFixedSize(true)
binding.signInfoRecyclerview.layoutManager = layoutManager
viewModel.liveDataSignMoreInfo.observe(viewLifecycleOwner) {
binding.signInfoTitle.text = it.name
val drawableLeft = resources.getDrawable(R.drawable.icon_main_moreinfo_text_left, null);
val drawableRight = resources.getDrawable(R.drawable.baseline_edit_note_48, null);
drawableLeft.setBounds(
0,
0,
drawableLeft.minimumWidth,
drawableLeft.minimumHeight
)//必须设置图片大小,否则不显示
drawableRight.setBounds(
0,
0,
drawableRight.minimumWidth,
drawableRight.minimumHeight
)
binding.signInfoTitle.setCompoundDrawables(
drawableLeft, null, drawableRight, null
)
when (it.renderEntity.code) {
//道路名
DataCodeEnum.OMDB_LINK_NAME.code -> {
val adapter = RoadNameInfoAdapter()
binding.signInfoRecyclerview.adapter = adapter
adapter.refreshData(SignUtil.getRoadNameList(it.renderEntity))
}
//车道边界类型
DataCodeEnum.OMDB_LANE_MARK_BOUNDARYTYPE.code -> {
val adapter = LaneBoundaryAdapter()
binding.signInfoRecyclerview.adapter = adapter
adapter.refreshData(SignUtil.getLaneBoundaryTypeInfo(it.renderEntity))
}
DataCodeEnum.OMDB_INTERSECTION.code -> {
val adapter = LaneBoundaryAdapter()
binding.signInfoRecyclerview.adapter = adapter
adapter.refreshData(SignUtil.getIntersectionInfo(it.renderEntity))
}
//收费站
DataCodeEnum.OMDB_TOLLGATE.code -> {
val adapter = LaneBoundaryAdapter()
binding.signInfoRecyclerview.adapter = adapter
adapter.refreshData(SignUtil.getTollgateInfo(it.renderEntity))
}
//电子眼
DataCodeEnum.OMDB_ELECTRONICEYE.code -> {
val drawable = resources.getDrawable(R.drawable.icon_electronic_eye_left, null)
drawable.setBounds(
0,
0,
drawable.minimumWidth,
drawable.minimumHeight
);//必须设置图片大小,否则不显示
binding.signInfoTitle.setCompoundDrawables(
drawable, null, drawableRight, null
)
val adapter = TwoItemAdapter()
binding.signInfoRecyclerview.adapter = adapter
adapter.refreshData(SignUtil.getElectronicEyeMoreInfo(it.renderEntity))
}
//交通标牌
DataCodeEnum.OMDB_TRAFFIC_SIGN.code -> {
val adapter = TwoItemAdapter()
binding.signInfoRecyclerview.adapter = adapter
adapter.refreshData(SignUtil.getTrafficSignMoreInfo(it.renderEntity))
}
else -> {
val adapter = SignUtil.getMoreInfoAdapter(it.renderEntity)
//增加详情为空不显示业务
if(adapter==null || adapter.data.isEmpty()){
activity?.run {
supportFragmentManager.beginTransaction().remove(this@SignMoreInfoFragment)
.commit()
}
}
binding.signInfoRecyclerview.adapter = adapter
}
}
}
binding.signInfoCancel.setOnClickListener {
activity?.run {
supportFragmentManager.beginTransaction().remove(this@SignMoreInfoFragment)
.commit()
}
}
binding.signInfoTitle.setOnClickListener {
activity?.run {
val rightController = findNavController(R.id.main_activity_right_fragment)
rightController.currentDestination?.let {
if (it.id == R.id.RightEmptyFragment) {
val bundle = Bundle()
val element = viewModel.liveDataSignMoreInfo.value
if (element != null) {
bundle.putParcelable("SignBean", element)
bundle.putBoolean("AutoSave", false)
rightController.navigate(R.id.EvaluationResultFragment, bundle)
}
}
}
}
}
}
override fun onDestroyView() {
super.onDestroyView()
viewModel.clearMarker()
_binding = null
}
}

Some files were not shown because too many files have changed in this diff Show More