fix: Realm数据查询接口封装
This commit is contained in:
parent
7b4556aa7f
commit
f2ac094aa9
@ -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<RenderEntity> {
|
||||
suspend fun queryLink(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, sort: Boolean = false): MutableList<RenderEntity> {
|
||||
val result = mutableListOf<RenderEntity>()
|
||||
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<RenderEntity> {
|
||||
val result = mutableListOf<RenderEntity>()
|
||||
withContext(Dispatchers.IO) {
|
||||
val polygon = getPolygonFromPoint(point, buffer, bufferType)
|
||||
// 根据polygon查询相交的tile号
|
||||
val tileXSet = mutableSetOf<Int>()
|
||||
tileXSet.toString()
|
||||
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
|
||||
val tileYSet = mutableSetOf<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
|
||||
|
||||
// 对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<RenderEntity> {
|
||||
val result = mutableListOf<RenderEntity>()
|
||||
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<RenderEntity>): List<RenderEntity> {
|
||||
val sortList = unSortList.stream().sorted { renderEntity, renderEntity2 ->
|
||||
val near = point.distance(renderEntity.wkt) - point.distance(renderEntity2.wkt)
|
||||
if (near<0) -1 else 1
|
||||
}.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 { // 如果单位是像素,需要根据当前屏幕像素计算出经纬度变化
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String?> = RealmDictionary()
|
||||
val tileX: RealmSet<Int> = RealmSet() // x方向的tile编码
|
||||
val tileY: RealmSet<Int> = RealmSet() // y方向的tile编码
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user