From 743316d4210ea356bd03f2912ea2b10346ed72a5 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 5 Apr 2020 12:33:23 -0700 Subject: [PATCH] By default zoom map to show all nodes, with names and icons. --- .../main/java/com/geeksville/mesh/NodeInfo.kt | 12 +++-- .../main/java/com/geeksville/mesh/ui/Map.kt | 48 ++++++++++++------- .../com/geeksville/mesh/ui/NodeInfoCard.kt | 2 + 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/NodeInfo.kt b/app/src/main/java/com/geeksville/mesh/NodeInfo.kt index 60eab32ce..e6e5f236c 100644 --- a/app/src/main/java/com/geeksville/mesh/NodeInfo.kt +++ b/app/src/main/java/com/geeksville/mesh/NodeInfo.kt @@ -111,11 +111,17 @@ data class NodeInfo( return (now - lastSeen <= timeout) || lastSeen == 0 } + /// return the position if it is valid, else null + val validPosition: Position? + get() { + return position?.takeIf { it.latitude != 0.0 || it.longitude != 0.0 } + } + /// @return distance in meters to some other node (or null if unknown) fun distance(o: NodeInfo?): Int? { - val p = position - val op = o?.position - return if (p != null && op != null && p.latitude != 0.0 && op.longitude != 0.0) + val p = validPosition + val op = o?.validPosition + return if (p != null && op != null) p.distance(op).toInt() else null diff --git a/app/src/main/java/com/geeksville/mesh/ui/Map.kt b/app/src/main/java/com/geeksville/mesh/ui/Map.kt index d39f995b1..447c6984d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Map.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Map.kt @@ -17,16 +17,15 @@ import com.geeksville.mesh.model.UIState import com.mapbox.geojson.Feature import com.mapbox.geojson.FeatureCollection import com.mapbox.geojson.Point -import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.Style import com.mapbox.mapboxsdk.style.expressions.Expression import com.mapbox.mapboxsdk.style.layers.Property import com.mapbox.mapboxsdk.style.layers.Property.TEXT_ANCHOR_TOP import com.mapbox.mapboxsdk.style.layers.Property.TEXT_JUSTIFY_AUTO -import com.mapbox.mapboxsdk.style.layers.PropertyFactory import com.mapbox.mapboxsdk.style.layers.PropertyFactory.* import com.mapbox.mapboxsdk.style.layers.SymbolLayer import com.mapbox.mapboxsdk.style.sources.GeoJsonSource @@ -91,19 +90,21 @@ fun MapContent() { } // Find all nodes with valid locations - val locations = NodeDB.nodes.values.mapNotNull { node -> - val p = node.position - if (p != null && (p.latitude != 0.0 || p.longitude != 0.0)) { - val f = Feature.fromGeometry( - Point.fromLngLat( - p.longitude, - p.latitude - ) + val nodesWithPosition = NodeDB.nodes.values.filter { it.validPosition != null } + val locations = nodesWithPosition.map { node -> + val p = node.position!! + mapLog.debug("Showing on map: $node") + + val f = Feature.fromGeometry( + Point.fromLngLat( + p.longitude, + p.latitude ) - node.user?.let { f.addStringProperty("name", it.longName) } - f - } else - null + ) + node.user?.let { + f.addStringProperty("name", it.longName) + } + f } val nodeSourceId = "node-positions" val nodeLayerId = "node-layer" @@ -116,8 +117,9 @@ fun MapContent() { val markerIcon = context.getDrawable(R.drawable.ic_twotone_person_pin_24)!! val nodeLayer = SymbolLayer(nodeLayerId, nodeSourceId).withProperties( - PropertyFactory.iconImage(markerImageId), - PropertyFactory.iconAnchor(Property.ICON_ANCHOR_BOTTOM) + iconImage(markerImageId), + iconAnchor(Property.ICON_ANCHOR_BOTTOM), + iconAllowOverlap(true) ) val labelLayer = SymbolLayer(labelLayerId, nodeSourceId).withProperties( @@ -125,7 +127,8 @@ fun MapContent() { textSize(12f), textColor(Color.RED), textVariableAnchor(arrayOf(TEXT_ANCHOR_TOP)), - textJustify(TEXT_JUSTIFY_AUTO) + textJustify(TEXT_JUSTIFY_AUTO), + textAllowOverlap(true) ) AndroidView(R.layout.map_view) { view -> @@ -148,12 +151,21 @@ fun MapContent() { //map.uiSettings.isScrollGesturesEnabled = true //map.uiSettings.isZoomGesturesEnabled = true - // Center on the user's position (if we have it) + // Zoom in on our set of markers + /* old code jsut zooomed in on the user NodeDB.ourNodeInfo?.position?.let { val cameraPos = CameraPosition.Builder().target( LatLng(it.latitude, it.longitude) ).zoom(9.0).build() map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPos), 1000) + } */ + if (nodesWithPosition.isNotEmpty()) { + val bounds = LatLngBounds.Builder() + + // Add all positions + bounds.includes(nodesWithPosition.map { it.position!! } + .map { LatLng(it.latitude, it.longitude) }) + map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 100)) } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt b/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt index eccfc19f5..a30d3f0d1 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt @@ -67,6 +67,8 @@ fun NodeHeading(node: NodeInfo) { fun NodeInfoCard(node: NodeInfo) { // Text("Node: ${it.user?.longName}") Row(modifier = LayoutPadding(16.dp)) { + UILog.debug("showing NodeInfo $node") + UserIcon( modifier = LayoutPadding(start = 0.dp, top = 0.dp, end = 0.dp, bottom = 0.dp), user = node