官术网_书友最值得收藏!

  • Kotlin Blueprints
  • Ashish Belagali Hardik Trivedi Akshay Chordiya
  • 319字
  • 2021-07-02 21:50:18

Extras for geospatial support

Unfortunately, Exposed doesn't natively support PostGIS functionality such as geometry types or geospatial requests. This is an excellent opportunity to use Extension functions by Kotlin and fill the missing support without modifying the original source.

Adding support for location

The location data for the message is in the form of coordinates. To store such a data structure in the database, we define PointColumnType to store and get the location data for the message:

     * It represents the point column type for Exposed
*/
class PointColumnType(private val srid: Int = 4326) : ColumnType()
{
override fun sqlType() = "GEOMETRY(Point, $srid)"
override fun valueFromDB(value: Any) = if (value is PGgeometry)
value.geometry else value
override fun notNullValueToDB(value: Any): Any {
if (value is Point) {
if (value.srid == Point.UNKNOWN_SRID) value.srid = srid
return PGgeometry(value)
}
return value
}
}

And add an Extension function to directly use Point Column in our Messages object:

    /**
* Extension function to get point column type from the table
*/
fun Table.point(name: String, srid: Int = 4326): Column<Point>
= registerColumn(name, PointColumnType())

Adding support for location-bound queries

One more extra geospatial functionality we need is firing SQL queries within a selected area of the map; that is a bounded box. For that we need to create an expression for the required column type, PGbox2d, which represents the bounded location:

    /**
* Special type to represent the box and if location of message
* is inside the specified box
*/
class WithinOp(private val expr1: Expression<*>, private val box:
PGbox2d) : Op<Boolean>() {
override fun toSQL(queryBuilder: QueryBuilder) =
"${expr1.toSQL(queryBuilder)} && ST_MakeEnvelope(${box.llb.x},
${box.llb.y}, ${box.urt.x}, ${box.urt.y}, 4326)"
}

And an Extension function to use the feature to check if the message is in the specified region:

    /**
* To check if the message location is within the specified box
area.
* Returns true if yes else false
*/
infix fun ExpressionWithColumnType<*>.within(box: PGbox2d):
Op<Boolean>= WithinOp(this, box)
主站蜘蛛池模板: 上饶市| 临夏县| 乐平市| 监利县| 汤阴县| 和平区| 潮安县| 台南市| 南宫市| 中宁县| 库尔勒市| 扶余县| 玉山县| 龙井市| 漠河县| 中牟县| 临清市| 安化县| 东乡县| 和林格尔县| 曲阜市| 上犹县| 大连市| 固安县| 奉新县| 微博| 亚东县| 扎赉特旗| 仙居县| 鲜城| 綦江县| 长乐市| 青铜峡市| 南安市| 龙门县| 九台市| 绥宁县| 崇礼县| 仁化县| 恩平市| 海南省|