Skip to content

Commit

Permalink
Release v4.7.2
Browse files Browse the repository at this point in the history
  • Loading branch information
alshan committed Apr 25, 2024
1 parent 732945e commit 43e6b30
Show file tree
Hide file tree
Showing 16 changed files with 156 additions and 25 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All scales should have the 'format' parameter.

## [4.7.2] - 2024-04-25

This release is 100% compatible with [Lets-Plot v 4.3.2](https://github.com/JetBrains/lets-plot/releases/tag/v4.3.2).

### Fixed

- LP occasionally crashes when drawing polygons [[#1084](https://github.com/JetBrains/lets-plot/issues/1084)].
- Regression of issue [[#966](https://github.com/JetBrains/lets-plot/issues/966)].
- Linetype doesn't work for `geomTile()` [[LPK-241](https://github.com/JetBrains/lets-plot-kotlin/issues/241)].


## [4.7.1] - 2024-04-22

This release is 100% compatible with [Lets-Plot v 4.3.1](https://github.com/JetBrains/lets-plot/releases/tag/v4.3.1).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ In this case the latest `library descriptor` will be pulled from the [Kotlin Jup
#### Library Descriptor Parameters

```
%use lets-plot(api=4.7.1, lib=4.3.1, js=4.3.1, isolatedFrame=false)
%use lets-plot(api=4.7.2, lib=4.3.2, js=4.3.2, isolatedFrame=false)
```
- `api` - version of the Lets-Plot Kotlin API.
- `lib` - version of the Lets-Plot Multiplatform (JARs).
Expand Down
12 changes: 6 additions & 6 deletions USAGE_BATIK_JFX_JS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ plugins {

dependencies {
// Lets-Plot Kotlin API
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.7.1")
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.7.2")
// Lets-Plot Multiplatform (Batik rendering)
implementation("org.jetbrains.lets-plot:lets-plot-batik:4.3.1")
implementation("org.jetbrains.lets-plot:lets-plot-batik:4.3.2")
}
```

Expand All @@ -75,9 +75,9 @@ plugins {

dependencies {
// Lets-Plot Kotlin API
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.7.1")
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.7.2")
// Lets-Plot Multiplatform (JFX Scene rendering)
implementation("org.jetbrains.lets-plot:lets-plot-jfx:4.3.1")
implementation("org.jetbrains.lets-plot:lets-plot-jfx:4.3.2")
}
```

Expand All @@ -95,7 +95,7 @@ kotlin {
named("jsMain") {
dependencies {
// Lets-Plot Kotlin API
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-js:4.7.1")
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-js:4.7.2")
}
}
}
Expand Down Expand Up @@ -193,7 +193,7 @@ val rawSpec = figure.toSpec()
```kotlin
val html: String = PlotHtmlExport.buildHtmlFromRawSpecs(
plotSpec = rawSpec,
scriptUrl = PlotHtmlHelper.scriptUrl(version="4.3.1"),
scriptUrl = PlotHtmlHelper.scriptUrl(version="4.3.2"),
iFrame = true
)
```
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ if (project.file("local.properties").exists()) {
allprojects {
group = "org.jetbrains.lets-plot"
version = when (name) {
"dokka" -> "4.7.1"
else -> "4.7.2-SNAPSHOT"
"dokka" -> "4.7.2"
else -> "4.7.2"
// else -> "0.0.0-SNAPSHOT" // for local publishing only
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2020. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/

package kotlinIsland

import org.geotools.api.feature.Feature
import org.geotools.api.feature.type.FeatureType
import org.geotools.feature.FeatureCollection
import org.geotools.geojson.feature.FeatureJSON
import java.io.File
import java.nio.file.Paths

/**
* Loads data and geometries from "Kotlin Island" GeoJSON files.
*/
internal object KotlinIslandGeojson {
fun loadPlaces(): FeatureCollection<FeatureType, Feature> {
// return loadResource("docs/examples/data/kotlin_places.geojson")
return loadResource("docs/examples/data/kotlin_places_no_crs.geojson")
}

@Suppress("SameParameterValue")
private fun loadResource(relativePathname: String): FeatureCollection<FeatureType, Feature> {
val fileName: String = Paths.get(relativePathname).toAbsolutePath().normalize().toString()

val geoJSONFile = File(fileName)
val featureCollection = FeatureJSON().readFeatureCollection(geoJSONFile.reader())
return featureCollection
}
}
34 changes: 34 additions & 0 deletions demo/geotools-batik/src/main/kotlin/kotlinIsland/PointsMapMain.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2021. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/

package kotlinIsland

import org.jetbrains.letsPlot.batik.plot.component.PlotViewerWindowBatik
import org.jetbrains.letsPlot.geom.geomPoint
import org.jetbrains.letsPlot.intern.toSpec
import org.jetbrains.letsPlot.label.ggtitle
import org.jetbrains.letsPlot.letsPlot
import org.jetbrains.letsPlot.toolkit.geotools.toSpatialDataset
import java.awt.Dimension

fun main() {
// GeoTools
val places = KotlinIslandGeojson.loadPlaces()

// Lets-Plot
val placesSD = places.toSpatialDataset()
val p = letsPlot() +
geomPoint(map = placesSD, color = "red") +
ggtitle("Kotlin Island Tourists Attractions")

PlotViewerWindowBatik(
"Spatial plot demo",
rawSpec = p.toSpec(),
windowSize = Dimension(800, 500),
preserveAspectRatio = false,
repaintDelay = 300
).open()

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import java.nio.file.Paths
/**
* Loads the world boundaries from naturalearth_lowres.shp
*/
object NaturalEarthShp {
internal object NaturalEarthShp {
fun loadPolygon(): SimpleFeatureCollection {
return loadResource("docs/examples/shp/naturalearth_lowres/naturalearth_lowres.shp")
}
Expand Down
2 changes: 1 addition & 1 deletion demo/js-frontend-app/src/jsMain/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</head>
<body>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/gh/JetBrains/[email protected].0/js-package/distr/lets-plot.min.js"></script>
src="https://cdn.jsdelivr.net/gh/JetBrains/[email protected].2/js-package/distr/lets-plot.min.js"></script>
<script src="js-frontend-app.js"></script>
<div>
<h2>Lets-Plot Kotlin/JS Demo.</h2>
Expand Down
1 change: 1 addition & 0 deletions devdocs/PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Specify "x.y.z-SNAPSHOT" version in `build.gradle.kts` file.
> You can find published SNAPSHOT artifacts here https://oss.sonatype.org/index.html#view-repositories;snapshots~browsestorage \
> In the "Browse Storage" tab enter ‘Path lookup’: org/jetbrains/lets-plot
> **Note**: SNAPSHOT artifacts are available at "https://oss.sonatype.org/content/repositories/snapshots" repository.
#### "Release" version

Expand Down
12 changes: 12 additions & 0 deletions docs/examples/data/kotlin_places.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC::CRS84" } },
"features": [
{ "type": "Feature", "properties": { "name": "Kronstadt Naval Cathedral", "type": "church" }, "geometry": { "type": "Point", "coordinates": [ 29.777455, 59.991744 ] } },
{ "type": "Feature", "properties": { "name": "Kronstadt History Museum", "type": "museum" }, "geometry": { "type": "Point", "coordinates": [ 29.791317, 59.986777 ] } },
{ "type": "Feature", "properties": { "name": "Kronstadt Naval Museum", "type": "museum" }, "geometry": { "type": "Point", "coordinates": [ 29.763422, 59.996108 ] } },
{ "type": "Feature", "properties": { "name": "City Russian Cemetery", "type": "cemetery" }, "geometry": { "type": "Point", "coordinates": [ 29.70613, 60.019788 ] } },
{ "type": "Feature", "properties": { "name": "Kronstadt Lutheran Cemetery", "type": "cemetery" }, "geometry": { "type": "Point", "coordinates": [ 29.749861, 60.002212 ] } },
{ "type": "Feature", "properties": { "name": "Vladimir Church", "type": "church" }, "geometry": { "type": "Point", "coordinates": [ 29.766254, 59.998515 ] } }
]
}
11 changes: 11 additions & 0 deletions docs/examples/data/kotlin_places_no_crs.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "name": "Kronstadt Naval Cathedral", "type": "church" }, "geometry": { "type": "Point", "coordinates": [ 29.777455, 59.991744 ] } },
{ "type": "Feature", "properties": { "name": "Kronstadt History Museum", "type": "museum" }, "geometry": { "type": "Point", "coordinates": [ 29.791317, 59.986777 ] } },
{ "type": "Feature", "properties": { "name": "Kronstadt Naval Museum", "type": "museum" }, "geometry": { "type": "Point", "coordinates": [ 29.763422, 59.996108 ] } },
{ "type": "Feature", "properties": { "name": "City Russian Cemetery", "type": "cemetery" }, "geometry": { "type": "Point", "coordinates": [ 29.70613, 60.019788 ] } },
{ "type": "Feature", "properties": { "name": "Kronstadt Lutheran Cemetery", "type": "cemetery" }, "geometry": { "type": "Point", "coordinates": [ 29.749861, 60.002212 ] } },
{ "type": "Feature", "properties": { "name": "Vladimir Church", "type": "church" }, "geometry": { "type": "Point", "coordinates": [ 29.766254, 59.998515 ] } }
]
}
4 changes: 2 additions & 2 deletions docs/geotools.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ the artifact `lets-plot-kotlin-geotools` must be included to make the `toSpatial

You can include it into a Gradle project.
```groovy
implementation 'org.jetbrains.lets-plot-kotlin:lets-plot-kotlin-geotools:4.7.1'
implementation 'org.jetbrains.lets-plot-kotlin:lets-plot-kotlin-geotools:4.7.2'
```

[ ![Download](https://api.bintray.com/packages/jetbrains/lets-plot-maven/lets-plot-kotlin-jars/images/download.svg)](https://bintray.com/jetbrains/lets-plot-maven/lets-plot-kotlin-jars/_latestVersion)
Expand All @@ -69,7 +69,7 @@ The `gt-geojson` artifact from GeoTools must be also included.
```groovy
dependencies {
...
implementation "org.jetbrains.lets-plot-kotlin:lets-plot-kotlin-geotools:4.7.1"
implementation "org.jetbrains.lets-plot-kotlin:lets-plot-kotlin-geotools:4.7.2"
implementation "org.geotools:gt-geojson:[30,)"
...
}
Expand Down
2 changes: 1 addition & 1 deletion future_changes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## [4.7.2] - 2024-mm-dd
## [4.7.3] - 2024-mm-dd

### Added

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ nexusStaging.version=0.30.0
nexusPublish.version=1.3.0

# Also update JS version in <home>/demo/js-frontend-app/src/main/resources/index.html
letsPlot.version=4.3.1
letsPlot.version=4.3.2

# The latest GeoTools 30-RC do not compile due to
# "renaming of all "org.opengis" packages into "org.geotools.api" ones"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
lets_plot.version=4.3.1
lets_plot_kotlin_api.version=4.7.1
lets_plot.version=4.3.2
lets_plot_kotlin_api.version=4.7.2
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,73 @@

package org.jetbrains.letsPlot.toolkit.geotools

import org.geotools.api.feature.Feature
import org.geotools.api.feature.simple.SimpleFeature
import org.geotools.api.feature.simple.SimpleFeatureType
import org.geotools.api.feature.type.FeatureType
import org.geotools.api.feature.type.GeometryDescriptor
import org.geotools.api.referencing.crs.CoordinateReferenceSystem
import org.geotools.data.simple.SimpleFeatureCollection
import org.geotools.feature.FeatureCollection
import org.geotools.geojson.geom.GeometryJSON
import org.jetbrains.letsPlot.spatial.SpatialDataset
import org.locationtech.jts.geom.Geometry
import org.geotools.api.feature.type.GeometryDescriptor

/**
* Transforms SimpleFeatureCollection to SpatialDataset with feature geometries encoded in GEOJSON format.
*
* @param decimals the number of decimals to use when encoding floating point numbers.
*/
fun SimpleFeatureCollection.toSpatialDataset(decimals: Int = 10): SpatialDataset {
@Suppress("UNCHECKED_CAST")
return _toSpatialDataset(this as FeatureCollection<FeatureType, Feature>, decimals)
}

/**
* Transforms abstract SimpleFeatureCollection to SpatialDataset with feature geometries encoded in GEOJSON format.
*
* @param decimals the number of decimals to use when encoding floating point numbers.
*/
fun FeatureCollection<FeatureType, Feature>.toSpatialDataset(decimals: Int = 10): SpatialDataset {
return _toSpatialDataset(this, decimals)
}

private fun _toSpatialDataset(
featureCollection: FeatureCollection<FeatureType, Feature>,
decimals: Int
): SpatialDataset {
val geojson = GeometryJSON(decimals)
val (data, geometries, CRS) = getDataAndGeometries(this) {
val (data, geometries, crs) = getDataAndGeometries(featureCollection) {
geojson.toString(it)
}
return SpatialDataset.withGEOJSON(data, geometries, CRS)
return SpatialDataset.withGEOJSON(data, geometries, crs)
}

private fun getDataAndGeometries(
featureCollection: SimpleFeatureCollection,
featureCollection: FeatureCollection<FeatureType, Feature>,
geometryToString: (Geometry) -> String
): Triple<Map<String, List<Any?>>, List<String>, String> {
val attributeDescriptors = featureCollection.schema.attributeDescriptors
): Triple<Map<String, List<Any?>>, List<String>, String?> {
require(featureCollection.schema is SimpleFeatureType) {
"GeoTools: SimpleFeatureType expected but was: ${featureCollection.schema::class.simpleName}"
}
val attributeDescriptors = (featureCollection.schema as SimpleFeatureType).attributeDescriptors

val dataAttributes = attributeDescriptors?.filter { it !is GeometryDescriptor }?.map { it!! } ?: emptyList()
val geometryAttribute = attributeDescriptors?.find { it is GeometryDescriptor }
?: throw IllegalArgumentException("No geometry attribute")

val crs = (geometryAttribute as GeometryDescriptor).coordinateReferenceSystem
// In GeoJSON the crs attribute is optional
val crs: CoordinateReferenceSystem? = (geometryAttribute as GeometryDescriptor).coordinateReferenceSystem

val data = dataAttributes.associate { it.localName to ArrayList<Any?>() }
val geometries = ArrayList<String>()

featureCollection.features().use {
while (it.hasNext()) {
val feature = it.next()
require(feature is SimpleFeature) {
"GeoTools: SimpleFeature expected but was: ${feature::class.simpleName}"
}
val featureGeometry = feature.getAttribute(geometryAttribute.name)
require(featureGeometry is Geometry) {
"Not a geometry: [${geometryAttribute.name}] = ${featureGeometry?.javaClass?.simpleName} (feature id: ${feature.id})"
Expand All @@ -54,5 +84,5 @@ private fun getDataAndGeometries(
geometries.add(geometryToString(featureGeometry))
}
}
return Triple(data, geometries, crs.name.code)
return Triple(data, geometries, crs?.name?.code)
}

0 comments on commit 43e6b30

Please sign in to comment.