Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package org.groundplatform.android.ui.datacollection.tasks.point
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import org.groundplatform.android.ui.datacollection.tasks.AbstractTaskMapFragment
import org.groundplatform.android.ui.datacollection.tasks.launchWhenTaskVisible
import org.groundplatform.android.ui.map.Feature
Expand Down Expand Up @@ -50,7 +51,10 @@ class DropPinTaskMapFragment @Inject constructor() :
taskViewModel.updateCameraPosition(position)
}

override fun renderFeatures(): Flow<Set<Feature>> = taskViewModel.features
override fun renderFeatures(): Flow<Set<Feature>> =
combine(taskViewModel.features, taskViewModel.existingLoiFeatures) { pinFeatures, existing ->
pinFeatures + existing
}

override fun setDefaultViewPort() {
val feature = taskViewModel.features.value?.firstOrNull() ?: return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ package org.groundplatform.android.ui.datacollection.tasks.point
import androidx.lifecycle.viewModelScope
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.groundplatform.android.data.local.LocalValueStore
import org.groundplatform.android.data.uuid.OfflineUuidGenerator
Expand All @@ -32,22 +37,48 @@ import org.groundplatform.android.ui.map.Feature
import org.groundplatform.android.ui.util.getDefaultColor
import org.groundplatform.domain.model.geometry.Point
import org.groundplatform.domain.model.job.Job
import org.groundplatform.domain.model.locationofinterest.LocationOfInterest
import org.groundplatform.domain.model.submission.DropPinTaskData
import org.groundplatform.domain.model.submission.TaskData
import org.groundplatform.domain.model.submission.isNullOrEmpty
import org.groundplatform.domain.model.task.Task
import org.groundplatform.domain.repository.LocationOfInterestRepositoryInterface
import org.groundplatform.domain.repository.SurveyRepositoryInterface

class DropPinTaskViewModel
@Inject
constructor(
private val uuidGenerator: OfflineUuidGenerator,
private val localValueStore: LocalValueStore,
private val loiRepository: LocationOfInterestRepositoryInterface,
private val surveyRepository: SurveyRepositoryInterface,
) : AbstractMapTaskViewModel() {

private var pinColor: Int = 0
private val _features = MutableStateFlow<Set<Feature>>(emptySet())
val features: StateFlow<Set<Feature>> = _features.asStateFlow()

/**
* Features representing LOIs that already exist in the survey, shown as background context while
* the user drops a new pin.
*/
val existingLoiFeatures: StateFlow<Set<Feature>> =
surveyRepository.activeSurveyFlow
.filterNotNull()
.flatMapLatest { survey -> loiRepository.getValidLois(survey) }
.map { lois -> lois.map { loi -> loi.toExistingFeature() }.toSet() }
.stateIn(viewModelScope, WhileSubscribed(5_000), emptySet())

private fun LocationOfInterest.toExistingFeature(): Feature =
Feature(
id = id,
type = Feature.Type.LOCATION_OF_INTEREST,
geometry = geometry,
style = Feature.Style(job.getDefaultColor()),
clusterable = false,
selected = false,
)

Comment on lines +61 to +81

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of duplicating this both in DropPinTaskViewModel and DrawAreaTaskViewModel, this can be moved to BaseMapViewModel, which both fragments can later access with getMapViewModel()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also a good option.

/** Whether the instructions dialog has been shown or not. */
internal var instructionsDialogShown: Boolean by localValueStore::dropPinInstructionsShown

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.groundplatform.android.ui.datacollection.tasks.AbstractTaskMapFragment
Expand Down Expand Up @@ -66,8 +67,8 @@ class DrawAreaTaskMapFragment @Inject constructor() :
}

override fun renderFeatures(): Flow<Set<Feature>> =
taskViewModel.draftArea.map { feature: Feature? ->
if (feature == null) setOf() else setOf(feature)
combine(taskViewModel.draftArea, taskViewModel.existingLoiFeatures) { draft, existing ->
setOfNotNull(draft) + existing
}

override fun onMapCameraMoved(position: CameraPosition) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
Expand All @@ -50,11 +53,14 @@ import org.groundplatform.domain.model.geometry.LineString
import org.groundplatform.domain.model.geometry.LinearRing
import org.groundplatform.domain.model.geometry.Polygon
import org.groundplatform.domain.model.job.Job
import org.groundplatform.domain.model.locationofinterest.LocationOfInterest
import org.groundplatform.domain.model.settings.MeasurementUnits
import org.groundplatform.domain.model.submission.DrawAreaTaskData
import org.groundplatform.domain.model.submission.DrawAreaTaskIncompleteData
import org.groundplatform.domain.model.submission.TaskData
import org.groundplatform.domain.model.task.Task
import org.groundplatform.domain.repository.LocationOfInterestRepositoryInterface
import org.groundplatform.domain.repository.SurveyRepositoryInterface
import org.groundplatform.domain.usecases.user.GetUserSettingsUseCase
import org.groundplatform.domain.util.calculateShoelacePolygonArea
import org.groundplatform.ui.util.getFormattedArea
Expand All @@ -73,12 +79,35 @@ internal constructor(
private val vibrationHelper: VibrationHelper,
private val localeAwareMeasureFormatter: LocaleAwareMeasureFormatter,
private val getUserSettingsUseCase: GetUserSettingsUseCase,
private val loiRepository: LocationOfInterestRepositoryInterface,
private val surveyRepository: SurveyRepositoryInterface,
) : AbstractMapTaskViewModel() {

/** Polygon [Feature] being drawn by the user. */
private val _draftArea: MutableStateFlow<Feature?> = MutableStateFlow(null)
val draftArea: StateFlow<Feature?> = _draftArea.asStateFlow()

/**
* Features representing LOIs that already exist in the survey, shown as background context while
* the user draws a new polygon.
*/
val existingLoiFeatures: StateFlow<Set<Feature>> =
surveyRepository.activeSurveyFlow
.filterNotNull()
.flatMapLatest { survey -> loiRepository.getValidLois(survey) }
.map { lois -> lois.map { loi -> loi.toExistingFeature() }.toSet() }
.stateIn(viewModelScope, WhileSubscribed(5_000), emptySet())

private fun LocationOfInterest.toExistingFeature(): Feature =
Feature(
id = id,
type = Feature.Type.LOCATION_OF_INTEREST,
geometry = geometry,
style = Feature.Style(job.getDefaultColor()),
clusterable = false,
selected = false,
)

/**
* Unique identifier for the currently active draft polygon or line being drawn.
*
Expand Down