Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove map_id, add sym_x and sym_y #148

Merged
merged 11 commits into from
Jun 15, 2020
Prev Previous commit
Next Next commit
Better error message for missing data key, more tests
  • Loading branch information
IKupriyanov-HORIS committed Jun 15, 2020
commit 50644ec970b7f1ccbd1dae071bc39d02e815a735
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,5 @@ object DataFrameUtil {
return b.build()
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import jetbrains.datalore.plot.base.Aes
import jetbrains.datalore.plot.base.DataFrame
import jetbrains.datalore.plot.base.GeomKind
import jetbrains.datalore.plot.base.GeomKind.*
import jetbrains.datalore.plot.base.data.DataFrameUtil.findVariableOrFail
import jetbrains.datalore.plot.base.data.DataFrameUtil.variables
import jetbrains.datalore.plot.config.ConfigUtil.createAesMapping
import jetbrains.datalore.plot.config.ConfigUtil.createDataFrame
Expand Down Expand Up @@ -51,12 +52,12 @@ class GeoConfig(
return geoDataFrame.getList(geoColumn)?.map { it as String } ?: error("$geoColumn not found in $gdfLocation")
}

val joinIds: List<Any>
val dataJoinColumn: String
val mapJoinColumn: String
val mapKeys: List<Any>
val dataKeyColumn: String
val mapKeyColumn: String
val geoJson: List<String>
val dataFrame: DataFrame
val autoId = "__gdf_id__"
val autoId = "__id__"

when {
// (aes(color='cyl'), data=data, map=gdf) - how to join without `map_join`?
Expand All @@ -71,9 +72,15 @@ class GeoConfig(
geoJson = getGeoJson(GEO_POSITIONS)

val mapJoin = layerOptions.getList(MAP_JOIN) ?: error("require map_join parameter")
dataJoinColumn = mapJoin[0] as String
mapJoinColumn = mapJoin[1] as String
joinIds = layerOptions.getMap(GEO_POSITIONS)?.getList(mapJoinColumn)?.requireNoNulls() ?: error("MapJoinColumn '$mapJoinColumn' is not found")
dataKeyColumn = mapJoin[0] as String
mapKeyColumn = mapJoin[1] as String
mapKeys = layerOptions.getMap(GEO_POSITIONS)?.getList(mapKeyColumn)?.requireNoNulls() ?: error("'$mapKeyColumn' is not found in map")

// All data keys should be present in map
data.get(findVariableOrFail(data, dataKeyColumn))
.firstOrNull { dataKey -> dataKey !in mapKeys }
?.let { error("'$it' not found in map") }

dataFrame = data
}

Expand All @@ -82,21 +89,21 @@ class GeoConfig(
require(layerOptions.has(GEO_POSITIONS)) { "'map' parameter is mandatory with MAP_DATA_META" }
geoJson = getGeoJson(GEO_POSITIONS)

dataJoinColumn = autoId
mapJoinColumn = autoId
joinIds = geoJson.indices.map(Int::toString)
dataFrame = DataFrame.Builder(data).put(DataFrame.Variable(dataJoinColumn), joinIds).build()
dataKeyColumn = autoId
mapKeyColumn = autoId
mapKeys = geoJson.indices.map(Int::toString)
dataFrame = DataFrame.Builder(data).put(DataFrame.Variable(dataKeyColumn), mapKeys).build()
}

// (data=gdf)
with(layerOptions) { has(DATA_META, GDF, GEOMETRY) && !has(GEO_POSITIONS) && !has(MAP_JOIN) } -> {
require(layerOptions.has(DATA)) { "'data' parameter is mandatory with DATA_META" }
geoJson = getGeoJson(DATA)

dataJoinColumn = autoId
mapJoinColumn = autoId
joinIds = geoJson.indices.map(Int::toString)
dataFrame = DataFrame.Builder(data).put(DataFrame.Variable(dataJoinColumn), joinIds).build()
dataKeyColumn = autoId
mapKeyColumn = autoId
mapKeys = geoJson.indices.map(Int::toString)
dataFrame = DataFrame.Builder(data).put(DataFrame.Variable(dataKeyColumn), mapKeys).build()
}

else -> error("GeoDataFrame not found in data or map")
Expand All @@ -112,13 +119,13 @@ class GeoConfig(

coordinatesCollector
.append(geoJson)
.setIdColumn(columnName = mapJoinColumn, values = joinIds)
.setIdColumn(columnName = mapKeyColumn, values = mapKeys)

dataAndCoordinates = rightJoin(
left = dataFrame,
leftKey = dataJoinColumn,
leftKey = dataKeyColumn,
right = createDataFrame(coordinatesCollector.buildCoordinatesMap()),
rightKey = mapJoinColumn
rightKey = mapKeyColumn
)

val coordinatesAutoMapping = coordinatesCollector.mappings
Expand All @@ -138,12 +145,12 @@ class GeoConfig(
}
}

const val POINT_X = "__gdf_x__"
const val POINT_Y = "__gdf_y__"
const val RECT_XMIN = "__gdf_xmin__"
const val RECT_YMIN = "__gdf_ymin__"
const val RECT_XMAX = "__gdf_xmax__"
const val RECT_YMAX = "__gdf_ymax__"
const val POINT_X = "__x__"
const val POINT_Y = "__y__"
const val RECT_XMIN = "__xmin__"
const val RECT_YMIN = "__ymin__"
const val RECT_XMAX = "__xmax__"
const val RECT_YMAX = "__ymax__"

internal abstract class CoordinatesCollector(
val mappings: Map<Aes<*>, String>
Expand Down
33 changes: 31 additions & 2 deletions plot-config/src/jvmTest/kotlin/plot/config/GeoConfigTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import jetbrains.datalore.plot.config.PlotConfigClientSideUtil.createPlotAssembl
import jetbrains.datalore.plot.parsePlotSpec
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.fail

class GeoConfigTest {
private val point = """{\"type\": \"Point\", \"coordinates\": [1.0, 2.0]}"""
Expand Down Expand Up @@ -227,8 +228,8 @@ class GeoConfigTest {
| "layers": [{
| "geom": "polygon",
| "data": {
| "fig": ["Polygon", "MPolygon", "C"],
| "value": [42, 23, 66]
| "fig": ["Polygon", "MPolygon"],
| "value": [42, 23]
| },
| "mapping": {"fill": "value"},
| "map": $gdf,
Expand Down Expand Up @@ -260,4 +261,32 @@ class GeoConfigTest {
)
)
}


@Test
fun `should show data key missing in map`() {
val spec = """
|{
| "kind": "plot",
| "layers": [{
| "geom": "polygon",
| "data": {
| "fig": ["Polygon", "MPolygon", "Missing_Key"],
| "value": [42, 23, 66]
| },
| "mapping": {"fill": "value"},
| "map": $gdf,
| "map_data_meta": {"geodataframe": {"geometry": "coord"}},
| "map_join": ["fig", "kind"]
| }]
|}
""".trimMargin()

try {
createPlotAssembler(parsePlotSpec(spec))
fail("'Missing_Key' is missing in map - should throw exception")
} catch (e: Exception) {
assertEquals("'Missing_Key' not found in map", e.localizedMessage)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ class GeoData : PlotConfigDemoBase() {

fun plotSpecList(): List<Map<String, Any>> {
return listOf(
ttt()
// mapGeoDataFrame_MapJoin(),
// mapGeoDataFrame_NoMapJoin_MixedShapes("polygon"),
// mapGeoDataFrame_NoMapJoin_MixedShapes("point"),
// mapGeoDataFrame_NoMapJoin_MixedShapes("path"),
// mapGeoDataFrame_Empty(),
// mapGeoDict_MapJoin(),
// dataGeoDataFrame_Empty(),
// dataGeoDataFrame_NoMapJoin_GeomText()
mapGeoDataFrame_MapJoin(),
mapGeoDataFrame_NoMapJoin_MixedShapes("polygon"),
mapGeoDataFrame_NoMapJoin_MixedShapes("point"),
mapGeoDataFrame_NoMapJoin_MixedShapes("path"),
mapGeoDataFrame_Empty(),
mapGeoDict_MapJoin(),
dataGeoDataFrame_Empty(),
dataGeoDataFrame_NoMapJoin_GeomText()
)
}

Expand All @@ -32,40 +31,6 @@ class GeoData : PlotConfigDemoBase() {
private const val multipolygon =
"""{\"type\": \"MultiPolygon\", \"coordinates\": [[[[11.0, 12.0], [13.0, 14.0], [15.0, 13.0], [11.0, 12.0]]]]}"""


fun ttt(): MutableMap<String, Any> {
val point = """{\"type\": \"Point\", \"coordinates\": [-5.0, 17.0]}"""
val multiPoint = """{\"type\": \"MultiPoint\", \"coordinates\": [[3.0, 15.0], [6.0, 13.0]]}"""
val lineString = """{\"type\": \"LineString\", \"coordinates\": [[0.0, 0.0], [5.0, 5.0]]}"""
val multiLineString = """{\"type\": \"MultiLineString\", \"coordinates\": [[[10.0, 0.0], [15.0, 5.0]], [[10.0, 5.0], [15.0, 0.0]]]}"""
val polygon = """{\"type\": \"Polygon\", \"coordinates\": [[[1.0, 1.0], [1.0, 9.0], [9.0, 9.0], [9.0, 1.0], [1.0, 1.0]], [[2.0, 2.0], [3.0, 2.0], [3.0, 3.0], [2.0, 3.0], [2.0, 2.0]], [[4.0, 4.0], [6.0, 4.0], [6.0, 6.0], [4.0, 6.0], [4.0, 4.0]]]}"""
val multipolygon = """{\"type\": \"MultiPolygon\", \"coordinates\": [[[[11.0, 12.0], [13.0, 14.0], [15.0, 13.0], [11.0, 12.0]]]]}"""
val gdf = """
{
"kind": ["Point", "MPoint", "Line", "MLine", "Polygon", "MPolygon"],
"coord": ["$point", "$multiPoint", "$lineString", "$multiLineString", "$polygon", "$multipolygon"]
}
"""
val spec = """
|{
| "kind": "plot",
| "layers": [{
| "geom": "polygon",
| "data": {
| "fig": ["Polygon", "MPolygon", "C"],
| "value": [42, 23, 66]
| },
| "mapping": {"fill": "value"},
| "map": $gdf,
| "map_data_meta": {"geodataframe": {"geometry": "coord"}},
| "map_join": ["fig", "kind"]
| }]
|}
""".trimMargin()
return parsePlotSpec(spec)

}

private fun mapGeoDict_MapJoin(): Map<String, Any> {
val spec = """
{
Expand Down