3 Commits

Author SHA1 Message Date
237b9ec1c5 add resource for geotiff demo 2025-06-14 14:55:55 +03:00
3ae45dbc93 add resource for geotiff demo 2025-06-14 14:55:49 +03:00
e6dab6071e Update readme template 2025-06-14 14:53:01 +03:00
6 changed files with 67 additions and 33 deletions

View File

@@ -13,6 +13,7 @@ import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import center.sciprog.maps.geotools.geoTiff
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import kotlinx.coroutines.delay
@@ -75,6 +76,10 @@ fun App() {
.color(Color.Blue)
.alpha(0.4f)
geoTiff(geoTiffStream = { javaClass.getResourceAsStream("/wind_direction.tif")!! })
.alpha(0.2f)
icon(pointOne, Icons.Filled.Home)
val marker1 = rectangle(55.744 to 38.614, size = DpSize(10.dp, 10.dp))
@@ -158,6 +163,7 @@ fun App() {
)
}
centerCoordinates.filterNotNull().onEach {
group(id = "center") {
circle(center = it, id = "circle", size = 1.dp).color(Color.Blue)

Binary file not shown.

View File

@@ -0,0 +1,21 @@
# Module maps-kt-geotools
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:maps-kt-geotools:0.4.0-dev-7`.
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:maps-kt-geotools:0.4.0-dev-7")
}
```

View File

@@ -52,7 +52,7 @@ public class GeoToolsMapProjection(
public companion object {
private val crsEPSG4326 by lazy { CRS.decode("EPSG:4326") }
internal val crsEPSG4326 by lazy { CRS.decode("EPSG:4326") }
public val EPSG4326: GeoToolsMapProjection = GeoToolsMapProjection(crsEPSG4326)

View File

@@ -9,56 +9,63 @@ import org.geotools.util.factory.Hints
import space.kscience.kmath.geometry.degrees
import space.kscience.maps.coordinates.Gmc
import space.kscience.maps.features.*
import java.awt.geom.AffineTransform
import java.awt.image.BufferedImage
import java.awt.image.RenderedImage
import java.io.InputStream
import java.lang.Boolean
import java.net.URL
import javax.media.jai.PlanarImage
import kotlin.String
private fun RenderedImage.toImageBitmap(): ImageBitmap {
// Convert RenderedImage to BufferedImage if needed
val bufferedImage = if (this is BufferedImage) {
this
} else {
val bi = BufferedImage(
this.width,
this.height,
BufferedImage.TYPE_INT_ARGB
)
val graphics = bi.createGraphics()
graphics.drawRenderedImage(this, null)
graphics.dispose()
bi
private fun RenderedImage.toImageBitmap(transform: AffineTransform = AffineTransform()): ImageBitmap {
val bufferedImage = when (this) {
is BufferedImage -> this
is PlanarImage -> this.asBufferedImage
else -> {
val bufferedImage = BufferedImage(
this.width,
this.height,
BufferedImage.TYPE_INT_ARGB
)
val graphics = bufferedImage.createGraphics()
graphics.drawRenderedImage(this, transform)
graphics.dispose()
bufferedImage
}
}
// Convert BufferedImage to Compose ImageBitmap
return bufferedImage.toComposeImageBitmap()
}
private fun Position.toGmc(): Gmc {
return Gmc(getOrdinate(0).degrees, getOrdinate(1).degrees)
}
/**
* Transform position to geodetic coordinates assuming the position already uses geodetic cooridnates
*/
private fun Position.toGmc(): Gmc = Gmc(getOrdinate(0).degrees, getOrdinate(1).degrees)
public fun FeatureGroup<Gmc>.geoTiff(
geoTiffUrl: URL,
public fun FeatureBuilder<Gmc>.geoTiff(
geoTiffStream: () -> InputStream,
hints: Hints = Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE),
id: String? = null,
): FeatureRef<Gmc, Feature<Gmc>> {
val reader = GeoTiffReader(geoTiffUrl, hints)
val coverage = reader.read(null)
val crs = coverage.coordinateReferenceSystem
geoTiffStream().use { stream ->
val reader = GeoTiffReader(stream, hints)
val coverage = reader.read(null)
val image = coverage.renderedImage.toImageBitmap()
val envelope = coverage.envelope2D.transform(GeoToolsMapProjection.crsEPSG4326, true)
val image = coverage.renderedImage.toImageBitmap()
val envelope = coverage.envelope2D
val rectangle: Rectangle<Gmc> = Rectangle(envelope.lowerCorner.toGmc(), envelope.upperCorner.toGmc())
val rectangle: Rectangle<Gmc> = space.Rectangle(envelope.lowerCorner.toGmc(), envelope.upperCorner.toGmc())
return feature(
id,
ScalableImageFeature<Gmc>(space, rectangle) {
BitmapPainter(image)
}
)
return feature(
id,
ScalableImageFeature<Gmc>(space, rectangle) {
BitmapPainter(image)
}
)
}
}