From 121cac3a278e58ec89806410acb1c52e0091428b Mon Sep 17 00:00:00 2001 From: xiaoyan Date: Fri, 21 Apr 2023 15:07:42 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2Link=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/navinfo/omqs/db/RealmOperateHelper.kt | 23 ++++++++++++++++-- .../personalcenter/PersonalCenterViewModel.kt | 3 ++- navinfo.jks | Bin 2066 -> 4095 bytes 3 files changed, 23 insertions(+), 3 deletions(-) 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 e4b1d608..899b4ea3 100644 --- a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt @@ -15,6 +15,7 @@ import org.locationtech.spatial4j.distance.DistanceUtils import org.oscim.core.GeoPoint import org.oscim.core.MercatorProjection import javax.inject.Inject +import kotlin.streams.toList class RealmOperateHelper() { @@ -28,18 +29,36 @@ class RealmOperateHelper() { * @param order 是否需要排序 * */ suspend fun queryLink(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, order: Boolean = false): MutableList { + val result = mutableListOf() withContext(Dispatchers.IO) { val polygon = getPolygonFromPoint(point, buffer, bufferType) // 根据polygon查询相交的tile号 val tileXSet = mutableSetOf() + tileXSet.toString() GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet) val tileYSet = mutableSetOf() GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet) + // 对tileXSet和tileYSet查询最大最小值 + val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null) + val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null) + val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null) + val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null) // 查询realm中对应tile号的数据 - Realm.getDefaultInstance().where(RenderEntity::class.java).equalTo("table", "HAD_LINK") + val realmList = Realm.getDefaultInstance().where(RenderEntity::class.java) + .equalTo("table", "HAD_LINK") + .and() + .rawPredicate("tileX>=$xStart and tileX<=$xEnd and tileY>=$yStart and tileY<=$yEnd") + .findAll() + // 将获取到的数据和查询的polygon做相交,只返回相交的数据 + val queryResult = realmList?.stream()?.filter { + polygon.intersects(GeometryTools.createGeometry(it.geometry)) + }?.toList() + queryResult?.let { + result.addAll(queryResult) + } } - return mutableListOf() + return result } private fun getPolygonFromPoint(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE): Polygon { 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 1318e3fe..4ea75e6b 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 @@ -224,7 +224,8 @@ class PersonalCenterViewModel @Inject constructor( fun readRealmData() { viewModelScope.launch(Dispatchers.IO) { - realmOperateHelper.queryLink(GeometryTools.createPoint(115.685817,28.62759)) + val result = realmOperateHelper.queryLink(GeometryTools.createPoint(115.685817,28.62759)) + Log.d("xiaoyan", result.size.toString()) } } } \ No newline at end of file diff --git a/navinfo.jks b/navinfo.jks index 28de488bb1bb1cef36b6d6d3dd05025caf34a629..5be224fe00413796de7a972d577c0fa70494c10b 100644 GIT binary patch delta 2023 zcmVFvyYrlf9+t2%bwNStx8?N{oHZ!;9+3Zm)Gmg zg-yBY*e9l*%eiZ-+1o9?sU=;(^r#G7zUXxhaWu|ju5^5VXlab5${n~we%CYi40zR* zI}k1jW~NfS5@dCoQfO4H)sB9PydyJUj0 zy@k_LMg*Lba$5NSd!pcdRB6AuEI^>wK993$AQME8=~Gd07t4v zK8kcOwGRP*t+s4e+x2)P0?|m^>Qpj*CRgUal?%jIS!iB+M{qxCLjjX@crUJCO11Z- z|Mlo8%RwO85Ny%qgD%@PZtbWqv)S8+cxQBY9i_}!JRPY%)@(@{y$r{12>=#@SsvlQ2<>kUA^A`nj z%>(%9%>Z4ZtPQ}uQ(QZivlj_?vC5ibj##74H_=zQ0+`-)wj8>;JBPD7?ZrgW<5fM> zcg{5E)HLuL33ctXleTww+W&4=*%QP1VMyMS!3>N4n{>~6Zt@hq7khm_W;?6ex#{13 z*d3D>FNh<6^z6X-(JgCByc~mp1!77Rz%fnUnb^~T?@KxEeFvY5H48-n3A~0bqoNA_ zT&RYWTld9#WW~ zBWax!;hpuqeUP(rvrm42Q-WVHA%~>*}SKw zd{@cZQ(FJrVX<3m4}{{NVj)R3j*iXC^CqGM0!A5F-RtM)rZ@ZHAW5Rx4E@S9!hf1i z0v^rCh>w8%JJ23y`{9i7pSuRF%3@7luPOIS>1nf=v73F(q7=MnqUQK!5v@dj`BP`D zxxwFjO*1Dvuxo5`yd{|_ikn9(=?s`DaRn7kQ(@~A((Z9p5Kr?b4{r`4ND2^Tcb%`A zUR54Cmo1d7rHNr zjL!6GO~}CL&|2NguAzk83L>>EZQZc91~O^FD9w5MF`tl3*;xa(5DvgssAI4zvn7zA zBwU>=s(XZD^PF}hqPysrz!Q8(QTj`X@xUNkbpsIgo>yu_v`fGU7o0BL79#UkKj+ihF1_>&L zNQUHr*e^JtUE_zEJaZPr1Tdbu@lRc3T9qU*EShZmLP$+6vL2ISe_r?9 z{v7&2nuyWCAPjO1O%+PWF|+Fqa9Rz{^^6wbTrJE<8H zuorl(eh;gKNmK=)sxHE%BCnY&&}V@cLEc7!JAz0HSEq?mpcGhH^Xy!ie}aAENXOA|AtX#1jx+%1~GIl@x^r^~274!ms zbq)t40%Zm#xSJ@-pN$J3WJH@etl8T4VsT}0BI0@m1nWt9yU#tC@Q zD%$9WOs#`2HQm#~K#Hk|KrQ{cQ_qwbu*kZFipWR+G-!VUiGSqCcmiT967KSIXK;j7 zZgodDM9{LqYc4!x%av>7b)egXTk=|R9@t+)KCuk)2NbTm4ZER%fz_Nk+3<-8{hsy? Fum*k~rE>rP delta 43 zcmew_KS_Y+-`jt085kItfS7UfPxepjBAcDhX Date: Fri, 21 Apr 2023 16:42:19 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20Realm=E6=95=B0=E6=8D=AE=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=8E=A5=E5=8F=A3=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/navinfo/omqs/db/RealmOperateHelper.kt | 91 +++++++++++++++++-- .../personalcenter/PersonalCenterViewModel.kt | 5 +- .../library/data/entity/RenderEntity.kt | 9 ++ .../collect/library/utils/GeometryTools.java | 15 +++ 4 files changed, 112 insertions(+), 8 deletions(-) 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 899b4ea3..ced6dcb2 100644 --- a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt @@ -26,9 +26,9 @@ class RealmOperateHelper() { * @param point 点位经纬度信息 * @param buffer 点位的外扩距离 * @param bufferType 点位外扩距离的单位: 米-Meter,像素-PIXEL - * @param order 是否需要排序 + * @param sort 是否需要排序 * */ - suspend fun queryLink(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, order: Boolean = false): MutableList { + suspend fun queryLink(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, sort: Boolean = false): MutableList { val result = mutableListOf() withContext(Dispatchers.IO) { val polygon = getPolygonFromPoint(point, buffer, bufferType) @@ -52,21 +52,100 @@ class RealmOperateHelper() { .findAll() // 将获取到的数据和查询的polygon做相交,只返回相交的数据 val queryResult = realmList?.stream()?.filter { - polygon.intersects(GeometryTools.createGeometry(it.geometry)) + polygon.intersects(it.wkt) }?.toList() queryResult?.let { result.addAll(queryResult) } + if (sort) { + result.clear() + result.addAll(sortRenderEntity(point, result)) + } + } + return result + } + /** + * 根据当前点位查询匹配的除Link外的其他要素数据 + * @param point 点位经纬度信息 + * @param buffer 点位的外扩距离 + * @param bufferType 点位外扩距离的单位: 米-Meter,像素-PIXEL + * @param sort 是否需要排序 + * */ + suspend fun queryElement(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, sort: Boolean = false): MutableList { + val result = mutableListOf() + withContext(Dispatchers.IO) { + val polygon = getPolygonFromPoint(point, buffer, bufferType) + // 根据polygon查询相交的tile号 + val tileXSet = mutableSetOf() + tileXSet.toString() + GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet) + val tileYSet = mutableSetOf() + GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet) + + // 对tileXSet和tileYSet查询最大最小值 + val xStart = tileXSet.stream().min(Comparator.naturalOrder()).orElse(null) + val xEnd = tileXSet.stream().max(Comparator.naturalOrder()).orElse(null) + val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null) + val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null) + // 查询realm中对应tile号的数据 + val realmList = Realm.getDefaultInstance().where(RenderEntity::class.java) + .notEqualTo("table", "HAD_LINK") + .and() + .rawPredicate("tileX>=$xStart and tileX<=$xEnd and tileY>=$yStart and tileY<=$yEnd") + .findAll() + // 将获取到的数据和查询的polygon做相交,只返回相交的数据 + val queryResult = realmList?.stream()?.filter { + polygon.intersects(it.wkt) + }?.toList() + queryResult?.let { + result.addAll(queryResult) + } + if (sort) { + result.clear() + result.addAll(sortRenderEntity(point, result)) + } } return result } + /** + * 根据linkPid查询关联的要素(除去Link数据) + * @param point 点位经纬度信息 + * @param buffer 点位的外扩距离 + * @param bufferType 点位外扩距离的单位: 米-Meter,像素-PIXEL + * @param sort 是否需要排序 + * */ + suspend fun queryLinkByLinkPid(linkPid: String): MutableList { + val result = mutableListOf() + withContext(Dispatchers.IO) { + val realmList = Realm.getDefaultInstance().where(RenderEntity::class.java) + .notEqualTo("table", "HAD_LINK") + .and() + .equalTo("properties['LINK_PID']", linkPid) + .findAll() + result.addAll(realmList) + } + return result + } + + /** + * 根据给定的点位对数据排序 + * @param point 点位经纬度信息 + * @param unSortList 未排序的数据 + * @return 排序后的数据 + * */ + fun sortRenderEntity(point: Point, unSortList: MutableList): List { + val sortList = unSortList.stream().sorted { renderEntity, renderEntity2 -> + val near = point.distance(renderEntity.wkt) - point.distance(renderEntity2.wkt) + if (near<0) -1 else 1 + }.toList() + return sortList + } + private fun getPolygonFromPoint(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE): Polygon { // 首先计算当前点位的buffer组成的geometry val wkt: Polygon = if (bufferType == BUFFER_TYPE.METER) { // 如果单位是米 - // 计算米和地球角度之间的关系,在Spatial4J中,经度和纬度的单位是度,而不是米。因此,将距离从米转换为度需要使用一个转换因子,这个转换因子是由地球的周长和360度之间的比例计算得出的。 - // 在这个例子中,使用的转换因子是111000.0,这是因为地球的周长约为40075公里,而每个经度的距离大约是地球周长的1/360,因此每个经度的距离约为111.32公里 - val distanceDegrees = DistanceUtils.dist2Degrees(buffer, DistanceUtils.EARTH_MEAN_RADIUS_KM) * 111000.0 + val distanceDegrees = GeometryTools.convertDistanceToDegree(buffer, point.y) // 计算外扩矩形 BufferOp.bufferOp(point, distanceDegrees) as Polygon } else { // 如果单位是像素,需要根据当前屏幕像素计算出经纬度变化 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 4ea75e6b..cfad6b4f 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 @@ -224,8 +224,9 @@ class PersonalCenterViewModel @Inject constructor( fun readRealmData() { viewModelScope.launch(Dispatchers.IO) { - val result = realmOperateHelper.queryLink(GeometryTools.createPoint(115.685817,28.62759)) - Log.d("xiaoyan", result.size.toString()) +// val result = realmOperateHelper.queryLink(GeometryTools.createPoint(115.685817,28.62759)) + val result = realmOperateHelper.queryLinkByLinkPid("84206617008217069") + Log.d("xiaoyan", result.toString()) } } } \ 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 2627658d..b4842cb2 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 @@ -6,6 +6,7 @@ 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 @@ -28,7 +29,15 @@ open class RenderEntity(): RealmObject() { // 根据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 var properties: RealmDictionary = RealmDictionary() val tileX: RealmSet = RealmSet() // x方向的tile编码 val tileY: RealmSet = RealmSet() // y方向的tile编码 diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java index 8f4c3411..e9cd2426 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java @@ -1566,4 +1566,19 @@ public class GeometryTools { return earthRadiusMeters * acos; // 最终结果 } + + /** + * 将平面坐标系中的距离(以米为单位)转换为地理坐标系中的角度(以度为单位) + * + * @param distance 平面坐标系中的距离(单位:米) + * @param latitude 点的纬度(单位:度) + * @return 对应的地理坐标系中的距离(单位:度) + */ + private static final double EARTH_RADIUS = 6371000.0; + public static double convertDistanceToDegree(double distance, double latitude) { + double radianDistance = distance / EARTH_RADIUS; + double radianLatitude = Math.toRadians(latitude); + double radianDegree = 2 * Math.asin(Math.sin(radianDistance / 2) / Math.cos(radianLatitude)); + return Math.toDegrees(radianDegree); + } }