Skip to content

Commit a50d051

Browse files
geometry & other fixes
1 parent e653cb8 commit a50d051

File tree

5 files changed

+71
-36
lines changed

5 files changed

+71
-36
lines changed

dataframe-geo/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ plugins {
77
alias(publisher)
88
alias(jupyter.api)
99
alias(ktlint)
10+
alias(dataframe)
11+
alias(ksp)
1012
}
1113
}
1214

dataframe-geo/src/main/kotlin/org/jetbrains/kotlinx/dataframe/geo/GeoDataFrame.kt

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ import org.jetbrains.kotlinx.dataframe.api.with
1717
*/
1818
class GeoDataFrame<T : WithGeometry>(val df: DataFrame<T>, val crs: CoordinateReferenceSystem?) {
1919
/**
20-
* Creates a new `GeoDataFrame` using a specified transformation block on the underlying DataFrame.
20+
* Creates a new `GeoDataFrame` with the modified underlying DataFrame.
2121
*
22-
* @param updateBlock The block defining the transformations to be applied to the DataFrame.
23-
* @return A new `GeoDataFrame` instance with updated data and the same CRS.
22+
* @param block The block defining the transformations to be applied to the DataFrame.
23+
* @return A new `GeoDataFrame` instance with updated dataframe and the same CRS.
2424
*/
25-
fun update(updateBlock: DataFrame<T>.() -> DataFrame<T>): GeoDataFrame<T> = GeoDataFrame(df.updateBlock(), crs)
25+
inline fun modify(block: DataFrame<T>.() -> DataFrame<T>): GeoDataFrame<T> = GeoDataFrame(df.block(), crs)
2626

2727
/**
2828
* Transforms the geometries to a specified Coordinate Reference System (CRS).
@@ -49,19 +49,26 @@ class GeoDataFrame<T : WithGeometry>(val df: DataFrame<T>, val crs: CoordinateRe
4949

5050
override fun equals(other: Any?): Boolean {
5151
if (this === other) return true
52-
if (other !is GeoDataFrame<*>) return false
52+
if (javaClass != other?.javaClass) return false
5353

54-
return df == other.df &&
55-
when {
56-
crs == null && other.crs == null -> true
57-
crs == null || other.crs == null -> false
58-
else -> CRS.equalsIgnoreMetadata(crs, other.crs)
59-
}
54+
other as GeoDataFrame<*>
55+
56+
if (df != other.df) return false
57+
58+
return when {
59+
crs == null && other.crs == null -> true
60+
crs == null || other.crs == null -> false
61+
else -> CRS.equalsIgnoreMetadata(crs, other.crs)
62+
}
6063
}
6164

62-
override fun toString(): String = super.toString()
65+
override fun hashCode(): Int {
66+
var result = df.hashCode()
67+
result = 31 * result + (crs?.hashCode() ?: 0)
68+
return result
69+
}
6370

64-
override fun hashCode(): Int = super.hashCode()
71+
override fun toString(): String = "GeoDataFrame(df=$df, crs=$crs)"
6572

6673
companion object {
6774
val DEFAULT_CRS = CRS.decode("EPSG:4326", true)
Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.jetbrains.kotlinx.dataframe.geo
22

3-
import org.jetbrains.kotlinx.dataframe.ColumnsContainer
4-
import org.jetbrains.kotlinx.dataframe.DataColumn
53
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
64
import org.locationtech.jts.geom.Geometry
5+
import org.locationtech.jts.geom.LineString
6+
import org.locationtech.jts.geom.MultiLineString
7+
import org.locationtech.jts.geom.MultiPoint
78
import org.locationtech.jts.geom.MultiPolygon
9+
import org.locationtech.jts.geom.Point
810
import org.locationtech.jts.geom.Polygon
911

1012
@DataSchema
@@ -13,26 +15,31 @@ interface WithGeometry {
1315
}
1416

1517
@DataSchema
16-
interface WithPolygon : WithGeometry {
18+
interface WithPolygonGeometry : WithGeometry {
1719
override val geometry: Polygon
1820
}
1921

2022
@DataSchema
21-
interface WithMultiPolygon : WithGeometry {
23+
interface WithMultiPolygonGeometry : WithGeometry {
2224
override val geometry: MultiPolygon
2325
}
2426

25-
@Suppress("UNCHECKED_CAST")
26-
@get:JvmName("geometry")
27-
val ColumnsContainer<WithGeometry>.geometry: DataColumn<Geometry>
28-
get() = get("geometry") as DataColumn<Geometry>
27+
@DataSchema
28+
interface WithPointGeometry : WithGeometry {
29+
override val geometry: Point
30+
}
2931

30-
@Suppress("UNCHECKED_CAST")
31-
@get:JvmName("geometryPolygon")
32-
val ColumnsContainer<WithPolygon>.geometry: DataColumn<Polygon>
33-
get() = get("geometry") as DataColumn<Polygon>
32+
@DataSchema
33+
interface WithMultiPointGeometry : WithGeometry {
34+
override val geometry: MultiPoint
35+
}
3436

35-
@Suppress("UNCHECKED_CAST")
36-
@get:JvmName("geometryMultiPolygon")
37-
val ColumnsContainer<WithMultiPolygon>.geometry: DataColumn<MultiPolygon>
38-
get() = get("geometry") as DataColumn<MultiPolygon>
37+
@DataSchema
38+
interface WithLineStringGeometry : WithGeometry {
39+
override val geometry: LineString
40+
}
41+
42+
@DataSchema
43+
interface WithMultiLineStringGeometry : WithGeometry {
44+
override val geometry: MultiLineString
45+
}

dataframe-geo/src/main/kotlin/org/jetbrains/kotlinx/dataframe/geo/geocode/Geocoder.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@ import kotlinx.serialization.json.Json
1414
import kotlinx.serialization.json.jsonArray
1515
import kotlinx.serialization.json.jsonObject
1616
import kotlinx.serialization.json.jsonPrimitive
17+
import org.jetbrains.annotations.ApiStatus.Experimental
1718
import org.jetbrains.kotlinx.dataframe.api.dataFrameOf
1819
import org.jetbrains.kotlinx.dataframe.geo.GeoDataFrame
1920
import org.jetbrains.kotlinx.dataframe.geo.toGeo
2021
import org.locationtech.jts.geom.Geometry
2122
import org.locationtech.jts.geom.GeometryFactory
2223
import org.locationtech.jts.io.geojson.GeoJsonReader
2324

25+
/**
26+
* Experimental geo coding utility.
27+
*/
28+
@Experimental
2429
object Geocoder {
2530

2631
private val url = "https://geo2.datalore.jetbrains.com/map_data/geocoding"

dataframe-geo/src/main/kotlin/org/jetbrains/kotlinx/dataframe/jupyter/IntegrationGeo.kt

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ package org.jetbrains.kotlinx.dataframe.jupyter
44

55
import org.jetbrains.kotlinx.dataframe.geo.GeoDataFrame
66
import org.jetbrains.kotlinx.dataframe.geo.WithGeometry
7-
import org.jetbrains.kotlinx.dataframe.geo.WithMultiPolygon
8-
import org.jetbrains.kotlinx.dataframe.geo.WithPolygon
7+
import org.jetbrains.kotlinx.dataframe.geo.WithLineStringGeometry
8+
import org.jetbrains.kotlinx.dataframe.geo.WithMultiLineStringGeometry
9+
import org.jetbrains.kotlinx.dataframe.geo.WithMultiPointGeometry
10+
import org.jetbrains.kotlinx.dataframe.geo.WithMultiPolygonGeometry
11+
import org.jetbrains.kotlinx.dataframe.geo.WithPointGeometry
12+
import org.jetbrains.kotlinx.dataframe.geo.WithPolygonGeometry
913
import org.jetbrains.kotlinx.dataframe.impl.codeGen.ReplCodeGeneratorImpl
1014
import org.jetbrains.kotlinx.jupyter.api.FieldHandler
1115
import org.jetbrains.kotlinx.jupyter.api.FieldHandlerExecution
@@ -29,17 +33,27 @@ internal class IntegrationGeo : JupyterIntegration() {
2933
import("org.jetbrains.kotlinx.dataframe.geo.jts.*")
3034
import("org.jetbrains.kotlinx.dataframe.geo.geotools.*")
3135
import("org.jetbrains.kotlinx.dataframe.geo.geocode.*")
36+
import("org.geotools.referencing.CRS")
37+
import("org.locationtech.jts.geom.*")
3238
onLoaded {
3339
useSchema<WithGeometry>()
34-
useSchema<WithPolygon>()
35-
useSchema<WithMultiPolygon>()
40+
useSchema<WithPolygonGeometry>()
41+
useSchema<WithMultiPolygonGeometry>()
42+
useSchema<WithPointGeometry>()
43+
useSchema<WithMultiPointGeometry>()
44+
useSchema<WithLineStringGeometry>()
45+
useSchema<WithMultiLineStringGeometry>()
3646
}
3747
val replCodeGeneratorImpl = ReplCodeGeneratorImpl()
3848
replCodeGeneratorImpl.process(WithGeometry::class)
39-
replCodeGeneratorImpl.process(WithPolygon::class)
40-
replCodeGeneratorImpl.process(WithMultiPolygon::class)
49+
replCodeGeneratorImpl.process(WithPolygonGeometry::class)
50+
replCodeGeneratorImpl.process(WithMultiPolygonGeometry::class)
51+
replCodeGeneratorImpl.process(WithPointGeometry::class)
52+
replCodeGeneratorImpl.process(WithMultiPointGeometry::class)
53+
replCodeGeneratorImpl.process(WithLineStringGeometry::class)
54+
replCodeGeneratorImpl.process(WithMultiLineStringGeometry::class)
4155
val execution = FieldHandlerFactory.createUpdateExecution<GeoDataFrame<*>> { geo, kProperty ->
42-
// TODO rewrite
56+
// TODO rewrite better
4357
val generatedDf = execute(
4458
codeWithConverter = replCodeGeneratorImpl.process(geo.df, kProperty),
4559
"(${kProperty.name}.df as DataFrame<*>)",

0 commit comments

Comments
 (0)