From 6a77e69ed7c0bbcacea421a3d7054552b0b14d60 Mon Sep 17 00:00:00 2001 From: xiaoyan <xiaoyan159@163.com> Date: Fri, 2 Jun 2023 10:05:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=BD=A6=E9=81=93?= =?UTF-8?q?=E8=BE=B9=E7=BA=BF=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/omdb_config.json | 20 +- .../com/navinfo/omqs/db/ImportPreProcess.kt | 71 +++++- .../omqs/ui/activity/login/LoginViewModel.kt | 2 +- .../personalcenter/PersonalCenterFragment.kt | 2 +- .../src/main/assets/editormarker.xml | 231 ++++++------------ .../src/main/assets/omdb/icon_arrow_right.png | Bin 0 -> 1032 bytes .../src/main/assets/omdb/icon_close.png | Bin 0 -> 279 bytes .../src/main/assets/omdb/icon_right.png | Bin 0 -> 305 bytes .../library/data/entity/ReferenceEntity.kt | 64 +++++ .../map/handler/LayerManagerHandler.kt | 15 ++ .../map/source/OMDBReferenceDataSource.java | 71 ++++++ .../map/source/OMDBReferenceDecoder.java | 186 ++++++++++++++ .../map/source/OMDBReferenceTileSource.java | 25 ++ vtm | 1 + 14 files changed, 529 insertions(+), 159 deletions(-) create mode 100644 collect-library/src/main/assets/omdb/icon_arrow_right.png create mode 100644 collect-library/src/main/assets/omdb/icon_close.png create mode 100644 collect-library/src/main/assets/omdb/icon_right.png create mode 100644 collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt create mode 100644 collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java create mode 100644 collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDecoder.java create mode 100644 collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceTileSource.java create mode 160000 vtm diff --git a/app/src/main/assets/omdb_config.json b/app/src/main/assets/omdb_config.json index d7ac2a91..c09fe454 100644 --- a/app/src/main/assets/omdb_config.json +++ b/app/src/main/assets/omdb_config.json @@ -20,6 +20,19 @@ "code": 2010, "name": "道路方向" }, + "2013": { + "table": "OMDB_LANE_MARK_BOUNDARYTYPE", + "code": 2013, + "name": "车道边界类型", + "transformer": [ + { + "k": "geometry", + "v": "~", + "klib": "geometry", + "vlib": "unpackingLaneBoundary()" + } + ] + }, "2019": { "table": "OMDB_LINK_SPEEDLIMIT", "code": 2019, @@ -55,6 +68,11 @@ "code": 2041, "name": "车道数" }, + "2083":{ + "table": "OMDB_RDBOUND_BOUNDARYTYPE", + "code": 2083, + "name": "道路边界类型" + }, "2201":{ "table": "OMDB_BRIDGE", "code": 2201, @@ -131,7 +149,7 @@ "k": "geometry", "v": "~", "klib": "geometry", - "vlib": "translateRightWithAngle()" + "vlib": "generateRestrictionRerference()" } ] }, 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 51bebc84..99abeeb1 100644 --- a/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt +++ b/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt @@ -1,7 +1,11 @@ package com.navinfo.omqs.db +import com.navinfo.collect.library.data.entity.ReferenceEntity import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.collect.library.utils.GeometryTools +import io.realm.Realm +import org.json.JSONArray +import org.json.JSONObject import org.locationtech.jts.algorithm.Angle import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.geom.Geometry @@ -60,7 +64,9 @@ class ImportPreProcess { var radian = 0.0 // geometry的角度,如果是点,获取angle,如果是线,获取最后两个点的方向 var point = Coordinate(geometry?.coordinate) if (Geometry.TYPENAME_POINT == geometry?.geometryType) { - val angle = if(renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get("angle")?.toDouble()!! + // angle为正北方向夹角,需要将其转换为与正东方向夹角 + var angle = if(renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get("angle")?.toDouble()!! + angle-=90 radian = Math.toRadians(angle) } else if (Geometry.TYPENAME_LINESTRING == geometry?.geometryType) { val p1: Coordinate = geometry.coordinates.get(geometry.coordinates.size - 2) @@ -77,6 +83,7 @@ class ImportPreProcess { // 计算偏移后的点 // val coordMid = // Coordinate(point.getX() + dy, point.getY() - dx) + // 计算指定距离外与当前位置成90度夹角的点位 val pointStart = GeoPoint(point.getY() - dx, point.getX() + dy) // val pointStart = GeoPoint(pointMid.latitude-dy, pointMid.longitude-dx) val pointEnd = GeoPoint(pointStart.latitude- dx, pointStart.longitude+ dy) @@ -107,4 +114,66 @@ class ImportPreProcess { } return "0" } + + /** + * 解析车道边线数据二级属性 + * */ + fun unpackingLaneBoundary(renderEntity: RenderEntity) { + if (renderEntity.code == 2013&&!renderEntity.properties["shapeList"].isNullOrEmpty()&&renderEntity.properties["shapeList"]!="null") { + // 解析shapeList,将数组中的属性放会properties + val shapeList = JSONArray(renderEntity.properties["shapeList"]) + val shape = shapeList.getJSONObject(0) + for (key in shape.keys()) { + renderEntity.properties[key] = shape[key].toString() + } + } + } + + /** + * 自动生成普通交限的参考数据 + * */ + fun generateRestrictionRerference(renderEntity: RenderEntity) { + // 获取当前renderEntity的geometry + val geometry = renderEntity.wkt + var radian = 0.0 // geometry的角度,如果是点,获取angle,如果是线,获取最后两个点的方向 + var point = Coordinate(geometry?.coordinate) + if (Geometry.TYPENAME_POINT == geometry?.geometryType) { + var angle = if(renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get("angle")?.toDouble()!! + radian = Math.toRadians(angle) + } + + // 计算偏移距离 + val dx: Double = GeometryTools.convertDistanceToDegree(3.0, geometry?.coordinate?.y!!) * Math.sin(radian) + val dy: Double = GeometryTools.convertDistanceToDegree(3.0, geometry?.coordinate?.y!!) * Math.cos(radian) + + // 计算偏移后的点 + val pointTranS = + GeoPoint(point.getY() - dx, point.getX() + dy) // 向右偏移的点 + + // 计算与原有方向平行的终点坐标 + val pointTranE = GeoPoint(pointTranS.latitude + dy, pointTranS.longitude + dx) + + renderEntity.geometry = GeometryTools.createGeometry(pointTranS).toString() + + // 将这个点记录在数据中 + val startEndReference = ReferenceEntity() + startEndReference.renderEntityId = renderEntity.id + startEndReference.name = "普通交限参考线" + startEndReference.table = renderEntity.table + // 起终点坐标组成的线 + startEndReference.geometry = GeometryTools.createLineString(listOf(GeoPoint(point.y, point.x), pointTranS)).toString() + startEndReference.properties["qi_table"] = renderEntity.table + startEndReference.properties["type"] = "s_2_e" + Realm.getDefaultInstance().insert(startEndReference) + + val angleReference = ReferenceEntity() + angleReference.renderEntityId = renderEntity.id + angleReference.name = "普通交限参考方向" + angleReference.table = renderEntity.table + // 与原有方向指向平行的线 + angleReference.geometry = GeometryTools.createLineString(listOf(pointTranS, pointTranE)).toString() + angleReference.properties["qi_table"] = renderEntity.table + angleReference.properties["type"] = "angle" + Realm.getDefaultInstance().insert(angleReference) + } } \ No newline at end of file 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 cd36992d..6177e508 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 @@ -228,7 +228,7 @@ class LoginViewModel @Inject constructor( .name("OMQS.realm") .encryptionKey(password) // .modules(Realm.getDefaultModule(), MyRealmModule()) - .schemaVersion(1) + .schemaVersion(2) .build() Realm.setDefaultConfiguration(config) // 拷贝配置文件到用户目录下 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 1e5e5a81..6930ef2c 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 @@ -111,7 +111,7 @@ class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks { viewModel.readRealmData() // 定位到指定位置 niMapController.mMapView.vtmMap.animator() - .animateTo(GeoPoint(28.724637921467508 ,115.83412668023867 )) + .animateTo(GeoPoint(40.03342017243118, 116.3211538409127 )) } R.id.personal_center_menu_task_list -> { findNavController().navigate(R.id.TaskManagerFragment) diff --git a/collect-library/src/main/assets/editormarker.xml b/collect-library/src/main/assets/editormarker.xml index 7815f74b..430e94cd 100644 --- a/collect-library/src/main/assets/editormarker.xml +++ b/collect-library/src/main/assets/editormarker.xml @@ -173,6 +173,9 @@ <!-- oneway --> <style-symbol id="oneway" repeat="true" src="assets:symbols/oneway.svg" /> + <!-- omdb --> + <style-line id="boundaryType" width="0.1" stipple-width="0.1" /> + <!--###### ASSIGNMENT ######--> <m e="way" k="natural" v="issea|sea"> @@ -1651,81 +1654,6 @@ <caption k="maxSpeed" fill="#000000" priority="0" size="16" stroke="#ffffff" stroke-width="1.0"></caption> <symbol src="assets:omdb/icon_4002_0.png" symbol-width="46" symbol-height="46"></symbol> -<!-- <circle fill="#ffffff" radius="28" scale-radius="true" stroke="#ff0000" stroke-width="6"/>--> -<!-- <m k="maxSpeed">--> -<!-- <m v="5">--> -<!-- <symbol src="assets:omdb/1101/1101_5_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="10">--> -<!-- <symbol src="assets:omdb/1101/1101_10_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="15">--> -<!-- <symbol src="assets:omdb/1101/1101_15_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="20">--> -<!-- <symbol src="assets:omdb/1101/1101_20_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="25">--> -<!-- <symbol src="assets:omdb/1101/1101_25_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="30">--> -<!-- <symbol src="assets:omdb/1101/1101_30_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="35">--> -<!-- <symbol src="assets:omdb/1101/1101_35_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="40">--> -<!-- <symbol src="assets:omdb/1101/1101_40_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="45">--> -<!-- <symbol src="assets:omdb/1101/1101_45_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="50">--> -<!-- <symbol src="assets:omdb/1101/1101_50_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="55">--> -<!-- <symbol src="assets:omdb/1101/1101_55_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="60">--> -<!-- <symbol src="assets:omdb/1101/1101_60_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="65">--> -<!-- <symbol src="assets:omdb/1101/1101_65_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="70">--> -<!-- <symbol src="assets:omdb/1101/1101_70_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="75">--> -<!-- <symbol src="assets:omdb/1101/1101_75_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="80">--> -<!-- <symbol src="assets:omdb/1101/1101_80_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="85">--> -<!-- <symbol src="assets:omdb/1101/1101_85_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="90">--> -<!-- <symbol src="assets:omdb/1101/1101_90_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="95">--> -<!-- <symbol src="assets:omdb/1101/1101_95_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="100">--> -<!-- <symbol src="assets:omdb/1101/1101_100_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="105">--> -<!-- <symbol src="assets:omdb/1101/1101_105_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="110">--> -<!-- <symbol src="assets:omdb/1101/1101_110_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="115">--> -<!-- <symbol src="assets:omdb/1101/1101_115_0.png"></symbol>--> -<!-- </m>--> -<!-- <m v="120">--> -<!-- <symbol src="assets:omdb/1101/1101_120_0.png"></symbol>--> -<!-- </m>--> -<!-- </m>--> <caption k="minSpeed" dy="-28" fill="#000000" priority="0" size="14" stroke="#ffffff" stroke-width="1.0"></caption> </m> @@ -1733,81 +1661,6 @@ <caption k="maxSpeed" fill="#000000" priority="0" size="14" stroke="#ffffff" stroke-width="1.0"></caption> <symbol src="assets:omdb/icon_4002_1.png" symbol-width="46" symbol-height="46"></symbol> -<!-- <circle fill="#ffffff" radius="28" scale-radius="true" stroke="#00ff00" stroke-width="6"/>--> -<!-- <m k="maxSpeed">--> -<!-- <m v="5">--> -<!-- <symbol src="assets:omdb/1101/1101_5_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="10">--> -<!-- <symbol src="assets:omdb/1101/1101_10_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="15">--> -<!-- <symbol src="assets:omdb/1101/1101_15_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="20">--> -<!-- <symbol src="assets:omdb/1101/1101_20_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="25">--> -<!-- <symbol src="assets:omdb/1101/1101_25_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="30">--> -<!-- <symbol src="assets:omdb/1101/1101_30_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="35">--> -<!-- <symbol src="assets:omdb/1101/1101_35_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="40">--> -<!-- <symbol src="assets:omdb/1101/1101_40_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="45">--> -<!-- <symbol src="assets:omdb/1101/1101_45_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="50">--> -<!-- <symbol src="assets:omdb/1101/1101_50_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="55">--> -<!-- <symbol src="assets:omdb/1101/1101_55_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="60">--> -<!-- <symbol src="assets:omdb/1101/1101_60_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="65">--> -<!-- <symbol src="assets:omdb/1101/1101_65_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="70">--> -<!-- <symbol src="assets:omdb/1101/1101_70_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="75">--> -<!-- <symbol src="assets:omdb/1101/1101_75_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="80">--> -<!-- <symbol src="assets:omdb/1101/1101_80_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="85">--> -<!-- <symbol src="assets:omdb/1101/1101_85_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="90">--> -<!-- <symbol src="assets:omdb/1101/1101_90_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="95">--> -<!-- <symbol src="assets:omdb/1101/1101_95_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="100">--> -<!-- <symbol src="assets:omdb/1101/1101_100_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="105">--> -<!-- <symbol src="assets:omdb/1101/1101_105_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="110">--> -<!-- <symbol src="assets:omdb/1101/1101_110_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="115">--> -<!-- <symbol src="assets:omdb/1101/1101_115_1.png"></symbol>--> -<!-- </m>--> -<!-- <m v="120">--> -<!-- <symbol src="assets:omdb/1101/1101_120_1.png"></symbol>--> -<!-- </m>--> -<!-- </m>--> <caption k="minSpeed" dy="-28" fill="#000000" priority="0" size="14" stroke="#ffffff" stroke-width="1.0"></caption> </m> @@ -1855,6 +1708,70 @@ <m v="OMDB_LANE_LINK_LG"> <line stroke="#ecf0f1" width="0.1" dasharray="35,35"/> </m> + <!-- 道路边界类型 --> + <m v="OMDB_RDBOUND_BOUNDARYTYPE"> + <line stroke="#ffffff" width="0.1"/> + </m> + <!-- 车道边界类型 --> + <m v="OMDB_LANE_MARK_BOUNDARYTYPE"> + <outline-layer id="boundary" stroke="#ffffff" width="0.2" /> + <m k="boundaryType"> + <!--标线--> + <m v="2"> + <m k="markType"> + <!--其他|实线--> + <m v="0|1"> + <m k="markColor"> + <m v="0|1"> + <line stroke="#ffffff" use="boundaryType"/> + </m> + <m v="2"> + <line stroke="#eccc68" use="boundaryType"/> + </m> + <m v="6"> + <line stroke="#0000ff" use="boundaryType"/> + </m> + <m v="7"> + <line stroke="#00ff00" use="boundaryType"/> + </m> + <m v="9"> + <line stroke="#8e44ad" use="boundaryType"/> + </m> + </m> + </m> + <!--虚线--> + <m v="2"> + <m k="markColor"> + <m v="0|1"> + <line stroke="#ffffff" use="boundaryType" dasharray="3,3"/> + </m> + <m v="2"> + <line stroke="#eccc68" use="boundaryType" dasharray="3,3"/> + </m> + <m v="6"> + <line stroke="#0000ff" use="boundaryType" dasharray="3,3"/> + </m> + <m v="7"> + <line stroke="#00ff00" use="boundaryType" dasharray="3,3"/> + </m> + <m v="9"> + <line stroke="#8e44ad" use="boundaryType" dasharray="3,3"/> + </m> + </m> + </m> + <!--导流区边线--> + <m v="4"> + <line outline="boundary" stroke="#545D6C"></line> + <lineSymbol src="assets:omdb/icon_right.png" repeat-start="0" repeat-gap="0.5"/> + </m> +<!-- <!–铺设路面边缘–>--> +<!-- <m v="5">--> +<!-- <line outline="#ffffff" fix="true" src="assets:omdb/icon_close.png" stroke="#ffffffff" use="boundaryType"/>--> +<!-- </m>--> + </m> + </m> + </m> + </m> <!--道路方向--> <m v="OMDB_LINK_DIRECT"> <m k="direct"> @@ -1874,11 +1791,15 @@ </m> <!--普通交限--> <m v="OMDB_RESTRICTION"> - <symbol src="assets:omdb/icon_4006_0.png" repeat="false" symbol-width="35" symbol-height="35" rotate="true" repeat-start="0" ></symbol> -<!-- <line stroke="#14582c" width="0.1"/>--> -<!-- <caption k="angle" fill="#000000" priority="0" size="14" stroke="#ffffff"--> -<!-- stroke-width="1.0"></caption>--> - + <m k="angle"> + <symbol src="assets:omdb/icon_4006_0.png" repeat="false" symbol-width="35" symbol-height="35" rotate="false" repeat-start="0" ></symbol> + </m> + <m k="type" v="angle"> + <symbol src="assets:omdb/icon_arrow_right.png" repeat-start="0" repeat-gap="2000" symbol-percent="45" repeat="false" rotate="true"></symbol> + </m> + <m k="type" v="s_2_e"> + <line stroke="#14582c" width="0.1" dasharray="1,1" repeat-gap="3" repeat-start="0"/> + </m> </m> </m> </rendertheme> \ No newline at end of file diff --git a/collect-library/src/main/assets/omdb/icon_arrow_right.png b/collect-library/src/main/assets/omdb/icon_arrow_right.png new file mode 100644 index 0000000000000000000000000000000000000000..b0246785a209f0298a7435042062a26414f0ca3a GIT binary patch literal 1032 zcmV+j1o!)iP)<h;3K|Lk000e1NJLTq002e+002e^1^@s6aW3M700001b5ch_0Itp) z=>Px&!bwCyRCr$P*iB3nXB@}z-}CJIu4}p?i`q1Z<;4WFr&3Bx6c4>LCPoiEaA@KI zjfa8?c+p5qdMMOZ5=}~)G$tB7*d`{v#9pk4FQIBLCeTn;ieOk51Xgg_-PxJvX=Y&s z4cpAqV4BJP_r&3uVfM4%=RZ5kK(A#57`ZGjKrngAAQ*yC8yZv$6+^|S2~aU=UNmE< z7%E0hfQnJ`q8UTQP%&x(RE(Mz%@`_%icu4wV${57#!xX-jG6!ylNB&WhqNMBNHb<V z00#gLU<`o%Z$O0t6WF;L)wMo%*+^PMFUIxg0!|_yPC>vND)DaG9$=B6lQAYG1~qZ& z>uCC?5e+8L^l~@_0dqd=Zv3de=)!yN`;boP`18&Lk`fP2#*$5a2}}Z6AY&<z-C#B? z%n2*=Gq)!5OT*fI4RuAwbz^?+3L)_L*BG>vfghgF)nA*<!kBYM%N=AV81LCqZ<~wB z5CgY--MS%+ty@E%RMxECCJg~sRULRRghcNRJbfI;)bJc4hCJ5%G<6BU6o7c{_NAi# zzpcGo?my@><QWIc-f}I!qyUP`0;s5610F8Js=e)Cz92FKy?AxK2l25P^xv5f8fW*v z7)tI2-~td+`X`pJ<{d1&QXcqj%l5U0LhF2x($ZIv*H>XK7ls6Lx)IpZ2ImKxvwx?0 zuONB*0%l(5h&-G`GHJZ(8P9xnb5@Vo2Ig6F`S%_#Z&5UP^CL13W(>X^jqud&Lh85k zNd0~l+~q)GTEl4HOT<R!riX<5(l#*9TPwObXJ4&Uj67Hbk%*fq&7YD1LYElpe~Hn7 z*?abZIb6}roht{E57_1Ai2N}XwGYe+7n2Xhyx*l$V$41;M=DNp2Wwubt(5OP0XIiN zGfvwEX5wg7mz1*gUBToYyCv{r*#Fl7+rY%yD^GFYu-c8<8l%g>pcztQQtl6T4W6^r z7d-P~$J;As{4O4}_I4LnWrRd#;c?*YV;KXa#DJ9I^OCN}6FWW<sCv9!KipJ$WL3!X ztyq$qxm8RQA#u0ZzoCJ3+<xQt8QW~7|Eyv@9kzVf<ncIqa?vczlQh6iggXbmS?=5g z0TXSnYVdO0GPl&?R?$B$?i_lQ54<2?vh%5}>Sr)n!ypsm{=rYHI~IRpDA;0hZ~X6$ zjoz}3;gpqaSun*|!C1P6VDg9&48f>vCMt%Cp<>hos2DXbnlV%i6{99V#i)7FjG<zv z7&QSZM$L<63>8Dgs0mOpYF;#Bs2D0nO@N9~^ZExES0W1-p<h`50000<MNUMnLSTY@ C4cSNl literal 0 HcmV?d00001 diff --git a/collect-library/src/main/assets/omdb/icon_close.png b/collect-library/src/main/assets/omdb/icon_close.png new file mode 100644 index 0000000000000000000000000000000000000000..33cb188465c6e33ae0bde2c1dbd01ba1d340ed7b GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}7d>4ZLn7SY zPWjJy$bqLd-n>v`cc-6{Uy}LCyhj?J4zfCFd|Nb4>B&FMJ5%@Q>)W%vt!bP4HI(70 zgJl5UpSjHHp5mU1m!#iV)c)<*->v0`(`09;%Ff==?(pZ@JvGngYZ(NXn)GKf9W*R_ zC$K-C)!`0D<BFY=gw!Lpu}quM{y=Z;PS#&+2Xf3CmL7{)dqkaK-@_cC8vi3NE4U}J zc09TwbMVHDy8@96IqBj@X8oR*z?5TE7soVBfWiB2UiS;d&e#j3oA^pt&;AL4xM&Kq Z{z5e!#TEOV7=fN+@O1TaS?83{1OVlrZl(YL literal 0 HcmV?d00001 diff --git a/collect-library/src/main/assets/omdb/icon_right.png b/collect-library/src/main/assets/omdb/icon_right.png new file mode 100644 index 0000000000000000000000000000000000000000..949982b5ace64c834908a5dfff9ca09eff231e7f GIT binary patch literal 305 zcmV-10nYx3P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#>q$gGR9HvtmC+5tFc3rSP3R_c6PScD32XwJP$n^Q)k+aR=q?fcN&YG|@~iLc z5<4I6td9=R9q0~(9guW#bV=S@L^uQR0&oB@keq8FG5{8Tw1Nl&_=_cN5PlqMoJawz z5Jv#Fbp&aMG{6dR0kAA()`=>B0%8L21aOXyqZ;4~Vj_8sB%>98_rb|{k{tgEAZZhy zNe&V5rO=`m%J<hex|m!@sU)NU3h^xgUc&H60Te~#Lh_fV#M2{?<c0I>tHe_PlH7hS zA7{S$j~E_-B)8wYg?P$=@Rt3!5O$ygbO*WvtsVFP(>_rle{GHp00000NkvXXu0mjf D>F#z* literal 0 HcmV?d00001 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 new file mode 100644 index 00000000..5697cd25 --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt @@ -0,0 +1,64 @@ +package com.navinfo.collect.library.data.entity + +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.PrimaryKey +import org.locationtech.jts.geom.Coordinate +import org.locationtech.jts.geom.Geometry +import org.oscim.core.MercatorProjection +import java.util.* + +/** + * 渲染要素对应的实体 + * */ +open class ReferenceEntity() : RealmObject() { + @PrimaryKey + var id: String = UUID.randomUUID().toString() // id + var renderEntityId: String = "" // 参考的renderEntity的Id + lateinit var name: String //要素名 + lateinit var table: String //要素表名 + var code: Int = 0 // 要素编码 + var geometry: String = "" // 要素渲染参考的geometry,该数据可能会在导入预处理环节被修改,原始geometry会保存在properties的geometry字段下 + get() { + wkt = GeometryTools.createGeometry(field) + return field + } + set(value) { + field = value + // 根据geometry自动计算当前要素的x-tile和y-tile + GeometryToolsKt.getTileXByGeometry(value, tileX) + GeometryToolsKt.getTileYByGeometry(value, tileY) + // 根据传入的geometry文本,自动转换为Geometry对象 + try { + wkt = GeometryTools.createGeometry(value) + } catch (e: Exception) { + + } + } + + @Ignore + var wkt: Geometry? = null + get() { + if (field == null || field!!.isEmpty) { + try { + field = GeometryTools.createGeometry(geometry) + } catch (e: Exception) { + + } + } + return field + } + var properties: RealmDictionary<String> = RealmDictionary() + var tileX: RealmSet<Int> = RealmSet() // x方向的tile编码 + var tileY: RealmSet<Int> = RealmSet() // y方向的tile编码 + + 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/map/handler/LayerManagerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt index ba22bce1..75aafa44 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt @@ -4,6 +4,7 @@ import androidx.appcompat.app.AppCompatActivity import com.navinfo.collect.library.map.NIMapView import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource +import com.navinfo.collect.library.map.source.OMDBReferenceTileSource import com.navinfo.collect.library.map.source.OMDBTileSource import com.navinfo.collect.library.system.Constant import okhttp3.Cache @@ -45,9 +46,12 @@ class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tracePa * 显示待测评OMDB数据的图层 * */ private lateinit var omdbVectorTileLayer: VectorTileLayer + private lateinit var omdbReferenceTileLayer: VectorTileLayer private lateinit var omdbLabelLayer: LabelLayer + private lateinit var omdbReferenceLabelLayer: LabelLayer private val omdbTileSource by lazy { OMDBTileSource() } + private val omdbReferenceTileSource by lazy { OMDBReferenceTileSource() } init { initMap() @@ -99,6 +103,7 @@ class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tracePa } private fun initOMDBVectorTileLayer() { + // 初始化OMDB相关图层 omdbVectorTileLayer = VectorTileLayer(mMapView.vtmMap, omdbTileSource) omdbLabelLayer = LabelLayer(mMapView.vtmMap, omdbVectorTileLayer, LabelTileLoaderHook(), Constant.OMDB_MIN_ZOOM) if(omdbVectorTileLayer!=null){ @@ -107,6 +112,16 @@ class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tracePa if(omdbLabelLayer!=null){ addLayer(omdbLabelLayer, NIMapView.LAYER_GROUPS.VECTOR_TILE) } + + // 初始化OMDB参考相关图层 + omdbReferenceTileLayer = VectorTileLayer(mMapView.vtmMap, omdbReferenceTileSource) + omdbReferenceLabelLayer = LabelLayer(mMapView.vtmMap, omdbReferenceTileLayer, LabelTileLoaderHook(), Constant.OMDB_MIN_ZOOM) + if(omdbReferenceTileLayer!=null){ + addLayer(omdbReferenceTileLayer,NIMapView.LAYER_GROUPS.VECTOR_TILE) + } + if(omdbReferenceLabelLayer!=null){ + addLayer(omdbReferenceLabelLayer, NIMapView.LAYER_GROUPS.VECTOR_TILE) + } } /** 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 new file mode 100644 index 00000000..917f632e --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java @@ -0,0 +1,71 @@ +package com.navinfo.collect.library.map.source; + +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import com.navinfo.collect.library.data.entity.ReferenceEntity; +import com.navinfo.collect.library.system.Constant; + +import org.oscim.layers.tile.MapTile; +import org.oscim.tiling.ITileDataSink; +import org.oscim.tiling.ITileDataSource; +import org.oscim.tiling.QueryResult; + +import java.util.List; + +import io.realm.Realm; +import io.realm.RealmQuery; + +public class OMDBReferenceDataSource implements ITileDataSource { + private final ThreadLocal<OMDBReferenceDecoder> mThreadLocalDecoders = new ThreadLocal<OMDBReferenceDecoder>() { + @Override + protected OMDBReferenceDecoder initialValue() { + return new OMDBReferenceDecoder(); + } + }; + + @RequiresApi(api = Build.VERSION_CODES.N) + @Override + public void query(MapTile tile, ITileDataSink mapDataSink) { + // 获取tile对应的坐标范围 + if (tile.zoomLevel>=Constant.OMDB_MIN_ZOOM&&tile.zoomLevel<=Constant.OVER_ZOOM) { + int m = Constant.OVER_ZOOM-tile.zoomLevel; + int xStart = (int)tile.tileX<<m; + int xEnd = (int)((tile.tileX+1)<<m); + int yStart = (int)tile.tileY<<m; + int yEnd = (int)((tile.tileY+1)<<m); + + RealmQuery<ReferenceEntity> realmQuery = Realm.getDefaultInstance().where(ReferenceEntity.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("table", type); + } + realmQuery.endGroup(); + } + List<ReferenceEntity> listResult = realmQuery/*.distinct("id")*/.findAll(); + if (!listResult.isEmpty()) { + mThreadLocalDecoders.get().decode(tile, mapDataSink, listResult); + } + mapDataSink.completed(QueryResult.SUCCESS); +// Log.d("RealmDBTileDataSource", "tile:"+tile.getBoundingBox().toString()); + } else { + mapDataSink.completed(QueryResult.SUCCESS); + } + } + + @Override + public void dispose() { + + } + + @Override + public void cancel() { + if (Realm.getDefaultInstance().isInTransaction()) { + Realm.getDefaultInstance().cancelTransaction(); + } + } +} 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 new file mode 100644 index 00000000..d859fde9 --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDecoder.java @@ -0,0 +1,186 @@ +package com.navinfo.collect.library.map.source; + +import static org.oscim.core.MercatorProjection.latitudeToY; +import static org.oscim.core.MercatorProjection.longitudeToX; + +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import com.navinfo.collect.library.data.entity.ReferenceEntity; + +import org.locationtech.jts.geom.Coordinate; +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 org.locationtech.jts.geom.MultiPoint; +import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.oscim.core.MapElement; +import org.oscim.core.Tag; +import org.oscim.core.Tile; +import org.oscim.tiling.ITileDataSink; +import org.oscim.tiling.source.mvt.TileDecoder; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +public class OMDBReferenceDecoder extends TileDecoder { + private final String mLocale; + + private static final float REF_TILE_SIZE = 4096.0f; + + private final GeometryFactory mGeomFactory; + private final MapElement mMapElement; + private ITileDataSink mTileDataSink; + private double mTileY, mTileX, mTileScale; + + public OMDBReferenceDecoder() { + super(); + mLocale = ""; + mGeomFactory = new GeometryFactory(); + mMapElement = new MapElement(); + mMapElement.layer = 5; + } + + @Override + public boolean decode(Tile tile, ITileDataSink sink, InputStream is) throws IOException { + mTileDataSink = sink; + mTileScale = 1 << tile.zoomLevel; + mTileX = tile.tileX / mTileScale; + mTileY = tile.tileY / mTileScale; + mTileScale *= Tile.SIZE; + return true; + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public boolean decode(Tile tile, ITileDataSink sink, List<ReferenceEntity> listResult) { + mTileDataSink = sink; + mTileScale = 1 << tile.zoomLevel; + mTileX = tile.tileX / mTileScale; + mTileY = tile.tileY / mTileScale; + mTileScale *= Tile.SIZE; + + listResult.stream().iterator().forEachRemaining(new Consumer<ReferenceEntity>() { + @Override + public void accept(ReferenceEntity renderEntity) { +// Log.d("RealmDBTileDataSource", renderEntity.getGeometry()); + Map<String, Object> properties= new HashMap<>(renderEntity.getProperties().size()); + properties.putAll(renderEntity.getProperties()); + parseGeometry(renderEntity.getTable(), renderEntity.getWkt(), properties); + } + }); + return true; + } + + public void parseGeometry(String layerName, Geometry geometry, Map<String, Object> tags) { + mMapElement.clear(); + mMapElement.tags.clear(); + + parseTags(tags, layerName); + if (mMapElement.tags.size() == 0) { + return; + } + + boolean err = false; + if (geometry instanceof Point) { + mMapElement.startPoints(); + processCoordinateArray(geometry.getCoordinates(), false); + } else if (geometry instanceof MultiPoint) { + MultiPoint multiPoint = (MultiPoint) geometry; + for (int i = 0; i < multiPoint.getNumGeometries(); i++) { + mMapElement.startPoints(); + processCoordinateArray(multiPoint.getGeometryN(i).getCoordinates(), false); + } + } else if (geometry instanceof LineString) { + processLineString((LineString) geometry); + } else if (geometry instanceof MultiLineString) { + MultiLineString multiLineString = (MultiLineString) geometry; + for (int i = 0; i < multiLineString.getNumGeometries(); i++) { + processLineString((LineString) multiLineString.getGeometryN(i)); + } + } else if (geometry instanceof Polygon) { + Polygon polygon = (Polygon) geometry; + processPolygon(polygon); + } else if (geometry instanceof MultiPolygon) { + MultiPolygon multiPolygon = (MultiPolygon) geometry; + for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { + processPolygon((Polygon) multiPolygon.getGeometryN(i)); + } + } else { + err = true; + } + + if (!err) { + mTileDataSink.process(mMapElement); + } + } + + private void processLineString(LineString lineString) { + mMapElement.startLine(); + processCoordinateArray(lineString.getCoordinates(), false); + } + + private void processPolygon(Polygon polygon) { + mMapElement.startPolygon(); + processCoordinateArray(polygon.getExteriorRing().getCoordinates(), true); + for (int i = 0; i < polygon.getNumInteriorRing(); i++) { + mMapElement.startHole(); + processCoordinateArray(polygon.getInteriorRingN(i).getCoordinates(), true); + } + } + + private void processCoordinateArray(Coordinate[] coordinates, boolean removeLast) { + int length = removeLast ? coordinates.length - 1 : coordinates.length; + for (int i = 0; i < length; i++) { + mMapElement.addPoint((float) ((longitudeToX(coordinates[i].x) - mTileX) * mTileScale), + (float) ((latitudeToY(coordinates[i].y) - mTileY) * mTileScale)); + } + +// int length = removeLast ? coordinates.length - 1 : coordinates.length; +// // 初始化3D数据类型 +// float[] point3D = new float[coordinates.length*3]; +// for (int i = 0; i < length; i++) { +// point3D[i*3] = (float) coordinates[i].x; +// point3D[(i*3)+1] = (float) coordinates[i].y; +// point3D[(i*3)+2] = (float) coordinates[i].z; +// } +// mMapElement.points = point3D; +// mMapElement.pointNextPos = mMapElement.points.length; +// mMapElement.type = GeometryBuffer.GeometryType.TRIS; + } + + private void parseTags(Map<String, Object> map, String layerName) { + mMapElement.tags.add(new Tag("layer", layerName)); + boolean hasName = false; + String fallbackName = null; + for (Map.Entry<String, Object> entry : map.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + String val = (value instanceof String) ? (String) value : String.valueOf(value); + if (key.startsWith(Tag.KEY_NAME)) { + int len = key.length(); + if (len == 4) { + fallbackName = val; + continue; + } + if (len < 7) + continue; + if (mLocale.equals(key.substring(5))) { + hasName = true; + mMapElement.tags.add(new Tag(Tag.KEY_NAME, val, false)); + } + } else { + mMapElement.tags.add(new Tag(key, val)); + } + } + if (!hasName && fallbackName != null) + mMapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false)); + } +} diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceTileSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceTileSource.java new file mode 100644 index 00000000..aa661822 --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceTileSource.java @@ -0,0 +1,25 @@ +package com.navinfo.collect.library.map.source; + +import com.navinfo.collect.library.system.Constant; + +import org.oscim.tiling.ITileDataSource; +import org.oscim.tiling.OverzoomTileDataSource; +import org.oscim.tiling.TileSource; + +public class OMDBReferenceTileSource extends TileSource { + + @Override + public ITileDataSource getDataSource() { + return new OverzoomTileDataSource(new OMDBReferenceDataSource(), Constant.OVER_ZOOM); + } + + @Override + public OpenResult open() { + return OpenResult.SUCCESS; + } + + @Override + public void close() { + + } +} diff --git a/vtm b/vtm new file mode 160000 index 00000000..fb0b88e9 --- /dev/null +++ b/vtm @@ -0,0 +1 @@ +Subproject commit fb0b88e916c51754baedfb7c5b42aa86b9dc337d