From 9a75af40451e5f2e483bf079718029c2edc58234 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 14 May 2020 00:43:32 -0700 Subject: [PATCH] Ensure consistency of longitude/latitude order and add a button to set boundary in collar details. --- .../fencelessgrazing/model/CollarDetails.kt | 3 ++- .../fencelessgrazing/model/CollarPos.kt | 5 ++++- .../ui/activities/BoundaryEditorActivity.kt | 4 +--- .../ui/activities/CollarDetailActivity.kt | 17 +++++++++++++++-- .../ui/activities/CollarListActivity.kt | 4 ++-- .../main/res/layout/activity_collar_detail.xml | 13 +++++++++++-- app/src/main/res/values/strings.xml | 3 +++ 7 files changed, 38 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarDetails.kt b/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarDetails.kt index ae6d6d5..695cf81 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarDetails.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarDetails.kt @@ -6,5 +6,6 @@ package com.danilafe.fencelessgrazing.model * @param id the collar's internal unique identifier. * @param name the collar's current designation in the system. * @param stimulus the number of stimulus activation reports in the last 24 hours. + * @param boundary the collar's current valid grazing boundary. */ -data class CollarDetails(val id: Int, val name: String, val stimulus: Int) \ No newline at end of file +data class CollarDetails(val id: Int, val name: String, val stimulus: Int, val boundary: List) \ No newline at end of file diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarPos.kt b/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarPos.kt index d0eb965..f4ba802 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarPos.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/model/CollarPos.kt @@ -2,6 +2,7 @@ package com.danilafe.fencelessgrazing.model import android.os.Parcelable import kotlinx.android.parcel.Parcelize +import org.osmdroid.util.GeoPoint /** * GPS coordinate returned by many of the project's API endpoints. @@ -10,5 +11,7 @@ import kotlinx.android.parcel.Parcelize * @param latitude the latitude of the GPS point. */ @Parcelize -data class CollarPos(val longitude: String, val latitude: String) : Parcelable +data class CollarPos(val longitude: String, val latitude: String) : Parcelable { + fun toGeoPoint(): GeoPoint = GeoPoint(latitude.toDouble(), longitude.toDouble()) +} diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/BoundaryEditorActivity.kt b/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/BoundaryEditorActivity.kt index 23f548f..4043ab7 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/BoundaryEditorActivity.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/BoundaryEditorActivity.kt @@ -34,9 +34,7 @@ class BoundaryEditorActivity : AppCompatActivity(), setContentView(R.layout.activity_boundary_editor) val requestedCenter = intent.getParcelableExtra("center")!! - center = GeoPoint( - requestedCenter.longitude.toDouble(), - requestedCenter.latitude.toDouble()) + center = requestedCenter.toGeoPoint() identifier = intent.getIntExtra("identifier", -1) queue = Volley.newRequestQueue(applicationContext) diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarDetailActivity.kt b/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarDetailActivity.kt index b4528f6..4042428 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarDetailActivity.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarDetailActivity.kt @@ -1,15 +1,18 @@ package com.danilafe.fencelessgrazing.ui.activities +import android.content.Intent import android.graphics.Color import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log +import android.view.View import android.widget.TextView import android.widget.Toast import com.android.volley.RequestQueue import com.android.volley.Response import com.android.volley.toolbox.Volley import com.danilafe.fencelessgrazing.R +import com.danilafe.fencelessgrazing.model.CollarPos import com.danilafe.fencelessgrazing.model.Polygon import com.danilafe.fencelessgrazing.requests.authenticated.CollarDetailRequest import com.danilafe.fencelessgrazing.requests.authenticated.CollarHistoryRequest @@ -174,7 +177,7 @@ class CollarDetailActivity : AppCompatActivity() { token, Response.Listener { dataPoints = - it.map { p -> GeoPoint(p.longitude.toDouble(), p.latitude.toDouble()) } + it.map { p -> p.toGeoPoint() } }, Response.ErrorListener { Toast.makeText(this, "Failed to retrieve history of collar", Toast.LENGTH_SHORT) @@ -199,6 +202,16 @@ class CollarDetailActivity : AppCompatActivity() { queue.add(detailRequest) } + fun changeGrazingBoundary(v : View) { + startActivity(Intent(this, BoundaryEditorActivity::class.java).apply { + val center = dataPoints.lastOrNull()?.let { + CollarPos(it.longitude.toString(), it.latitude.toString()) + } ?: CollarPos("0", "0") + putExtra("center", center) + putExtra("identifier", collarId) + }) + } + /** * Given a new location history of the animal, configures * updates the [map] to include the relevant elements (such as the animal's @@ -235,7 +248,7 @@ class CollarDetailActivity : AppCompatActivity() { */ private fun updateBoundingBox(oldValue: Polygon?, polygon: Polygon) { if(oldValue == null) map.overlays.add(mapPolygon) - val points = polygon.dataPoints.map { GeoPoint(it.latitude.toDouble(), it.longitude.toDouble()) } + val points = polygon.dataPoints.map { it.toGeoPoint() } val polygonPoints = points.toMutableList() polygonPoints.add(polygonPoints[0]) mapPolygon.points = polygonPoints diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarListActivity.kt b/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarListActivity.kt index 16e4f99..e168678 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarListActivity.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/ui/activities/CollarListActivity.kt @@ -196,7 +196,7 @@ class CollarListActivity : AppCompatActivity() { centerSet = true val averageLongitude = summaries.map { it.pos.longitude.toDouble() }.average() val averageLatitude = summaries.map { it.pos.latitude.toDouble() }.average() - map.controller.setCenter(GeoPoint(averageLongitude, averageLatitude)) + map.controller.setCenter(GeoPoint(averageLatitude, averageLongitude)) } /** @@ -208,7 +208,7 @@ class CollarListActivity : AppCompatActivity() { // Create or update overlay val overlay = collarOverlays[it.id] ?: Marker(map) overlay.title = it.name - overlay.position = GeoPoint(it.pos.longitude.toDouble(), it.pos.latitude.toDouble()) + overlay.position = it.pos.toGeoPoint() // Store new / existing overlay. if(!collarOverlays.containsKey(it.id)) map.overlays.add(overlay) diff --git a/app/src/main/res/layout/activity_collar_detail.xml b/app/src/main/res/layout/activity_collar_detail.xml index 8b91acb..a04d63d 100644 --- a/app/src/main/res/layout/activity_collar_detail.xml +++ b/app/src/main/res/layout/activity_collar_detail.xml @@ -29,9 +29,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="10dp" - android:layout_marginTop="10dp" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/collarName" /> + app:layout_constraintTop_toBottomOf="@+id/changeBoundaryButton" /> +