diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/items/MappableItemsParser.kt b/collect_app/src/main/java/org/odk/collect/android/widgets/items/MappableItemsParser.kt index acd3c39acb1..a8901f0af85 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/items/MappableItemsParser.kt +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/items/MappableItemsParser.kt @@ -14,13 +14,14 @@ import org.odk.collect.geo.geopoly.GeoPolyUtils.parseGeometry import org.odk.collect.geo.items.IconifiedText import org.odk.collect.geo.items.MappableItem import org.odk.collect.icons.R +import org.odk.collect.maps.MapPoint object MappableItemsParser { fun parseChoices( choices: List, - options: Options, - translator: (SelectChoice) -> String + options: Options = Options(), + translator: (SelectChoice) -> String = { it.value } ): List { return choices.mapIndexedNotNull { index, selectChoice -> val geometry = selectChoice.getChild(GEOMETRY) @@ -40,46 +41,27 @@ object MappableItemsParser { } if (points.size == 1) { - val markerColor = - getPropertyValue(selectChoice, MARKER_COLOR) - val markerSymbol = - getPropertyValue(selectChoice, MARKER_SYMBOL) - - MappableItem.Point( - index.toLong(), - translator(selectChoice), - properties, - point = points[0], - smallIcon = if (markerSymbol.isNullOrBlank()) R.drawable.ic_map_marker_with_hole_small else R.drawable.ic_map_marker_small, - largeIcon = if (markerSymbol.isNullOrBlank()) R.drawable.ic_map_marker_with_hole_big else R.drawable.ic_map_marker_big, - color = markerColor ?: options.color, - symbol = markerSymbol, - action = options.action - ) - } else if (points.first() != points.last()) { - MappableItem.Line( - index.toLong(), - translator(selectChoice), - properties, - points = points, - strokeWidth = getPropertyValue(selectChoice, STROKE_WIDTH), - strokeColor = getPropertyValue(selectChoice, STROKE) - ?: options.color, - action = options.action - ) + parsePoint(selectChoice, index, translator, properties, points, options) } else { - MappableItem.Polygon( - index.toLong(), - translator(selectChoice), - properties, - points = points, - strokeWidth = getPropertyValue(selectChoice, STROKE_WIDTH), - strokeColor = getPropertyValue(selectChoice, STROKE) - ?: options.color, - fillColor = getPropertyValue(selectChoice, FILL) - ?: options.color, - action = options.action - ) + if (points.first() != points.last()) { + parsePolygon( + selectChoice, + index, + translator, + properties, + points, + options + ) + } else { + parseLine( + selectChoice, + index, + translator, + properties, + points, + options + ) + } } } else { null @@ -93,6 +75,74 @@ object MappableItemsParser { } } + private fun parseLine( + selectChoice: SelectChoice, + index: Int, + translator: (SelectChoice) -> String, + properties: List, + points: List, + options: Options + ): MappableItem.Polygon { + val strokeColor = getPropertyValue(selectChoice, STROKE) + val fillColor = getPropertyValue(selectChoice, FILL) + return MappableItem.Polygon( + index.toLong(), + translator(selectChoice), + properties, + points = points, + strokeWidth = getPropertyValue(selectChoice, STROKE_WIDTH), + strokeColor = if (!strokeColor.isNullOrBlank()) strokeColor else options.color, + fillColor = if (!fillColor.isNullOrBlank()) fillColor else options.color, + action = options.action + ) + } + + private fun parsePolygon( + selectChoice: SelectChoice, + index: Int, + translator: (SelectChoice) -> String, + properties: List, + points: List, + options: Options + ): MappableItem.Line { + val strokeColor = getPropertyValue(selectChoice, STROKE) + return MappableItem.Line( + index.toLong(), + translator(selectChoice), + properties, + points = points, + strokeWidth = getPropertyValue(selectChoice, STROKE_WIDTH), + strokeColor = if (!strokeColor.isNullOrBlank()) strokeColor else options.color, + action = options.action + ) + } + + private fun parsePoint( + selectChoice: SelectChoice, + index: Int, + translator: (SelectChoice) -> String, + properties: List, + points: List, + options: Options + ): MappableItem.Point { + val markerColor = + getPropertyValue(selectChoice, MARKER_COLOR) + val markerSymbol = + getPropertyValue(selectChoice, MARKER_SYMBOL) + + return MappableItem.Point( + index.toLong(), + translator(selectChoice), + properties, + point = points[0], + smallIcon = if (markerSymbol.isNullOrBlank()) R.drawable.ic_map_marker_with_hole_small else R.drawable.ic_map_marker_small, + largeIcon = if (markerSymbol.isNullOrBlank()) R.drawable.ic_map_marker_with_hole_big else R.drawable.ic_map_marker_big, + color = if (!markerColor.isNullOrBlank()) markerColor else options.color, + symbol = markerSymbol, + action = options.action + ) + } + private fun getPropertyValue(selectChoice: SelectChoice, propertyName: String): String? { return selectChoice.additionalChildren.firstOrNull { it.first == propertyName }?.second } diff --git a/collect_app/src/test/java/org/odk/collect/android/widgets/items/MappableItemsParserTest.kt b/collect_app/src/test/java/org/odk/collect/android/widgets/items/MappableItemsParserTest.kt new file mode 100644 index 00000000000..99bf2467aef --- /dev/null +++ b/collect_app/src/test/java/org/odk/collect/android/widgets/items/MappableItemsParserTest.kt @@ -0,0 +1,95 @@ +package org.odk.collect.android.widgets.items + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.Test +import org.odk.collect.android.widgets.support.FormElementFixtures.selectChoice +import org.odk.collect.android.widgets.support.FormElementFixtures.treeElement +import org.odk.collect.geo.items.MappableItem + +class MappableItemsParserTest { + + @Test + fun `uses Options color when point marker color is blank`() { + val choices = listOf( + selectChoice( + value = "a", + item = treeElement( + children = listOf( + treeElement(GeoSelectChoiceElements.GEOMETRY, "1.0 -1.0 0 0"), + treeElement(GeoSelectChoiceElements.MARKER_COLOR, "") + ) + ) + ) + ) + + val mappableItems = MappableItemsParser.parseChoices( + choices, + MappableItemsParser.Options(color = "#ffffff") + ) + assertThat((mappableItems[0] as MappableItem.Point).color, equalTo("#ffffff")) + } + + @Test + fun `uses Options color when line stroke is blank`() { + val choices = listOf( + selectChoice( + value = "a", + item = treeElement( + children = listOf( + treeElement(GeoSelectChoiceElements.GEOMETRY, "1.0 -1.0 0 0;2.0 -2.0 0 0"), + treeElement(GeoSelectChoiceElements.STROKE, "") + ) + ) + ) + ) + + val mappableItems = MappableItemsParser.parseChoices( + choices, + MappableItemsParser.Options(color = "#ffffff") + ) + assertThat((mappableItems[0] as MappableItem.Line).strokeColor, equalTo("#ffffff")) + } + + @Test + fun `uses Options color when polygon stroke is blank`() { + val choices = listOf( + selectChoice( + value = "a", + item = treeElement( + children = listOf( + treeElement(GeoSelectChoiceElements.GEOMETRY, "1.0 -1.0 0 0;1.0 -1.0 0 0"), + treeElement(GeoSelectChoiceElements.STROKE, "") + ) + ) + ) + ) + + val mappableItems = MappableItemsParser.parseChoices( + choices, + MappableItemsParser.Options(color = "#ffffff") + ) + assertThat((mappableItems[0] as MappableItem.Polygon).strokeColor, equalTo("#ffffff")) + } + + @Test + fun `uses Options color when polygon fill is blank`() { + val choices = listOf( + selectChoice( + value = "a", + item = treeElement( + children = listOf( + treeElement(GeoSelectChoiceElements.GEOMETRY, "1.0 -1.0 0 0;1.0 -1.0 0 0"), + treeElement(GeoSelectChoiceElements.FILL, "") + ) + ) + ) + ) + + val mappableItems = MappableItemsParser.parseChoices( + choices, + MappableItemsParser.Options(color = "#ffffff") + ) + assertThat((mappableItems[0] as MappableItem.Polygon).fillColor, equalTo("#ffffff")) + } +} \ No newline at end of file