Skip to content

Commit

Permalink
initial draft
Browse files Browse the repository at this point in the history
  • Loading branch information
cbullinger committed Jul 27, 2023
1 parent b9eff13 commit b4f9708
Show file tree
Hide file tree
Showing 16 changed files with 596 additions and 2 deletions.
2 changes: 1 addition & 1 deletion examples/kotlin/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pluginManagement {
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
version("realm", "1.10.0")
version("realm", "1.11.0-SNAPSHOT")
version("kotlinx-coroutines", "1.7.0")
version("kotlinx-serialization", "1.5.0")
library("realm-plugin", "io.realm.kotlin", "gradle-plugin").versionRef("realm")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package com.mongodb.realm.realmkmmapp

import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.annotations.ExperimentalGeoSpatialApi
import io.realm.kotlin.ext.query
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.internal.platform.runBlocking
import io.realm.kotlin.types.EmbeddedRealmObject
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Ignore
import io.realm.kotlin.types.annotations.PrimaryKey
import io.realm.kotlin.types.geo.*
import org.mongodb.kbson.ObjectId
import kotlin.test.Test
import kotlin.test.assertEquals


class Geospatial : RealmTest() {

// :snippet-start: geopoint-model
class Company : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var location: CustomGeoPoint? = null
}
// :snippet-end:

// :snippet-start: custom-geopoint
class CustomGeoPoint : EmbeddedRealmObject {
constructor(latitude: Double, longitude: Double) {
coordinates.apply {
add(longitude)
add(latitude)
}
}
// Empty constructor required by Realm
constructor() : this(0.0, 0.0)

// Name and type required by Realm
var coordinates: RealmList<Double> = realmListOf()

// Name, type, and value required by Realm
private var type: String = "Point"

@Ignore
var latitude: Double
get() = coordinates[1]
set(value) {
coordinates[1] = value
}

@Ignore
var longitude: Double
get() = coordinates[0]
set(value) {
coordinates[0] = value
}
}
// :snippet-end:

@OptIn(ExperimentalGeoSpatialApi::class)
@Test
fun geospatialTest() {
val REALM_NAME = getRandom()
runBlocking {
val config = RealmConfiguration.Builder(schema = setOf(Company::class, CustomGeoPoint::class))
.directory(TMP_PATH)
.name(REALM_NAME)
.build()
val realm = Realm.open(config)

// :snippet-start: create-geopoint
realm.writeBlocking {
copyToRealm(
Company().apply {
location = CustomGeoPoint(47.68, -122.35)
}
)
copyToRealm(
Company().apply {
location = CustomGeoPoint(47.9, -121.85)
}
)
}
// :snippet-end:
// :snippet-start: geocircle
val circle1 = GeoCircle.create(
center = GeoPoint.create(47.8, -122.6),
radius = Distance.fromKilometers(44.4)
)
val circle2 = GeoCircle.create(
center = GeoPoint.create(47.3, -121.9),
radius = Distance.fromDegrees(0.25)
)
// :snippet-end:
// :snippet-start: geobox
val box1 = GeoBox.Companion.create(
bottomLeft = GeoPoint.create(47.3, -122.7),
topRight = GeoPoint.create(48.1, -122.1)
)
val box2 = GeoBox.Companion.create(
bottomLeft = GeoPoint.create(47.5, -122.4),
topRight = GeoPoint.create(47.9, -121.8)
)
// :snippet-end:

// :snippet-start: geopolygon
// Create a basic polygon
val basicPolygon = GeoPolygon.create(
listOf(
GeoPoint.create(48.0, -122.8),
GeoPoint.create(48.2, -121.8),
GeoPoint.create(47.6, -121.6),
GeoPoint.create(47.0, -122.0),
GeoPoint.create(47.2, -122.6),
GeoPoint.create(48.0, -122.8)
)
)

// Create a polygon with a single hole
val outerRing = listOf(
GeoPoint.create(48.0, -122.8),
GeoPoint.create(48.2, -121.8),
GeoPoint.create(47.6, -121.6),
GeoPoint.create(47.0, -122.0),
GeoPoint.create(47.2, -122.6),
GeoPoint.create(48.0, -122.8)
)

val hole1 = listOf(
GeoPoint.create(47.8, -122.6),
GeoPoint.create(47.7, -122.2),
GeoPoint.create(47.4, -122.6),
GeoPoint.create(47.6, -122.5),
GeoPoint.create(47.8, -122.6)
)

val polygonWithOneHole = GeoPolygon.create(outerRing, hole1)

// Add a second hole to the polygon
val hole2 = listOf(
GeoPoint.create(47.55, -122.05),
GeoPoint.create(47.5, -121.9),
GeoPoint.create(47.3, -122.1),
GeoPoint.create(47.55, -122.05)
)

val polygonWithTwoHoles = GeoPolygon.create(outerRing, hole1, hole2)
// :snippet-end:

// :snippet-start: geopoint-query
var geopointQuery =
realm.query<Company>("location GEOWITHIN $circle1").find()
// :snippet-end:

// :snippet-start: geocircle-query
val companiesInLargeCircle =
realm.query<Company>("location GEOWITHIN $circle1").find()
println("Companies in large circle: ${companiesInLargeCircle.size}")

val companiesInSmallCircle =
realm.query<Company>("location GEOWITHIN $circle2").find()
println("Companies in small circle: ${companiesInSmallCircle.size}")
// :snippet-end:
// :snippet-start: geobox-query
val companiesInLargeBox =
realm.query<Company>("location GEOWITHIN $box1").find()
println("Companies in large box: ${companiesInLargeBox.size}")

val companiesInSmallBox =
realm.query<Company>("location GEOWITHIN $box2").find()
println("Companies in small box: ${companiesInSmallBox.size}")
// :snippet-end:
// :snippet-start: geopolygon-query
val companiesInBasicPolygon =
realm.query<Company>("location GEOWITHIN $basicPolygon").find()
println("Companies in basic polygon: ${companiesInBasicPolygon.size}")

val companiesInPolygonWithHoles =
realm.query<Company>("location GEOWITHIN $polygonWithTwoHoles").find()
println("Companies in polygon with holes: ${companiesInPolygonWithHoles.size}")
// :snippet-end:
assertEquals(1, companiesInLargeCircle.size)
assertEquals(0, companiesInSmallCircle.size)
assertEquals(1, companiesInLargeBox.size)
assertEquals(2, companiesInSmallBox.size)
assertEquals(2, companiesInBasicPolygon.size)
assertEquals(1, companiesInPolygonWithHoles.size)
realm.close()
Realm.deleteRealm(config)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
realm.writeBlocking {
copyToRealm(
Company().apply {
location = CustomGeoPoint(47.68, -122.35)
}
)
copyToRealm(
Company().apply {
location = CustomGeoPoint(47.9, -121.85)
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class CustomGeoPoint : EmbeddedRealmObject {
constructor(latitude: Double, longitude: Double) {
coordinates.apply {
add(longitude)
add(latitude)
}
}
// Empty constructor required by Realm
constructor() : this(0.0, 0.0)

// Name and type required by Realm
var coordinates: RealmList<Double> = realmListOf()

// Name, type, and value required by Realm
private var type: String = "Point"

@Ignore
var latitude: Double
get() = coordinates[1]
set(value) {
coordinates[1] = value
}

@Ignore
var longitude: Double
get() = coordinates[0]
set(value) {
coordinates[0] = value
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
val companiesInLargeBox =
realm.query<Company>("location GEOWITHIN $box1").find()
println("Companies in large box: ${companiesInLargeBox.size}")

val companiesInSmallBox =
realm.query<Company>("location GEOWITHIN $box2").find()
println("Companies in small box: ${companiesInSmallBox.size}")
8 changes: 8 additions & 0 deletions source/examples/generated/kotlin/Geospatial.snippet.geobox.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
val box1 = GeoBox.Companion.create(
bottomLeft = GeoPoint.create(47.3, -122.7),
topRight = GeoPoint.create(48.1, -122.1)
)
val box2 = GeoBox.Companion.create(
bottomLeft = GeoPoint.create(47.5, -122.4),
topRight = GeoPoint.create(47.9, -121.8)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
val companiesInLargeCircle =
realm.query<Company>("location GEOWITHIN $circle1").find()
println("Companies in large circle: ${companiesInLargeCircle.size}")

val companiesInSmallCircle =
realm.query<Company>("location GEOWITHIN $circle2").find()
println("Companies in small circle: ${companiesInSmallCircle.size}")
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
val circle1 = GeoCircle.create(
center = GeoPoint.create(47.8, -122.6),
radius = Distance.fromKilometers(44.4)
)
val circle2 = GeoCircle.create(
center = GeoPoint.create(47.3, -121.9),
radius = Distance.fromDegrees(0.25)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Company : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var location: CustomGeoPoint? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var geopointQuery =
realm.query<Company>("location GEOWITHIN $circle1").find()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
val companiesInBasicPolygon =
realm.query<Company>("location GEOWITHIN $basicPolygon").find()
println("Companies in basic polygon: ${companiesInBasicPolygon.size}")

val companiesInPolygonWithHoles =
realm.query<Company>("location GEOWITHIN $polygonWithTwoHoles").find()
println("Companies in polygon with holes: ${companiesInPolygonWithHoles.size}")
41 changes: 41 additions & 0 deletions source/examples/generated/kotlin/Geospatial.snippet.geopolygon.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Create a basic polygon
val basicPolygon = GeoPolygon.create(
listOf(
GeoPoint.create(48.0, -122.8),
GeoPoint.create(48.2, -121.8),
GeoPoint.create(47.6, -121.6),
GeoPoint.create(47.0, -122.0),
GeoPoint.create(47.2, -122.6),
GeoPoint.create(48.0, -122.8)
)
)

// Create a polygon with a single hole
val outerRing = listOf(
GeoPoint.create(48.0, -122.8),
GeoPoint.create(48.2, -121.8),
GeoPoint.create(47.6, -121.6),
GeoPoint.create(47.0, -122.0),
GeoPoint.create(47.2, -122.6),
GeoPoint.create(48.0, -122.8)
)

val hole1 = listOf(
GeoPoint.create(47.8, -122.6),
GeoPoint.create(47.7, -122.2),
GeoPoint.create(47.4, -122.6),
GeoPoint.create(47.6, -122.5),
GeoPoint.create(47.8, -122.6)
)

val polygonWithOneHole = GeoPolygon.create(outerRing, hole1)

// Add a second hole to the polygon
val hole2 = listOf(
GeoPoint.create(47.55, -122.05),
GeoPoint.create(47.5, -121.9),
GeoPoint.create(47.3, -122.1),
GeoPoint.create(47.55, -122.05)
)

val polygonWithTwoHoles = GeoPolygon.create(outerRing, hole1, hole2)
2 changes: 1 addition & 1 deletion source/sdk/kotlin/realm-database/schemas.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Model Data - Kotlin SDK
:titlesonly:

Define an Object Model </sdk/kotlin/realm-database/schemas/define-realm-object-model>
Data Types </sdk/kotlin/realm-database/schemas/supported-types>
Supported Data Types </sdk/kotlin/realm-database/schemas/data-types>
Property Annotations </sdk/kotlin/realm-database/schemas/property-annotations>
Relationships </sdk/kotlin/realm-database/schemas/relationships>
Change an Object Model </sdk/kotlin/realm-database/schemas/change-an-object-model>
Expand Down
22 changes: 22 additions & 0 deletions source/sdk/kotlin/realm-database/schemas/data-types.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.. _kotlin-realm-data-types:

=============================
Realm Data Types - Kotlin SDK
=============================

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

.. toctree::
:titlesonly:
:hidden:

Data Types </sdk/kotlin/realm-database/schemas/data-types/supported-types>
Geospatial Data </sdk/kotlin/realm-database/schemas/data-types/geospatials>


- :doc:`Data Types </sdk/kotlin/realm-database/schemas/data-types/supported-types>`
- :doc:`Geospatial Data </sdk/kotlin/realm-database/schemas/data-types/geospatials>`
Loading

0 comments on commit b4f9708

Please sign in to comment.