diff --git a/app/build.gradle b/app/build.gradle index 20f4585a..1c5fbf77 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -107,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' diff --git a/app/src/main/assets/omdb_config.json b/app/src/main/assets/omdb_config.json index 80729987..fb431a34 100644 --- a/app/src/main/assets/omdb_config.json +++ b/app/src/main/assets/omdb_config.json @@ -1,721 +1,704 @@ [ - { - "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, - "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": false, - "zoomMin": 15, - "zoomMax": 17 - }, - "2019": { - "table": "OMDB_LINK_SPEEDLIMIT", - "code": 2019, - "name": "常规线限速", - "zoomMin": 15, - "zoomMax": 17 - }, - "2020": { - "table": "OMDB_LINK_SPEEDLIMIT_COND", - "code": 2020, - "name": "条件线限速", - "zoomMin": 15, - "zoomMax": 17 - }, - "2021": { - "table": "OMDB_LINK_SPEEDLIMIT_VAR", - "code": 2021, - "name": "可变线限速", - "zoomMin": 15, - "zoomMax": 17 - }, - "2041":{ - "table": "OMDB_LANE_NUM", - "code": 2041, - "name": "车道数" - }, - "2097":{ - "table": "OMDB_PHY_LANENUM", - "code": 2097, - "name": "物理车道数" - }, - "2083":{ - "table": "OMDB_RDBOUND_BOUNDARYTYPE", - "code": 2083, - "name": "道路边界类型", - "checkLinkId": false, - "filterData": true, - "zoomMin": 18, - "zoomMax": 20, - "catch":true - }, - "2090":{ - "table": "OMDB_LANE_CONSTRUCTION", - "code": 2090, - "name": "车道施工", - "existSubCode": true, - "checkLinkId": false, - "catch":true, - "zoomMin": 18, - "zoomMax": 20 - }, - "2092":{ - "table": "OMDB_LANE_TYPE_ACCESS", - "code": 2092, - "name": "车道类型", - "catch":true, - "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, - "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()" - } - ] - }, - "2638":{ - "table": "OMDB_LANE_ACCESS", - "code": 2638, - "name": "通行车辆类型Lane", - "zoomMin": 15, - "zoomMax": 20, - "catch":true, - "filterData": false, - "checkLinkId": false, - "transformer": [ - { - "k": "geometry", - "v": "~", - "klib": "geometry", - "vlib": "generateLaneAccessType()" - } - ] - }, - "3001":{ - "table": "OMDB_OBJECT_OH_STRUCT", - "code": 3001, - "name": "上方障碍物", - "zoomMin": 15, - "zoomMax": 20, - "catch":true, - "checkLinkId": false, - "transformer": [ - { - "k": "geometry", - "v": "~", - "klib": "geometry", - "vlib": "getPolygonCenterPoint()" - } - ] - }, - "3002":{ - "table": "OMDB_OBJECT_TEXT", - "code": 3002, - "name": "文字", - "zoomMin": 18, - "zoomMax": 20, - "catch":true, - "checkLinkId": false, - "transformer": [] - }, - "3003":{ - "table": "OMDB_OBJECT_SYMBOL", - "code": 3003, - "name": "符号", - "checkLinkId": false, - "zoomMin": 18, - "zoomMax": 20, - "catch":true, - "transformer": [] - }, - "3004":{ - "table": "OMDB_OBJECT_ARROW", - "code": 3004, - "name": "箭头", - "checkLinkId": false, - "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": 18, - "zoomMax": 20, - "is3D": true, - "catch":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()" - } - ] - }, - "3012":{ - "table": "OMDB_FILL_AREA", - "code": 3012, - "name": "导流区", - "catch":true, - "checkLinkId": false, - "zoomMin": 18, - "zoomMax": 20 - }, - "3014":{ - "table": "OMDB_CROSS_WALK", - "code": 3014, - "name": "人行横道", - "catch":true, - "checkLinkId": false, - "zoomMin": 18, - "zoomMax": 20 - }, - "3016":{ - "table": "OMDB_OBJECT_STOPLOCATION", - "code": 3016, - "name": "停止位置", - "checkLinkId": false, - "filterData": true, - "zoomMin": 18, - "catch":true, - "zoomMax": 20 - }, - "3027":{ - "table": "OMDB_OBJECT_REFUGE_ISLAND", - "code": 3027, - "name": "路口内交通岛", - "catch":true, - "checkLinkId": false, - "zoomMin": 18, - "zoomMax": 20 - }, - "4001": { - "table": "OMDB_INTERSECTION", - "code": 4001, - "name": "路口", - "zoomMin": 15, - "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()" - } - ] - }, - "4003":{ - "table": "OMDB_SPEEDLIMIT_COND", - "code": 4003, - "name": "条件点限速", - "catch":true, - "zoomMin": 15, - "zoomMax": 20, - "transformer": [ - { - "k": "maxSpeed", - "v": "0|", - "klib": "maxSpeed", - "vlib": "限" - } - ] - }, - "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": "上" - } - ] - }, - "4005": { - "table": "OMDB_LANE_SPEEDLIMIT", - "code": 4005, - "name": "车道点限速", - "zoomMin": 18, - "zoomMax": 20, - "filterData": true, - "catch": true, - "transformer": [ - { - "k": "geometry", - "v": "~", - "klib": "geometry", - "vlib": "obtainLaneSpeedLimitName()" - } - ] - }, - "4006": { - "table": "OMDB_RESTRICTION", - "code": 4006, - "name": "普通交限", - "zoomMin": 15, - "zoomMax": 17, - "filterData":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, - "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": false, - "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, - "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, - "checkLinkId": false, - "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 - } - - } - } + { + "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": false, + "zoomMin": 15, + "zoomMax": 17 + }, + "2019": { + "table": "OMDB_LINK_SPEEDLIMIT", + "code": 2019, + "name": "常规线限速", + "zoomMin": 15, + "zoomMax": 17 + }, + "2020": { + "table": "OMDB_LINK_SPEEDLIMIT_COND", + "code": 2020, + "name": "条件线限速", + "zoomMin": 15, + "zoomMax": 17 + }, + "2021": { + "table": "OMDB_LINK_SPEEDLIMIT_VAR", + "code": 2021, + "name": "可变线限速", + "zoomMin": 15, + "zoomMax": 17 + }, + "2083": { + "table": "OMDB_RDBOUND_BOUNDARYTYPE", + "code": 2083, + "name": "道路边界类型", + "checkLinkId": false, + "filterData": true, + "zoomMin": 18, + "zoomMax": 20, + "catch": true + }, + "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": true, + "zoomMin": 18, + "zoomMax": 20, + "transformer": [ + { + "k": "geometry", + "v": "~", + "klib": "geometry", + "vlib": "filterLaneTypeAccess()" + }, + { + "k": "geometry", + "v": "~", + "klib": "geometry", + "vlib": "generateLaneTypeAccessS2ERefPoint()" + } + ] + }, + "2097": { + "table": "OMDB_PHY_LANENUM", + "code": 2097, + "name": "物理车道数" + }, + "2201": { + "table": "OMDB_BRIDGE", + "code": 2201, + "name": "桥", + "catch": true, + "existSubCode": true, + "isDependOnOtherTable": true, + "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()" + } + ] + }, + "2638": { + "table": "OMDB_LANE_ACCESS", + "code": 2638, + "name": "通行车辆类型Lane", + "zoomMin": 15, + "zoomMax": 20, + "catch": true, + "filterData": false, + "checkLinkId": false, + "transformer": [ + { + "k": "geometry", + "v": "~", + "klib": "geometry", + "vlib": "generateLaneAccessType()" + } + ] + }, + "3001": { + "table": "OMDB_OBJECT_OH_STRUCT", + "code": 3001, + "name": "上方障碍物", + "zoomMin": 15, + "zoomMax": 20, + "catch": true, + "checkLinkId": false, + "transformer": [ + { + "k": "geometry", + "v": "~", + "klib": "geometry", + "vlib": "getPolygonCenterPoint()" + } + ] + }, + "3002": { + "table": "OMDB_OBJECT_TEXT", + "code": 3002, + "name": "文字", + "zoomMin": 18, + "zoomMax": 20, + "catch": true, + "checkLinkId": false, + "transformer": [] + }, + "3003": { + "table": "OMDB_OBJECT_SYMBOL", + "code": 3003, + "name": "符号", + "checkLinkId": false, + "zoomMin": 18, + "zoomMax": 20, + "catch": true, + "transformer": [] + }, + "3004": { + "table": "OMDB_OBJECT_ARROW", + "code": 3004, + "name": "箭头", + "checkLinkId": false, + "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": 18, + "zoomMax": 20, + "is3D": true, + "catch": 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()" + } + ] + }, + "3012": { + "table": "OMDB_FILL_AREA", + "code": 3012, + "name": "导流区", + "catch": true, + "checkLinkId": false, + "zoomMin": 18, + "zoomMax": 20 + }, + "3014": { + "table": "OMDB_CROSS_WALK", + "code": 3014, + "name": "人行横道", + "catch": true, + "checkLinkId": false, + "zoomMin": 18, + "zoomMax": 20 + }, + "3016": { + "table": "OMDB_OBJECT_STOPLOCATION", + "code": 3016, + "name": "停止位置", + "checkLinkId": false, + "filterData": true, + "zoomMin": 18, + "catch": true, + "zoomMax": 20 + }, + "3027": { + "table": "OMDB_OBJECT_REFUGE_ISLAND", + "code": 3027, + "name": "路口内交通岛", + "catch": true, + "checkLinkId": false, + "zoomMin": 18, + "zoomMax": 20 + }, + "4001": { + "table": "OMDB_INTERSECTION", + "code": 4001, + "name": "路口", + "zoomMin": 15, + "isDependOnOtherTable": true, + "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()" + } + ] + }, + "4003": { + "table": "OMDB_SPEEDLIMIT_COND", + "code": 4003, + "name": "条件点限速", + "catch": true, + "zoomMin": 15, + "zoomMax": 20, + "transformer": [ + { + "k": "maxSpeed", + "v": "0|", + "klib": "maxSpeed", + "vlib": "限" + } + ] + }, + "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": "上" + } + ] + }, + "4005": { + "table": "OMDB_LANE_SPEEDLIMIT", + "code": 4005, + "name": "车道点限速", + "zoomMin": 18, + "zoomMax": 20, + "filterData": true, + "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": 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": "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()" + } + ] + }, + "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": 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": true, + "checkLinkId": false, + "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 + } + } + } ] \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/Constant.kt b/app/src/main/java/com/navinfo/omqs/Constant.kt index a0decc44..0ccf4148 100644 --- a/app/src/main/java/com/navinfo/omqs/Constant.kt +++ b/app/src/main/java/com/navinfo/omqs/Constant.kt @@ -40,6 +40,20 @@ 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 + /** * 当前安装任务 */ @@ -79,6 +93,11 @@ class Constant { */ lateinit var DOWNLOAD_PATH: String + /** + * 日志目录 + */ + lateinit var USER_DATA_LOG_PATH: String + /** * 图层管理对应的配置 * */ @@ -107,6 +126,11 @@ class Constant { */ var MapMarkerCloseEnable = false + /** + * 轨迹显隐 + */ + var MapTraceCloseEnable = false + /** * 是否开启线捕捉 */ diff --git a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt index 2a35c533..5e2238e4 100644 --- a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt +++ b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt @@ -8,6 +8,7 @@ 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 @@ -20,6 +21,7 @@ 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) // 初始化友盟统计 diff --git a/app/src/main/java/com/navinfo/omqs/bean/ImportConfig.kt b/app/src/main/java/com/navinfo/omqs/bean/ImportConfig.kt index 2bfedff9..6e07e485 100644 --- a/app/src/main/java/com/navinfo/omqs/bean/ImportConfig.kt +++ b/app/src/main/java/com/navinfo/omqs/bean/ImportConfig.kt @@ -4,6 +4,7 @@ import android.util.Log import com.google.gson.annotations.Expose import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.omqs.db.ImportPreProcess +import io.realm.Realm import kotlin.reflect.KFunction import kotlin.reflect.KParameter import kotlin.reflect.full.declaredMemberFunctions @@ -12,22 +13,22 @@ import kotlin.reflect.full.declaredMemberFunctions class ImportConfig { @Expose var tableMap: MutableMap = mutableMapOf() + @Expose val tableGroupName: String = "OMDB数据" - @Expose - var checked : Boolean = true - val preProcess: ImportPreProcess = ImportPreProcess() - fun transformProperties(renderEntity: RenderEntity): RenderEntity? { + @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()) { - Log.e("qj", "子表转换为空===${renderEntity.code}") return renderEntity } - Log.e("qj", "子表转换不为空===${renderEntity.code}") 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 @@ -36,7 +37,10 @@ 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 } @@ -44,26 +48,32 @@ class ImportConfig { m@ for (k in processKeyOrValue(key)) { if (renderEntity.properties.containsKey(k)) { // json配置的key可以匹配到数据 for (v in processKeyOrValue(value)) { - if ("~" == v ) { // ~符可以匹配任意元素 + if ("~" == v) { // ~符可以匹配任意元素 if (valuelib.endsWith(")")) { // 以()结尾,说明该value配置是一个function,需要通过反射调用指定方法 // 获取方法名 val methodName = valuelib.substringBefore("(") // 获取参数 - val params: List = valuelib.substringAfter("(").substringBefore(")").split(",").filter{ it.isNotEmpty() }.map { it.trim() } - val method = preProcess::class.members.filter { it.name == methodName }.first() as KFunction<*> + val params: List = + 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( methodParams[0] to preProcess, - methodParams[1] to renderEntity + 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("'", "") + if (methodParams.size > index + 2) { + callByParams[methodParams[index + 2]] = + value.replace("'", "") } } - when(val result = method.callBy(callByParams)) { // 如果方法返回的数据类型是boolean,且返回为false,则该数据不处理 + when (val result = + method.callBy(callByParams)) { // 如果方法返回的数据类型是boolean,且返回为false,则该数据不处理 is Boolean -> if (!result) { return null @@ -78,8 +88,12 @@ class ImportConfig { // 获取方法名 val methodName = valuelib.substringBefore("(") // 获取参数 - val params: List = valuelib.substringAfter("(").substringBefore(")").split(",").filter{ it.isNotEmpty() }.map { it.trim() } - val method = preProcess::class.members.filter { it.name == methodName }.first() as KFunction<*> + val params: List = + 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( @@ -88,11 +102,11 @@ class ImportConfig { ) for ((index, value) in params.withIndex()) { // 前2个参数确定为对象本身和RenderEntity,因此自定义参数从index+2开始设置 - if (methodParams.size>index+2) { - callByParams[methodParams[index+2]] = value + if (methodParams.size > index + 2) { + callByParams[methodParams[index + 2]] = value } } - when(val result = method.callBy(callByParams)) { + when (val result = method.callBy(callByParams)) { is Boolean -> if (!result) { return null @@ -107,6 +121,7 @@ class ImportConfig { } } } + preProcess.realm = null return renderEntity } @@ -125,14 +140,15 @@ class TableInfo { val zoomMin: Int = 16 val zoomMax: Int = 21 val checkLinkId: Boolean = true//是否需要校验linkid - val filterData : Boolean = false//是否需要过滤数据 - val existSubCode : Boolean = false//是否存在子编码 - - val catch: Boolean = false//是否需要捕捉 // 需要根据丹丹提供的捕捉原则进行设置,参考文档W行设置条件,https://navinfo.feishu.cn/sheets/shtcnfsxKZhekU26ezBcHgl7aWh?sheet=BZd6yM + 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 = mutableListOf() - var is3D : Boolean = false // 是否支持3D,默认情况下都不支持3D,在数据导入阶段会自动抹去Z轴高程信息 + var is3D: Boolean = false // 是否支持3D,默认情况下都不支持3D,在数据导入阶段会自动抹去Z轴高程信息 } class Transform { diff --git a/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt b/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt index 1d307a3f..003ea649 100644 --- a/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt @@ -2,64 +2,61 @@ package com.navinfo.omqs.db import android.content.Context import android.database.Cursor.* -import android.os.Build -import android.provider.ContactsContract.Data import android.util.Log -import androidx.annotation.RequiresApi -import com.blankj.utilcode.util.FileIOUtils +import com.alibaba.fastjson.JSON import com.blankj.utilcode.util.ZipUtils import com.google.gson.Gson import com.google.gson.reflect.TypeToken -import com.navinfo.collect.library.data.entity.HadLinkDvoBean -import com.navinfo.collect.library.data.entity.RenderEntity -import com.navinfo.collect.library.data.entity.TaskBean +import com.navinfo.collect.library.data.entity.* import com.navinfo.collect.library.enums.DataCodeEnum -import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.collect.library.utils.DeflaterUtil +import com.navinfo.collect.library.utils.StrZipUtil import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant.Companion.currentInstallTaskConfig import com.navinfo.omqs.Constant.Companion.currentInstallTaskFolder import com.navinfo.omqs.Constant.Companion.installTaskid import com.navinfo.omqs.bean.ImportConfig +import com.navinfo.omqs.bean.TableInfo import com.navinfo.omqs.db.deep.LinkList import com.navinfo.omqs.hilt.OMDBDataBaseHiltFactory +import com.navinfo.omqs.util.CMLog import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.realm.Realm import io.realm.RealmConfiguration -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.withContext -import org.locationtech.jts.geom.Geometry -import org.locationtech.jts.geom.GeometryFactory -import org.locationtech.jts.geom.LineString -import org.locationtech.jts.geom.MultiLineString +import kotlinx.coroutines.sync.Mutex import org.spatialite.database.SQLiteDatabase +import sun.misc.BASE64Encoder +import java.io.BufferedReader import java.io.File +import java.io.FileReader +import java.util.* import javax.inject.Inject -import kotlin.streams.toList /** * 导入omdb数据的帮助类 * */ class ImportOMDBHelper @AssistedInject constructor( - @Assisted("context") val context: Context, - @Assisted("omdbFile") val omdbFile: File + @Assisted("context") val context: Context, @Assisted("omdbFile") val omdbFile: File ) { @Inject lateinit var omdbHiltFactory: OMDBDataBaseHiltFactory @Inject lateinit var gson: Gson - private val database by lazy { - omdbHiltFactory.obtainOmdbDataBaseHelper( - context, - omdbFile.absolutePath, - 1 - ).writableDatabase - } - private val configFile: File = - File("${Constant.USER_DATA_PATH}", Constant.OMDB_CONFIG) + + // private val database by lazy { +// omdbHiltFactory.obtainOmdbDataBaseHelper( +// context, omdbFile.absolutePath, 1 +// ).writableDatabase +// } + private val configFile: File = File("${Constant.USER_DATA_PATH}", Constant.OMDB_CONFIG) private val importConfigList by lazy { openConfigFile() @@ -80,759 +77,701 @@ class ImportOMDBHelper @AssistedInject constructor( } } - /** - * 读取指定数据表的数据集 - * */ - @RequiresApi(Build.VERSION_CODES.N) - suspend fun getOMDBTableData(table: String): Flow>> = - withContext(Dispatchers.IO) { - val listResult: MutableList> = mutableListOf() - flow>> { - if (database.isOpen) { - val comumns = mutableListOf() - // 获取要读取的列名 - val columns = getColumns(database, table) - // 处理列名,如果列名是GEOMETRY,则使用spatialite函数ST_AsText读取blob数据 - val finalColumns = columns.stream().map { - val column = it.replace("\"", "", true) - if ("GEOMETRY".equals(column, ignoreCase = true)) { - "ST_AsText($column)" - } else { - column - } - }.toList() +// /** +// * 读取指定数据表的数据集 +// * */ +// @RequiresApi(Build.VERSION_CODES.N) +// suspend fun getOMDBTableData(table: String): Flow>> = +// withContext(Dispatchers.IO) { +// val listResult: MutableList> = mutableListOf() +// flow>> { +// if (database.isOpen) { +// val comumns = mutableListOf() +// // 获取要读取的列名 +// val columns = getColumns(database, table) +// // 处理列名,如果列名是GEOMETRY,则使用spatialite函数ST_AsText读取blob数据 +// val finalColumns = columns.stream().map { +// val column = it.replace("\"", "", true) +// if ("GEOMETRY".equals(column, ignoreCase = true)) { +// "ST_AsText($column)" +// } else { +// column +// } +// }.toList() +// +// val cursor = database.query( +// table, +// finalColumns.toTypedArray(), +// "1=1", +// mutableListOf().toTypedArray(), +// null, +// null, +// null, +// null +// ) +// with(cursor) { +// if (moveToFirst()) { +// while (moveToNext()) { +// val rowMap = mutableMapOf() +// for (columnIndex in 0 until columnCount) { +// var columnName = getColumnName(columnIndex) +// if (columnName.startsWith("ST_AsText(")) { +// columnName = columnName.replace("ST_AsText(", "") +// .substringBeforeLast(")") +// } +// when (getType(columnIndex)) { +// FIELD_TYPE_NULL -> rowMap[columnName] = "" +// FIELD_TYPE_INTEGER -> rowMap[columnName] = +// getInt(columnIndex) +// +// FIELD_TYPE_FLOAT -> rowMap[columnName] = +// getFloat(columnIndex) +// +// FIELD_TYPE_BLOB -> rowMap[columnName] = +// String(getBlob(columnIndex), Charsets.UTF_8) +// +// else -> rowMap[columnName] = getString(columnIndex) +// } +// } +// listResult.add(rowMap) +// } +// } +// } +// emit(listResult) +// cursor.close() +// } +// } +// } - val cursor = database.query( - table, finalColumns.toTypedArray(), "1=1", - mutableListOf().toTypedArray(), null, null, null, null - ) - with(cursor) { - if (moveToFirst()) { - while (moveToNext()) { - val rowMap = mutableMapOf() - for (columnIndex in 0 until columnCount) { - var columnName = getColumnName(columnIndex) - if (columnName.startsWith("ST_AsText(")) { - columnName = columnName.replace("ST_AsText(", "") - .substringBeforeLast(")") - } - when (getType(columnIndex)) { - FIELD_TYPE_NULL -> rowMap[columnName] = "" - FIELD_TYPE_INTEGER -> rowMap[columnName] = - getInt(columnIndex) - - FIELD_TYPE_FLOAT -> rowMap[columnName] = - getFloat(columnIndex) - - FIELD_TYPE_BLOB -> rowMap[columnName] = - String(getBlob(columnIndex), Charsets.UTF_8) - - else -> rowMap[columnName] = getString(columnIndex) - } - } - listResult.add(rowMap) - } - } - } - emit(listResult) - cursor.close() - } - } - } /** * 从zip文件中导入数据到Realm中 * @param omdbZipFile omdb数据抽取生成的Zip文件 * @param configFile 对应的配置文件 * */ - suspend fun importOmdbZipFile(omdbZipFile: File, task: TaskBean): Flow = - withContext(Dispatchers.IO) { - installTaskid = task.id.toString() - currentInstallTaskFolder = File(Constant.USER_DATA_PATH + "/$installTaskid") - if (!currentInstallTaskFolder.exists()) currentInstallTaskFolder.mkdirs() - currentInstallTaskConfig = RealmConfiguration.Builder() - .directory(currentInstallTaskFolder) + suspend fun importOmdbZipFile( + omdbZipFile: File, task: TaskBean, scope: CoroutineScope + ): Boolean { + val channel = Channel>(Channel.RENDEZVOUS) + + installTaskid = task.id.toString() + currentInstallTaskFolder = File(Constant.USER_DATA_PATH + "/$installTaskid") + if (!currentInstallTaskFolder.exists()) currentInstallTaskFolder.mkdirs() + currentInstallTaskConfig = + RealmConfiguration.Builder().directory(currentInstallTaskFolder) .name("OMQS.realm") .encryptionKey(Constant.PASSWORD) - .allowQueriesOnUiThread(true) - .schemaVersion(2) - .build() - val unZipFolder = File(omdbZipFile.parentFile, "result") +// .allowQueriesOnUiThread(true) + .schemaVersion(2).build() - flow { - if (unZipFolder.exists()) { - unZipFolder.deleteRecursively() + val unZipFolder = File(omdbZipFile.parentFile, "result") + if (unZipFolder.exists()) { + unZipFolder.deleteRecursively() + } + unZipFolder.mkdirs() + // 开始解压zip文件 + val unZipFiles = ZipUtils.unzipFile(omdbZipFile, unZipFolder) + // 先获取当前配置的所有图层的个数,方便后续计算数据解析进度 + var tableNum = 0 + var processIndex = 0 + + for (importConfig in importConfigList) { + tableNum += importConfig.tableMap.size + } + //缓存任务link信息,便于下面与数据进行任务link匹配 + val hashMap: HashMap = HashMap() + +// val lineList = arrayOfNulls(task.hadLinkDvoList.size) +// var index = 0 + task.hadLinkDvoList.forEach { + hashMap[it.linkPid.toLong()] = it +// lineList[index] = GeometryTools.createGeometry(it.geometry) as LineString +// index++ + } + //需要关联查询的表 + val listDependOnEntry = + mutableMapOf, ImportConfig>() + //协程池 + val listJob = mutableListOf() + try { + CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "数据安装", "开始安装数据") + Constant.INSTALL_DATA = true + for (importConfig in importConfigList) { + for ((index, currentEntry) in importConfig.tableMap.entries.withIndex()) { + if (currentEntry.value.isDependOnOtherTable) { + listDependOnEntry[currentEntry] = importConfig + continue + } + val job = scope.launch(Dispatchers.IO) { + importData( + channel, + unZipFiles, + currentEntry, + task, + importConfig, + hashMap + ) + } + listJob.add(job) } - unZipFolder.mkdirs() - // 开始解压zip文件 - val unZipFiles = ZipUtils.unzipFile(omdbZipFile, unZipFolder) - - // 先获取当前配置的所有图层的个数,方便后续计算数据解析进度 - var tableNum = 0 - var processIndex = 0 - //下载数据统计 - var dataIndex = 0 - //数据库插入的统计 - var insertIndex = 0 - //单个表要素统计 - var elementIndex = 0 - //单个表要素时间统计 - var tableImportTime = System.currentTimeMillis() - //总表要素统计时间 - var dataImportTime = System.currentTimeMillis() - - Realm.getInstance(currentInstallTaskConfig).beginTransaction() - - for (importConfig in importConfigList) { - tableNum += importConfig.tableMap.size - } - //缓存任务link信息,便于下面与数据进行任务link匹配 - val hashMap: HashMap = HashMap() - - val lineList = arrayOfNulls(task.hadLinkDvoList.size) - var index = 0 - task.hadLinkDvoList.forEach { - hashMap[it.linkPid.toLong()] = it - lineList[index] = GeometryTools.createGeometry(it.geometry) as LineString - index++ + } + val channelJob = scope.launch(Dispatchers.IO) { + val iterator = channel.iterator() + while (iterator.hasNext()) { + val next = iterator.next() + val realm = Realm.getInstance(currentInstallTaskConfig) + realm.executeTransaction { + it.copyToRealm(next) + } + realm.close() } - val resHashMap: HashMap = - HashMap() //define empty hashmap - try { + } - var multipLine = MultiLineString(lineList, GeometryFactory()) + listJob.joinAll() + channel.close() + channelJob.join() + Log.e("jingo", "channel close 等待结束") + for ((currentEntry, importConfig) in listDependOnEntry) { + importData( + channel, + unZipFiles, + currentEntry, + task, + importConfig, + hashMap, + false + ) + } + Log.e("jingo", "安装结束") + CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "数据安装", "安装结束") - // 遍历解压后的文件,读取该数据返回 - Log.d("ImportOMDBHelper", "表解析===开始时间$dataImportTime===") + } catch (e: Exception) { + Log.e("jingo", "安装报错1 ${e.message}") + return false + }finally { + Constant.INSTALL_DATA = false + } + return true + } - for (importConfig in importConfigList) { + private suspend fun importData( + f: Channel>, + unZipFiles: List, + currentEntry: MutableMap.MutableEntry, + task: TaskBean, + importConfig: ImportConfig, + hashMap: HashMap, + isEmit: Boolean = true + ) { + val resHashMap: HashMap = HashMap() //define empty hashmap + var listRenderEntity = mutableListOf() + //单个表要素统计 + var elementIndex = 0 + val currentConfig = currentEntry.value - for ((index, currentEntry) in importConfig.tableMap.entries.withIndex()) { - processIndex += 1 - Log.d( - "ImportOMDBHelper", - "表解析===开始时间$tableImportTime===${currentEntry.value.table}" + CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "importOmdbZipFile", "${currentConfig.table}开始") + + try { + var realm: Realm? = null + if (!isEmit) { + realm = Realm.getInstance(currentInstallTaskConfig) + realm.beginTransaction() + } + val txtFile = unZipFiles.find { + it.name == currentConfig.table + } + if (txtFile != null && txtFile.exists()) { + val fileReader = FileReader(txtFile) + val bufferedReader = BufferedReader(fileReader) + var line: String? = bufferedReader.readLine() + var time = System.currentTimeMillis() + var newTime = 0L + while (line != null) { + if (line == null || line.trim() == "") { + line = bufferedReader.readLine() + continue + } + newTime = System.currentTimeMillis() + Log.e( + "jingo", + "安装数据 ${currentConfig.table} $elementIndex ${listRenderEntity.size} ${newTime - time}" + ) + time = newTime + elementIndex += 1 + val map = gson.fromJson>( + line, object : TypeToken>() {}.type + ).toMutableMap() + map["qi_table"] = currentConfig.table + map["qi_name"] = currentConfig.name + map["qi_code"] = + if (currentConfig.code == 0) currentConfig.code else currentEntry.key + map["qi_zoomMin"] = currentConfig.zoomMin + map["qi_zoomMax"] = currentConfig.zoomMax + + // 先查询这个mesh下有没有数据,如果有则跳过即可 + val renderEntity = RenderEntity() + renderEntity.code = map["qi_code"].toString() + renderEntity.name = map["qi_name"].toString() + renderEntity.table = map["qi_table"].toString() + renderEntity.taskId = task.id + renderEntity.zoomMin = map["qi_zoomMin"].toString().toInt() + renderEntity.zoomMax = map["qi_zoomMax"].toString().toInt() + + // 在外层记录当前数据的linkPid + if (map.containsKey("linkPid")) { + renderEntity.linkPid = map["linkPid"].toString().split(",")[0] + } else if (map.containsKey("linkList")) { + val linkList = map["linkList"].toString() + if (!linkList.isNullOrEmpty() && linkList != "null") { + val list: List = gson.fromJson( + linkList, object : TypeToken>() {}.type ) - Log.d( - "ImportOMDBHelper", - "表解析===processIndex${processIndex}====${processIndex}/${tableNum}" - ) - val listResult = mutableListOf() - val currentConfig = currentEntry.value - val txtFile = unZipFiles.find { - it.name == currentConfig.table + renderEntity.linkPid = list[0].linkPid + } + } + + renderEntity.geometry = map["geometry"].toString() + for ((key, value) in map) { + when (value) { + is String -> renderEntity.properties[key] = value + is Int -> renderEntity.properties[key] = value.toInt().toString() + + is Double -> renderEntity.properties[key] = + value.toDouble().toString() + + else -> renderEntity.properties[key] = value.toString() + } + } + // 如果properties中不包含name,那么自动将要素名称添加进properties中 + if (!renderEntity.properties.containsKey("name")) { + renderEntity.properties["name"] = renderEntity.name; + } + + if (currentConfig.filterData) { + when (renderEntity.code.toInt()) { + + DataCodeEnum.OMDB_POLE.code.toInt() -> { + //过滤树类型的杆状物,无需导入到数据库中 + val poleType = renderEntity.properties["poleType"] + if (poleType != null && poleType.toInt() == 2) { + line = bufferedReader.readLine() + continue + } } - // 将listResult数据插入到Realm数据库中 - currentConfig?.let { - val list = FileIOUtils.readFile2List(txtFile, "UTF-8") - Log.d("ImportOMDBHelper", "开始解析:${txtFile?.name}") - if (list != null) { - // 将list数据转换为map - for ((index, line) in list.withIndex()) { - if (line == null || line.trim() == "") { + + DataCodeEnum.OMDB_LANE_MARK_BOUNDARYTYPE.code.toInt() -> { + val boundaryType = renderEntity.properties["boundaryType"] + if (boundaryType != null) { + when (boundaryType.toInt()) { + 0, 1, 6, 8, 9 -> { + renderEntity.enable = 0 + line = bufferedReader.readLine() continue } - elementIndex += 1 - dataIndex += 1 - Log.d("ImportOMDBHelper", "解析第:${index + 1}行---${txtFile?.name}") - val map = gson.fromJson>( - line, - object : TypeToken>() {}.getType() - ) - .toMutableMap() - map["qi_table"] = currentConfig.table - map["qi_name"] = currentConfig.name - map["qi_code"] = - if (currentConfig.code == 0) currentConfig.code else currentEntry.key - map["qi_zoomMin"] = currentConfig.zoomMin - map["qi_zoomMax"] = currentConfig.zoomMax - - // 先查询这个mesh下有没有数据,如果有则跳过即可 - val renderEntity = RenderEntity() - renderEntity.code = map["qi_code"].toString() - renderEntity.name = map["qi_name"].toString() - renderEntity.table = map["qi_table"].toString() - renderEntity.taskId = task.id - renderEntity.zoomMin = map["qi_zoomMin"].toString().toInt() - renderEntity.zoomMax = map["qi_zoomMax"].toString().toInt() - - renderEntity.geometry = map["geometry"].toString() - Log.d("ImportOMDBHelper", "解析===1处理3D") - // 其他数据插入到Properties中 -/* if (!currentConfig.is3D) { // 如果是非3d要素,则自动将Z轴坐标全部置为0 - val coordinates = - renderEntity.wkt?.coordinates?.map { coordinate -> - coordinate.z = 0.0 - coordinate - }?.toTypedArray() - var newGeometry: Geometry? = null - if (renderEntity.wkt?.geometryType == Geometry.TYPENAME_POINT) { - newGeometry = GeometryTools.createPoint( - coordinates!![0].x, - coordinates!![0].y - ) - } else if (renderEntity.wkt?.geometryType == Geometry.TYPENAME_LINESTRING) { - newGeometry = - GeometryTools.createLineString(coordinates) - } else if (renderEntity.wkt?.geometryType == Geometry.TYPENAME_POLYGON) { - newGeometry = - GeometryTools.createLineString(coordinates) - } - if (newGeometry != null) { - renderEntity.geometry = newGeometry.toString() - } - }*/ - Log.d("ImportOMDBHelper", "解析===2处理3D") - Log.d("ImportOMDBHelper", "解析===1处理属性") - for ((key, value) in map) { - when (value) { - is String -> renderEntity.properties.put(key, value) - is Int -> renderEntity.properties.put( - key, - value.toInt().toString() - ) - - is Double -> renderEntity.properties.put( - key, - value.toDouble().toString() - ) - - else -> renderEntity.properties.put( - key, - value.toString() - ) - } - } - Log.d("ImportOMDBHelper", "解析===2处理属性") - Log.d("ImportOMDBHelper", "解析===1处理name") - // 如果properties中不包含name,那么自动将要素名称添加进properties中 - if (!renderEntity.properties.containsKey("name")) { - renderEntity.properties["name"] = renderEntity.name; - } - Log.d("ImportOMDBHelper", "解析===2处理name") - Log.d("ImportOMDBHelper", "解析===1处理杆状物") - - if (currentConfig.filterData) { - when (renderEntity.code.toInt()) { - - DataCodeEnum.OMDB_POLE.code.toInt() -> { - //过滤树类型的杆状物,无需导入到数据库中 - val poleType = - renderEntity.properties["poleType"] - if (poleType != null && poleType.toInt() == 2) { - continue - } - } - - DataCodeEnum.OMDB_LANE_MARK_BOUNDARYTYPE.code.toInt() -> { - var boundaryType = renderEntity.properties["boundaryType"] - if (boundaryType != null) { - when (boundaryType.toInt()) { - 0, 1, 6, 8, 9 -> { - renderEntity.enable = 0 - Log.e( - "qj", - "过滤不显示数据${renderEntity.table}" - ) - continue - } - } - } - } - - DataCodeEnum.OMDB_RDBOUND_BOUNDARYTYPE.code.toInt() -> { - var boundaryType = - renderEntity.properties["boundaryType"] - if (boundaryType != null) { - when (boundaryType.toInt()) { - 0, 1, 3, 4, 5, 7, 9 -> { - renderEntity.enable = 0 - Log.e( - "qj", - "过滤不显示数据${renderEntity.table}" - ) - continue - } - } - } - } - - DataCodeEnum.OMDB_OBJECT_STOPLOCATION.code.toInt() -> { - var locationType = - renderEntity.properties["locationType"] - if (locationType != null) { - when (locationType.toInt()) { - 3, 4 -> { - renderEntity.enable = 0 - Log.e( - "qj", - "过滤不显示数据${renderEntity.table}" - ) - continue - } - } - } - } - - DataCodeEnum.OMDB_RESTRICTION.code.toInt() -> { - if (renderEntity.properties.containsKey("linkIn") && renderEntity.properties.containsKey( - "linkOut" - ) - ) { - var linkIn = - renderEntity.properties["linkIn"] - var linkOut = - renderEntity.properties["linkOut"] - if (linkIn != null && linkOut != null) { - var checkMsg = "$linkIn$linkOut" - if (resHashMap.containsKey(checkMsg)) { - Log.e( - "qj", - "${renderEntity.name}==过滤交限linkin与linkout相同且存在多条数据" - ) - continue - } else { - resHashMap[checkMsg] = renderEntity - } - } - } - } - } - - } - - Log.d("ImportOMDBHelper", "解析===2处理杆状物") - Log.d("ImportOMDBHelper", "解析===1任务路线匹配") - - //遍历判断只显示与任务Link相关的任务数据 - if (currentConfig.checkLinkId) { - - if (renderEntity.properties.containsKey("linkPid")) { - - var currentLinkPid = - renderEntity.properties["linkPid"] - - Log.d( - "ImportOMDBHelper", - "解析===1任务路线匹配${currentLinkPid}" - ) - - if (!currentLinkPid.isNullOrEmpty() && currentLinkPid != "null") { - - var list = currentLinkPid.split(",") - - if (list != null && list.isNotEmpty()) { - - Log.d( - "ImportOMDBHelper", - "解析===1任务路线匹配${list.size}" - ) - - m@ for (linkPid in list) { - if (hashMap.containsKey(linkPid.toLong())) { - renderEntity.enable = 1 - Log.e( - "qj", - "${renderEntity.name}==包括任务link" - ) - break@m - } - } - } - } - - } else if (renderEntity.code.toInt() == DataCodeEnum.OMDB_INTERSECTION.code.toInt()||renderEntity.code.toInt() == DataCodeEnum.OMDB_LANE_CONSTRUCTION.code.toInt() && renderEntity.properties.containsKey( - "linkList" - ) - ) { - - if (renderEntity.properties["linkList"] != null) { - - Log.e( - "qj", - "linkList==开始${renderEntity.name}==${renderEntity.properties["linkList"]}}" - ) - - val linkList = - renderEntity.properties["linkList"] - - if (!linkList.isNullOrEmpty() && linkList != "null") { - - Log.e( - "qj", - "linkList==${renderEntity.name}==${renderEntity.properties["linkList"]}}" - ) - - val list: List = gson.fromJson( - linkList, - object : - TypeToken>() {}.type - ) - - if (list != null) { - m@ for (link in list) { - if (hashMap.containsKey(link.linkPid.toLong())) { - renderEntity.enable = 1 - Log.e( - "qj", - "${renderEntity.name}==包括任务link" - ) - break@m - } - } - } - } - } - } else { - //不包括linkPid直接过滤 - continue - } - //过滤掉非任务路线上的数据 - if (renderEntity.enable != 1) { - Log.e( - "qj", - "${renderEntity.name}==过滤不包括任务路线上的数据" - ) - continue - } - - } else { - renderEntity.enable = 1 - - /* var geometry = GeometryTools.createGeometry(renderEntity.geometry) - if(multipLine.intersects(geometry)){ - renderEntity.enable = 1 - }else{ - val dis = multipLine.distance(GeometryTools.createGeometry(renderEntity.geometry)) - if(dis>36){ - continue - }else{ - renderEntity.enable = 1 - } - }*/ - Log.e("qj", "${renderEntity.name}==不包括任务linkPid") - } - Log.d("ImportOMDBHelper", "解析===2任务路线匹配") - Log.d("ImportOMDBHelper", "解析===1预处理") - - if (currentConfig.catch) { - renderEntity.catchEnable = 1 - } else { - renderEntity.catchEnable = 0 - } - - // 对renderEntity做预处理后再保存 - val resultEntity = importConfig.transformProperties(renderEntity) - Log.d("ImportOMDBHelper", "解析===2预处理") - if (resultEntity != null) { - - Log.d("ImportOMDBHelper", "解析===1子code处理") - //对code编码需要特殊处理 存在多个属性值时,渲染优先级:SA>PA,存在多个属性值时,渲染优先级:FRONTAGE>MAIN_SIDE_A CCESS - - if (currentConfig.existSubCode) { - when (renderEntity.code.toInt()) { - DataCodeEnum.OMDB_LINK_ATTRIBUTE.code.toInt() -> { - - Log.e("qj", "道路属性===0") - - var type = renderEntity.properties["sa"] - - if (type != null && type == "1") { - renderEntity.code = - DataCodeEnum.OMDB_LINK_ATTRIBUTE_SA.code - Log.e("qj", "道路属性===1") - } else { - type = renderEntity.properties["pa"] - if (type != null && type == "1") { - renderEntity.code = - DataCodeEnum.OMDB_LINK_ATTRIBUTE_PA.code - Log.e("qj", "道路属性===2") - } else { - type = - renderEntity.properties["frontage"] - if (type != null && type == "1") { - renderEntity.code = - DataCodeEnum.OMDB_LINK_ATTRIBUTE_FORNTAGE.code - renderEntity.zoomMin = 15 - renderEntity.zoomMax = 17 - Log.e("qj", "道路属性===3") - } else { - type = - renderEntity.properties["mainSideAccess"] - if (type != null && type == "1") { - renderEntity.code = - DataCodeEnum.OMDB_LINK_ATTRIBUTE_MAIN_SIDE_ACCESS.code - renderEntity.zoomMin = 15 - renderEntity.zoomMax = 17 - Log.e("qj", "道路属性===4") - } else { - renderEntity.enable = 0 - renderEntity.zoomMin = 15 - renderEntity.zoomMax = 17 - Log.e( - "qj", - "过滤不显示数据${renderEntity.table}" - ) - Log.e("qj", "道路属性===5") - continue - } - } - } - } - } - //桥 - DataCodeEnum.OMDB_BRIDGE.code.toInt() -> { - when (renderEntity.properties["bridgeType"]) { - "1" -> renderEntity.code = - DataCodeEnum.OMDB_BRIDGE_1.code - "2" -> renderEntity.code = - DataCodeEnum.OMDB_BRIDGE_2.code -// "3" -> renderEntity.code = DataCodeEnum.OMDB_BRIDGE_3.code - else -> DataCodeEnum.OMDB_BRIDGE.code - } - } - - DataCodeEnum.OMDB_RAMP.code.toInt() -> { - /*匝道*/ - var formWay = - renderEntity.properties["formOfWay"] - if (formWay != null) { - when (formWay.toInt()) { - 93 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_1.code - - 98 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_2.code - - 99 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_3.code - - 100 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_4.code - - 102 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_5.code - - 103 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_6.code - - 104 -> renderEntity.code = - DataCodeEnum.OMDB_RAMP_7.code - } - } - } - - DataCodeEnum.OMDB_LINK_FORM1.code.toInt() -> { - /*道路形态1*/ - var formWay = - renderEntity.properties["formOfWay"] - if (formWay != null) { - when (formWay.toInt()) { - 35 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM1_1.code - - 37 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM1_2.code - - 38 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM1_3.code - } - } - } - - DataCodeEnum.OMDB_LINK_FORM2.code.toInt() -> { - Log.e( - "qj", - "道路形态2${renderEntity.properties["formOfWay"]}" - ) - /*道路形态2*/ - var formWay = - renderEntity.properties["formOfWay"] - if (formWay != null) { - when (formWay.toInt()) { - 10 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_1.code - - 11 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_2.code - - 17 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_3.code - - 18 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_4.code - - 20 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_5.code - - 22 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_6.code - - 36 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_7.code - - 52 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_8.code - - 53 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_9.code - - 54 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_10.code - - 60 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_11.code - - 84 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_12.code - - 85 -> renderEntity.code = - DataCodeEnum.OMDB_LINK_FORM2_13.code - } - } - } - - DataCodeEnum.OMDB_LANE_CONSTRUCTION.code.toInt() -> { - //特殊处理空数据,渲染原则使用 - var startTime = - renderEntity.properties["startTime"] - if (startTime == null || startTime == "") { - renderEntity.properties["startTime"] = - "null" - } - } - } - - if (renderEntity.table == DataCodeEnum.OMDB_NODE_FORM.name) {//特殊处理,因为code相同,使用表名判断 - //过滤不需要渲染的要素 - var formOfWay = - renderEntity.properties["formOfWay"] - if (formOfWay != null && formOfWay.toInt() == 30) { - renderEntity.enable = 2 - renderEntity.code = - DataCodeEnum.OMDB_NODE_FORM.code - } else { - Log.e( - "qj", - "过滤不显示数据${renderEntity.table}" - ) - continue - } - } else if (renderEntity.table == DataCodeEnum.OMDB_NODE_PA.name) {//特殊处理,因为code相同,使用表名判断 - //过滤不需要渲染的要素 - var attributeType = - renderEntity.properties["attributeType"] - if (attributeType != null && attributeType.toInt() == 30) { - renderEntity.enable = 2 - renderEntity.code = - DataCodeEnum.OMDB_NODE_PA.code - } else { - Log.e( - "qj", - "过滤不显示数据${renderEntity.table}" - ) - continue - } - } - } - - Log.d("ImportOMDBHelper", "解析===2子code处理") - ++insertIndex - Log.e("qj", "统计==${insertIndex}") - - //移除该字段,减少数据量 - if (renderEntity.properties.containsKey("geometry")) { - renderEntity.properties.remove("geometry") - } - Log.d("ImportOMDBHelper", "解析===1insert") - Realm.getInstance(currentInstallTaskConfig) - .insert(renderEntity) - Log.d("ImportOMDBHelper", "解析===2insert") - if (currentConfig.code == DataCodeEnum.OMDB_RD_LINK.code.toInt()) { - listResult.add(renderEntity) - } - } } } } - // 如果当前解析的是OMDB_RD_LINK数据,将其缓存在预处理类中,以便后续处理其他要素时使用 - if (currentConfig.code == DataCodeEnum.OMDB_RD_LINK.code.toInt()) { - importConfig.preProcess.cacheRdLink = - listResult.associateBy { it.properties["linkPid"] } + DataCodeEnum.OMDB_RDBOUND_BOUNDARYTYPE.code.toInt() -> { + val boundaryType = renderEntity.properties["boundaryType"] + if (boundaryType != null) { + when (boundaryType.toInt()) { + 0, 1, 3, 4, 5, 7, 9 -> { + renderEntity.enable = 0 + line = bufferedReader.readLine() + continue + } + } + } } - // 1个文件发送一次flow流 - emit("${processIndex}/${tableNum}") - Log.d("ImportOMDBHelper", "表解析===2${currentConfig.table}") - Log.d( - "ImportOMDBHelper", - "表解析===结束用时时间${(System.currentTimeMillis() - tableImportTime)}===${currentEntry.value.table}===$elementIndex" - ) - elementIndex = 0 - tableImportTime = System.currentTimeMillis() - if (insertIndex % 20000 == 0) { - Log.d( - "ImportOMDBHelper", - "表解析===结束用时时间===事物开始" - ) - Realm.getInstance(currentInstallTaskConfig).commitTransaction() - Realm.getInstance(currentInstallTaskConfig).beginTransaction() - Log.d( - "ImportOMDBHelper", - "表解析===结束用时时间===事物结束" - ) + + DataCodeEnum.OMDB_OBJECT_STOPLOCATION.code.toInt() -> { + val locationType = renderEntity.properties["locationType"] + if (locationType != null) { + when (locationType.toInt()) { + 3, 4 -> { + renderEntity.enable = 0 + line = bufferedReader.readLine() + continue + } + } + } + } + + DataCodeEnum.OMDB_RESTRICTION.code.toInt() -> { + if (renderEntity.properties.containsKey("linkIn") && renderEntity.properties.containsKey( + "linkOut" + ) + ) { + val linkIn = renderEntity.properties["linkIn"] + val linkOut = renderEntity.properties["linkOut"] + if (linkIn != null && linkOut != null) { + val checkMsg = "$linkIn$linkOut" + if (resHashMap.containsKey(checkMsg)) { + line = bufferedReader.readLine() + continue + } else { + resHashMap[checkMsg] = renderEntity + } + } + } } } } - Realm.getInstance(currentInstallTaskConfig).commitTransaction() - Realm.getInstance(currentInstallTaskConfig).close() - Log.d( - "ImportOMDBHelper", - "表解析===结束用时时间${(System.currentTimeMillis() - dataImportTime)}===$dataIndex===插入$insertIndex" - ) - Log.e("qj", "安装结束") - } catch (e: Exception) { - if (Realm.getInstance(currentInstallTaskConfig).isInTransaction) { - Realm.getInstance(currentInstallTaskConfig).cancelTransaction() + + //遍历判断只显示与任务Link相关的任务数据 + if (currentConfig.checkLinkId) { + + if (renderEntity.linkPid.isNotEmpty()) { + + val currentLinkPid = renderEntity.linkPid + + if (!currentLinkPid.isNullOrEmpty() && currentLinkPid != "null") { + + val list = currentLinkPid.split(",") + + if (list.isNotEmpty()) { + + m@ for (linkPid in list) { + if (hashMap.containsKey(linkPid.toLong())) { + renderEntity.enable = 1 + break@m + } + } + } + } + + } else if (renderEntity.code.toInt() == DataCodeEnum.OMDB_INTERSECTION.code.toInt() || renderEntity.code.toInt() == DataCodeEnum.OMDB_LANE_CONSTRUCTION.code.toInt() && renderEntity.properties.containsKey( + "linkList" + ) + ) { + + if (renderEntity.properties["linkList"] != null) { + + val linkList = renderEntity.properties["linkList"] + + if (!linkList.isNullOrEmpty() && linkList != "null") { + val list: List = gson.fromJson( + linkList, object : TypeToken>() {}.type + ) + + m@ for (link in list) { + if (hashMap.containsKey(link.linkPid.toLong())) { + renderEntity.enable = 1 + break@m + } + } + } + } + } else { + //不包括linkPid直接过滤 + line = bufferedReader.readLine() + continue + } + //过滤掉非任务路线上的数据 + if (renderEntity.enable != 1) { + line = bufferedReader.readLine() + continue + } + + } else { + renderEntity.enable = 1 } - Log.e("ImportOMDBHelper", "安装失败", e) - throw e + + if (currentConfig.catch) { + renderEntity.catchEnable = 1 + } else { + renderEntity.catchEnable = 0 + } + + // 对renderEntity做预处理后再保存 + val resultEntity = importConfig.transformProperties(renderEntity, realm) + if (resultEntity != null) { + + //对code编码需要特殊处理 存在多个属性值时,渲染优先级:SA>PA,存在多个属性值时,渲染优先级:FRONTAGE>MAIN_SIDE_A CCESS + if (currentConfig.existSubCode) { + when (renderEntity.code.toInt()) { + DataCodeEnum.OMDB_LINK_ATTRIBUTE.code.toInt() -> { + + var type = renderEntity.properties["sa"] + if (type != null && type == "1") { + renderEntity.code = + DataCodeEnum.OMDB_LINK_ATTRIBUTE_SA.code + } else { + type = renderEntity.properties["pa"] + if (type != null && type == "1") { + renderEntity.code = + DataCodeEnum.OMDB_LINK_ATTRIBUTE_PA.code + } else { + type = renderEntity.properties["frontage"] + if (type != null && type == "1") { + renderEntity.code = + DataCodeEnum.OMDB_LINK_ATTRIBUTE_FORNTAGE.code + renderEntity.zoomMin = 15 + renderEntity.zoomMax = 17 + } else { + type = renderEntity.properties["mainSideAccess"] + if (type != null && type == "1") { + renderEntity.code = + DataCodeEnum.OMDB_LINK_ATTRIBUTE_MAIN_SIDE_ACCESS.code + renderEntity.zoomMin = 15 + renderEntity.zoomMax = 17 + } else { + renderEntity.enable = 0 + renderEntity.zoomMin = 15 + renderEntity.zoomMax = 17 + line = bufferedReader.readLine() + continue + } + } + } + } + } + //桥 + DataCodeEnum.OMDB_BRIDGE.code.toInt() -> { + when (renderEntity.properties["bridgeType"]) { + "1" -> renderEntity.code = + DataCodeEnum.OMDB_BRIDGE_1.code + "2" -> renderEntity.code = + DataCodeEnum.OMDB_BRIDGE_2.code + // "3" -> renderEntity.code = DataCodeEnum.OMDB_BRIDGE_3.code + else -> DataCodeEnum.OMDB_BRIDGE.code + } + } + + DataCodeEnum.OMDB_RAMP.code.toInt() -> { + /*匝道*/ + val formWay = renderEntity.properties["formOfWay"] + if (formWay != null) { + when (formWay.toInt()) { + 93 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_1.code + + 98 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_2.code + + 99 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_3.code + + 100 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_4.code + + 102 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_5.code + + 103 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_6.code + + 104 -> renderEntity.code = + DataCodeEnum.OMDB_RAMP_7.code + } + } + } + + DataCodeEnum.OMDB_LINK_FORM1.code.toInt() -> { + /*道路形态1*/ + val formWay = renderEntity.properties["formOfWay"] + if (formWay != null) { + when (formWay.toInt()) { + 35 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM1_1.code + + 37 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM1_2.code + + 38 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM1_3.code + } + } + } + + DataCodeEnum.OMDB_LINK_FORM2.code.toInt() -> { + /*道路形态2*/ + val formWay = renderEntity.properties["formOfWay"] + if (formWay != null) { + when (formWay.toInt()) { + 10 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_1.code + + 11 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_2.code + + 17 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_3.code + + 18 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_4.code + + 20 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_5.code + + 22 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_6.code + + 36 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_7.code + + 52 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_8.code + + 53 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_9.code + + 54 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_10.code + + 60 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_11.code + + 84 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_12.code + + 85 -> renderEntity.code = + DataCodeEnum.OMDB_LINK_FORM2_13.code + } + } + } + + DataCodeEnum.OMDB_LANE_CONSTRUCTION.code.toInt() -> { + //特殊处理空数据,渲染原则使用 + val startTime = renderEntity.properties["startTime"] + if (startTime == null || startTime == "") { + renderEntity.properties["startTime"] = "null" + } + } + } + + if (renderEntity.table == DataCodeEnum.OMDB_NODE_FORM.name) {//特殊处理,因为code相同,使用表名判断 + //过滤不需要渲染的要素 + val formOfWay = renderEntity.properties["formOfWay"] + if (formOfWay != null && formOfWay.toInt() == 30) { + renderEntity.enable = 2 + renderEntity.code = DataCodeEnum.OMDB_NODE_FORM.code + } else { + line = bufferedReader.readLine() + continue + } + } else if (renderEntity.table == DataCodeEnum.OMDB_NODE_PA.name) {//特殊处理,因为code相同,使用表名判断 + //过滤不需要渲染的要素 + val attributeType = renderEntity.properties["attributeType"] + if (attributeType != null && attributeType.toInt() == 30) { + renderEntity.enable = 2 + renderEntity.code = DataCodeEnum.OMDB_NODE_PA.code + } else { + line = bufferedReader.readLine() + continue + } + } + } + + + //移除该字段,减少数据量 + if (renderEntity.properties.containsKey("geometry")) { + renderEntity.properties.remove("geometry") + } + + //移除该字段,减少数据量 + if (renderEntity.properties.containsKey("linkPid")) { + renderEntity.properties.remove("linkPid") + } + + // 如果当前解析的是OMDB_RD_LINK数据,将其缓存在预处理类中,以便后续处理其他要素时使用 + if (currentConfig.code == DataCodeEnum.OMDB_RD_LINK.code.toInt()) { + if (renderEntity.linkRelation == null) { + renderEntity.linkRelation = LinkRelation() + } + renderEntity.linkRelation!!.linkPid = renderEntity.linkPid + renderEntity.linkRelation!!.sNodeId = + renderEntity.properties["snodePid"] + renderEntity.linkRelation!!.eNodeId = + renderEntity.properties["enodePid"] + } + + //去掉暂用控件较大的字段多余属性字段 + if (renderEntity.properties.containsKey("shapeList")) { + renderEntity.properties.remove("shapeList") + } + + renderEntity.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(renderEntity.properties)) + + listRenderEntity.add(renderEntity) + } + + if (listRenderEntity.size > 20000) { + Log.e( + "jingo", + "安装数据 ${currentConfig.table} $elementIndex ${listRenderEntity.size}" + ) + if (isEmit) { + f.send(listRenderEntity) + delay(20) + } else { + realm!!.copyToRealm(listRenderEntity) + realm!!.commitTransaction() + realm!!.close() + realm = Realm.getInstance(currentInstallTaskConfig) + realm.beginTransaction() + } + listRenderEntity = mutableListOf() +// + } + line = bufferedReader.readLine() } - emit("finish") - } - } - // 获取指定数据表的列名 - fun getColumns(db: SQLiteDatabase, tableName: String): List { - val columns = mutableListOf() + CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "importOmdbZipFile", "${currentConfig.table}结束===总量$elementIndex") - // 查询 sqlite_master 表获取指定数据表的元数据信息 - val cursor = db.query( - "sqlite_master", - arrayOf("sql"), - "type='table' AND name=?", - arrayOf(tableName), - null, - null, - null - ) + if (isEmit) { + f.send(listRenderEntity) + delay(20) - // 从元数据信息中解析出列名 - if (cursor.moveToFirst()) { - val sql = cursor.getString(0) - val startIndex = sql.indexOf("(") + 1 - val endIndex = sql.lastIndexOf(")") - val columnDefs = sql.substring(startIndex, endIndex).split(",") - for (columnDef in columnDefs) { - val columnName = columnDef.trim().split(" ")[0] - if (!columnName.startsWith("rowid", true)) { // 排除 rowid 列 - columns.add(columnName) + } else { + bufferedReader.close() + realm!!.copyToRealm(listRenderEntity) + realm!!.commitTransaction() } } + if (!isEmit) { + realm!!.close() + } + } catch (e: Exception) { + Log.e("jingo", "安装报错 ${currentConfig.table} ${elementIndex} ${e.message}") + throw e } - cursor.close() - return columns + Log.e("jingo", "完成 ${currentConfig.table}") } + + +// // 获取指定数据表的列名 +// fun getColumns(db: SQLiteDatabase, tableName: String): List { +// val columns = mutableListOf() +// +// // 查询 sqlite_master 表获取指定数据表的元数据信息 +// val cursor = db.query( +// "sqlite_master", +// arrayOf("sql"), +// "type='table' AND name=?", +// arrayOf(tableName), +// null, +// null, +// null +// ) +// +// // 从元数据信息中解析出列名 +// if (cursor.moveToFirst()) { +// val sql = cursor.getString(0) +// val startIndex = sql.indexOf("(") + 1 +// val endIndex = sql.lastIndexOf(")") +// val columnDefs = sql.substring(startIndex, endIndex).split(",") +// for (columnDef in columnDefs) { +// val columnName = columnDef.trim().split(" ")[0] +// if (!columnName.startsWith("rowid", true)) { // 排除 rowid 列 +// columns.add(columnName) +// } +// } +// } +// cursor.close() +// return columns +// } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt b/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt index 276c137f..81857102 100644 --- a/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt +++ b/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt @@ -1,10 +1,15 @@ package com.navinfo.omqs.db import android.util.Log +import com.alibaba.fastjson.JSON +import com.google.gson.Gson +import com.navinfo.collect.library.data.entity.LinkRelation import com.navinfo.collect.library.data.entity.ReferenceEntity import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.collect.library.enums.DataCodeEnum +import com.navinfo.collect.library.utils.DeflaterUtil import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.collect.library.utils.StrZipUtil import com.navinfo.omqs.Constant import io.realm.Realm import io.realm.RealmModel @@ -15,30 +20,44 @@ import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.geom.Geometry import org.locationtech.jts.io.WKTWriter import org.oscim.core.GeoPoint +import java.util.* class ImportPreProcess { val code2NameMap = Code2NameMap() - lateinit var cacheRdLink: Map + + // lateinit var cacheRdLink: Map val defaultTranslateDistance = 3.0 val testFlag: Boolean = false - var realm:Realm? = null + var realm: Realm? = null + val gson = Gson() fun checkCircleRoad(renderEntity: RenderEntity): Boolean { val linkInId = renderEntity.properties["linkIn"] val linkOutId = renderEntity.properties["linkOut"] - // 根据linkIn和linkOut获取对应的link数据 - val linkInEntity = cacheRdLink[linkInId] - val linkOutEntity = cacheRdLink[linkOutId] - Log.d( - "checkCircleRoad", - "LinkInEntity: ${linkInId}- ${linkInEntity?.properties?.get("snodePid")},LinkOutEntity: ${linkOutId}- ${ - linkOutEntity?.properties?.get("enodePid") - }" - ) - // 查询linkIn的sNode和linkOut的eNode是否相同,如果相同,认为数据是环形路口,返回false - if (linkInEntity != null && linkOutEntity != null) { - if (linkInEntity.properties["snodePid"] == linkOutEntity.properties["enodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["snodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["enodePid"]) { - return false +// // 根据linkIn和linkOut获取对应的link数据 +// val linkInEntity = cacheRdLink[linkInId] +// val linkOutEntity = cacheRdLink[linkOutId] + realm?.let { + val linkInEntity = it.where(RenderEntity::class.java) + .equalTo("code", DataCodeEnum.OMDB_RD_LINK.code) + .and().equalTo("linkPid", linkInId) + .findFirst() + val linkOutEntity = it.where(RenderEntity::class.java) + .equalTo("code", DataCodeEnum.OMDB_RD_LINK.code) + .and().equalTo("linkPid", linkOutId) + .findFirst() + + Log.d( + "checkCircleRoad", + "LinkInEntity: ${linkInId}- ${linkInEntity?.properties?.get("snodePid")},LinkOutEntity: ${linkOutId}- ${ + linkOutEntity?.properties?.get("enodePid") + }" + ) + // 查询linkIn的sNode和linkOut的eNode是否相同,如果相同,认为数据是环形路口,返回false + if (linkInEntity != null && linkOutEntity != null) { + if (linkInEntity.properties["snodePid"] == linkOutEntity.properties["enodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["snodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["enodePid"]) { + return false + } } } return true @@ -200,16 +219,16 @@ class ImportPreProcess { startGeometry!!.coordinates[startGeometry.numPoints - 1] // 获取这个geometry对应的结束点坐标 if (translateGeometry.geometryType == Geometry.TYPENAME_LINESTRING) { // 如果是线数据,则取倒数第二个点作为偏移的起止点 pointEnd = - translateGeometry!!.coordinates[translateGeometry.numPoints - 2] // 获取这个geometry对应的结束点坐标 + translateGeometry.coordinates[translateGeometry.numPoints - 2] // 获取这个geometry对应的结束点坐标 } if (startGeometry.geometryType == Geometry.TYPENAME_LINESTRING) { // 如果是线数据,则取倒数第二个点作为偏移的起止点 pointStart = - startGeometry!!.coordinates[startGeometry.numPoints - 2] // 获取这个geometry对应的结束点坐标 + startGeometry.coordinates[startGeometry.numPoints - 2] // 获取这个geometry对应的结束点坐标 } // 将这个起终点的线记录在数据中 val startEndReference = ReferenceEntity() - startEndReference.renderEntityId = renderEntity.id +// startEndReference.renderEntityId = renderEntity.id startEndReference.name = "${renderEntity.name}参考线" startEndReference.table = renderEntity.table startEndReference.zoomMin = renderEntity.zoomMin @@ -222,6 +241,7 @@ class ImportPreProcess { startEndReference.properties["qi_table"] = renderEntity.table startEndReference.properties["type"] = "s_2_e" val listResult = mutableListOf() + startEndReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(startEndReference.properties)) listResult.add(startEndReference) insertData(listResult) } @@ -254,7 +274,7 @@ class ImportPreProcess { // 将这个起终点的线记录在数据中 val startReference = ReferenceEntity() - startReference.renderEntityId = renderEntity.id +// startReference.renderEntityId = renderEntity.id startReference.name = "${renderEntity.name}参考点" startReference.code = renderEntity.code startReference.table = renderEntity.table @@ -262,7 +282,6 @@ class ImportPreProcess { startReference.zoomMax = renderEntity.zoomMax startReference.taskId = renderEntity.taskId startReference.enable = renderEntity.enable - // 起点坐标 startReference.geometry = GeometryTools.createGeometry(GeoPoint(pointStart.y, pointStart.x)).toString() @@ -272,7 +291,7 @@ class ImportPreProcess { listResult.add(startReference) val endReference = ReferenceEntity() - endReference.renderEntityId = renderEntity.id +// endReference.renderEntityId = renderEntity.id endReference.name = "${renderEntity.name}参考点" endReference.code = renderEntity.code endReference.table = renderEntity.table @@ -306,7 +325,7 @@ class ImportPreProcess { // 将这个起终点的线记录在数据中 val startReference = ReferenceEntity() - startReference.renderEntityId = renderEntity.id +// startReference.renderEntityId = renderEntity.id startReference.name = "${renderEntity.name}参考点" startReference.code = renderEntity.code startReference.table = renderEntity.table @@ -338,12 +357,13 @@ class ImportPreProcess { Log.e("qj", "generateS2EReferencePoint===${startReference.geometry}") startReference.properties["geometry"] = startReference.geometry + startReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(startReference.properties)) listResult.add(startReference) Log.e("qj", "generateS2EReferencePoint===1") val endReference = ReferenceEntity() - endReference.renderEntityId = renderEntity.id +// endReference.renderEntityId = renderEntity.id endReference.name = "${renderEntity.name}参考点" endReference.code = renderEntity.code endReference.table = renderEntity.table @@ -372,7 +392,7 @@ class ImportPreProcess { Log.e("qj", "generateS2EReferencePoint===e_2_p${renderEntity.name}") } endReference.properties["geometry"] = endReference.geometry - + endReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(endReference.properties)) listResult.add(endReference) Log.e("qj", "generateS2EReferencePoint===4") insertData(listResult) @@ -458,7 +478,7 @@ class ImportPreProcess { val coorEnd = Coordinate(pointStart.getX() + dx, pointStart.getY() + dy, pointStart.z) val angleReference = ReferenceEntity() - angleReference.renderEntityId = renderEntity.id +// angleReference.renderEntityId = renderEntity.id angleReference.name = "${renderEntity.name}参考方向" angleReference.table = renderEntity.table angleReference.zoomMin = renderEntity.zoomMin @@ -470,6 +490,7 @@ class ImportPreProcess { WKTWriter(3).write(GeometryTools.createLineString(arrayOf(pointStart, coorEnd))) angleReference.properties["qi_table"] = renderEntity.table angleReference.properties["type"] = "angle" + angleReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(angleReference.properties)) listResult.add(angleReference) } insertData(listResult) @@ -553,10 +574,12 @@ class ImportPreProcess { renderEntityTemp.catchEnable = renderEntity.catchEnable var dis = -lateralOffset.toDouble() / 100000000 //最小值取10厘米,否正渲染太近无法显示 - if (dis > 0 && dis < 0.0000028) { - dis = 0.0000028 - } else if (dis > -0.0000028 && dis < 0) { - dis = -0.0000028 + if (dis > 0 && dis < 0.000005) { + dis = 0.000005 + Log.d("lateralOffset", "$dis") + } else if (dis > -0.000005 && dis < 0) { + dis = -0.000005 + Log.d("lateralOffset", "$dis") } renderEntityTemp.geometry = GeometryTools.computeLine( dis, @@ -605,7 +628,7 @@ class ImportPreProcess { for (i in 0 until laneInfoDirectArray.length()) { // 根据后续的数据生成辅助表数据 val referenceEntity = ReferenceEntity() - referenceEntity.renderEntityId = renderEntity.id +// referenceEntity.renderEntityId = renderEntity.id referenceEntity.name = "${renderEntity.name}参考方向" referenceEntity.table = renderEntity.table referenceEntity.enable = renderEntity.enable @@ -613,7 +636,7 @@ class ImportPreProcess { referenceEntity.zoomMin = renderEntity.zoomMin referenceEntity.zoomMax = renderEntity.zoomMax // 与原数据使用相同的geometry - referenceEntity.geometry = renderEntity.geometry.toString() + referenceEntity.geometry = renderEntity.geometry referenceEntity.properties["qi_table"] = renderEntity.table referenceEntity.properties["currentDirect"] = laneInfoDirectArray[i].toString().split(",").distinct().joinToString("_") @@ -624,6 +647,7 @@ class ImportPreProcess { referenceEntity.properties["symbol"] = "assets:omdb/4601/${type}/1301_${referenceEntity.properties["currentDirect"]}.svg" Log.d("unpackingLaneInfo", referenceEntity.properties["symbol"].toString()) + referenceEntity.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(referenceEntity.properties)) listResult.add(referenceEntity) } insertData(listResult) @@ -716,14 +740,16 @@ class ImportPreProcess { * 生成车道中心线面宽度 * */ fun generateAddWidthLine(renderEntity: RenderEntity) { + var newTime = 0L // 添加车道中心面渲染原则,根据车道宽度进行渲染 val angleReference = ReferenceEntity() - angleReference.renderEntityId = renderEntity.id + // angleReference.renderEntityId = renderEntity.id angleReference.name = "${renderEntity.name}车道中线面" angleReference.table = renderEntity.table - angleReference.geometry = - GeometryTools.createGeometry(renderEntity.geometry).buffer(0.000035) - .toString()//GeometryTools.computeLine(0.000035,0.000035,renderEntity.geometry) + Log.e("jingo", "几何转换开始") + angleReference.geometry = renderEntity.geometry + //GeometryTools.createGeometry(renderEntity.geometry).buffer(0.000035).toString()//GeometryTools.computeLine(0.000035,0.000035,renderEntity.geometry) + Log.e("jingo", "几何转换结束") angleReference.properties["qi_table"] = renderEntity.table angleReference.properties["widthProperties"] = "3" angleReference.zoomMin = renderEntity.zoomMin @@ -731,6 +757,7 @@ class ImportPreProcess { angleReference.taskId = renderEntity.taskId angleReference.enable = renderEntity.enable val listResult = mutableListOf() + angleReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(angleReference.properties)) listResult.add(angleReference) insertData(listResult) } @@ -748,7 +775,7 @@ class ImportPreProcess { for (i in 0 until nodeListJsonArray.length()) { val nodeJSONObject = nodeListJsonArray.getJSONObject(i) val intersectionReference = ReferenceEntity() - intersectionReference.renderEntityId = renderEntity.id +// intersectionReference.renderEntityId = renderEntity.id intersectionReference.name = "${renderEntity.name}参考点" intersectionReference.code = renderEntity.code intersectionReference.table = renderEntity.table @@ -761,6 +788,7 @@ class ImportPreProcess { GeometryTools.createGeometry(nodeJSONObject["geometry"].toString()).toString() intersectionReference.properties["qi_table"] = renderEntity.table intersectionReference.properties["type"] = "node" + intersectionReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(intersectionReference.properties)) listResult.add(intersectionReference) } insertData(listResult) @@ -915,7 +943,7 @@ class ImportPreProcess { val coorEnd = Coordinate(pointStart.getX() + dx, pointStart.getY() + dy, pointStart.z) val dynamicSrcReference = ReferenceEntity() - dynamicSrcReference.renderEntityId = renderEntity.id +// dynamicSrcReference.renderEntityId = renderEntity.id dynamicSrcReference.name = "${renderEntity.name}动态icon" dynamicSrcReference.table = renderEntity.table dynamicSrcReference.zoomMin = renderEntity.zoomMin @@ -929,17 +957,17 @@ class ImportPreProcess { dynamicSrcReference.properties["type"] = "dynamicSrc" val code = renderEntity.properties[codeName] dynamicSrcReference.properties["src"] = "${prefix}${code}${suffix}" + dynamicSrcReference.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(dynamicSrcReference.properties)) listResult.add(dynamicSrcReference) } insertData(listResult) } private fun insertData(list: List) { - Log.e("qj", "子表插入==") - if (list != null && list.isNotEmpty()) { - Log.e("qj", "子表插入开始==") - Realm.getInstance(Constant.currentInstallTaskConfig).insert(list) - Log.e("qj", "子表插入结束==") + realm?.let { + if (list != null && list.isNotEmpty()) { + it.copyToRealm(list) + } } } diff --git a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt index 30cfb6d6..97f81dd7 100644 --- a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt @@ -6,7 +6,6 @@ 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 @@ -65,13 +64,12 @@ class RealmOperateHelper() { 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) - .greaterThanOrEqualTo("tileX", xStart) - .lessThanOrEqualTo("tileX", xEnd) - .greaterThanOrEqualTo("tileY", yStart) - .lessThanOrEqualTo("tileY", yEnd) + .rawPredicate(sql) .findAll() // 将获取到的数据和查询的polygon做相交,只返回相交的数据 val dataList = realm.copyFromRealm(realmList) @@ -133,12 +131,11 @@ class RealmOperateHelper() { 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) - .greaterThanOrEqualTo("tileX", xStart) - .lessThanOrEqualTo("tileX", xEnd) - .greaterThanOrEqualTo("tileY", yStart) - .lessThanOrEqualTo("tileY", yEnd) + .rawPredicate(sql) .findAll() // 将获取到的数据和查询的polygon做相交,只返回相交的数据 val dataList = realm.copyFromRealm(realmList) @@ -178,7 +175,8 @@ class RealmOperateHelper() { ) val realm = getRealmDefaultInstance() try { - val realmList = realm.where(HadLinkDvoBean::class.java).equalTo("taskId", taskId).findAll() + val realmList = + realm.where(HadLinkDvoBean::class.java).equalTo("taskId", taskId).findAll() var linkBean: HadLinkDvoBean? = null var nearLast: Double = 99999.99 for (link in realmList) { @@ -206,7 +204,7 @@ class RealmOperateHelper() { val realm = getSelectTaskRealmInstance() val realmR = realm.where(RenderEntity::class.java).equalTo("table", "OMDB_RD_LINK_KIND") - .equalTo("properties['${LinkTable.linkPid}']", linkPid).findFirst() + .equalTo("linkPid", linkPid).findFirst() if (realmR != null) { link = realm.copyFromRealm(realmR) } @@ -238,7 +236,7 @@ class RealmOperateHelper() { // val realm = getSelectTaskRealmInstance() val realmR = getSelectTaskRealmTools(realm, RenderEntity::class.java, true) - .equalTo("properties['${LinkTable.linkPid}']", linkPid).findAll() + .equalTo("linkPid", linkPid).findAll() val dataList = realm.copyFromRealm(realmR) @@ -284,11 +282,11 @@ class RealmOperateHelper() { val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null) val realm = getSelectTaskRealmInstance() var realmList = mutableListOf() + 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) - .greaterThanOrEqualTo("tileX", xStart) - .lessThanOrEqualTo("tileX", xEnd) - .greaterThanOrEqualTo("tileY", yStart) - .lessThanOrEqualTo("tileY", yEnd) + .rawPredicate(sql) // 筛选不显示的数据 if (catchAll) { // 查询realm中对应tile号的数据 @@ -333,7 +331,7 @@ class RealmOperateHelper() { val result = mutableListOf() val realmList = getSelectTaskRealmTools(realm, RenderEntity::class.java, false) .notEqualTo("table", DataCodeEnum.OMDB_RD_LINK.name) - .equalTo("properties['${LinkTable.linkPid}']", linkPid) + .equalTo("linkPid", linkPid) .findAll() result.addAll(realm.copyFromRealm(realmList)) return result diff --git a/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt b/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt index 69963b8b..4dffc1b4 100644 --- a/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt +++ b/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt @@ -154,20 +154,6 @@ class GlobalModule { ) } -// /** -// * realm 注册 -// */ -// @Provides -// @Singleton -// fun provideRealmService(context: Application): RealmCoroutineScope { -// return RealmCoroutineScope(context) -// } - -// @Singleton -// @Provides -// fun provideRealmDefaultInstance(): Realm { -// return Realm.getDefaultInstance() -// } @Singleton @Provides diff --git a/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt b/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt index 38cf4f82..e93e47fa 100644 --- a/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt +++ b/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt @@ -155,21 +155,20 @@ class TaskDownloadScope( fileNew ) if (task != null) { - importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task).collect { - Log.e("jingo", "数据安装 $it") - if (it == "finish") { - change(FileDownloadStatus.DONE) - Log.e("jingo", "数据安装结束") - withContext(Dispatchers.Main) { - //任务与当前一致,需要更新渲染图层 - if (MapParamUtils.getTaskId() == taskBean.id) { - downloadManager.mapController.layerManagerHandler.updateOMDBVectorTileLayer() - } + if (importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task, this)) { +// if (it == "finish") { + change(FileDownloadStatus.DONE) + Log.e("jingo", "数据安装结束") + withContext(Dispatchers.Main) { + //任务与当前一致,需要更新渲染图层 + if (MapParamUtils.getTaskId() == taskBean.id) { + downloadManager.mapController.layerManagerHandler.updateOMDBVectorTileLayer() } - } else { - change(FileDownloadStatus.IMPORTING, it) } + } else { + change(FileDownloadStatus.IMPORTING, "anzhuang") } +// } } } catch (e: Exception) { Log.e("jingo", "数据安装失败 ${e.toString()}") diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginActivity.kt index f6a9b4f4..75801d42 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginActivity.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginActivity.kt @@ -1,7 +1,5 @@ package com.navinfo.omqs.ui.activity.login -import android.app.Activity -import android.app.ActivityManager import android.content.Intent import android.os.Bundle import android.util.DisplayMetrics @@ -11,7 +9,6 @@ import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog import androidx.databinding.DataBindingUtil import androidx.lifecycle.Observer -import androidx.lifecycle.viewModelScope import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.navinfo.omqs.R import com.navinfo.omqs.databinding.ActivityLoginBinding @@ -19,8 +16,6 @@ import com.navinfo.omqs.ui.activity.CheckPermissionsActivity import com.navinfo.omqs.ui.activity.map.MainActivity import com.umeng.commonsdk.UMConfigure import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch /** * 登陆页面 diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt index 037b2e97..ef7cd2f3 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt @@ -8,10 +8,13 @@ import android.widget.Toast import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase import com.blankj.utilcode.util.FileIOUtils import com.blankj.utilcode.util.ResourceUtils import com.google.gson.Gson import com.google.gson.reflect.TypeToken +import com.navinfo.collect.library.data.entity.LinkRelation import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.collect.library.data.entity.TaskBean import com.navinfo.collect.library.utils.GeometryTools @@ -27,6 +30,8 @@ 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 @@ -282,6 +287,12 @@ class LoginViewModel @Inject constructor( 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 //已上传后不在更新操作时间 @@ -293,8 +304,10 @@ class LoginViewModel @Inject constructor( } } else { for (hadLink in task.hadLinkDvoList) { - if(hadLink.geometry==null||hadLink.mesh==null){ + if(hadLink.geometry==null){ inSertData = false + }else if(hadLink.mesh==null){ + hadLink.mesh = "" }else{ hadLink.taskId = task.id } @@ -418,12 +431,15 @@ class LoginViewModel @Inject constructor( 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) // 656e6372797000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -431,8 +447,9 @@ class LoginViewModel @Inject constructor( .directory(userFolder) .name("OMQS.realm") .encryptionKey(Constant.PASSWORD) - .allowQueriesOnUiThread(true) - .schemaVersion(2) +// .allowQueriesOnUiThread(true) + .schemaVersion(3) + // .migration(migration) .build() Realm.setDefaultConfiguration(config) // 拷贝配置文件到用户目录下 @@ -458,4 +475,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) + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt index e19683fe..e3cc8287 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt @@ -27,6 +27,7 @@ import com.google.android.material.tabs.TabLayout import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.handler.MeasureLayerHandler +import com.navinfo.collect.library.utils.DeflaterUtil import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.omqs.Constant import com.navinfo.omqs.R @@ -56,6 +57,8 @@ import kotlinx.coroutines.launch import org.oscim.core.GeoPoint import org.oscim.renderer.GLViewport import org.videolan.vlc.Util +import sun.misc.BASE64Decoder +import sun.misc.BASE64Encoder import java.math.BigDecimal import java.math.RoundingMode import javax.inject.Inject @@ -190,7 +193,8 @@ class MainActivity : BaseActivity() { viewModel.speakMode = SpeakMode(this) // 在mapController初始化前获取当前OMDB图层显隐 viewModel.refreshOMDBLayer(LayerConfigUtils.getLayerConfigList()) - mapController.mMapView.vtmMap.viewport().maxZoomLevel = com.navinfo.collect.library.system.Constant.MAX_ZOOM + mapController.mMapView.vtmMap.viewport().maxZoomLevel = + com.navinfo.collect.library.system.Constant.MAX_ZOOM //关联生命周期 binding.lifecycleOwner = this //给xml转递对象 @@ -344,17 +348,17 @@ class MainActivity : BaseActivity() { } } viewModel.liveDataAutoLocation.observe(this) { - if (it == true) { + if (it == true && Constant.INDOOR_IP == null || Constant.INDOOR_IP == "") { onClickLocation() } } viewModel.liveDataSignMoreInfo.observe(this) { - if(!rightController.backQueue.isEmpty()){ + if (!rightController.backQueue.isEmpty()) { rightController.navigateUp() } - lifecycleScope.launch{ + lifecycleScope.launch { delay(100) val bundle = Bundle() @@ -367,8 +371,10 @@ class MainActivity : BaseActivity() { supportFragmentManager.beginTransaction() .replace(R.id.main_activity_sign_more_info_fragment, SignMoreInfoFragment()) .commit() - }else{ - supportFragmentManager.beginTransaction().add(R.id.main_activity_sign_more_info_fragment, SignMoreInfoFragment()).commit() + } else { + supportFragmentManager.beginTransaction() + .add(R.id.main_activity_sign_more_info_fragment, SignMoreInfoFragment()) + .commit() } } } @@ -437,10 +443,12 @@ class MainActivity : BaseActivity() { if (loadingDialog.isShowing) loadingDialog.dismiss() } + NaviStatus.NAVI_STATUS_PATH_PLANNING -> { if (!loadingDialog.isShowing) loadingDialog.show() } + NaviStatus.NAVI_STATUS_PATH_ERROR_NODE -> { Toast.makeText( this, @@ -458,9 +466,11 @@ class MainActivity : BaseActivity() { ).show() loadingDialog.dismiss() } + NaviStatus.NAVI_STATUS_PATH_SUCCESS -> { loadingDialog.dismiss() } + NaviStatus.NAVI_STATUS_DISTANCE_OFF -> { Toast.makeText( this, @@ -468,6 +478,7 @@ class MainActivity : BaseActivity() { Toast.LENGTH_SHORT ).show() } + NaviStatus.NAVI_STATUS_DIRECTION_OFF -> { } } @@ -494,6 +505,18 @@ class MainActivity : BaseActivity() { } } + viewModel.liveDataLoadData.observe(this) { + when (it) { + LoadDataStatus.LOAD_DATA_STATUS_BEGIN -> { + showLoadingDialog("正在加载数据...") + } + + LoadDataStatus.LOAD_DATA_STATUS_FISISH -> { + hideLoadingDialog() + } + } + } + lifecycleScope.launch { // 初始化地图图层控制接收器 FlowEventBus.subscribe>( @@ -791,6 +814,9 @@ class MainActivity : BaseActivity() { */ fun zoomInOnclick(view: View) { //Log.e("qj", "computeline==${GeometryTools.computeLine(175.0/1000000000,"LINESTRING(116.71523523056109 39.92252072202544 16.08, 116.7152446525368 39.922528935578065 16.04, 116.7152492633007 39.92253304221301 16.03, 116.71525397428678 39.922537148987885 16.02, 116.7152585850368 39.92254115561753 16, 116.71526319579864 39.9225452622508 15.99, 116.7152678065473 39.92254926887934 15.99, 116.71527241730776 39.92255337551149 15.97, 116.71527702806752 39.9225574821431 15.96, 116.71528163882658 39.92256158877415 15.94, 116.71528624957249 39.92256559540047 15.92, 116.7152908603302 39.92256970203041 15.91, 116.7152954710872 39.9225738086598 15.9, 116.71529998162082 39.92257791514826 15.88, 116.71530459237646 39.92258202177656 15.87, 116.71530920313141 39.9225861284043 15.86, 116.71531381388567 39.92259023503148 15.85, 116.7153183244166 39.92259434151779 15.84, 116.71532293516951 39.92259844814387 15.82, 116.71532754590925 39.92260245476522 15.82, 116.71533205643817 39.92260656124991 15.8, 116.71533666718902 39.922610667874345 15.79, 116.71534127793919 39.92261477449822 15.78, 116.71534588868865 39.922618881121544 15.77, 116.7153503992149 39.92262298760407 15.76, 116.715355009963 39.92262709422631 15.75, 116.71535962071042 39.922631200847974 15.75, 116.71536423144467 39.9226352074649 15.74, 116.71536884219071 39.922639314085465 15.73, 116.71537335271358 39.922643420565294 15.72, 116.71537796345827 39.92264752718475 15.72, 116.71538257420224 39.92265163380365 15.72, 116.71538718494553 39.92265574042201 15.71, 116.71539179567566 39.92265974703562 15.71, 116.71539640641758 39.92266385365286 15.7, 116.7154010171588 39.92266796026954 15.7, 116.71540562789932 39.92267206688567 15.7, 116.71541023862667 39.92267607349705 15.69, 116.71541484936583 39.922680180112074 15.68, 116.7154194601043 39.922684286726536 15.68, 116.71542407084206 39.92268839334044 15.67, 116.71542868157914 39.92269249995378 15.66, 116.71543339252533 39.922696506702415 15.66, 116.715438003261 39.92270061331464 15.65, 116.71544261399599 39.92270471992631 15.64, 116.7154472247178 39.92270872653324 15.64, 116.71545193567363 39.92271283328377 15.63, 116.71545654640653 39.92271693989375 15.62, 116.71546115712626 39.922720946499005 15.62, 116.71546586806747 39.92272495324363 15.61, 116.71547047879827 39.92272905985193 15.6, 116.71547518973806 39.92273306659542 15.59, 116.71547990067711 39.92273707333831 15.59, 116.71548461161544 39.922741080080634 15.58, 116.71548922233096 39.9227450866825 15.58, 116.71549393326787 39.92274909342366 15.57, 116.71549854398198 39.9227531000244 15.57, 116.71550325491746 39.922757106764415 15.56, 116.71550796583975 39.922761013499674 15.55, 116.71551267677377 39.92276502023853 15.55, 116.71551738770708 39.9227690269768 15.54, 116.71552209863965 39.9227730337145 15.54, 116.71552680957151 39.922777040451614 15.53, 116.71553152050265 39.92278104718814 15.52, 116.71553633164253 39.922784954059665 15.52, 116.7155410425722 39.92278896079502 15.51, 116.71554575350116 39.92279296752979 15.51, 116.71555046442938 39.92279697426398 15.5, 116.71555527556629 39.92280088113311 15.49, 116.71555998648057 39.92280478786194 15.48, 116.71556469740662 39.922808794594374 15.48, 116.71556940831947 39.92281270132205 15.47, 116.7155742194534 39.922816608188796 15.47, 116.71557893037725 39.922820614919466 15.47, 116.71558374150969 39.92282452178501 15.46, 116.71558855264136 39.92282842864994 15.46, 116.71559326356302 39.92283243537885 15.45, 116.71559807469322 39.922836342242576 15.45, 116.71560288582265 39.922840249105704 15.44, 116.7156076969638 39.9228442559724 15.43, 116.71561250809172 39.92284816283432 15.43, 116.71561731921888 39.922852069695615 15.42, 116.7156221303453 39.92285597655631 15.42, 116.71562684124932 39.922859883276885 15.42, 116.71563165237423 39.92286379013638 15.41, 116.71563646349838 39.92286769699527 15.41, 116.7156411744002 39.922871603714064 15.41, 116.71564598552287 39.92287551057175 15.41, 116.71565079664477 39.922879417428824 15.4, 116.71565560776592 39.922883324285294 15.4, 116.71566041888632 39.922887231141154 15.39, 116.71566512978445 39.922891137856986 15.39, 116.71567004112484 39.922895044851046 15.39, 116.71567485224296 39.92289895170508 15.38, 116.71567966334786 39.92290275855433 15.38, 116.71568457468592 39.92290666554651 15.38, 116.71568938580177 39.922910572398706 15.37, 116.71569429712578 39.92291437938545 15.37, 116.7156992084615 39.922918286375754 15.37, 116.71570411978394 39.92292209336123 15.36, 116.71570903110559 39.92292590034607 15.36, 116.7157140426478 39.92292970746958 15.36, 116.71571895396787 39.92293351445314 15.35, 116.71572396550846 39.92293732157533 15.35, 116.71572887682693 39.92294112855762 15.35, 116.71573388835341 39.92294483567432 15.34, 116.71573889989156 39.922948642794545 15.34, 116.71574391142887 39.922952449914106 15.33, 116.7157489229529 39.92295615702883 15.33, 116.71575383426735 39.92295996400789 15.32, 116.71575884578974 39.9229636711213 15.32, 116.7157638573238 39.92296747823824 15.32, 116.71576886884453 39.922971185350335 15.32, 116.71577378015579 39.922974992326814 15.31, 116.7157787916749 39.92297869943759 15.31, 116.71578380320568 39.9229825065519 15.31, 116.71578881472315 39.92298621366136 15.3, 116.7157937260312 39.92299002063527 15.3, 116.71579873754702 39.922993727743425 15.3, 116.71580374907452 39.92299753485509 15.3, 116.71580876058873 39.92300124196192 15.3, 116.7158137721021 39.92300494906809 15.29, 116.71581878362713 39.92300875617778 15.29, 116.71582379513886 39.923012463282625 15.29, 116.71582880664977 39.92301617038681 15.29, 116.7158339183808 39.92301987762931 15.28, 116.71583892987755 39.92302348472798 15.28, 116.71584404160689 39.923027191969105 15.27, 116.7158491533229 39.92303079920537 15.27, 116.71585426505052 39.92303450644512 15.27, 116.71585947698568 39.92303811381891 15.27, 116.71586458869909 39.923041721053096 15.26, 116.7158698006325 39.92304532842547 15.26, 116.715875012565 39.92304893579713 15.26, 116.7158802244966 39.92305254316806 15.26, 116.71588543642733 39.92305615053829 15.25, 116.71589064834468 39.92305965790362 15.25, 116.7158958602736 39.92306326527241 15.25, 116.7159011724099 39.9230667727751 15.25, 116.71590638433705 39.92307038014245 15.25, 116.71591169647151 39.92307388764366 15.24, 116.71591690839685 39.92307749500956 15.24, 116.71592222052946 39.923081002509306 15.24, 116.71592743244052 39.923084509869575 15.23, 116.7159327445713 39.92308801736784 15.23, 116.71593805670116 39.92309152486536 15.23, 116.71594326860951 39.92309503222346 15.23, 116.71594858073753 39.923098539719504 15.23, 116.71595379264407 39.92310204707615 15.23, 116.71595910477025 39.92310555457072 15.22, 116.71596431667498 39.92310906192592 15.22, 116.71596962879933 39.92311256941902 15.22, 116.71597494092273 39.92311607691136 15.22, 116.71598025303274 39.92311948439879 15.21, 116.7159855651543 39.92312299188965 15.21, 116.71599087726246 39.92312639937558 15.21, 116.71599628959011 39.92312980699931 15.21, 116.71600160169638 39.92313321448375 15.2, 116.71600701402213 39.92313662210594 15.2, 116.71601242634688 39.92314002972738 15.2, 116.71601773843786 39.92314333720536 15.2, 116.71602315076072 39.92314674482525 15.2, 116.7160285630826 39.92315015244437 15.2, 116.71603397539106 39.923153460058536 15.19, 116.71603938771102 39.9231568676761 15.19, 116.7160449002378 39.923160175427135 15.19, 116.71605031255581 39.923163583043134 15.19, 116.71605572486038 39.923166890654194 15.19, 116.71606123739667 39.923170298407015 15.19, 116.71606664969929 39.92317360601651 15.18, 116.71607216222111 39.92317691376356 15.18, 116.71607767474192 39.92318022150982 15.18, 116.71608308704162 39.92318352911695 15.18, 116.71608859956046 39.92318683686161 15.18, 116.7160941120783 39.92319014460546 15.18, 116.71609952436255 39.92319335220606 15.18, 116.7161050368784 39.92319665994833 15.18, 116.71611054938076 39.923199867685604 15.18, 116.71611606189461 39.92320317542626 15.17, 116.71612167461498 39.92320638330014 15.17, 116.71612718711431 39.92320959103499 15.17, 116.71613269961263 39.923212798769036 15.17, 116.71613831232992 39.923216006640445 15.17, 116.71614392504615 39.92321921451102 15.17, 116.71614943752895 39.923222322238445 15.17, 116.71615505024315 39.92322553010736 15.16, 116.7161606629438 39.92322863797127 15.16, 116.71616637586328 39.92323174597244 15.16, 116.71617198857432 39.923234953838836 15.16, 116.71617760127184 39.92323806170023 15.15, 116.7161832139683 39.92324116956078 15.15, 116.71618882666372 39.9232442774205 15.15, 116.71619453957788 39.9232473854174 15.15, 116.71620015227123 39.92325049327543 15.14, 116.71620586518323 39.923253601270616 15.14, 116.71621147787447 39.92325670912697 15.14, 116.71621719078435 39.92325981712044 15.14, 116.71622290368066 39.923262825108864 15.13, 116.71622861658837 39.9232659331006 15.13, 116.71623432949501 39.92326904109148 15.12, 116.7162400423881 39.92327204907731 15.12, 116.71624575529258 39.92327515706645 15.12, 116.71625146818349 39.92327816505055 15.12, 116.71625718107332 39.92328117303378 15.12, 116.71626299418162 39.92328418115398 15.12, 116.71626880728878 39.92328718927328 15.12, 116.71627452017535 39.923290197253884 15.12, 116.7162803332803 39.92329320537141 15.11, 116.7162862466036 39.92329621362581 15.11, 116.71629205969381 39.92329912173736 15.11, 116.71629787279538 39.923302129852175 15.11, 116.71630378610277 39.92330503809964 15.11, 116.7163095991896 39.923307946208475 15.11, 116.71631551249467 39.9233108544541 15.11, 116.71632132557926 39.92331376256112 15.11, 116.71632723888203 39.92331667080491 15.11, 116.71633315218365 39.923319579047764 15.11, 116.71633906547164 39.923322387285516 15.11, 116.71634487855167 39.9233252953889 15.11, 116.71635079183736 39.923328103624804 15.11, 116.71635670512187 39.923330911859786 15.12, 116.7163626184177 39.923333820098016 15.12, 116.7163685316999 39.92333662833113 15.12, 116.71637444498094 39.923339436563325 15.12, 116.71638045846748 39.92334214492792 15.13, 116.71638637174618 39.923344953158235 15.13, 116.71639238524283 39.923347761525115 15.13, 116.71639829850669 39.92335046974937 15.13, 116.71640431200096 39.92335327811434 15.13, 116.71641032548153 39.923355986474164 15.13, 116.71641633896091 39.923358694833034 15.14, 116.71642235243908 39.92336140319093 15.14, 116.71642836591604 39.92336411154787 15.14, 116.7164343794043 39.92336691990802 15.14, 116.71644039287887 39.92336962826304 15.14, 116.71644640635223 39.92337233661709 15.14, 116.71645241982439 39.92337504497017 15.14, 116.71645843329536 39.9233777533223 15.14, 116.71646454698399 39.92338046181075 15.15, 116.71647056045252 39.92338317016094 15.14, 116.71647657391985 39.92338587851015 15.15, 116.7164826875923 39.92338848699148 15.15, 116.7164887010572 39.92339119533876 15.15, 116.71649481473968 39.92339390382228 15.15, 116.71650082820216 39.92339661216761 15.15, 116.71650694186967 39.92339922064498 15.15, 116.71651305553594 39.92340182912136 15.15, 116.71651906899477 39.92340453746377 15.15, 116.71652518265857 39.92340714593817 15.15, 116.71653129632114 39.923409754411566 15.15, 116.71653740998245 39.92341236288397 15.15, 116.71654352363004 39.92341487135121 15.16, 116.71654963728885 39.92341747982162 15.16, 116.71655575093396 39.92341998828686 15.16, 116.71656186459028 39.92342259675527 15.16, 116.71656797823289 39.92342510521852 15.16, 116.71657419209275 39.92342761381777 15.16, 116.71658030573283 39.923430122279 15.16, 116.7165864193717 39.923432630739235 15.16, 116.71659263322773 39.92343513933543 15.16, 116.71659874687653 39.92343774779782 15.17, 116.71660496073002 39.92344025639196 15.17, 116.71661107436383 39.92344276484817 15.17, 116.71661728821475 39.92344527344027 15.17, 116.7166235020644 39.92344778203134 15.17, 116.71662971591275 39.923450290621375 15.17, 116.7166359297598 39.923452799210374 15.18, 116.71664214360558 39.92345530779835 15.18, 116.7166482572318 39.92345781624847 15.19, 116.71665447106253 39.923460224830215 15.19, 116.71666068490445 39.92346273341511 15.19, 116.7166668987326 39.92346514199479 15.19, 116.71667311255946 39.92346755057344 15.2, 116.71667932638503 39.92346995915106 15.2, 116.7166855402218 39.92347246773181 15.2, 116.71669175404479 39.92347487630736 15.21, 116.7166979678665 39.92347728488188 15.21, 116.7167041816869 39.92347969345537 15.21, 116.71671039549352 39.92348200202364 15.22, 116.71671660931135 39.92348441059506 15.22, 116.71672292334588 39.92348681930205 15.23, 116.71672913714863 39.9234891278672 15.23, 116.71673545118051 39.92349153657207 15.23, 116.71674176519859 39.9234938452717 15.24, 116.71674807921534 39.92349615397027 15.24, 116.71675439323073 39.92349846266776 15.24, 116.71676070725728 39.923500871368354 15.25, 116.71676702127003 39.92350318006371 15.25, 116.71677333528143 39.923505488757996 15.25, 116.7167796492915 39.92350779745122 15.26, 116.71678596330021 39.923510106143375 15.26, 116.71679227729514 39.923512314830276 15.27, 116.71679849108345 39.92351462338389 15.27, 116.71680480508819 39.92351693207285 15.27, 116.71681121929683 39.923519140892935 15.27, 116.71681753329888 39.92352144957974 15.28, 116.7168238472871 39.92352365826131 15.29, 116.71683026150413 39.92352596708229 15.29, 116.7168366757073 39.923528175898 15.29, 116.71684308990908 39.923530384712606 15.3, 116.7168494038919 39.92353259338984 15.3, 116.71685581810343 39.92353490220642 15.31, 116.71686213208355 39.9235371108815 15.31, 116.71686854627985 39.92353931969171 15.32, 116.71687486025728 39.92354152836462 15.32, 116.71688127445086 39.92354373717266 15.32, 116.71688758842558 39.923545945843415 15.33, 116.7168940026164 39.92354815464925 15.34, 116.71690031658844 39.923550363317844 15.34, 116.71690673076404 39.92355247211731 15.34, 116.7169132451681 39.92355468105595 15.35, 116.7169196593534 39.92355688985735 15.36, 116.71692607352483 39.92355899865349 15.36, 116.71693258791218 39.92356110758456 15.36, 116.7169390020933 39.92356331638264 15.37, 116.71694541626057 39.92356542517543 15.37, 116.7169517302092 39.92356753383113 15.38, 116.71695814437373 39.92356964262173 15.39, 116.71696455854935 39.9235718514154 15.39, 116.71697097271111 39.92357396020379 15.4, 116.71697738685899 39.923575968986896 15.41, 116.71698380101797 39.923578077773065 15.41, 116.71699031539268 39.923580186694025 15.41, 116.71699672954887 39.92358229547797 15.42, 116.71700324390825 39.92358430439248 15.43, 116.71700975826622 39.923586313305854 15.43, 116.71701627262276 39.92358832221809 15.44, 116.71702278697786 39.92359033112917 15.44, 116.71702920111456 39.92359233990333 15.45, 116.71703571545434 39.92359424880797 15.47, 116.71704222980519 39.92359625771565 15.47, 116.7170487441421 39.923598166618014 15.48, 116.7170552584776 39.923600075519225 15.49, 116.71706177281166 39.9236019844193 15.49, 116.71706818692746 39.923603893182545 15.51, 116.71707450081256 39.92360570180485 15.51, 116.71709684999163 39.92361243233016 15.55)")}") + val geometryStr = "LINESTRING(116.71523523056109 39.92252072202544 16.08, 116.7152446525368 39.922528935578065 16.04, 116.7152492633007 39.92253304221301 16.03, 116.71525397428678 39.922537148987885 16.02, 116.7152585850368 39.92254115561753 16, 116.71526319579864 39.9225452622508 15.99, 116.7152678065473 39.92254926887934 15.99, 116.71527241730776 39.92255337551149 15.97, 116.71527702806752 39.9225574821431 15.96, 116.71528163882658 39.92256158877415 15.94, 116.71528624957249 39.92256559540047 15.92, 116.7152908603302 39.92256970203041 15.91, 116.7152954710872 39.9225738086598 15.9, 116.71529998162082 39.92257791514826 15.88, 116.71530459237646 39.92258202177656 15.87, 116.71530920313141 39.9225861284043 15.86, 116.71531381388567 39.92259023503148 15.85, 116.7153183244166 39.92259434151779 15.84, 116.71532293516951 39.92259844814387 15.82, 116.71532754590925 39.92260245476522 15.82, 116.71533205643817 39.92260656124991 15.8, 116.71533666718902 39.922610667874345 15.79, 116.71534127793919 39.92261477449822 15.78, 116.71534588868865 39.922618881121544 15.77, 116.7153503992149 39.92262298760407 15.76, 116.715355009963 39.92262709422631 15.75, 116.71535962071042 39.922631200847974 15.75, 116.71536423144467 39.9226352074649 15.74, 116.71536884219071 39.922639314085465 15.73, 116.71537335271358 39.922643420565294 15.72, 116.71537796345827 39.92264752718475 15.72, 116.71538257420224 39.92265163380365 15.72, 116.71538718494553 39.92265574042201 15.71, 116.71539179567566 39.92265974703562 15.71, 116.71539640641758 39.92266385365286 15.7, 116.7154010171588 39.92266796026954 15.7, 116.71540562789932 39.92267206688567 15.7, 116.71541023862667 39.92267607349705 15.69, 116.71541484936583 39.922680180112074 15.68, 116.7154194601043 39.922684286726536 15.68, 116.71542407084206 39.92268839334044 15.67, 116.71542868157914 39.92269249995378 15.66, 116.71543339252533 39.922696506702415 15.66, 116.715438003261 39.92270061331464 15.65, 116.71544261399599 39.92270471992631 15.64, 116.7154472247178 39.92270872653324 15.64, 116.71545193567363 39.92271283328377 15.63, 116.71545654640653 39.92271693989375 15.62, 116.71546115712626 39.922720946499005 15.62, 116.71546586806747 39.92272495324363 15.61, 116.71547047879827 39.92272905985193 15.6, 116.71547518973806 39.92273306659542 15.59, 116.71547990067711 39.92273707333831 15.59, 116.71548461161544 39.922741080080634 15.58, 116.71548922233096 39.9227450866825 15.58, 116.71549393326787 39.92274909342366 15.57, 116.71549854398198 39.9227531000244 15.57, 116.71550325491746 39.922757106764415 15.56, 116.71550796583975 39.922761013499674 15.55, 116.71551267677377 39.92276502023853 15.55, 116.71551738770708 39.9227690269768 15.54, 116.71552209863965 39.9227730337145 15.54, 116.71552680957151 39.922777040451614 15.53, 116.71553152050265 39.92278104718814 15.52, 116.71553633164253 39.922784954059665 15.52, 116.7155410425722 39.92278896079502 15.51, 116.71554575350116 39.92279296752979 15.51, 116.71555046442938 39.92279697426398 15.5, 116.71555527556629 39.92280088113311 15.49, 116.71555998648057 39.92280478786194 15.48, 116.71556469740662 39.922808794594374 15.48, 116.71556940831947 39.92281270132205 15.47, 116.7155742194534 39.922816608188796 15.47, 116.71557893037725 39.922820614919466 15.47, 116.71558374150969 39.92282452178501 15.46, 116.71558855264136 39.92282842864994 15.46, 116.71559326356302 39.92283243537885 15.45, 116.71559807469322 39.922836342242576 15.45, 116.71560288582265 39.922840249105704 15.44, 116.7156076969638 39.9228442559724 15.43, 116.71561250809172 39.92284816283432 15.43, 116.71561731921888 39.922852069695615 15.42, 116.7156221303453 39.92285597655631 15.42, 116.71562684124932 39.922859883276885 15.42, 116.71563165237423 39.92286379013638 15.41, 116.71563646349838 39.92286769699527 15.41, 116.7156411744002 39.922871603714064 15.41, 116.71564598552287 39.92287551057175 15.41, 116.71565079664477 39.922879417428824 15.4, 116.71565560776592 39.922883324285294 15.4, 116.71566041888632 39.922887231141154 15.39, 116.71566512978445 39.922891137856986 15.39, 116.71567004112484 39.922895044851046 15.39, 116.71567485224296 39.92289895170508 15.38, 116.71567966334786 39.92290275855433 15.38, 116.71568457468592 39.92290666554651 15.38, 116.71568938580177 39.922910572398706 15.37, 116.71569429712578 39.92291437938545 15.37, 116.7156992084615 39.922918286375754 15.37, 116.71570411978394 39.92292209336123 15.36, 116.71570903110559 39.92292590034607 15.36, 116.7157140426478 39.92292970746958 15.36, 116.71571895396787 39.92293351445314 15.35, 116.71572396550846 39.92293732157533 15.35, 116.71572887682693 39.92294112855762 15.35, 116.71573388835341 39.92294483567432 15.34, 116.71573889989156 39.922948642794545 15.34, 116.71574391142887 39.922952449914106 15.33, 116.7157489229529 39.92295615702883 15.33, 116.71575383426735 39.92295996400789 15.32, 116.71575884578974 39.9229636711213 15.32, 116.7157638573238 39.92296747823824 15.32, 116.71576886884453 39.922971185350335 15.32, 116.71577378015579 39.922974992326814 15.31, 116.7157787916749 39.92297869943759 15.31, 116.71578380320568 39.9229825065519 15.31, 116.71578881472315 39.92298621366136 15.3, 116.7157937260312 39.92299002063527 15.3, 116.71579873754702 39.922993727743425 15.3, 116.71580374907452 39.92299753485509 15.3, 116.71580876058873 39.92300124196192 15.3, 116.7158137721021 39.92300494906809 15.29, 116.71581878362713 39.92300875617778 15.29, 116.71582379513886 39.923012463282625 15.29, 116.71582880664977 39.92301617038681 15.29, 116.7158339183808 39.92301987762931 15.28, 116.71583892987755 39.92302348472798 15.28, 116.71584404160689 39.923027191969105 15.27, 116.7158491533229 39.92303079920537 15.27, 116.71585426505052 39.92303450644512 15.27, 116.71585947698568 39.92303811381891 15.27, 116.71586458869909 39.923041721053096 15.26, 116.7158698006325 39.92304532842547 15.26, 116.715875012565 39.92304893579713 15.26, 116.7158802244966 39.92305254316806 15.26, 116.71588543642733 39.92305615053829 15.25, 116.71589064834468 39.92305965790362 15.25, 116.7158958602736 39.92306326527241 15.25, 116.7159011724099 39.9230667727751 15.25, 116.71590638433705 39.92307038014245 15.25, 116.71591169647151 39.92307388764366 15.24, 116.71591690839685 39.92307749500956 15.24, 116.71592222052946 39.923081002509306 15.24, 116.71592743244052 39.923084509869575 15.23, 116.7159327445713 39.92308801736784 15.23, 116.71593805670116 39.92309152486536 15.23, 116.71594326860951 39.92309503222346 15.23, 116.71594858073753 39.923098539719504 15.23, 116.71595379264407 39.92310204707615 15.23, 116.71595910477025 39.92310555457072 15.22, 116.71596431667498 39.92310906192592 15.22, 116.71596962879933 39.92311256941902 15.22, 116.71597494092273 39.92311607691136 15.22, 116.71598025303274 39.92311948439879 15.21, 116.7159855651543 39.92312299188965 15.21, 116.71599087726246 39.92312639937558 15.21, 116.71599628959011 39.92312980699931 15.21, 116.71600160169638 39.92313321448375 15.2, 116.71600701402213 39.92313662210594 15.2, 116.71601242634688 39.92314002972738 15.2, 116.71601773843786 39.92314333720536 15.2, 116.71602315076072 39.92314674482525 15.2, 116.7160285630826 39.92315015244437 15.2, 116.71603397539106 39.923153460058536 15.19, 116.71603938771102 39.9231568676761 15.19, 116.7160449002378 39.923160175427135 15.19, 116.71605031255581 39.923163583043134 15.19, 116.71605572486038 39.923166890654194 15.19, 116.71606123739667 39.923170298407015 15.19, 116.71606664969929 39.92317360601651 15.18, 116.71607216222111 39.92317691376356 15.18, 116.71607767474192 39.92318022150982 15.18, 116.71608308704162 39.92318352911695 15.18, 116.71608859956046 39.92318683686161 15.18, 116.7160941120783 39.92319014460546 15.18, 116.71609952436255 39.92319335220606 15.18, 116.7161050368784 39.92319665994833 15.18, 116.71611054938076 39.923199867685604 15.18, 116.71611606189461 39.92320317542626 15.17, 116.71612167461498 39.92320638330014 15.17, 116.71612718711431 39.92320959103499 15.17, 116.71613269961263 39.923212798769036 15.17, 116.71613831232992 39.923216006640445 15.17, 116.71614392504615 39.92321921451102 15.17, 116.71614943752895 39.923222322238445 15.17, 116.71615505024315 39.92322553010736 15.16, 116.7161606629438 39.92322863797127 15.16, 116.71616637586328 39.92323174597244 15.16, 116.71617198857432 39.923234953838836 15.16, 116.71617760127184 39.92323806170023 15.15, 116.7161832139683 39.92324116956078 15.15, 116.71618882666372 39.9232442774205 15.15, 116.71619453957788 39.9232473854174 15.15, 116.71620015227123 39.92325049327543 15.14, 116.71620586518323 39.923253601270616 15.14, 116.71621147787447 39.92325670912697 15.14, 116.71621719078435 39.92325981712044 15.14, 116.71622290368066 39.923262825108864 15.13, 116.71622861658837 39.9232659331006 15.13, 116.71623432949501 39.92326904109148 15.12, 116.7162400423881 39.92327204907731 15.12, 116.71624575529258 39.92327515706645 15.12, 116.71625146818349 39.92327816505055 15.12, 116.71625718107332 39.92328117303378 15.12, 116.71626299418162 39.92328418115398 15.12, 116.71626880728878 39.92328718927328 15.12, 116.71627452017535 39.923290197253884 15.12, 116.7162803332803 39.92329320537141 15.11, 116.7162862466036 39.92329621362581 15.11, 116.71629205969381 39.92329912173736 15.11, 116.71629787279538 39.923302129852175 15.11, 116.71630378610277 39.92330503809964 15.11, 116.7163095991896 39.923307946208475 15.11, 116.71631551249467 39.9233108544541 15.11, 116.71632132557926 39.92331376256112 15.11, 116.71632723888203 39.92331667080491 15.11, 116.71633315218365 39.923319579047764 15.11, 116.71633906547164 39.923322387285516 15.11, 116.71634487855167 39.9233252953889 15.11, 116.71635079183736 39.923328103624804 15.11, 116.71635670512187 39.923330911859786 15.12, 116.7163626184177 39.923333820098016 15.12, 116.7163685316999 39.92333662833113 15.12, 116.71637444498094 39.923339436563325 15.12, 116.71638045846748 39.92334214492792 15.13, 116.71638637174618 39.923344953158235 15.13, 116.71639238524283 39.923347761525115 15.13, 116.71639829850669 39.92335046974937 15.13, 116.71640431200096 39.92335327811434 15.13, 116.71641032548153 39.923355986474164 15.13, 116.71641633896091 39.923358694833034 15.14, 116.71642235243908 39.92336140319093 15.14, 116.71642836591604 39.92336411154787 15.14, 116.7164343794043 39.92336691990802 15.14, 116.71644039287887 39.92336962826304 15.14, 116.71644640635223 39.92337233661709 15.14, 116.71645241982439 39.92337504497017 15.14, 116.71645843329536 39.9233777533223 15.14, 116.71646454698399 39.92338046181075 15.15, 116.71647056045252 39.92338317016094 15.14, 116.71647657391985 39.92338587851015 15.15, 116.7164826875923 39.92338848699148 15.15, 116.7164887010572 39.92339119533876 15.15, 116.71649481473968 39.92339390382228 15.15, 116.71650082820216 39.92339661216761 15.15, 116.71650694186967 39.92339922064498 15.15, 116.71651305553594 39.92340182912136 15.15, 116.71651906899477 39.92340453746377 15.15, 116.71652518265857 39.92340714593817 15.15, 116.71653129632114 39.923409754411566 15.15, 116.71653740998245 39.92341236288397 15.15, 116.71654352363004 39.92341487135121 15.16, 116.71654963728885 39.92341747982162 15.16, 116.71655575093396 39.92341998828686 15.16, 116.71656186459028 39.92342259675527 15.16, 116.71656797823289 39.92342510521852 15.16, 116.71657419209275 39.92342761381777 15.16, 116.71658030573283 39.923430122279 15.16, 116.7165864193717 39.923432630739235 15.16, 116.71659263322773 39.92343513933543 15.16, 116.71659874687653 39.92343774779782 15.17, 116.71660496073002 39.92344025639196 15.17, 116.71661107436383 39.92344276484817 15.17, 116.71661728821475 39.92344527344027 15.17, 116.7166235020644 39.92344778203134 15.17, 116.71662971591275 39.923450290621375 15.17, 116.7166359297598 39.923452799210374 15.18, 116.71664214360558 39.92345530779835 15.18, 116.7166482572318 39.92345781624847 15.19, 116.71665447106253 39.923460224830215 15.19, 116.71666068490445 39.92346273341511 15.19, 116.7166668987326 39.92346514199479 15.19, 116.71667311255946 39.92346755057344 15.2, 116.71667932638503 39.92346995915106 15.2, 116.7166855402218 39.92347246773181 15.2, 116.71669175404479 39.92347487630736 15.21, 116.7166979678665 39.92347728488188 15.21, 116.7167041816869 39.92347969345537 15.21, 116.71671039549352 39.92348200202364 15.22, 116.71671660931135 39.92348441059506 15.22, 116.71672292334588 39.92348681930205 15.23, 116.71672913714863 39.9234891278672 15.23, 116.71673545118051 39.92349153657207 15.23, 116.71674176519859 39.9234938452717 15.24, 116.71674807921534 39.92349615397027 15.24, 116.71675439323073 39.92349846266776 15.24, 116.71676070725728 39.923500871368354 15.25, 116.71676702127003 39.92350318006371 15.25, 116.71677333528143 39.923505488757996 15.25, 116.7167796492915 39.92350779745122 15.26, 116.71678596330021 39.923510106143375 15.26, 116.71679227729514 39.923512314830276 15.27, 116.71679849108345 39.92351462338389 15.27, 116.71680480508819 39.92351693207285 15.27, 116.71681121929683 39.923519140892935 15.27, 116.71681753329888 39.92352144957974 15.28, 116.7168238472871 39.92352365826131 15.29, 116.71683026150413 39.92352596708229 15.29, 116.7168366757073 39.923528175898 15.29, 116.71684308990908 39.923530384712606 15.3, 116.7168494038919 39.92353259338984 15.3, 116.71685581810343 39.92353490220642 15.31, 116.71686213208355 39.9235371108815 15.31, 116.71686854627985 39.92353931969171 15.32, 116.71687486025728 39.92354152836462 15.32, 116.71688127445086 39.92354373717266 15.32, 116.71688758842558 39.923545945843415 15.33, 116.7168940026164 39.92354815464925 15.34, 116.71690031658844 39.923550363317844 15.34, 116.71690673076404 39.92355247211731 15.34, 116.7169132451681 39.92355468105595 15.35, 116.7169196593534 39.92355688985735 15.36, 116.71692607352483 39.92355899865349 15.36, 116.71693258791218 39.92356110758456 15.36, 116.7169390020933 39.92356331638264 15.37, 116.71694541626057 39.92356542517543 15.37, 116.7169517302092 39.92356753383113 15.38, 116.71695814437373 39.92356964262173 15.39, 116.71696455854935 39.9235718514154 15.39, 116.71697097271111 39.92357396020379 15.4, 116.71697738685899 39.923575968986896 15.41, 116.71698380101797 39.923578077773065 15.41, 116.71699031539268 39.923580186694025 15.41, 116.71699672954887 39.92358229547797 15.42, 116.71700324390825 39.92358430439248 15.43, 116.71700975826622 39.923586313305854 15.43, 116.71701627262276 39.92358832221809 15.44, 116.71702278697786 39.92359033112917 15.44, 116.71702920111456 39.92359233990333 15.45, 116.71703571545434 39.92359424880797 15.47, 116.71704222980519 39.92359625771565 15.47, 116.7170487441421 39.923598166618014 15.48, 116.7170552584776 39.923600075519225 15.49, 116.71706177281166 39.9236019844193 15.49, 116.71706818692746 39.923603893182545 15.51, 116.71707450081256 39.92360570180485 15.51, 116.71709684999163 39.92361243233016 15.55)" + val geoByteArray = DeflaterUtil.zipString(geometryStr) + Log.e("qj","字节转化===${DeflaterUtil.unzipString(geoByteArray)}") mapController.animationHandler.zoomIn() } @@ -844,6 +870,7 @@ class MainActivity : BaseActivity() { */ fun setTopMenuButtonVisibility(visibility: Int) { binding.mainActivityMenu.visibility = visibility + binding.mainActivityStatusCamera.visibility = visibility if (visibility != View.VISIBLE) { binding.mainActivityMenuGroup.visibility = View.INVISIBLE binding.mainActivityMenu.isSelected = false @@ -1033,7 +1060,6 @@ class MainActivity : BaseActivity() { binding.mainActivitySnapshotRewind.isEnabled = value binding.mainActivitySnapshotNext.isEnabled = value binding.mainActivitySnapshotPause.isEnabled = value - binding.mainActivitySnapshotFinish.isEnabled = value viewModel.cancelTrace() } @@ -1148,7 +1174,6 @@ class MainActivity : BaseActivity() { } private fun setIndoorGroupEnable(enable: Boolean) { - binding.mainActivitySnapshotFinish.isEnabled = enable binding.mainActivityTraceSnapshotPoints.isEnabled = enable //binding.mainActivitySnapshotMediaFlag.isEnabled = enable binding.mainActivitySnapshotRewind.isEnabled = enable @@ -1222,10 +1247,10 @@ class MainActivity : BaseActivity() { /** * 隐藏更多信息面板 */ - fun backSignMoreInfo(){ + fun backSignMoreInfo() { val fragment = supportFragmentManager.findFragmentById(R.id.main_activity_sign_more_info_fragment) - if(fragment!=null&&!fragment.isHidden){ + if (fragment != null && !fragment.isHidden) { supportFragmentManager.beginTransaction().remove(fragment).commit() } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt index de2cde10..e7b7b478 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.navigation.findNavController import com.blankj.utilcode.util.ToastUtils +import com.google.gson.Gson import com.navinfo.collect.library.data.dao.impl.TraceDataBase import com.navinfo.collect.library.data.entity.* import com.navinfo.collect.library.enums.DataCodeEnum @@ -50,7 +51,9 @@ import io.realm.Realm import io.realm.RealmConfiguration import io.realm.RealmSet import kotlinx.coroutines.* +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.sync.Mutex import org.locationtech.jts.geom.Geometry import org.oscim.core.GeoPoint @@ -67,6 +70,18 @@ import kotlin.concurrent.fixedRateTimer * 创建Activity全局viewmode */ +enum class LoadDataStatus { + /** + * 加载开始 + */ + LOAD_DATA_STATUS_BEGIN, + + /** + * 加载结束 + */ + LOAD_DATA_STATUS_FISISH, +} + @HiltViewModel class MainViewModel @Inject constructor( private val mapController: NIMapController, @@ -94,6 +109,9 @@ class MainViewModel @Inject constructor( //地图点击捕捉到的轨迹列表 val liveDataNILocationList = MutableLiveData() + //加载数据 + val liveDataLoadData = MutableLiveData() + //左侧看板数据 val liveDataSignList = MutableLiveData>() @@ -239,11 +257,14 @@ class MainViewModel @Inject constructor( //导航信息 private var naviEngine: NaviEngine? = null + private var naviEngineNew: NaviEngineNew = NaviEngineNew(realmOperateHelper) + // 0:不导航 1:导航 2:暂停 private var naviEngineStatus = 0 // 定义一个互斥锁 private val naviMutex = Mutex() + private var testRealm: Realm? = null; init { mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition -> @@ -271,6 +292,10 @@ class MainViewModel @Inject constructor( object : OnGeoPointClickListener { override fun onMapClick(tag: String, point: GeoPoint) { if (tag == TAG) { + //数据安装时不允许操作数据 + if(Constant.INSTALL_DATA){ + return + } if (bMeasuringTool) { mapController.measureLayerHandler.addPoint(measuringType, point) } else { @@ -321,6 +346,7 @@ class MainViewModel @Inject constructor( }) viewModelScope.launch(Dispatchers.IO) { + liveDataLoadData.postValue(LoadDataStatus.LOAD_DATA_STATUS_BEGIN) getTaskBean() //初始化选中的任务高亮高亮 if (currentTaskBean != null) { @@ -329,6 +355,7 @@ class MainViewModel @Inject constructor( initQsRecordData() initNoteData() initNILocationData() + liveDataLoadData.postValue(LoadDataStatus.LOAD_DATA_STATUS_FISISH) } sharedPreferences.registerOnSharedPreferenceChangeListener(this) MapParamUtils.setTaskId(sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1)) @@ -336,32 +363,45 @@ class MainViewModel @Inject constructor( File(Constant.USER_DATA_PATH + "/${MapParamUtils.getTaskId()}") Constant.currentSelectTaskConfig = RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder) - .name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true) + .name("OMQS.realm").encryptionKey(Constant.PASSWORD) +// .assetFile("${Constant.currentSelectTaskFolder}/OMQS.realm") +// .readOnly() +// .allowQueriesOnUiThread(true) .schemaVersion(2).build() MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) socketServer = SocketServer(mapController, traceDataBase, sharedPreferences) -// viewModelScope.launch(Dispatchers.Default) { -// naviTestFlow().collect { point -> -// if (naviEngineStatus == 1) { -// naviEngine?.let { + viewModelScope.launch(Dispatchers.IO) { + + naviTestFlow().collect { point -> + if (naviEngineStatus == 1) { + naviEngineNew.let { // naviMutex.lock() + if (testRealm == null) + testRealm = realmOperateHelper.getSelectTaskRealmInstance() + if (currentTaskBean != null) { + naviEngineNew.bindingRoute( + taskBean = currentTaskBean!!, + geoPoint = point, + realm = testRealm!! + ) + } // it.bindingRoute(null, point) // naviMutex.unlock() -// } -// } -// } -// } + } + } + } + } } -// fun naviTestFlow(): Flow = flow { -// -// while (true) { -// emit(mapController.mMapView.vtmMap.mapPosition.geoPoint) -// delay(1000) -// } -// } + fun naviTestFlow(): Flow = flow { + + while (true) { + emit(mapController.mMapView.vtmMap.mapPosition.geoPoint) + delay(5000) + } + } /** * 获取当前任务 @@ -403,7 +443,10 @@ class MainViewModel @Inject constructor( naviOption = naviOption, callback = object : OnNaviEngineCallbackListener { - override fun planningPathStatus(status: NaviStatus) { + override fun planningPathStatus( + status: NaviStatus, linkdId: String?, + geometry: String? + ) { when (status) { NaviStatus.NAVI_STATUS_PATH_PLANNING -> naviEngineStatus = 0 NaviStatus.NAVI_STATUS_PATH_ERROR_NODE -> naviEngineStatus = 0 @@ -415,8 +458,24 @@ class MainViewModel @Inject constructor( NaviStatus.NAVI_STATUS_DIRECTION_OFF -> {} } liveDataNaviStatus.postValue(status) + if (geometry != null) { + viewModelScope.launch(Dispatchers.Main) { + + val lineString = GeometryTools.createGeometry(geometry) + val envelope = lineString.envelopeInternal + mapController.animationHandler.animateToBox( + envelope.maxX, + envelope.maxY, + envelope.minX, + envelope.minY + ) + + mapController.lineHandler.showLine(geometry) + } + } } + override suspend fun bindingResults( route: NaviRoute?, list: List @@ -526,7 +585,20 @@ class MainViewModel @Inject constructor( ).niLocationDao.findToTaskIdAll(id.toString()) if (list != null) { for (location in list) { + Constant.TRACE_COUNT++ + + if(Constant.TRACE_COUNT%Constant.TRACE_COUNT_MORE_TIME==0){ + mapController.markerHandle.addNiLocationMarkerItemRough(location) + Log.e("qj","${Constant.TRACE_COUNT}===轨迹") + } + + if(Constant.TRACE_COUNT%Constant.TRACE_COUNT_TIME==0){ + mapController.markerHandle.addNiLocationMarkerItemSimple(location) + Log.e("qj","${Constant.TRACE_COUNT}===轨迹") + } + mapController.markerHandle.addNiLocationMarkerItem(location) + } } } @@ -535,6 +607,7 @@ class MainViewModel @Inject constructor( * 初始化定位信息 */ private fun initLocation() { + var gson = Gson(); //用于定位点存储到数据库 viewModelScope.launch(Dispatchers.Default) { @@ -588,12 +661,23 @@ class MainViewModel @Inject constructor( lastNiLocaion!!.longitude ) } - //室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过2.5并小于60米 - if (Constant.INDOOR_IP.isEmpty() && (disance == 0.0 || (disance > 2.5 && disance < 60))) { + //室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过6并小于60米 + if (Constant.INDOOR_IP.isEmpty() && (disance == 0.0 || (disance > 6.0 && disance < 60))) { + Log.e("jingo", "轨迹插入开始") + CMLog.writeLogtoFile(MainViewModel::class.java.name,"insertTrace","开始") traceDataBase.niLocationDao.insert(location) mapController.markerHandle.addNiLocationMarkerItem(location) + + if(Constant.TRACE_COUNT%Constant.TRACE_COUNT_TIME==0){ + mapController.markerHandle.addNiLocationMarkerItemSimple(location) + } + if(Constant.TRACE_COUNT%Constant.TRACE_COUNT_MORE_TIME==0){ + mapController.markerHandle.addNiLocationMarkerItemRough(location) + } mapController.mMapView.vtmMap.updateMap(true) lastNiLocaion = location + CMLog.writeLogtoFile(MainViewModel::class.java.name,"insertTrace",gson.toJson(location)) + Log.e("jingo", "轨迹插入结束") } } } @@ -786,7 +870,7 @@ class MainViewModel @Inject constructor( if (linkList.isNotEmpty()) { val link = linkList[0] - val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid] + val linkId = link.linkPid //看板数据 val signList = mutableListOf() val topSignList = mutableListOf() @@ -816,8 +900,12 @@ class MainViewModel @Inject constructor( val newLineString = GeometryTools.createLineString(linePoints) linkId?.let { + val time = System.currentTimeMillis() val elementList = realmOperateHelper.queryLinkByLinkPid(realm, it) - Log.e("jingo", "捕捉到数据 ${elementList.size} 个") + Log.e( + "jingo", + "捕捉到数据 ${elementList.size} 个 ${System.currentTimeMillis() - time}" + ) for (element in elementList) { if (element.code == DataCodeEnum.OMDB_LINK_NAME.code) { hisRoadName = true @@ -930,7 +1018,7 @@ class MainViewModel @Inject constructor( .equalTo("table", DataCodeEnum.OMDB_RD_LINK_KIND.name) .and() .equalTo( - "properties['${RenderEntity.Companion.LinkTable.linkPid}']", + "linkPid", outLink ).findFirst() if (linkOutEntity != null) { @@ -964,6 +1052,7 @@ class MainViewModel @Inject constructor( if (!hisRoadName) { liveDataRoadName.postValue(null) } + Log.e("jingo", "另一个地方查询数据库") realm.close() } } catch (e: Exception) { @@ -980,8 +1069,9 @@ class MainViewModel @Inject constructor( fun onClickLocationButton() { val mapPosition: MapPosition = mapController.mMapView.vtmMap.getMapPosition() mapPosition.setBearing(0f) // 锁定角度,自动将地图旋转到正北方向 - mapController.mMapView.vtmMap.setMapPosition(mapPosition) + mapController.mMapView.vtmMap.mapPosition = mapPosition mapController.locationLayerHandler.animateToCurrentPosition() + naviEngineStatus = 1 } /** @@ -1658,7 +1748,7 @@ class MainViewModel @Inject constructor( val tempTime = nowTime - lastTime if (tempTime > 10000) { liveDataMessage.postValue("下个定位点与当前定位点时间间隔超过10秒(${tempTime}),将直接跳转到下个点") - delay(5000) + delay(2000) } else { delay(tempTime) } diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/SignAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/SignAdapter.kt index a12f81a1..9c09dce6 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/SignAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/SignAdapter.kt @@ -37,6 +37,8 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) : 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 } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt index b7281da4..e26c0e5f 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt @@ -23,7 +23,6 @@ import com.blankj.utilcode.util.ToastUtils import com.navinfo.collect.library.data.entity.AttachmentBean import com.navinfo.collect.library.data.entity.HadLinkDvoBean import com.navinfo.collect.library.data.entity.QsRecordBean -import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable import com.navinfo.collect.library.data.entity.TaskBean import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.OnGeoPointClickListener @@ -236,7 +235,7 @@ class EvaluationResultViewModel @Inject constructor( } else { val linkList = realmOperateHelper.queryLink(realm, point = point) if (linkList.isNotEmpty()) { - it.linkId = linkList[0].properties[LinkTable.linkPid] ?: "" + it.linkId = linkList[0].linkPid mapController.lineHandler.showLine(linkList[0].geometry) Log.e("jingo", "捕捉道路EEE 2") return diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt index 8ddf24ea..51342551 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt @@ -7,6 +7,7 @@ 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 @@ -21,6 +22,7 @@ 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 @@ -40,6 +42,7 @@ 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 /** @@ -73,35 +76,35 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit? 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) { - } - - @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_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() { @@ -151,7 +154,7 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit? val mapPosition: MapPosition = niMapController.mMapView.vtmMap.getMapPosition() mapPosition.setBearing(0f) // 锁定角度,自动将地图旋转到正北方向 - niMapController.mMapView.vtmMap.setMapPosition(mapPosition) + niMapController.mMapView.vtmMap.mapPosition = mapPosition it.title = "开启地图旋转及视角" } else { it.title = "锁定地图旋转及视角" @@ -168,6 +171,17 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit? 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) { @@ -258,6 +272,13 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit? it.title = "隐藏Marker" } } + R.id.personal_center_menu_trace -> { + if (Constant.MapTraceCloseEnable) { + it.title = "显示轨迹" + } else { + it.title = "隐藏轨迹" + } + } } } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt index 1c8c0a26..8c247086 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt @@ -1,17 +1,12 @@ package com.navinfo.omqs.ui.fragment.personalcenter import android.net.Uri -import android.os.Build import android.util.Log -import androidx.annotation.RequiresApi 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 @@ -24,7 +19,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.apache.commons.io.input.BOMInputStream import java.io.* -import java.util.* import javax.inject.Inject @@ -37,119 +31,119 @@ class PersonalCenterViewModel @Inject constructor( val liveDataMessage = MutableLiveData() - /** - * 导入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( - "HAD_LINK", "HAD_SPEEDLIMIT", "HAD_SPEEDLIMIT_COND", "HAD_SPEEDLIMIT_VAR" - )/*listOf("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 - ) - } - } - } - } - ZipUtils.zipFiles( - mutableListOf( - hadLinkFile, - hadLinkKindFile, - hadLinkDirectFile, - hadSpeedLimitFile, - hadSpeedLimitCondFile, - hadSpeedLimitVarFile - ), File(importOMDBHelper.omdbFile.parentFile, "output.zip") - ) - - Log.d("OMQSApplication", "生成数据完成") - } +// /** +// * 导入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( +// "HAD_LINK", "HAD_SPEEDLIMIT", "HAD_SPEEDLIMIT_COND", "HAD_SPEEDLIMIT_VAR" +// )/*listOf("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 +// ) +// } +// } +// } +// } +// ZipUtils.zipFiles( +// mutableListOf( +// hadLinkFile, +// hadLinkKindFile, +// hadLinkDirectFile, +// hadSpeedLimitFile, +// hadSpeedLimitCondFile, +// hadSpeedLimitVarFile +// ), File(importOMDBHelper.omdbFile.parentFile, "output.zip") +// ) +// +// Log.d("OMQSApplication", "生成数据完成") +// } /** * 导入OMDB数据 @@ -158,15 +152,12 @@ class PersonalCenterViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { Log.d("OMQSApplication", "开始导入数据") if (task != null) { - importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task).collect { - Log.d("importOMDBData", it) - } + importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task, this) } else { val newTask = TaskBean() newTask.id = -1 - importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, newTask).collect { - Log.d("importOMDBData", it) - } + importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, newTask, this) + } Log.d("OMQSApplication", "导入数据完成") } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt index 34bf24f0..b40efbc1 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt @@ -79,7 +79,9 @@ class TaskFragment : BaseFragment() { viewModel.liveDataAddLinkDialog.observe(viewLifecycleOwner){ viewModel.addTaskLink(requireContext(),it) } + viewModel.liveDataUpdateTask.observe(viewLifecycleOwner) { + } //注意:使用滑动菜单不能开启滑动删除,否则只有滑动删除没有滑动菜单 val mSwipeMenuCreator = SwipeMenuCreator { _, rightMenu, _ -> diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt index 6d70679d..9c08a0db 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt @@ -89,8 +89,15 @@ class TaskListFragment : BaseFragment() { deleteItem.background = requireContext().getDrawable(R.color.red) deleteItem.setTextColor(requireContext().resources.getColor(R.color.white)) rightMenu.addMenuItem(deleteItem) - } + val resetDownLoad = SwipeMenuItem(context) + resetDownLoad.height = Util.convertDpToPx(requireContext(), 60) + resetDownLoad.width = Util.convertDpToPx(requireContext(), 80) + resetDownLoad.text = "重新下载" + resetDownLoad.background = requireContext().getDrawable(R.color.btn_bg_blue) + resetDownLoad.setTextColor(requireContext().resources.getColor(R.color.white)) + rightMenu.addMenuItem(resetDownLoad) + } val layoutManager = LinearLayoutManager(context) //// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能 @@ -104,11 +111,15 @@ class TaskListFragment : BaseFragment() { binding.taskListRecyclerview.setOnItemMenuClickListener { menuBridge, position -> menuBridge.closeMenu() val taskBean = adapter.data[position] - if (taskBean.syncStatus != FileManager.Companion.FileUploadStatus.DONE) { - Toast.makeText(context, "数据未上传,不允许关闭!", Toast.LENGTH_SHORT) - .show() - } else { - viewModel.removeTask(requireContext(), taskBean) + if(menuBridge.position==0){ + if (taskBean.syncStatus != FileManager.Companion.FileUploadStatus.DONE) { + Toast.makeText(context, "数据未上传,不允许关闭!", Toast.LENGTH_SHORT) + .show() + } else { + viewModel.removeTask(requireContext(), taskBean) + } + }else{ + viewModel.resetDownload(requireContext(), taskBean) } } @@ -134,6 +145,39 @@ class TaskListFragment : BaseFragment() { binding.taskListRecyclerview.smoothScrollToPosition(position) } + viewModel.liveDataLoadTask.observe(viewLifecycleOwner){ + when(it){ + TaskLoadStatus.TASK_LOAD_STATUS_BEGIN->{ + showLoadingDialog("正在切换任务") + } + TaskLoadStatus.TASK_LOAD_STATUS_FISISH->{ + hideLoadingDialog() + } + } + } + + viewModel.liveDataCloseTask.observe(viewLifecycleOwner){ + when(it){ + TaskDelStatus.TASK_DEL_STATUS_BEGIN->{ + showLoadingDialog("正在重置...") + } + TaskDelStatus.TASK_DEL_STATUS_LOADING->{ + showLoadingDialog("正在重置...") + } + TaskDelStatus.TASK_DEL_STATUS_SUCCESS->{ + hideLoadingDialog() + Toast.makeText(context,"成功重置",Toast.LENGTH_LONG).show() + + } + TaskDelStatus.TASK_DEL_STATUS_FAILED->{ + hideLoadingDialog() + } + TaskDelStatus.TASK_DEL_STATUS_CANCEL->{ + + } + } + } + //监听并调用上传 viewModel.liveDataTaskUpload.observe(viewLifecycleOwner) { for ((key, value) in it) { diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt index 358f63c7..4b9a84b7 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.SharedPreferences import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.os.Build +import android.util.Log import android.view.View import android.widget.Toast import androidx.annotation.RequiresApi @@ -31,6 +32,44 @@ import org.oscim.core.GeoPoint import java.io.File import javax.inject.Inject +enum class TaskDelStatus { + /** + * 删除开始 + */ + TASK_DEL_STATUS_BEGIN, + + /** + * 删除中 + */ + TASK_DEL_STATUS_LOADING, + + /** + * 删除成功 + */ + TASK_DEL_STATUS_SUCCESS, + + /** + * 删除失败 + */ + TASK_DEL_STATUS_FAILED, + + /** + * 取消删除 + */ + TASK_DEL_STATUS_CANCEL, +} + +enum class TaskLoadStatus { + /** + * 加载开始 + */ + TASK_LOAD_STATUS_BEGIN, + + /** + * 加载结束 + */ + TASK_LOAD_STATUS_FISISH, +} @HiltViewModel class TaskViewModel @Inject constructor( @@ -61,7 +100,17 @@ class TaskViewModel @Inject constructor( /** * 用来确定是否关闭 */ - val liveDataCloseTask = MutableLiveData() + val liveDataCloseTask = MutableLiveData() + + /** + * 用来确定是否加载 + */ + val liveDataLoadTask = MutableLiveData() + + /** + * 用来更新任务 + */ + val liveDataUpdateTask = MutableLiveData() /** * 提示信息 @@ -107,13 +156,14 @@ class TaskViewModel @Inject constructor( if (currentSelectTaskBean == null) { liveDataToastMessage.postValue("还没有开启任何任务") } else { - val links = realmOperateHelper.queryLink(realm, + val links = realmOperateHelper.queryLink( + realm, point = point, ) if (links.isNotEmpty()) { val l = links[0] for (link in currentSelectTaskBean!!.hadLinkDvoList) { - if (link.linkPid == l.properties["linkPid"]) { + if (link.linkPid == l.linkPid) { return@launch } } @@ -125,13 +175,14 @@ class TaskViewModel @Inject constructor( } else { viewModelScope.launch(Dispatchers.IO) { val realm = realmOperateHelper.getSelectTaskRealmInstance() - val links = realmOperateHelper.queryLink(realm, + val links = realmOperateHelper.queryLink( + realm, point = point, ) if (links.isNotEmpty()) { val l = links[0] for (link in currentSelectTaskBean!!.hadLinkDvoList) { - if (link.linkPid == l.properties["linkPid"]) { + if (link.linkPid == l.linkPid) { liveDataSelectLink.postValue(link.linkPid) mapController.lineHandler.showLine(link.geometry) break @@ -178,22 +229,34 @@ class TaskViewModel @Inject constructor( 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 = "" + Log.e("qj", "${task.id}==null") + } + } task.hadLinkDvoList = item.hadLinkDvoList task.syncStatus = item.syncStatus //已上传后不在更新操作时间 if (task.syncStatus != FileManager.Companion.FileUploadStatus.DONE) { //赋值时间,用于查询过滤 task.operationTime = DateTimeUtil.getNowDate().time - }else{//已上传数据不做更新 + } else {//已上传数据不做更新 continue } } else { for (hadLink in task.hadLinkDvoList) { hadLink.taskId = task.id + if (hadLink.mesh == null) { + hadLink.mesh = "" + Log.e("qj", "${task.id}==新增==null") + } } //赋值时间,用于查询过滤 task.operationTime = DateTimeUtil.getNowDate().time } + Log.e("qj", "${task.id}") realm.copyToRealmOrUpdate(task) } } @@ -271,16 +334,45 @@ class TaskViewModel @Inject constructor( currentSelectTaskBean = taskBean liveDataTaskLinks.value = taskBean.hadLinkDvoList + + liveDataLoadTask.postValue(TaskLoadStatus.TASK_LOAD_STATUS_BEGIN) + showTaskLinks(taskBean) - MapParamUtils.setTaskId(taskBean.id) - Constant.currentSelectTaskFolder = File(Constant.USER_DATA_PATH + "/${taskBean.id}") - Constant.currentSelectTaskConfig = - RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder) - .name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true) - .schemaVersion(2).build() - MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) - mapController.layerManagerHandler.updateOMDBVectorTileLayer() - mapController.mMapView.updateMap(true) + + //重新加载轨迹 + viewModelScope.launch(Dispatchers.IO) { + Constant.TRACE_COUNT = 0 + val list: List? = TraceDataBase.getDatabase( + mapController.mMapView.context, Constant.USER_DATA_PATH + ).niLocationDao.findToTaskIdAll(taskBean.id.toString()) + list!!.forEach { + + Constant.TRACE_COUNT ++ + + if(Constant.TRACE_COUNT%Constant.TRACE_COUNT_MORE_TIME==0){ + mapController.markerHandle.addNiLocationMarkerItemRough(it) + } + + if(Constant.TRACE_COUNT%Constant.TRACE_COUNT_TIME==0){ + mapController.markerHandle.addNiLocationMarkerItemSimple(it) + } + + mapController.markerHandle.addNiLocationMarkerItem(it) + + } + liveDataLoadTask.postValue(TaskLoadStatus.TASK_LOAD_STATUS_FISISH) + withContext(Dispatchers.Main){ + MapParamUtils.setTaskId(taskBean.id) + Constant.currentSelectTaskFolder = File(Constant.USER_DATA_PATH + "/${taskBean.id}") + Constant.currentSelectTaskConfig = + RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder) + .name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true) + .schemaVersion(2).build() + MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) + mapController.layerManagerHandler.updateOMDBVectorTileLayer() + mapController.mMapView.updateMap(true) + } + } } @@ -410,6 +502,71 @@ class TaskViewModel @Inject constructor( } } + /** + * 重新下载数据任务 + */ + fun resetDownload(context: Context, taskBean: TaskBean) { + val mDialog = FirstDialog(context) + mDialog.setTitle("提示?") + mDialog.setMessage("是否重置下载状态,请确认!") + mDialog.setPositiveButton( + "确定" + ) { dialog, _ -> + dialog.dismiss() + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_BEGIN) + viewModelScope.launch(Dispatchers.IO) { + //删除已下载的数据 + val fileTemp = + File("${Constant.DOWNLOAD_PATH}${taskBean.evaluationTaskName}_${taskBean.dataVersion}.zip") + if (fileTemp.exists()) { + fileTemp.delete() + } + val taskFileTemp = File(Constant.USER_DATA_PATH + "/${taskBean.id}") + //重命名 + if (taskFileTemp.exists()) { + /* var currentSelectTaskFolder = File(Constant.USER_DATA_PATH + "/${taskBean.id}") + var currentSelectTaskConfig = + RealmConfiguration.Builder().directory(currentSelectTaskFolder) + .name("OMQS.realm").encryptionKey(Constant.PASSWORD) + .allowQueriesOnUiThread(true) + .schemaVersion(2).build() + Realm.getInstance(currentSelectTaskConfig).executeTransaction { r -> + //删除已有所有数据 + r.delete(RenderEntity::class.java) + r.delete(ReferenceEntity::class.java) + } + Realm.getInstance(currentSelectTaskConfig).close()*/ + } + //将下载状态修改已下载 + val realm = realmOperateHelper.getRealmDefaultInstance() + taskBean.syncStatus = FileManager.Companion.FileUploadStatus.NONE + taskBean.status = FileManager.Companion.FileDownloadStatus.NONE + realm.beginTransaction() + realm.copyToRealmOrUpdate(taskBean) + realm.commitTransaction() + realm.close() + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_SUCCESS) + withContext(Dispatchers.Main) { + if (taskBean.id == currentSelectTaskBean?.id ?: 0) { + mapController.layerManagerHandler.updateOMDBVectorTileLayer() + } else { + setSelectTaskBean(taskBean) + } + realmOperateHelper.getRealmDefaultInstance().refresh() + //重新加载数据 + getLocalTaskList() + } + } + } + mDialog.setNegativeButton( + "取消" + ) { _, _ -> + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_CANCEL) + mDialog.dismiss() + } + mDialog.show() + } + /** * 关闭任务 */ @@ -421,7 +578,9 @@ class TaskViewModel @Inject constructor( "确定" ) { dialog, _ -> dialog.dismiss() + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_BEGIN) viewModelScope.launch(Dispatchers.IO) { + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_LOADING) val realm = realmOperateHelper.getRealmDefaultInstance() realm.executeTransaction { val objects = @@ -455,14 +614,14 @@ class TaskViewModel @Inject constructor( FileManager.checkOMDBFileInfo(item) } liveDataTaskList.postValue(taskList) - liveDataCloseTask.postValue(true) + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_SUCCESS) realm.close() } } mDialog.setNegativeButton( "取消" ) { _, _ -> - liveDataCloseTask.postValue(false) + liveDataCloseTask.postValue(TaskDelStatus.TASK_DEL_STATUS_CANCEL) mDialog.dismiss() } mDialog.show() @@ -559,7 +718,7 @@ class TaskViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { val hadLinkDvoBean = HadLinkDvoBean( taskId = currentSelectTaskBean!!.id, - linkPid = data.properties["linkPid"]!!, + linkPid = data.linkPid, geometry = data.geometry, linkStatus = 2 ) @@ -572,8 +731,8 @@ class TaskViewModel @Inject constructor( r.copyToRealmOrUpdate(currentSelectTaskBean!!) } //根据Link数据查询对应数据上要素,对要素进行显示重置 - data.properties["linkPid"]?.let { - realmOperateHelper.queryLinkToMutableRenderEntityList(realm,it) + data.linkPid.let { + realmOperateHelper.queryLinkToMutableRenderEntityList(realm, it) ?.forEach { renderEntity -> if (renderEntity.enable != 1) { renderEntity.enable = 1 @@ -628,7 +787,10 @@ class TaskViewModel @Inject constructor( //重置数据为隐藏 if (hadLinkDvoBean.linkStatus == 2) { - realmOperateHelper.queryLinkToMutableRenderEntityList(realm,hadLinkDvoBean.linkPid) + realmOperateHelper.queryLinkToMutableRenderEntityList( + realm, + hadLinkDvoBean.linkPid + ) ?.forEach { renderEntity -> if (renderEntity.enable == 1) { renderEntity.enable = 0 diff --git a/app/src/main/java/com/navinfo/omqs/util/CMLog.java b/app/src/main/java/com/navinfo/omqs/util/CMLog.java new file mode 100644 index 00000000..6eb82f97 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/util/CMLog.java @@ -0,0 +1,349 @@ +package com.navinfo.omqs.util; + +import android.app.ActivityManager; +import android.app.ActivityManager.MemoryInfo; +import android.content.Context; +import android.util.Log; + +import com.navinfo.omqs.Constant; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * 带日志文件输入的,又可控开关的日志调试 + * + * @author qj + * @version 1.0 + * @data 2016-8-23 + */ +public class CMLog { + //CrashHandler实例 + /** + * + */ + private static CMLog instance; + /** + * + */ + private static Boolean MYLOG_SWITCH = true; //日志文件总开关 + /** + * + */ + private static Boolean MYLOG_WRITE_TO_FILE = true;//日志写入文件开关 + /** + * + */ + private static char MYLOG_TYPE = 'v';//输入日志类型,w代表只输出告警信息等,v代表输出所有信息 +// private static String MYLOG_PATH_SDCARD_DIR = FMConstant.USER_DATA_LOG_PATH;// 日志文件在sdcard中的路径 + /** + * + */ + private static int SDCARD_LOG_FILE_SAVE_DAYS = 0;// sd卡中日志文件的最多保存天数 + /** + * + */ + private static String MYLOGFILEName = "Log.txt";// 本类输出的日志文件名称 + /** + * + */ + private static String STACKLOGFILEName = "StackLog.txt";// 本类输出的日志文件名称 + /** + * + */ + private static SimpleDateFormat myLogSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//日志的输出格式 + /** + * + */ + private static SimpleDateFormat logfile = new SimpleDateFormat("yyyy-MM-dd-HH");//日志文件格式 + /** + * + */ + private static Context mContext; + /** + * + */ + private static boolean flag; + /** + * + */ + private static int count = 0; + /** + * + */ + private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); + + /** + * 获取CrashHandler实例 ,单例模式 + * @return + */ + public static CMLog getInstance() { + if (instance == null) + instance = new CMLog(); + return instance; + } + + /** + * 初始化 + * @param context + */ + public void init(Context context) { + mContext = context; + } + + /** + * @param tag + * @param msg + */ + public static void w(String tag, Object msg) {//警告信息 + log(tag, msg.toString(), 'w'); + } + + /** + * @param tag + * @param msg + */ + public static void e(String tag, Object msg) {//错误信息 + log(tag, msg.toString(), 'e'); + } + + /** + * @param tag + * @param msg + */ + public static void d(String tag, Object msg) {//调试信息 + log(tag, msg.toString(), 'd'); + } + + /** + * @param tag + * @param msg + */ + public static void i(String tag, Object msg) {// + log(tag, msg.toString(), 'i'); + } + + /** + * @param tag + * @param msg + */ + public static void v(String tag, Object msg) { + log(tag, msg.toString(), 'v'); + } + + /** + * @param tag + * @param text + */ + public static void w(String tag, String text) { + log(tag, text, 'w'); + } + + /** + * @param tag + * @param text + */ + public static void e(String tag, String text) { + log(tag, text, 'e'); + } + + /** + * @param tag + * @param text + */ + public static void d(String tag, String text) { + log(tag, text, 'd'); + } + + /** + * @param tag + * @param text + */ + public static void i(String tag, String text) { + log(tag, text, 'i'); + } + + /** + * @param tag + * @param text + */ + public static void v(String tag, String text) { + log(tag, text, 'v'); + } + + /** + * 根据tag, msg和等级,输出日志 + * + * @param tag + * @param msg + * @param level + * @return void + * @since v 1.0 + */ + private static void log(String tag, String msg, char level) { + if (MYLOG_SWITCH) { + if ('e' == level && ('e' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { // 输出错误信息 + Log.e(tag, msg); + } else if ('w' == level && ('w' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { + Log.w(tag, msg); + } else if ('d' == level && ('d' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { + Log.d(tag, msg); + } else if ('i' == level && ('d' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { + Log.i(tag, msg); + } else { + Log.v(tag, msg); + } + if (MYLOG_WRITE_TO_FILE) + writeLogtoFile(String.valueOf(level), tag, msg); + } + } + + /** + * 打开日志文件并写入日志 + * + * @param mylogtype + * @param tag + * @param text + **/ + public static void writeLogtoFile(String mylogtype, String tag, String text) { + if (!flag&&MYLOG_WRITE_TO_FILE) { + flag = true; + try { + Log.e("qj", "日志写入0"); + // 新建或打开日志文件 + Date nowtime = new Date(); + String needWriteFiel = logfile.format(nowtime); + // String needWriteMessage = myLogSdf.format(nowtime) + " " + mylogtype + String needWriteMessage = simpleDateFormat.format(nowtime) + " " + mylogtype + + " " + count + " " + tag + " " + text + "\r\n"; + //输出内存使用情况 + ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + MemoryInfo memoryInfo = new MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); +/* needWriteMessage += " 系统剩余内存: " + (memoryInfo.availMem / 1024) + "(KB)\n"; + needWriteMessage += " 系统是否处于低内存运行: " + memoryInfo.lowMemory + "\n"; + needWriteMessage += " 当系统剩余内存低于: " + (memoryInfo.threshold / 1024) + "(KB)\n";*/ + if (new File(Constant.USER_DATA_LOG_PATH).exists() == false) { + new File(Constant.USER_DATA_LOG_PATH).mkdirs(); + } + File file = new File(Constant.USER_DATA_LOG_PATH, needWriteFiel + MYLOGFILEName); + Log.e("qj", "日志写入1"); + + if (!file.exists()) + file.createNewFile(); + Log.e("qj", "日志写入2"); + + FileWriter filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖 + BufferedWriter bufWriter = new BufferedWriter(filerWriter); + bufWriter.write(needWriteMessage); + bufWriter.newLine(); + bufWriter.close(); + filerWriter.close(); + Log.e("qj", "日志写入结束"); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + flag = false; + } + } + + count ++; + + if(count>10000){ + count = 0; + } + } + + /** + * 写入调用栈的信息,包括文件名,行号,接口名称 + * + * @param extMsg 扩展信息,如果不为NULL,则输出到栈信息之前 + */ + public static void writeStackLogtoFile(String extMsg) {// 新建或打开日志文件 + StackTraceElement[] eles = Thread.currentThread().getStackTrace(); + Date nowtime = new Date(); + String needWriteFiel = logfile.format(nowtime); + String needWriteMessage = "[Java Stack]:" + myLogSdf.format(nowtime) + "\n"; + + if(eles!=null&&eles.length>3){ + needWriteMessage += "\t file name :" + eles[3].getFileName() + "\n"; + needWriteMessage += "\t line num :" + eles[3].getLineNumber() + "\n"; + needWriteMessage += "\t class name:" + eles[3].getClassName() + "\n"; + needWriteMessage += "\t method :" + eles[3].getMethodName() + "\n"; + } + + if (extMsg != null && extMsg.length() > 0) { + needWriteMessage += "\t extMsg :" + extMsg + "\n"; + } + + if (new File(Constant.USER_DATA_LOG_PATH).exists() == false) { + new File(Constant.USER_DATA_LOG_PATH).mkdirs(); + } + File file = new File(Constant.USER_DATA_LOG_PATH, needWriteFiel + + STACKLOGFILEName); + try { + FileWriter filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖 + BufferedWriter bufWriter = new BufferedWriter(filerWriter); + bufWriter.write(needWriteMessage); + bufWriter.newLine(); + bufWriter.close(); + filerWriter.close(); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * 删除制定的日志文件 + */ + public static void delFile() {// 删除日志文件 + String needDelFiel = logfile.format(getDateBefore()); + File file = new File(Constant.USER_DATA_LOG_PATH, needDelFiel + MYLOGFILEName); + if (file.exists()) { + file.delete(); + } + } + + /** + * 得到现在时间前的几天日期,用来得到需要删除的日志文件名 + * @return + */ + private static Date getDateBefore() { + Date nowtime = new Date(); + Calendar now = Calendar.getInstance(); + now.setTime(nowtime); + now.set(Calendar.DATE, now.get(Calendar.DATE) + - SDCARD_LOG_FILE_SAVE_DAYS); + return now.getTime(); + } + + //输出错误日志 + + /** + * 得到现在时间前的几天日期,用来得到需要删除的日志文件名 + * @param e + * @param TAG + */ + public static void writeStackLogtoFile(Exception e, String TAG) { + String errorInfo = ""; + for (int i = 0; i < e.getStackTrace().length; i++) { + errorInfo += e.getStackTrace()[i]; + } + writeLogtoFile("异常崩溃", "异常", "异常信息:" + errorInfo); + } + + /** + * @param mylogWriteToFile + */ + public static void setMylogWriteToFile(Boolean mylogWriteToFile) { + MYLOG_WRITE_TO_FILE = mylogWriteToFile; + } +} diff --git a/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt b/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt index d2613b24..cfe0ce05 100644 --- a/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt +++ b/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt @@ -11,15 +11,17 @@ import com.navinfo.omqs.bean.NaviRoute import com.navinfo.omqs.bean.NaviRouteItem import com.navinfo.omqs.db.RealmOperateHelper import io.realm.Realm +import org.locationtech.jts.geom.Geometry import org.locationtech.jts.geom.LineString import org.locationtech.jts.geom.Point import org.oscim.core.GeoPoint interface OnNaviEngineCallbackListener { - fun planningPathStatus(code: NaviStatus) + fun planningPathStatus(code: NaviStatus, linkdId: String? = null, geometry: String? = null) // fun planningPathError(errorCode: NaviStatus, errorMessage: String) suspend fun bindingResults(route: NaviRoute?, list: List) + } enum class NaviStatus { @@ -73,6 +75,7 @@ class NaviEngine( DataCodeEnum.OMDB_TRAFFICLIGHT.name, // DataCodeEnum.OMDB_RESTRICTION.name, DataCodeEnum.OMDB_LANEINFO.name, + DataCodeEnum.OMDB_CLM_LANEINFO.name, DataCodeEnum.OMDB_TRAFFIC_SIGN.name, DataCodeEnum.OMDB_WARNINGSIGN.name, DataCodeEnum.OMDB_TOLLGATE.name @@ -205,9 +208,12 @@ class NaviEngine( callback.planningPathStatus(NaviStatus.NAVI_STATUS_PATH_PLANNING) val pathList = mutableListOf() val realm = realmOperateHelper.getSelectTaskRealmInstance() - for (link in taskBean.hadLinkDvoList) { + Log.e("jingo", "路径计算 条数 ${taskBean.hadLinkDvoList.size}") + for (i in 0 until taskBean.hadLinkDvoList.size) { + val link = taskBean.hadLinkDvoList[i] + Log.e("jingo","获取 S E $i 总共 ${taskBean.hadLinkDvoList.size}") //测线不参与导航 - if (link.linkStatus == 3) { + if (link!!.linkStatus == 3) { continue } val route = NaviRoute( @@ -217,7 +223,7 @@ class NaviEngine( route.pointList = GeometryTools.getGeoPoints(link.geometry) val res = realm.where(RenderEntity::class.java).`in`("table", QUERY_KEY_LINK_INFO_LIST) - .equalTo("properties['linkPid']", link.linkPid).findAll() + .equalTo("linkPid", link.linkPid).findAll() var bHasNode = false var bHasDir = false var bHasName = false @@ -255,13 +261,17 @@ class NaviEngine( } if (!bHasNode) { callback.planningPathStatus( - NaviStatus.NAVI_STATUS_PATH_ERROR_NODE + NaviStatus.NAVI_STATUS_PATH_ERROR_NODE, + link.linkPid, + link.geometry ) return } if (!bHasDir) { callback.planningPathStatus( - NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION + NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION, + link!!.linkPid, + link.geometry ) return } @@ -346,7 +356,9 @@ class NaviEngine( if (!bHasLast && !bHasNext) { bBreak = false callback.planningPathStatus( - NaviStatus.NAVI_STATUS_PATH_ERROR_BLOCKED + NaviStatus.NAVI_STATUS_PATH_ERROR_BLOCKED, + tempRouteList[0].linkId, + GeometryTools.getLineString(tempRouteList[0].pointList) ) realm.close() return @@ -356,11 +368,13 @@ class NaviEngine( val itemMap: MutableMap> = mutableMapOf() //查询每根link上的关联要素 - for (route in newRouteList) { + for (i in newRouteList.indices) { + val route = newRouteList[i] + Log.e("jingo","获取 插入要素 $i 总共 ${newRouteList.size}") itemMap.clear() //常规点限速 val res = realm.where(RenderEntity::class.java) - .equalTo("properties['linkPid']", route.linkId).and().`in`( + .equalTo("linkPid", route.linkId).and().`in`( "table", QUERY_KEY_ITEM_LIST ).findAll() diff --git a/app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt b/app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt new file mode 100644 index 00000000..04ae27d5 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt @@ -0,0 +1,84 @@ +package com.navinfo.omqs.util + +import com.navinfo.collect.library.data.entity.HadLinkDvoBean +import com.navinfo.collect.library.data.entity.NiLocation +import com.navinfo.collect.library.data.entity.RenderEntity +import com.navinfo.collect.library.data.entity.TaskBean +import com.navinfo.collect.library.enums.DataCodeEnum +import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.omqs.db.RealmOperateHelper +import io.realm.Realm +import org.oscim.core.GeoPoint + +class NaviEngineNew( + private val realmOperateHelper: RealmOperateHelper, +) { + /** + * 要查询的link基本信息列表 + */ + private val QUERY_KEY_LINK_INFO_LIST = arrayOf( + DataCodeEnum.OMDB_RD_LINK.name, + DataCodeEnum.OMDB_LINK_DIRECT.name, + DataCodeEnum.OMDB_LINK_NAME.name, + ) + + + private val locationList = mutableListOf() + + + suspend fun bindingRoute( + niLocation: NiLocation? = null, + taskBean: TaskBean, + geoPoint: GeoPoint, + realm:Realm + ) { + var latestRoute: HadLinkDvoBean? = null + var lastDis = -1.0 + + for (link in taskBean.hadLinkDvoList) { + val linkGeometry = GeometryTools.createGeometry(link.geometry) + val footAndDistance = GeometryTools.pointToLineDistance(geoPoint, linkGeometry) + val meterD = footAndDistance.getMeterDistance() + if (meterD < 15 && (lastDis < 0 || lastDis > meterD)) { + latestRoute = link + lastDis = meterD + } + } + + + + latestRoute?.let { + + val res2 = + realm.where(RenderEntity::class.java).`in`("table", QUERY_KEY_LINK_INFO_LIST) + .equalTo("linkPid", it.linkPid).findAll() + if (res2 != null) { + for (entity in res2) { + when (entity.code) { + DataCodeEnum.OMDB_RD_LINK.code -> { + val snodePid = entity.properties["snodePid"] + if (snodePid != null) { + } else { + } + val enodePid = entity.properties["enodePid"] + if (enodePid != null) { + } else { + } + } + DataCodeEnum.OMDB_LINK_DIRECT.code -> { + val direct = entity.properties["direct"] + if (direct != null) { + } + } + DataCodeEnum.OMDB_LINK_NAME.code -> { +// var name = realm.copyFromRealm(res4) + } + } + } + + } + + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt b/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt index 81d67890..8151e9cb 100644 --- a/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt +++ b/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt @@ -35,7 +35,7 @@ class SignUtil { return SignBean( iconId = getSignIcon(element), iconText = getSignIconText(element), - linkId = element.properties[RenderEntity.Companion.LinkTable.linkPid] + linkId = element.linkPid ?: "", name = getSignNameText(element), bottomRightText = getSignBottomRightText( @@ -107,7 +107,7 @@ class SignUtil { //物理车道数OMDB_PHY_LANENUM DataCodeEnum.OMDB_LANE_NUM.code, DataCodeEnum.OMDB_PHY_LANENUM.code -> { - "${data.properties["laneNum"]}|${data.properties["laneS2e"]}|${data.properties["laneE2s"]}" + "${data.properties["laneS2e"]}|${data.properties["laneE2s"]}" } //常规点限速,条件点限速 @@ -208,7 +208,7 @@ class SignUtil { DataCodeEnum.OMDB_RD_LINK.code -> { list.add( TwoItemAdapterItem( - title = "linkPid", text = "${data.properties["linkPid"]}" + title = "linkPid", text = "${data.linkPid}" ) ) list.add( @@ -226,7 +226,7 @@ class SignUtil { DataCodeEnum.OMDB_RD_LINK_KIND.code -> { list.add( TwoItemAdapterItem( - title = "linkPid", text = "${data.properties["linkPid"]}" + title = "linkPid", text = "${data.linkPid}" ) ) try { @@ -244,7 +244,7 @@ class SignUtil { DataCodeEnum.OMDB_LINK_DIRECT.code -> { list.add( TwoItemAdapterItem( - title = "linkPid", text = "${data.properties["linkPid"]}" + title = "linkPid", text = "${data.linkPid}" ) ) try { @@ -286,11 +286,11 @@ class SignUtil { //车道数//增加物理车道数DataCodeEnum.OMDB_PHY_LANENUM.code DataCodeEnum.OMDB_PHY_LANENUM.code, DataCodeEnum.OMDB_LANE_NUM.code -> { - list.add( +/* list.add( TwoItemAdapterItem( title = "车道总数", text = "${data.properties["laneNum"]}" ) - ) + )*/ list.add( TwoItemAdapterItem( title = "顺方向车道数", text = "${data.properties["laneS2e"]}" @@ -333,7 +333,7 @@ class SignUtil { DataCodeEnum.OMDB_LINK_CONSTRUCTION.code -> { list.add( TwoItemAdapterItem( - title = "linkPid", text = "${data.properties["linkPid"]}" + title = "linkPid", text = "${data.linkPid}" ) ) @@ -386,7 +386,7 @@ class SignUtil { DataCodeEnum.OMDB_WARNINGSIGN.code -> { list.add( TwoItemAdapterItem( - title = "linkPid", text = "${data.properties["linkPid"]}" + title = "linkPid", text = "${data.linkPid}" ) ) list.add( @@ -751,7 +751,7 @@ class SignUtil { fun getTollgateInfo(renderEntity: RenderEntity): List { val list = mutableListOf() list.add( - LaneBoundaryItem("linkPid", "${renderEntity.properties["linkPid"]}", null) + LaneBoundaryItem("linkPid", "${renderEntity.linkPid}", null) ) list.add( LaneBoundaryItem("收费站号码", "${renderEntity.properties["tollgatePid"]}", null) @@ -1426,14 +1426,14 @@ class SignUtil { ) DataCodeEnum.OMDB_RD_LINK_KIND.code -> stringBuffer.append("种别${item.iconText},") DataCodeEnum.OMDB_LINK_DIRECT.code -> stringBuffer.append("${item.iconText},") - DataCodeEnum.OMDB_PHY_LANENUM.code,//物理车道数 +/* DataCodeEnum.OMDB_PHY_LANENUM.code,//物理车道数 DataCodeEnum.OMDB_LANE_NUM.code -> stringBuffer.append( "${ item.iconText.substringBefore( "|" ) }车道" - ) + )*/ } } return stringBuffer.toString() diff --git a/app/src/main/res/menu/personal_center_menu.xml b/app/src/main/res/menu/personal_center_menu.xml index f065497c..0b568fcd 100644 --- a/app/src/main/res/menu/personal_center_menu.xml +++ b/app/src/main/res/menu/personal_center_menu.xml @@ -48,12 +48,17 @@ android:title="锁定地图旋转及视角" /> + - @@ -1720,22 +1719,22 @@ - + - + - + - + - + diff --git a/collect-library/src/main/assets/omdb/icon_2013_0.svg b/collect-library/src/main/assets/omdb/icon_2013_0.svg index bcb9b125..1a97174a 100644 --- a/collect-library/src/main/assets/omdb/icon_2013_0.svg +++ b/collect-library/src/main/assets/omdb/icon_2013_0.svg @@ -1,11 +1,10 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/collect-library/src/main/assets/omdb/icon_2013_1.svg b/collect-library/src/main/assets/omdb/icon_2013_1.svg index bd3e6b1e..ac4fd446 100644 --- a/collect-library/src/main/assets/omdb/icon_2013_1.svg +++ b/collect-library/src/main/assets/omdb/icon_2013_1.svg @@ -1,11 +1,10 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/collect-library/src/main/assets/omdb/icon_2013_2.svg b/collect-library/src/main/assets/omdb/icon_2013_2.svg index eeb06059..9b4e18f7 100644 --- a/collect-library/src/main/assets/omdb/icon_2013_2.svg +++ b/collect-library/src/main/assets/omdb/icon_2013_2.svg @@ -1,11 +1,10 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/collect-library/src/main/assets/omdb/icon_2013_6.svg b/collect-library/src/main/assets/omdb/icon_2013_6.svg index ad834913..8f5ad291 100644 --- a/collect-library/src/main/assets/omdb/icon_2013_6.svg +++ b/collect-library/src/main/assets/omdb/icon_2013_6.svg @@ -1,11 +1,10 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/collect-library/src/main/assets/omdb/icon_2013_7.svg b/collect-library/src/main/assets/omdb/icon_2013_7.svg index 4528138f..305c101d 100644 --- a/collect-library/src/main/assets/omdb/icon_2013_7.svg +++ b/collect-library/src/main/assets/omdb/icon_2013_7.svg @@ -1,11 +1,10 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/HadLinkDvoBean.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/HadLinkDvoBean.kt index 8b486d45..d85d5dd3 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/HadLinkDvoBean.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/HadLinkDvoBean.kt @@ -1,5 +1,7 @@ package com.navinfo.collect.library.data.entity +import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.collect.library.utils.GeometryToolsKt import io.realm.RealmObject import io.realm.annotations.PrimaryKey @@ -12,11 +14,13 @@ open class HadLinkDvoBean @JvmOverloads constructor( * 图幅号 */ var mesh: String = "", + /** * linkPid */ @PrimaryKey var linkPid: String = "", + /** * (几何)加偏后 */ @@ -31,10 +35,12 @@ open class HadLinkDvoBean @JvmOverloads constructor( * 1:源库link,2:选择link 3:现场新增 */ var linkStatus: Int = 1, + /** * 详细属性 */ var linkInfo: LinkInfoBean? = null, + /** * 长度(米) */ diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/LinkRelation.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/LinkRelation.kt new file mode 100644 index 00000000..06e38f9e --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/LinkRelation.kt @@ -0,0 +1,30 @@ +package com.navinfo.collect.library.data.entity + +import android.os.Parcelable +import com.navinfo.collect.library.system.Constant +import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.collect.library.utils.GeometryToolsKt +import io.realm.RealmDictionary +import io.realm.RealmObject +import io.realm.RealmSet +import io.realm.annotations.Ignore +import io.realm.annotations.Index +import io.realm.annotations.PrimaryKey +import kotlinx.parcelize.Parcelize +import org.locationtech.jts.geom.Coordinate +import org.locationtech.jts.geom.Geometry +import org.oscim.core.MercatorProjection +import java.util.* + +/** + * 渲染要素对应的实体 + * */ +@Parcelize +open class LinkRelation() : RealmObject(), Parcelable { + @Index + var linkPid:String = "" + @Index + var sNodeId: String? = null + @Index + var eNodeId: String? = null +} \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt index 07d2917b..415ad9c1 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt @@ -1,7 +1,12 @@ package com.navinfo.collect.library.data.entity +import android.util.Log +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.navinfo.collect.library.utils.DeflaterUtil import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryToolsKt +import com.navinfo.collect.library.utils.StrZipUtil import io.realm.RealmDictionary import io.realm.RealmObject import io.realm.RealmSet @@ -14,18 +19,28 @@ import java.util.* * 渲染要素对应的实体 * */ open class ReferenceEntity() : RealmObject() { - @PrimaryKey - var id: String = UUID.randomUUID().toString() // id - var renderEntityId: String = "" // 参考的renderEntity的Id + // @PrimaryKey +// var id: Int = 0 // id +// var renderEntityId: Int = 0 // 参考的renderEntity的Id + @Ignore lateinit var name: String //要素名 lateinit var table: String //要素表名 + var propertiesDb: String = "" var code: String = "0" // 要素编码 + + @Ignore var zoomMin: Int = 18 //显示最小级别 + + @Ignore var zoomMax: Int = 23 //显示最大级别 var taskId: Int = 0 //任务ID - var enable:Int = 0 // 默认0不是显示 1为渲染显示 - - var geometry: String = "" // 要素渲染参考的geometry,该数据可能会在导入预处理环节被修改,原始geometry会保存在properties的geometry字段下 + var enable: Int = 0 // 默认0不是显示 1为渲染显示 + var tileXMin: Int = 0 + var tileXMax: Int = 0 + var tileYMin: Int = 0 + var tileYMax: Int = 0 + var geometry: String = + "" // 要素渲染参考的geometry,该数据可能会在导入预处理环节被修改,原始geometry会保存在properties的geometry字段下 get() { wkt = GeometryTools.createGeometry(field) return field @@ -34,7 +49,13 @@ open class ReferenceEntity() : RealmObject() { field = value // 根据geometry自动计算当前要素的x-tile和y-tile GeometryToolsKt.getTileXByGeometry(value, tileX) + tileXMin = tileX.min() + tileXMax = tileX.max() + GeometryToolsKt.getTileYByGeometry(value, tileY) + + tileYMin = tileY.min() + tileYMax = tileY.max() // 根据传入的geometry文本,自动转换为Geometry对象 try { wkt = GeometryTools.createGeometry(value) @@ -55,11 +76,29 @@ open class ReferenceEntity() : RealmObject() { } return field } + + @Ignore var properties: RealmDictionary = RealmDictionary() + get() { + if (propertiesDb != null && propertiesDb!!.isNotEmpty() && field.isEmpty()) { + try { + val gson = Gson() + val type = object : TypeToken>() {}.type + field = gson.fromJson(DeflaterUtil.unzipString(propertiesDb), type) + } catch (e: Exception) { + Log.e("jingo","ReferenceEntity 转 properties $e") + } + } + return field + } + + @Ignore var tileX: RealmSet = RealmSet() // x方向的tile编码 + + @Ignore var tileY: RealmSet = RealmSet() // y方向的tile编码 - constructor(name: String): this() { + constructor(name: String) : this() { this.name = name } } \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt index deeade38..75516708 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt @@ -1,40 +1,59 @@ package com.navinfo.collect.library.data.entity import android.os.Parcelable -import com.navinfo.collect.library.system.Constant +import android.util.Log +import com.alibaba.fastjson.JSON +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.navinfo.collect.library.utils.DeflaterUtil import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryToolsKt +import com.navinfo.collect.library.utils.StrZipUtil import io.realm.RealmDictionary import io.realm.RealmObject import io.realm.RealmSet import io.realm.annotations.Ignore -import io.realm.annotations.PrimaryKey +import io.realm.annotations.Index import kotlinx.parcelize.Parcelize -import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.geom.Geometry -import org.oscim.core.MercatorProjection -import java.util.* /** * 渲染要素对应的实体 * */ @Parcelize open class RenderEntity() : RealmObject(), Parcelable { - @PrimaryKey - var id: String = UUID.randomUUID().toString() // id + // @PrimaryKey +// var id: String = UUID.randomUUID().toString() // id lateinit var name: String //要素名 lateinit var table: String //要素表名 var code: String = "0" // 要素编码 - var geometry: String = "" // 要素渲染参考的geometry,该数据可能会在导入预处理环节被修改,原始geometry会保存在properties的geometry字段下 + var propertiesDb: String = "" + var geometry: String = + "" // 要素渲染参考的geometry,该数据可能会在导入预处理环节被修改,原始geometry会保存在properties的geometry字段下 get() { wkt = GeometryTools.createGeometry(field) return field } + // get() { +// if (geometryDb != null && geometryDb.isNotEmpty() && field.isEmpty()) { +// field = StrZipUtil.uncompress(geometryDb) +// } +// return field +// } set(value) { field = value +// geometryDb = StrZipUtil.compress(value) // 根据geometry自动计算当前要素的x-tile和y-tile GeometryToolsKt.getTileXByGeometry(value, tileX) + + tileXMin = tileX.min() + tileXMax = tileX.max() + GeometryToolsKt.getTileYByGeometry(value, tileY) + + tileYMin = tileY.min() + tileYMax = tileY.max() + // 根据传入的geometry文本,自动转换为Geometry对象 try { wkt = GeometryTools.createGeometry(value) @@ -50,36 +69,47 @@ open class RenderEntity() : RealmObject(), Parcelable { try { field = GeometryTools.createGeometry(geometry) } catch (e: Exception) { - + Log.e("jingo","RenderEntity 转 wkt失败 $e") } } return field } + + @Ignore var properties: RealmDictionary = RealmDictionary() + get() { + if (propertiesDb != null && propertiesDb!!.isNotEmpty()&& field.isEmpty()) { + try { + val gson = Gson() + val type = object : TypeToken>() {}.type + field = gson.fromJson(DeflaterUtil.unzipString(propertiesDb), type) + } catch (e: Exception) { + Log.e("jingo","RenderEntity 转 properties $e") + } + } + return field + } + + + @Ignore var tileX: RealmSet = RealmSet() // x方向的tile编码 + + @Ignore var tileY: RealmSet = RealmSet() // y方向的tile编码 + var tileXMin: Int = 0 + var tileXMax: Int = 0 + var tileYMin: Int = 0 + var tileYMax: Int = 0 var taskId: Int = 0 //任务ID var zoomMin: Int = 18 //显示最小级别 var zoomMax: Int = 23 //显示最大级别 - var enable:Int = 0 // 默认0不是显示 1为渲染显示 2为常显 - var catchEnable:Int = 0 // 0不捕捉 1捕捉 + var enable: Int = 0 // 默认0不是显示 1为渲染显示 2为常显 + var catchEnable: Int = 0 // 0不捕捉 1捕捉 + @Index + var linkPid: String = "" // RenderEntity关联的linkPid集合(可能会关联多个) + var linkRelation: LinkRelation? = null constructor(name: String) : this() { this.name = name } - - companion object { - object LinkTable { - //道路linkId - const val linkPid = "linkPid" - } - - object LimitTable { - const val linkPid = "linkPid" - } - - object KindCodeTable { - const val linkPid = "linkPid" - } - } } \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/enums/DataCodeEnum.kt b/collect-library/src/main/java/com/navinfo/collect/library/enums/DataCodeEnum.kt index 511c9b77..68d28973 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/enums/DataCodeEnum.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/enums/DataCodeEnum.kt @@ -81,6 +81,7 @@ enum class DataCodeEnum(var tableName: String, var code: String) { OMDB_TRAFFICLIGHT("交通灯", "4022"), OMDB_TOLLGATE("收费站", "4023"), OMDB_LANEINFO("车信", "4601"), + OMDB_CLM_LANEINFO("车信CLM", "4602"), OMDB_LANE_LINK_LG("车道中心线", "5001"); companion object { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java index 423f1e96..a6b6858d 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java @@ -608,6 +608,7 @@ public final class NIMapView extends RelativeLayout { LABEL(4)/*图标,文字图层*/, OPERATE_LINE(5)/*操作图层组*/, OPERATE_MARKER(6)/*操作图层组*/; + int groupIndex; LAYER_GROUPS(int groupIndex) { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt index a44d100f..0eb6252e 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt @@ -171,7 +171,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : mCurrentLocation?.run { val mapPosition = mMapView.vtmMap.mapPosition mapPosition.setPosition(this.latitude, this.longitude) - mMapView.vtmMap.animator().animateTo(300, mapPosition) + mMapView.vtmMap.animator().animateTo(800, mapPosition) } } @@ -224,7 +224,6 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc val call = callback; override fun onReceiveLocation(location: BDLocation) { call(location) - Log.e("jingo", "定位结果:速度=" + location.speed + " 方向=" + location.direction) } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt index b7e38784..d7bc72c7 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt @@ -28,6 +28,8 @@ import org.oscim.backend.canvas.Paint import org.oscim.core.GeoPoint import org.oscim.layers.marker.* import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener +import org.oscim.layers.tile.vector.VectorTileLayer +import org.oscim.layers.vector.VectorLayer import org.oscim.layers.vector.geometries.* import org.oscim.map.Map import java.util.* @@ -43,8 +45,17 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : */ private val mDefaultTextColor = "#4E55AF" + /** + * 默认Marker可用状态 + */ private var markerEnable = true + /** + * 默认轨迹可用状态 + */ + private var traceMarkerEnable = true + + /** * 文字画笔 */ @@ -179,6 +190,68 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : layer } + /** + * 评测精简数据marker 图层 + */ + private val niLocationItemizedLayerRough: ItemizedLayer by lazy { + + val symbol = MarkerSymbol(niLocationBitmap, MarkerSymbol.HotspotPlace.CENTER) + val layerRough = ItemizedLayer( + mapView.vtmMap, + symbol, + ) + layerRough.setOnItemGestureListener(object : OnItemGestureListener { + override fun onItemSingleTapUp(index: Int, item: MarkerInterface?): Boolean { + val tag = mMapView.listenerTagList.last() + val listenerList = mMapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + } + } + return true + } + + override fun onItemLongPress(index: Int, item: MarkerInterface?): Boolean { + return true + } + + }) + layerRough.isEnabled = false + addLayer(layerRough, NIMapView.LAYER_GROUPS.OPERATE_MARKER) + layerRough + } + + /** + * 评测精简数据marker 图层 + */ + private val niLocationItemizedLayerSimple: ItemizedLayer by lazy { + + val symbol = MarkerSymbol(niLocationBitmap, MarkerSymbol.HotspotPlace.CENTER) + val layerSimple = ItemizedLayer( + mapView.vtmMap, + symbol, + ) + layerSimple.setOnItemGestureListener(object : OnItemGestureListener { + override fun onItemSingleTapUp(index: Int, item: MarkerInterface?): Boolean { + val tag = mMapView.listenerTagList.last() + val listenerList = mMapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + } + } + return true + } + + override fun onItemLongPress(index: Int, item: MarkerInterface?): Boolean { + return true + } + + }) + addLayer(layerSimple, NIMapView.LAYER_GROUPS.OPERATE_MARKER) + layerSimple + } + + /** * 评测数据marker 图层 */ @@ -213,7 +286,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : } }) - + layer.isEnabled = false addLayer(layer, NIMapView.LAYER_GROUPS.OPERATE_MARKER) layer } @@ -277,13 +350,20 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : // 设置矢量图层均在12级以上才显示 mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition -> if (e == Map.SCALE_EVENT) { - if(markerEnable){ + if (markerEnable) { qsRecordItemizedLayer.isEnabled = mapPosition.getZoomLevel() >= 12 - }else{ + } else { qsRecordItemizedLayer.isEnabled = false } - - niLocationItemizedLayer.isEnabled = mapPosition.getZoomLevel() >= 12 + if (traceMarkerEnable) { + niLocationItemizedLayer.isEnabled = mapPosition.getZoomLevel() in 18..20 + niLocationItemizedLayerSimple.isEnabled = mapPosition.getZoomLevel() in 14..17 + niLocationItemizedLayerRough.isEnabled = mapPosition.getZoomLevel() in 12..13 + } else { + niLocationItemizedLayer.isEnabled = false + niLocationItemizedLayerSimple.isEnabled = false + niLocationItemizedLayerRough.isEnabled = false + } } }) } @@ -379,13 +459,30 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : mMapView.updateMap(true) } - fun setQsRecordMarkEnable(enable:Boolean){ + /** + * Marker是否显示 + */ + fun setQsRecordMarkEnable(enable: Boolean) { qsRecordItemizedLayer.isEnabled = enable markerEnable = enable qsRecordItemizedLayer.populate() mMapView.updateMap(true) } + /** + * 轨迹是否显示 + */ + fun setTraceMarkEnable(enable: Boolean) { + niLocationItemizedLayer.isEnabled = enable + niLocationItemizedLayerSimple.isEnabled = enable + niLocationItemizedLayerRough.isEnabled = enable + traceMarkerEnable = enable + niLocationItemizedLayer.populate() + niLocationItemizedLayerSimple.populate() + niLocationItemizedLayerRough.populate() + mMapView.updateMap(true) + } + /** * 增加或更新便签 @@ -520,11 +617,27 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : * 添加质检数据marker */ fun addNiLocationMarkerItem(niLocation: NiLocation) { - synchronized(this) { - var geoMarkerItem = createNILocationBitmap(niLocation) - niLocationItemizedLayer.addItem(geoMarkerItem) - niLocationItemizedLayer.update() - } + var geoMarkerItem = createNILocationBitmap(niLocation) + niLocationItemizedLayer.addItem(geoMarkerItem) + niLocationItemizedLayer.update() + } + + /** + * 添加质检数据marker + */ + fun addNiLocationMarkerItemSimple(niLocation: NiLocation) { + var geoMarkerItem = createNILocationBitmap(niLocation) + niLocationItemizedLayerSimple.addItem(geoMarkerItem) + niLocationItemizedLayerSimple.update() + } + + /** + * 添加质检数据marker + */ + fun addNiLocationMarkerItemRough(niLocation: NiLocation) { + var geoMarkerItem = createNILocationBitmap(niLocation) + niLocationItemizedLayerRough.addItem(geoMarkerItem) + niLocationItemizedLayerRough.update() } private fun createNILocationBitmap(niLocation: NiLocation): MarkerItem { @@ -791,6 +904,10 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : fun clearNiLocationLayer() { niLocationItemizedLayer.removeAllItems() niLocationItemizedLayer.update() + niLocationItemizedLayerSimple.removeAllItems() + niLocationItemizedLayerSimple.update() + niLocationItemizedLayerRough.removeAllItems() + niLocationItemizedLayerRough.update() } /** @@ -805,6 +922,30 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : return niLocationItemizedLayer.itemList.size } + fun getNILocationItemizedLayerSimpleSize(): Int { + return niLocationItemizedLayerSimple.itemList.size + } + + fun getNILocationSimple(index: Int): NiLocation? { + return if (index > -1 && index < getNILocationItemizedLayerSimpleSize()) { + ((niLocationItemizedLayerSimple.itemList[index]) as MarkerItem).uid as NiLocation + } else { + null + } + } + + fun getNILocationItemizedLayerRoughSize(): Int { + return niLocationItemizedLayerRough.itemList.size + } + + fun getNILocationRough(index: Int): NiLocation? { + return if (index > -1 && index < getNILocationItemizedLayerRoughSize()) { + ((niLocationItemizedLayerRough.itemList[index]) as MarkerItem).uid as NiLocation + } else { + null + } + } + fun getNILocation(index: Int): NiLocation? { return if (index > -1 && index < getNILocationItemizedLayerSize()) { ((niLocationItemizedLayer.itemList[index]) as MarkerItem).uid as NiLocation @@ -833,6 +974,27 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : return -1 } + + fun getNILocationSimpleIndex(niLocation: NiLocation): Int? { + + var list = niLocationItemizedLayerSimple.itemList + + if (niLocation != null && list.isNotEmpty()) { + + var index = -1 + + list.forEach { + + index += 1 + + if (((it as MarkerItem).uid as NiLocation).id.equals(niLocation.id)) { + return index + } + } + } + + return -1 + } } interface OnQsRecordItemClickListener : BaseClickListener { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java index 61a0334b..0aea8ff3 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java @@ -6,6 +6,7 @@ import android.util.Log; import androidx.annotation.RequiresApi; import com.navinfo.collect.library.data.entity.ReferenceEntity; +import com.navinfo.collect.library.data.entity.RenderEntity; import com.navinfo.collect.library.system.Constant; import com.navinfo.collect.library.utils.GeometryTools; import com.navinfo.collect.library.utils.MapParamUtils; @@ -17,6 +18,7 @@ import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.QueryResult; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -41,14 +43,18 @@ public class OMDBReferenceDataSource implements ITileDataSource { @RequiresApi(api = Build.VERSION_CODES.N) @Override public void query(MapTile tile, ITileDataSink mapDataSink) { + if(MapParamUtils.getTaskConfig() == null) + return; // 获取tile对应的坐标范围 if (tile.zoomLevel >= Constant.OMDB_MIN_ZOOM && tile.zoomLevel <= Constant.DATA_ZOOM) { + Realm realm = Realm.getInstance(MapParamUtils.getTaskConfig()); + RealmQuery realmQuery = realm.where(ReferenceEntity.class); int m = Constant.DATA_ZOOM - tile.zoomLevel; int xStart = tile.tileX; int xEnd = tile.tileX + 1; int yStart = tile.tileY; int yEnd = tile.tileY + 1; - if (m>0) { + if (m > 0) { xStart = (int) (xStart << m); xEnd = (int) (xEnd << m); yStart = (int) (yStart << m); @@ -56,21 +62,22 @@ public class OMDBReferenceDataSource implements ITileDataSource { } final int currentTileX = xStart; - if(isUpdate){ - Realm.getInstance(MapParamUtils.getTaskConfig()).refresh(); + if (isUpdate) { + realm.refresh(); isUpdate = false; } - String sql = " tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + ""; + String sql = " ((tileXMin <= " + xStart + " and tileXMax >= " + xStart + ") or (tileXMin <=" + xEnd + " and tileXMax >=" + xStart + ")) and ((tileYMin <= " + yStart + " and tileYMax >= " + yStart + ") or (tileYMin <=" + yEnd + " and tileYMin >=" + yStart + "))"; - if(MapParamUtils.getDataLayerEnum()!=null){ +// String sql = " tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + ""; + + if (MapParamUtils.getDataLayerEnum() != null) { sql += " and enable" + MapParamUtils.getDataLayerEnum().getSql(); - }else{ + } else { sql += " and enable>=0"; } - RealmQuery realmQuery = Realm.getInstance(MapParamUtils.getTaskConfig()).where(ReferenceEntity.class) - .rawPredicate(sql); + realmQuery.rawPredicate(sql); // 筛选不显示的数据 if (Constant.HAD_LAYER_INVISIABLE_ARRAY != null && Constant.HAD_LAYER_INVISIABLE_ARRAY.length > 0) { realmQuery.beginGroup(); @@ -91,10 +98,11 @@ public class OMDBReferenceDataSource implements ITileDataSource { } else { mapDataSink.completed(QueryResult.SUCCESS); } - Realm.getInstance(MapParamUtils.getTaskConfig()).close(); + realm.close(); } else { mapDataSink.completed(QueryResult.SUCCESS); } + } @Override @@ -104,13 +112,12 @@ public class OMDBReferenceDataSource implements ITileDataSource { @Override public void cancel() { - if (Realm.getDefaultInstance().isInTransaction()) { - Realm.getDefaultInstance().cancelTransaction(); - } +// if (Realm.getDefaultInstance().isInTransaction()) { +// Realm.getDefaultInstance().cancelTransaction(); +// } } - public void update(){ + public void update() { isUpdate = true; - Log.e("qj",Thread.currentThread().getName()); } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDecoder.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDecoder.java index 3ade4b72..a0b9e2e7 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDecoder.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDecoder.java @@ -4,10 +4,13 @@ import static org.oscim.core.MercatorProjection.latitudeToY; import static org.oscim.core.MercatorProjection.longitudeToX; import android.os.Build; +import android.util.Log; import androidx.annotation.RequiresApi; import com.navinfo.collect.library.data.entity.ReferenceEntity; +import com.navinfo.collect.library.enums.DataCodeEnum; +import com.navinfo.collect.library.utils.GeometryTools; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; @@ -100,7 +103,14 @@ public class OMDBReferenceDecoder extends TileDecoder { processCoordinateArray(multiPoint.getGeometryN(i).getCoordinates(), false); } } else if (geometry instanceof LineString) { - processLineString((LineString) geometry); + //将车道中心进行转化面渲染 + if(layerName!=null&&layerName.equals(DataCodeEnum.OMDB_LANE_LINK_LG.name())){ + Log.e("qj","车道中心线转化开始"); + processPolygon((Polygon)GeometryTools.createGeometry(GeometryTools.computeLine(0.000035,0.000035,geometry.toString()))); + Log.e("qj","车道中心线转化结束"); + }else{ + processLineString((LineString) geometry); + } } else if (geometry instanceof MultiLineString) { MultiLineString multiLineString = (MultiLineString) geometry; for (int i = 0; i < multiLineString.getNumGeometries(); i++) { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java index 9bc939e7..b74840e3 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java @@ -11,21 +11,45 @@ import com.navinfo.collect.library.utils.GeometryTools; import com.navinfo.collect.library.utils.MapParamUtils; import org.locationtech.jts.geom.Polygon; +import org.oscim.core.MapPosition; import org.oscim.layers.tile.MapTile; +import org.oscim.map.Map; import org.oscim.map.Viewport; import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.QueryResult; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import io.realm.Realm; +import io.realm.RealmConfiguration; import io.realm.RealmQuery; public class OMDBTileDataSource implements ITileDataSource { + + class RealmObject { + int threadCode; + int realmConfigCode; + Realm realm; + } + +// class DataObject { +// int threadCode = 0; +// byte zoom = 0; +// String lonLat = ""; +// List listIds = new ArrayList<>(); +// } + private boolean isUpdate; private Viewport viewport; + + private List realmObjectList = new ArrayList<>(); + +// private List dataObjectList = new ArrayList<>(); + private final ThreadLocal mThreadLocalDecoders = new ThreadLocal() { @Override protected OMDBDataDecoder initialValue() { @@ -40,36 +64,63 @@ public class OMDBTileDataSource implements ITileDataSource { @RequiresApi(api = Build.VERSION_CODES.N) @Override public void query(MapTile tile, ITileDataSink mapDataSink) { + if(MapParamUtils.getTaskConfig() == null) + return; // 获取tile对应的坐标范围 if (tile.zoomLevel >= Constant.OMDB_MIN_ZOOM && tile.zoomLevel <= Constant.DATA_ZOOM) { + Realm realm = null; + int threadCode = Thread.currentThread().hashCode(); + synchronized (realmObjectList) { + int configCode = MapParamUtils.getTaskConfig().hashCode(); + for (RealmObject object : realmObjectList) { + if (object.threadCode == threadCode) { + if (object.realmConfigCode == configCode) { + realm = object.realm; + } else { + object.realm.close(); + realmObjectList.remove(object); + } + break; + } + } + if (realm == null) { + realm = Realm.getInstance(MapParamUtils.getTaskConfig()); + RealmObject o = new RealmObject(); + o.threadCode = threadCode; + o.realmConfigCode = configCode; + o.realm = realm; + realmObjectList.add(o); + } + } + +// Realm realm = Realm.getInstance(MapParamUtils.getTaskConfig()); + RealmQuery realmQuery = realm.where(RenderEntity.class); int m = Constant.DATA_ZOOM - tile.zoomLevel; int xStart = tile.tileX; int xEnd = tile.tileX + 1; int yStart = tile.tileY; int yEnd = tile.tileY + 1; - if (m>0) { + if (m > 0) { xStart = (int) (xStart << m); xEnd = (int) (xEnd << m); yStart = (int) (yStart << m); yEnd = (int) (yEnd << m); } - final int currentTileX = xStart; - if(isUpdate){ - Realm.getInstance(MapParamUtils.getTaskConfig()).refresh(); + if (isUpdate) { + realm.refresh(); isUpdate = false; } - String sql =" tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + ""; - - if(MapParamUtils.getDataLayerEnum()!=null){ + String sql = " ((tileXMin <= " + xStart + " and tileXMax >= " + xStart + ") or (tileXMin <=" + xEnd + " and tileXMax >=" + xStart + ")) and ((tileYMin <= " + yStart + " and tileYMax >= " + yStart + ") or (tileYMin <=" + yEnd + " and tileYMin >=" + yStart + "))"; + if (MapParamUtils.getDataLayerEnum() != null) { sql += " and enable" + MapParamUtils.getDataLayerEnum().getSql(); - }else{ + } else { sql += " and enable>=0"; } + realmQuery.rawPredicate(sql); - RealmQuery realmQuery = Realm.getInstance(MapParamUtils.getTaskConfig()).where(RenderEntity.class).rawPredicate(sql); - // 筛选不显示的数据 +// 筛选不显示的数据 if (Constant.HAD_LAYER_INVISIABLE_ARRAY != null && Constant.HAD_LAYER_INVISIABLE_ARRAY.length > 0) { realmQuery.beginGroup(); for (String type : Constant.HAD_LAYER_INVISIABLE_ARRAY) { @@ -77,13 +128,17 @@ public class OMDBTileDataSource implements ITileDataSource { } realmQuery.endGroup(); } - List listResult = realmQuery/*.distinct("id")*/.findAll(); + long time = System.currentTimeMillis(); + List listResult = realmQuery.findAll(); + long newTime = System.currentTimeMillis() - time; + + Log.e("jingo", "当前OMDBTileDataSource " + Thread.currentThread().hashCode() + " 当前realm " + realm.hashCode() + " 查询耗时" + newTime + " 条数" + listResult.size()); // 数据记录的tile号是以正外接tile号列表,此处过滤并未与当前tile相交的数据 if (!listResult.isEmpty()) { Polygon tilePolygon = GeometryTools.getTilePolygon(tile); -// System.out.println("第一条数据的最小x值:" + listResult.get(0).getTileX().stream().min(Integer::compare).get()); -// System.out.println("当前tile的:" + listResult.get(0).getTileX().stream().min(Integer::compare).get()); - listResult = listResult.stream().filter((RenderEntity renderEntity) -> renderEntity.getWkt().intersects(tilePolygon)) + listResult = listResult.stream().filter((RenderEntity renderEntity) -> + renderEntity.getWkt().intersects(tilePolygon) + ) /*过滤数据,只有最小x(屏幕的最小x或数据的最小x会被渲染,跨Tile的其他数据不再重复渲染)*/ // .filter((RenderEntity renderEntity) -> MercatorProjection.longitudeToTileX(viewport.fromScreenPoint(0,0).getLongitude(), (byte) Constant.DATA_ZOOM) == currentTileX || renderEntity.getTileX().stream().min(Integer::compare).get() == currentTileX) .collect(Collectors.toList()); @@ -92,7 +147,7 @@ public class OMDBTileDataSource implements ITileDataSource { } else { mapDataSink.completed(QueryResult.SUCCESS); } - Realm.getInstance(MapParamUtils.getTaskConfig()).close(); +// realm.close(); } else { mapDataSink.completed(QueryResult.SUCCESS); } @@ -105,13 +160,12 @@ public class OMDBTileDataSource implements ITileDataSource { @Override public void cancel() { - if (Realm.getDefaultInstance().isInTransaction()) { - Realm.getDefaultInstance().cancelTransaction(); - } +// if (Realm.getDefaultInstance().isInTransaction()) { +// Realm.getDefaultInstance().cancelTransaction(); +// } } - public void update(){ + public void update() { isUpdate = true; - Log.e("qj",Thread.currentThread().getName()); } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileSource.java index ab35f515..86f66737 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileSource.java @@ -27,7 +27,7 @@ public class OMDBTileSource extends RealmDBTileSource { @Override public OpenResult open() { - Log.d("qj", Realm.getDefaultInstance().where(RenderEntity.class).findAll().size()+"open安装数量"); +// Log.d("qj", Realm.getDefaultInstance().where(RenderEntity.class).findAll().size()+"open安装数量"); return OpenResult.SUCCESS; } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/RealmDBTileDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/RealmDBTileDataSource.java index 279a799f..771153d0 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/RealmDBTileDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/RealmDBTileDataSource.java @@ -35,27 +35,29 @@ public class RealmDBTileDataSource implements ITileDataSource { public void query(MapTile tile, ITileDataSink mapDataSink) { // 获取tile对应的坐标范围 if (tile.zoomLevel>=15&&tile.zoomLevel<=Constant.OVER_ZOOM) { - int m = Constant.OVER_ZOOM-tile.zoomLevel; - int xStart = (int)tile.tileX< realmQuery = Realm.getDefaultInstance().where(GeometryFeatureEntity.class) - .rawPredicate("tileX>="+xStart+" and tileX<="+xEnd+" and tileY>="+yStart+" and tileY<="+yEnd); - // 筛选不显示的数据 - if (Constant.HAD_LAYER_INVISIABLE_ARRAY!=null&&Constant.HAD_LAYER_INVISIABLE_ARRAY.length>0) { - realmQuery.beginGroup(); - for (String type: Constant.HAD_LAYER_INVISIABLE_ARRAY) { - realmQuery.notEqualTo("name", type); - } - realmQuery.endGroup(); - } - List listResult = realmQuery.distinct("id").findAll(); - mThreadLocalDecoders.get().decode(tile, mapDataSink, listResult); - mapDataSink.completed(QueryResult.SUCCESS); - Realm.getDefaultInstance().close(); + Log.e("jingo","RealmDBTileDataSource RealmDBTileDataSource RealmDBTileDataSource"); +// int m = Constant.OVER_ZOOM-tile.zoomLevel; +// int xStart = (int)tile.tileX< realmQuery = Realm.getDefaultInstance().where(GeometryFeatureEntity.class) +// .rawPredicate("tileX>="+xStart+" and tileX<="+xEnd+" and tileY>="+yStart+" and tileY<="+yEnd); +// // 筛选不显示的数据 +// if (Constant.HAD_LAYER_INVISIABLE_ARRAY!=null&&Constant.HAD_LAYER_INVISIABLE_ARRAY.length>0) { +// realmQuery.beginGroup(); +// for (String type: Constant.HAD_LAYER_INVISIABLE_ARRAY) { +// realmQuery.notEqualTo("name", type); +// } +// realmQuery.endGroup(); +// } +// List listResult = realmQuery.distinct("id").findAll(); +// mThreadLocalDecoders.get().decode(tile, mapDataSink, listResult); +// mapDataSink.completed(QueryResult.SUCCESS); +// Realm.getDefaultInstance().close(); // Log.d("RealmDBTileDataSource", "tile:"+tile.getBoundingBox().toString()); + mapDataSink.completed(QueryResult.SUCCESS); } else { mapDataSink.completed(QueryResult.SUCCESS); } @@ -68,8 +70,8 @@ public class RealmDBTileDataSource implements ITileDataSource { @Override public void cancel() { - if (Realm.getInstance(RealmUtils.getInstance().getRealmConfiguration()).isInTransaction()) { - Realm.getInstance(RealmUtils.getInstance().getRealmConfiguration()).cancelTransaction(); - } +// if (Realm.getInstance(RealmUtils.getInstance().getRealmConfiguration()).isInTransaction()) { +// Realm.getInstance(RealmUtils.getInstance().getRealmConfiguration()).cancelTransaction(); +// } } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/DeflaterUtil.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/DeflaterUtil.java new file mode 100644 index 00000000..eebbc008 --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/DeflaterUtil.java @@ -0,0 +1,202 @@ +package com.navinfo.collect.library.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; +import org.apache.commons.net.util.Base64; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +/** + * DeflaterUtils 压缩字符串 + */ + +public class DeflaterUtil{ + + private DeflaterUtil() { + + } + + private static final int BUFFER_SIZE = 8192; + + /** + * 压缩 + */ + + public static String zipString(String unzipString) { + + /* + + * https://www.yiibai.com/javazip/javazip_deflater.html#article-start + + * 0 ~ 9 压缩等级 低到高 + + * public static final int BEST_COMPRESSION = 9; 最佳压缩的压缩级别。 + + * public static final int BEST_SPEED = 1; 压缩级别最快的压缩。 + + * public static final int DEFAULT_COMPRESSION = -1; 默认压缩级别。 + + * public static final int DEFAULT_STRATEGY = 0; 默认压缩策略。 + + * public static final int DEFLATED = 8; 压缩算法的压缩方法(目前唯一支持的压缩方法)。 + + * public static final int FILTERED = 1; 压缩策略最适用于大部分数值较小且数据分布随机分布的数据。 + + * public static final int FULL_FLUSH = 3; 压缩刷新模式,用于清除所有待处理的输出并重置拆卸器。 + + * public static final int HUFFMAN_ONLY = 2; 仅用于霍夫曼编码的压缩策略。 + + * public static final int NO_COMPRESSION = 0; 不压缩的压缩级别。 + + * public static final int NO_FLUSH = 0; 用于实现最佳压缩结果的压缩刷新模式。 + + * public static final int SYNC_FLUSH = 2; 用于清除所有未决输出的压缩刷新模式; 可能会降低某些压缩算法的压缩率。 + + */ + + //使用指定的压缩级别创建一个新的压缩器。 + + Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION); + + //设置压缩输入数据。 + + deflater.setInput(unzipString.getBytes(StandardCharsets.UTF_8)); + + //当被调用时,表示压缩应该以输入缓冲区的当前内容结束。 + + deflater.finish(); + + final byte[] bytes = new byte[256]; + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(256); + + while (!deflater.finished()) { + + //压缩输入数据并用压缩数据填充指定的缓冲区。 + + int length = deflater.deflate(bytes); + + outputStream.write(bytes, 0, length); + + } + + deflater.end(); + + return Base64.encodeBase64String(outputStream.toByteArray()); + + + } + + /** + * 解压缩 + */ + + public static String unzipString(String zipString) { + + byte[] decode = Base64.decodeBase64(zipString); + + //创建一个新的解压缩器 https://www.yiibai.com/javazip/javazip_inflater.html + + Inflater inflater = new Inflater(); + + //设置解压缩的输入数据。 + + inflater.setInput(decode); + + final byte[] bytes = new byte[256]; + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(256); + + try { + + //finished() 如果已到达压缩数据流的末尾,则返回true。 + + while (!inflater.finished()) { + + //将字节解压缩到指定的缓冲区中。 + + int length = inflater.inflate(bytes); + + outputStream.write(bytes, 0, length); + + } + + } catch (DataFormatException e) { + + e.printStackTrace(); + + return null; + + } finally { + + //关闭解压缩器并丢弃任何未处理的输入。 + + inflater.end(); + + } + + try { + + return outputStream.toString("UTF-8"); + + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + + return null; + + } + + } + + + public static byte[] compress(byte[] bytes) { + if (bytes == null) { + throw new NullPointerException("bytes is null"); + } + int lenght = 0; + Deflater deflater = new Deflater(); + deflater.setInput(bytes); + deflater.finish(); + byte[] outputBytes = new byte[BUFFER_SIZE]; + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + while (!deflater.finished()) { + lenght = deflater.deflate(outputBytes); + bos.write(outputBytes, 0, lenght); + } + deflater.end(); + return bos.toByteArray(); + } catch (IOException e) { + throw new RuntimeException("Deflater compress error", e); + } + } + + public static byte[] decompress(byte[] bytes) { + if (bytes == null) { + throw new NullPointerException("bytes is null"); + } + int length = 0; + Inflater inflater = new Inflater(); + inflater.setInput(bytes); + byte[] outputBytes = new byte[BUFFER_SIZE]; + try (ByteArrayOutputStream bos = new ByteArrayOutputStream();) { + while (!inflater.finished()) { + length = inflater.inflate(outputBytes); + if (length == 0) { + break; + } + bos.write(outputBytes, 0, length); + } + inflater.end(); + return bos.toByteArray(); + } catch (Exception e) { + throw new RuntimeException("Deflater decompress error", e); + } + } + +} diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryToolsKt.kt b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryToolsKt.kt index b626079c..f108e2c4 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryToolsKt.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryToolsKt.kt @@ -49,7 +49,6 @@ class GeometryToolsKt { } } } - println("YGeometry-time:" + (System.currentTimeMillis() - startTime)) } /** @@ -93,7 +92,6 @@ class GeometryToolsKt { } } } - println("XGeometry-time:" + (System.currentTimeMillis() - startTime)) } fun getMasterPoint(wkt: String): String { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/StrZipUtil.kt b/collect-library/src/main/java/com/navinfo/collect/library/utils/StrZipUtil.kt new file mode 100644 index 00000000..67c0fcfe --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/StrZipUtil.kt @@ -0,0 +1,282 @@ +package com.navinfo.collect.library.utils + +import sun.misc.BASE64Decoder +import sun.misc.BASE64Encoder +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.util.* +import java.util.zip.* + +object StrZipUtil { + + /** + * @param input 需要压缩的字符串 + * @return 压缩后的字符串 + * @throws IOException IO + */ + fun compress(input: String): String { + if (input.isEmpty()) { + return input + } + try { + val out = ByteArrayOutputStream() + val gzipOs = GZIPOutputStream(out) + gzipOs.write(input.toByteArray()) + gzipOs.close() + return BASE64Encoder().encode(out.toByteArray()) + } catch (e: Exception) { + return input + } + + } + + /** + * @param zippedStr 压缩后的字符串 + * @return 解压缩后的 + * @throws IOException IO + */ + fun uncompress(zippedStr: String): String { + if (zippedStr.isEmpty()) { + return zippedStr + } + try { + val out = ByteArrayOutputStream() + val `in` = ByteArrayInputStream( + BASE64Decoder().decodeBuffer(zippedStr) + ) + val gzipIs = GZIPInputStream(`in`) + val buffer = ByteArray(256) + var n: Int + while (gzipIs.read(buffer).also { n = it } >= 0) { + out.write(buffer, 0, n) + } + // toString()使用平台默认编码,也可以显式的指定如toString("GBK") + return out.toString() + } catch (e: Exception) { + return zippedStr + } + + } + + /*** + * 压缩GZip + * + * @param data + * @return + */ + fun gZip(data: ByteArray?): ByteArray? { + var b: ByteArray? = null + try { + val bos = ByteArrayOutputStream() + val gzip = GZIPOutputStream(bos) + gzip.write(data) + gzip.finish() + gzip.close() + b = bos.toByteArray() + bos.close() + } catch (ex: java.lang.Exception) { + ex.printStackTrace() + } + return b + } + + /*** + * 解压GZip + * + * @param data + * @return + */ + fun unGZip(data: ByteArray?): ByteArray? { + var b: ByteArray? = null + try { + val bis = ByteArrayInputStream(data) + val gzip = GZIPInputStream(bis) + val buf = ByteArray(1024) + var num = -1 + val baos = ByteArrayOutputStream() + while (gzip.read(buf, 0, buf.size).also { num = it } != -1) { + baos.write(buf, 0, num) + } + b = baos.toByteArray() + baos.flush() + baos.close() + gzip.close() + bis.close() + } catch (ex: java.lang.Exception) { + ex.printStackTrace() + } + return b + } + + + /*** + * 压缩Zip + * + * @param data + * @return + */ + fun zip(data: ByteArray): ByteArray? { + var b: ByteArray? = null + try { + val bos = ByteArrayOutputStream() + val zip = ZipOutputStream(bos) + val entry = ZipEntry("zip") + entry.size = data.size.toLong() + zip.putNextEntry(entry) + zip.write(data) + zip.closeEntry() + zip.close() + b = bos.toByteArray() + bos.close() + } catch (ex: java.lang.Exception) { + ex.printStackTrace() + } + return b + } + + /*** + * 解压Zip + * + * @param data + * @return + */ + fun unZip(data: ByteArray?): ByteArray? { + var b: ByteArray? = null + try { + val bis = ByteArrayInputStream(data) + val zip = ZipInputStream(bis) + while (zip.nextEntry != null) { + val buf = ByteArray(1024) + var num = -1 + val baos = ByteArrayOutputStream() + while (zip.read(buf, 0, buf.size).also { num = it } != -1) { + baos.write(buf, 0, num) + } + b = baos.toByteArray() + baos.flush() + baos.close() + } + zip.close() + bis.close() + } catch (ex: java.lang.Exception) { + ex.printStackTrace() + } + return b + } + +// /*** +// * 压缩BZip2 +// * +// * @param data +// * @return +// */ +// public static byte[] bZip2(byte[] data) { +// byte[] b = null; +// try { +// ByteArrayOutputStream bos = new ByteArrayOutputStream(); +// CBZip2OutputStream bzip2 = new CBZip2OutputStream(bos); +// bzip2.write(data); +// bzip2.flush(); +// bzip2.close(); +// b = bos.toByteArray(); +// bos.close(); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// return b; +// } + +// /*** +// * 解压BZip2 +// * +// * @param data +// * @return +// */ +// public static byte[] unBZip2(byte[] data) { +// byte[] b = null; +// try { +// ByteArrayInputStream bis = new ByteArrayInputStream(data); +// CBZip2InputStream bzip2 = new CBZip2InputStream(bis); +// byte[] buf = new byte[1024]; +// int num = -1; +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// while ((num = bzip2.read(buf, 0, buf.length)) != -1) { +// baos.write(buf, 0, num); +// } +// b = baos.toByteArray(); +// baos.flush(); +// baos.close(); +// bzip2.close(); +// bis.close(); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// return b; +// } + + // /*** + // * 压缩BZip2 + // * + // * @param data + // * @return + // */ + // public static byte[] bZip2(byte[] data) { + // byte[] b = null; + // try { + // ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // CBZip2OutputStream bzip2 = new CBZip2OutputStream(bos); + // bzip2.write(data); + // bzip2.flush(); + // bzip2.close(); + // b = bos.toByteArray(); + // bos.close(); + // } catch (Exception ex) { + // ex.printStackTrace(); + // } + // return b; + // } + // /*** + // * 解压BZip2 + // * + // * @param data + // * @return + // */ + // public static byte[] unBZip2(byte[] data) { + // byte[] b = null; + // try { + // ByteArrayInputStream bis = new ByteArrayInputStream(data); + // CBZip2InputStream bzip2 = new CBZip2InputStream(bis); + // byte[] buf = new byte[1024]; + // int num = -1; + // ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // while ((num = bzip2.read(buf, 0, buf.length)) != -1) { + // baos.write(buf, 0, num); + // } + // b = baos.toByteArray(); + // baos.flush(); + // baos.close(); + // bzip2.close(); + // bis.close(); + // } catch (Exception ex) { + // ex.printStackTrace(); + // } + // return b; + // } + /** + * 把字节数组转换成16进制字符串 + * + * @param bArray + * @return + */ + fun bytesToHexString(bArray: ByteArray): String? { + val sb = StringBuffer(bArray.size) + var sTemp: String + for (i in bArray.indices) { + sTemp = Integer.toHexString(0xFF and bArray[i].toInt()) + if (sTemp.length < 2) sb.append(0) + sb.append(sTemp.uppercase(Locale.getDefault())) + } + return sb.toString() + } +} \ No newline at end of file