Saving polylines to firebase in Kotlin? - firebase

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(this)
}
#SuppressLint("MissingPermission", "PotentialBehaviorOverride")
override fun onMapReady(googleMap: GoogleMap?) {
map = googleMap!!
map.isMyLocationEnabled = true
map.setOnMyLocationButtonClickListener(this)
map.setOnMarkerClickListener(this)
map.uiSettings.apply {
isZoomControlsEnabled = false
isZoomGesturesEnabled = false
isRotateGesturesEnabled = false
isTiltGesturesEnabled = false
isCompassEnabled = false
isScrollGesturesEnabled = false
}
observeTrackerService()
}
private fun observeTrackerService() {
TrackerService.locationList.observe(viewLifecycleOwner, {
if (it != null) {
locationList = it
if (locationList.size > 1) {
binding.stopButton.enable()
}
drawPolyline()
followPolyline()
}
})
TrackerService.started.observe(viewLifecycleOwner, {
started.value = it
})
TrackerService.startTime.observe(viewLifecycleOwner, {
startTime = it
})
TrackerService.stopTime.observe(viewLifecycleOwner, {
stopTime = it
if (stopTime != 0L) {
showBiggerPicture()
displayResults()
}
})
}
private fun drawPolyline() {
val polyline = map.addPolyline(
PolylineOptions().apply {
width(10f)
color(Color.BLUE)
jointType(JointType.ROUND)
startCap(ButtCap())
endCap(ButtCap())
addAll(locationList)
}
)
polylineList.add(polyline)
}
private fun followPolyline() {
if (locationList.isNotEmpty()) {
map.animateCamera(
(CameraUpdateFactory.newCameraPosition(
setCameraPosition(
locationList.last()
)
)), 1000, null)
}
}
}
private fun showBiggerPicture() {
val bounds = LatLngBounds.Builder()
for (location in locationList) {
bounds.include(location)
}
map.animateCamera(
CameraUpdateFactory.newLatLngBounds(
bounds.build(), 100
), 2000, null
)
addMarker(locationList.first())
addMarker(locationList.last())
}
private fun addMarker(position: LatLng){
val marker = map.addMarker(MarkerOptions().position(position))
markerList.add(marker)
}
private fun displayResults() {
val result = Result(
calculateTheDistance(locationList),
calculateElapsedTime(startTime, stopTime)
)
lifecycleScope.launch {
delay(2500)
val directions = MapsFragmentDirections.actionMapsFragmentToResultFragment(result)
findNavController().navigate(directions)
binding.startButton.apply {
hide()
enable()
}
binding.stopButton.hide()
binding.resetButton.show()
} `
I would like to send the polylines to Firestore. How to send the polylines in code to Firestore? Can anyone help? My code has a map fragment with buttons. This is a distance tracking app. The app plots the distance using polylines. How to convert polylines to arrays. Here I am doing a location tracking app. I want to convert the polylines to arrays so that I could save it cloud.

According to the official documentation, a Polyline is not a Firestore supported data-type. So there is no way you can add such an object to Firestore.
What's a polyline?
It's basically a list of points. So what you can do instead is to add all these points to Firestore. You can add them as simple as latitude and longitude or as GeoPoint objects. If you have additional details for the locations, you can add them as documents in a collection, otherwise, you can store them in an array within a document.
To read them, simply create a reference to the document, loop through the array, create a new LatLng object of each location, and add all of them to the polyline.

Related

Adding document İD to firebase document as a field

I have a model with default values. My app gets the data from user through EditTexts and add them to Firebase Firestore. I hava an addData function (in AddAnalyzeActivity) and savefunction (in AddAnalyzeViewModel) for this operation. I'm getting EditText entries in AddAnalyzeActivity and adding them to my model but on this step ı want to add document id to my model but I can't access the documentIds properly in AddAnalyzeActivity. I can only access them with a forEach method when I try to retrieving the mentioned data with retrieveData function (in PairDetailVM) from Firestore but If I try to add document Ids in retrieveData method it only adds default value of documentId.
What I tried to:
Using #DocumentId annotation in my model.
Setting null default value of documentId in my model.
Getting a list of all documents' ids but can't match them with actual items.
Here is the screenShot for logic:
AnalyzeModel:
data class AnalyzeModel(
var concept: String?="",
var reason: String?="",
var result: String?="",
var rrRatio: Double?=0.0,
var tarih: Timestamp=Timestamp.now(),
var tradingViewUrl: String="",
var id : String="")
addData :
fun addData(view: View) {
val tarih = com.google.firebase.Timestamp.now()
val rr = rrText.text.toString()
var doubleRR = rr.toDoubleOrNull()
if (doubleRR == null) { doubleRR = 0.0 }
val analyzeDTO = AnalyzeModel(
conceptText.text.toString(),
reasonForText.text.toString(),
resultAddingText.text.toString(),
doubleRR,
tarih,
chartImage.text.toString()
)
viewModel.save(analyzeDTO)
val intent = Intent(this, PairDetailActivity::class.java)
startActivity(intent)
finish()
}
save :
fun save(data: AnalyzeModel) {
database.collection(dbCollection!!).document("Specified").collection("Pairs")
.document(chosenPair!!)
.collection("Analysis")
.add(data)
.addOnFailureListener { exception ->
exception.printStackTrace()
Toast.makeText(getApplication(), exception.localizedMessage, Toast.LENGTH_LONG).show()
}
}
retrieveData:
private fun retrieveData() {
val docRef = collectionRef.orderBy("tarih", Query.Direction.DESCENDING)
docRef.addSnapshotListener { value, error ->
try {
if (value != null && !value.isEmpty) {
val allAnalysis= ArrayList<AnalyzeModel>()
val documents = value.documents
documents.forEach {
val analyze = it.toObject(AnalyzeModel::class.java)
if (analyze!=null){
allAnalysis.add(analyze)
}
}
list.value = allAnalysis
} else if (error != null) {
Toast.makeText(Application(), error.localizedMessage, Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
If you want to save the document ID into the document itself, consider separating the creation of the new DocumentReference from writing to it, by using set instead of add.
fun save(data: AnalyzeModel) {
val newRef = database.collection(dbCollection!!).document("Specified").collection("Pairs")
.document(chosenPair!!)
.collection("Analysis")
.document() // 👈 generates a new reference with a unique ID
data.id = newRef.id // 👈 set the ID into your object
newRef.set(data) // 👈 writes the data to the new reference
.addOnFailureListener { exception ->
exception.printStackTrace()
Toast.makeText(getApplication(), exception.localizedMessage, Toast.LENGTH_LONG).show()
}
}
Also see the second snippet in the documentation on adding a document

How to retrieve data from firestore when the barcode reader scans the barcode

Based on : https://github.com/yuriy-budiyev/code-scanner
I would like to retrieve the data from firestore class when the barcode reader scans the barcode but I don't know how to do it. And also i want to proceed to the other page after scanned the barcode. Please help me to solve to it. Here is my code :
private fun codeScanner() {
codeScanner = CodeScanner(this, scanner_view)
codeScanner.apply {
camera = CodeScanner.CAMERA_BACK
formats = CodeScanner.ONE_DIMENSIONAL_FORMATS
autoFocusMode = AutoFocusMode.SAFE
isAutoFocusEnabled = true
isFlashEnabled = false
decodeCallback = DecodeCallback {
runOnUiThread {
tv_textView.text=it.text
}
}
errorCallback = ErrorCallback {
runOnUiThread {
Log.e("Scan", "Camera initialization error: ${it.message}")
}
}
}
scanner_view.setOnClickListener {
codeScanner.startPreview()
}
}
Here's how my data in firestore looks like:
Firestore

How to make a search field to insert the result in a LazyColumn

How to make a search field to insert the result in a LazyColumn
My code:
#Composable
private fun SearchTopBar(){
TopAppBar(title={ },
navigationIcon = {
IconButton(onClick = { onBackPressed() }) {
Icon(imageVector = Icons.Default.ArrowBack, contentDescription = stringResource(
id = R.string.back
),tint= colorResource(id = R.color.black) )
}
},
contentColor = Color.White,
backgroundColor = colorResource(id = R.color.pastel_green),
actions = {
TextField()
}
)
}
#Composable
private fun Main(){
Scaffold(topBar={SearchTopBar()},content={})
}
Dynamically change the content the search that comes from the api
I would introduce a ViewModel with two states:
val query: StateFlow<String>
val items: StateFlow<T>
Then use the stateHoisting pattern with the value, onValueChanged to modify your query.
Your items should observe your query in the viewModel and update the items.
And you could again observe the result items in your Composable with viewModel.items.collectAsState()
See this example for more information

HERE-SDK lite drag marker in MapView

I am just trying out the SDK Lite API and I am wondering how I can achieve to drag a MapMarker object from one place to another. I suggest, it works somehow with disabling the default onPan gesture, but actually the problem starts with picking an existing object.
Here is my code so far:
public void pickMarker(Point2D p) {
map.getGestures().disableDefaultAction(GestureType.PAN);
map.pickMapItems(p, 20f, pickMapItemsResult -> {
if (pickMapItemsResult != null) {
pickedMarker = pickMapItemsResult.getTopmostMarker();
} else {
map.getGestures().enableDefaultAction(GestureType.PAN);
}
});
}
public void dragMarker(Point2D p) {
if (pickedMarker != null) {
pickedMarker.setCoordinates(map.getCamera().viewToGeoCoordinates(p));
}
}
public boolean releaseMarker(Point2D p) {
map.getGestures().enableDefaultAction(GestureType.PAN);
if (pickedMarker != null) {
GeoCoordinates newCoordinates = map.getCamera().viewToGeoCoordinates(p);
pickedMarker.setCoordinates(newCoordinates);
pickedMarker = null;
return true;
}
return false;
}
while these functions are called on the three states of the onPanListener:
mapView.getGestures().setPanListener((gestureState, point2D, point2DUpdate, v) -> {
if (gestureState.equals(GestureState.BEGIN)) {
mapViewUIEngine.pickMarker(point2D);
}
if (gestureState.equals(GestureState.UPDATE)) {
mapViewUIEngine.dragMarker(point2DUpdate);
}
if (gestureState.equals(GestureState.END)) {
if (mapViewUIEngine.releaseMarker(point2DUpdate)) {
regionController.movePoint(0,
updateNewLocation(point2D, point2DUpdate);
}
}
});
From one of the developer in Github I now know, that the polygon is returned instead of the marker (which is lying on a polygon line, but how can I get the marker instead?
You can use map markers to precisely point to a location on the map.
The following method will add a custom map marker to the map:
MapImage mapImage = MapImageFactory.fromResource(context.getResources(), R.drawable.here_car);
MapMarker mapMarker = new MapMarker(geoCoordinates);
mapMarker.addImage(mapImage, new MapMarkerImageStyle());
mapView.getMapScene().addMapMarker(mapMarker);
For more details, please refer
https://developer.here.com/documentation/android-sdk/dev_guide/topics/map-items.html#add-map-markers

kotlin Assign the result of this transformation to a variables

Hi I am working with the next code:
private fun getAttributesMap(navMenu: NavItem?): AttributesMap {
var attributesString = navMenu?.attributes
val attributesMap = mutableMapOf<String, String>()
attributesString?.lines()?.map {
val pair = it.split("=")
if (pair?.size == 2) {
attributesMap.put(pair[0], pair[1])
}
}
return AttributesMap(attributesMap)
}
But according with the documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html
I should be able to assign the result of this transformation to attributesMap. Any clues about how it will be with the kotlin .map approach?
Thanks!!
A combination of map and filter will work:
val attributesMap = attributesString.lines()
.map { it.split("=") }
.filter { it.size == 2 } //filter all with more or less elements
.map { it[0] to it[1] } //convert to Pair
.toMap() //convert to Map

Resources