symbole angepasst
unused fun gelöscht
This commit is contained in:
@@ -26,7 +26,7 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
setContent {
|
||||
SnapAndSolveTheme {
|
||||
MainScreen(application=application)
|
||||
MainScreen(application=application, context=this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import DamageFilterDialog
|
||||
import DamageListDialog
|
||||
import MapViewModel
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
@@ -37,12 +38,12 @@ import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@Composable
|
||||
fun MainScreen(modifier: Modifier = Modifier, application: Application) {
|
||||
fun MainScreen(modifier: Modifier = Modifier, application: Application, context: Context) {
|
||||
var showReport by rememberSaveable { mutableStateOf(false) }
|
||||
var sliderOpen by rememberSaveable { mutableStateOf(false) }
|
||||
var showSettings by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
val mapViewModel = remember { MapViewModel(application) }
|
||||
val mapViewModel = remember { MapViewModel(application, context) }
|
||||
val albumViewModel = remember { AlbumViewModel(Dispatchers.Default) }
|
||||
|
||||
fun openReport() {
|
||||
@@ -196,19 +197,16 @@ fun ContentScreen(
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(bottom = 12.dp)
|
||||
)
|
||||
|
||||
SliderMenuItem(
|
||||
text = "Einstellungen",
|
||||
icon = Icons.Default.Settings,
|
||||
onClick = onOpenSettings
|
||||
)
|
||||
|
||||
SliderMenuItem(
|
||||
text = "Schäden filtern",
|
||||
icon = Icons.Default.FilterAlt,
|
||||
onClick = { showFilterDialog = true }
|
||||
)
|
||||
|
||||
SliderMenuItem(
|
||||
text = "Schadensliste",
|
||||
icon = Icons.Default.FormatListNumbered,
|
||||
@@ -233,24 +231,3 @@ fun AppTopBar(
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
suspend fun loadFirstAttachmentBitmap(
|
||||
feature: ArcGISFeature
|
||||
): ImageBitmap? {
|
||||
|
||||
// Feature muss geladen sein
|
||||
feature.load().getOrThrow()
|
||||
|
||||
// Attachments abrufen
|
||||
val attachments = feature.fetchAttachments().getOrThrow()
|
||||
|
||||
val first = attachments.firstOrNull() ?: return null
|
||||
|
||||
// Attachment-Daten laden
|
||||
val data = first.fetchData().getOrThrow()
|
||||
|
||||
val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
|
||||
return bitmap.asImageBitmap()
|
||||
}
|
||||
*/
|
||||
@@ -1,4 +1,5 @@
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -35,7 +36,7 @@ import java.io.ByteArrayOutputStream
|
||||
|
||||
|
||||
|
||||
class MapViewModel(application: Application) : AndroidViewModel(application) {
|
||||
class MapViewModel(application: Application, context: Context) : AndroidViewModel(application) {
|
||||
|
||||
companion object {
|
||||
// Zentrale Definition der Schadenstypen
|
||||
@@ -99,7 +100,7 @@ class MapViewModel(application: Application) : AndroidViewModel(application) {
|
||||
println("DEBUG: Fehler beim Laden der Tabelle: ${it.message}")
|
||||
}
|
||||
featureLayer = FeatureLayer.createWithFeatureTable(serviceFeatureTable)
|
||||
featureLayer.renderer = createTypStatusRenderer()
|
||||
featureLayer.renderer = createTypStatusRenderer(context)
|
||||
map.operationalLayers.add(featureLayer)
|
||||
|
||||
// ===== DEBUG: Felder nach dem Hinzufügen zur Map =====
|
||||
@@ -219,27 +220,9 @@ class MapViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
when (selectedOperation) {
|
||||
FeatureOperationType.DEFAULT -> selectFeatureAt(singleTapConfirmedEvent.screenCoordinate)
|
||||
FeatureOperationType.DELETE -> deleteFeatureAt(singleTapConfirmedEvent.screenCoordinate)
|
||||
FeatureOperationType.UPDATE_ATTRIBUTE -> selectFeatureForAttributeEditAt(singleTapConfirmedEvent.screenCoordinate)
|
||||
FeatureOperationType.UPDATE_GEOMETRY -> updateFeatureGeometryAt(singleTapConfirmedEvent.screenCoordinate)
|
||||
FeatureOperationType.PICK_REPORT_LOCATION -> pickReportLocation(singleTapConfirmedEvent.screenCoordinate)
|
||||
// RATE_FEATURE wird nicht mehr gebraucht - wird im DEFAULT mit behandelt!
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteFeatureAt(screenCoordinate: ScreenCoordinate) {
|
||||
featureLayer?.let { featureLayer ->
|
||||
// Clear any existing selection.
|
||||
featureLayer.clearSelection()
|
||||
selectedFeature = null
|
||||
viewModelScope.launch {
|
||||
// Determine if a user tapped on a feature.
|
||||
mapViewProxy.identify(featureLayer, screenCoordinate, 10.dp).onSuccess { identifyResult ->
|
||||
selectedFeature = (identifyResult.geoElements.firstOrNull() as? ArcGISFeature)?.also {
|
||||
featureLayer.selectFeature(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,7 +414,6 @@ class MapViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
enum class FeatureOperationType(val operationName: String, val instruction: String) {
|
||||
DEFAULT("Default", ""),
|
||||
DELETE("Delete feature", "Select an existing feature to delete it."),
|
||||
UPDATE_ATTRIBUTE("Update attribute", "Select an existing feature to edit its attribute."),
|
||||
UPDATE_GEOMETRY("Update geometry", "Select an existing feature and tap the map to move it to a new position."),
|
||||
PICK_REPORT_LOCATION("Pick report location", "Tippe auf die Karte, um die Position zu setzen."),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import MapViewModel
|
||||
import MapViewModel.Companion.DAMAGE_TYPES
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@@ -148,14 +147,7 @@ fun DamageFilterDialog(
|
||||
selectedFilters - type
|
||||
}
|
||||
},
|
||||
emoji = when (type) {
|
||||
"Straße" -> "🛣️"
|
||||
"Gehweg" -> "🚶"
|
||||
"Fahrradweg" -> "🚴"
|
||||
"Beleuchtung" -> "💡"
|
||||
"Sonstiges" -> "📍"
|
||||
else -> "•"
|
||||
}
|
||||
emoji = getEmojiForType(type)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -645,11 +645,11 @@ fun formatDistance(meters: Double?): String {
|
||||
|
||||
fun getEmojiForType(typ: String): String {
|
||||
return when (typ) {
|
||||
"Straße" -> "🛣️"
|
||||
"Gehweg" -> "🚶"
|
||||
"Fahrradweg" -> "🚴"
|
||||
"Beleuchtung" -> "💡"
|
||||
"Sonstiges" -> "📍"
|
||||
"Straße" -> String(Character.toChars(0x1F6E3))
|
||||
"Gehweg" -> String(Character.toChars(0x1F6B5))
|
||||
"Fahrradweg" -> String(Character.toChars(0x1F6B2))
|
||||
"Beleuchtung" -> String(Character.toChars(0x1F4A1))
|
||||
"Sonstiges" -> String(Character.toChars(0x1F4CC))
|
||||
else -> "•"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,108 @@
|
||||
package com.example.snapandsolve.view
|
||||
|
||||
import android.content.Context
|
||||
import com.arcgismaps.Color
|
||||
import com.arcgismaps.mapping.symbology.*
|
||||
import kotlin.collections.iterator
|
||||
import com.example.snapandsolve.R
|
||||
|
||||
fun createTypStatusRenderer(): UniqueValueRenderer {
|
||||
|
||||
// Status -> Hintergrundfarbe
|
||||
val statusColor = mapOf(
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
fun makeStatusTypeSymbol(
|
||||
context: Context,
|
||||
foregroundDrawableRes: Int,
|
||||
statusColor: Color
|
||||
): Symbol {
|
||||
val white = Color.fromRgba(255, 255, 255, 255)
|
||||
|
||||
// Hintergrund: weißer Kreis + Outline in Statusfarbe
|
||||
val background = SimpleMarkerSymbol(
|
||||
style = SimpleMarkerSymbolStyle.Circle,
|
||||
color = white,
|
||||
size = 20f
|
||||
).apply {
|
||||
outline = SimpleLineSymbol(
|
||||
style = SimpleLineSymbolStyle.Solid,
|
||||
color = statusColor,
|
||||
width = 2.5f
|
||||
)
|
||||
}
|
||||
|
||||
// Drawable aus Ressourcen laden
|
||||
val drawable = ContextCompat.getDrawable(context, foregroundDrawableRes)
|
||||
?: throw IllegalArgumentException("Drawable resource not found: $foregroundDrawableRes")
|
||||
|
||||
// Drawable zu Bitmap konvertieren
|
||||
val bitmap = drawableToBitmap(drawable)
|
||||
|
||||
// Bitmap zu BitmapDrawable konvertieren
|
||||
val bitmapDrawable = BitmapDrawable(context.resources, bitmap)
|
||||
|
||||
// Vordergrund: BitmapDrawable als PictureMarkerSymbol
|
||||
val foreground = PictureMarkerSymbol.createWithImage(bitmapDrawable).apply {
|
||||
width = 16f
|
||||
height = 16f
|
||||
}
|
||||
|
||||
return CompositeSymbol(listOf(background, foreground))
|
||||
}
|
||||
|
||||
// Hilfsfunktion: Drawable zu Bitmap konvertieren
|
||||
private fun drawableToBitmap(drawable: Drawable): Bitmap {
|
||||
if (drawable is BitmapDrawable) {
|
||||
return drawable.bitmap
|
||||
}
|
||||
|
||||
// Für VectorDrawables und andere Drawable-Typen
|
||||
val bitmap = Bitmap.createBitmap(
|
||||
drawable.intrinsicWidth.takeIf { it > 0 } ?: 1,
|
||||
drawable.intrinsicHeight.takeIf { it > 0 } ?: 1,
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
|
||||
val canvas = Canvas(bitmap)
|
||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||
drawable.draw(canvas)
|
||||
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun createTypStatusRenderer(context: Context): UniqueValueRenderer {
|
||||
val statusColorByName = mapOf(
|
||||
"neu" to Color.fromRgba(220, 50, 50, 255),
|
||||
"in Bearbeitung" to Color.fromRgba(255, 180, 0, 255),
|
||||
"Schaden behoben" to Color.fromRgba(60, 180, 75, 255)
|
||||
)
|
||||
|
||||
// Typ -> Icon-Style (aus Standardbibliothek)
|
||||
val typeIcon = mapOf(
|
||||
"Straße" to SimpleMarkerSymbolStyle.Square,
|
||||
"Gehweg" to SimpleMarkerSymbolStyle.Triangle,
|
||||
"Fahrradweg" to SimpleMarkerSymbolStyle.Diamond,
|
||||
"Beleuchtung" to SimpleMarkerSymbolStyle.X,
|
||||
"Sonstiges" to SimpleMarkerSymbolStyle.Cross
|
||||
val typeIconRes = mapOf(
|
||||
"Straße" to R.drawable.motorway,
|
||||
"Gehweg" to R.drawable.pedestrian,
|
||||
"Fahrradweg" to R.drawable.bike,
|
||||
"Beleuchtung" to R.drawable.lightbulb,
|
||||
"Sonstiges" to R.drawable.pin
|
||||
)
|
||||
|
||||
val renderer = UniqueValueRenderer().apply {
|
||||
fieldNames.addAll(listOf("typ", "status"))
|
||||
|
||||
defaultLabel = "Sonstige"
|
||||
defaultSymbol = makeStatusTypeSymbol(
|
||||
iconStyle = SimpleMarkerSymbolStyle.Circle,
|
||||
backgroundFill = Color.fromRgba(180, 180, 180, 255)
|
||||
)
|
||||
}
|
||||
|
||||
for ((typ, iconStyle) in typeIcon) {
|
||||
for ((status, bgColor) in statusColor) {
|
||||
for ((typ, iconRes) in typeIconRes) {
|
||||
for ((status, outlineColor) in statusColorByName) {
|
||||
val label = "$typ • $status"
|
||||
|
||||
renderer.uniqueValues.add(
|
||||
UniqueValue(
|
||||
label = label,
|
||||
description = label,
|
||||
symbol = makeStatusTypeSymbol(iconStyle, bgColor),
|
||||
symbol = makeStatusTypeSymbol(
|
||||
context = context,
|
||||
foregroundDrawableRes = iconRes,
|
||||
statusColor = outlineColor
|
||||
),
|
||||
values = listOf(typ, status)
|
||||
)
|
||||
)
|
||||
@@ -49,38 +112,3 @@ fun createTypStatusRenderer(): UniqueValueRenderer {
|
||||
return renderer
|
||||
}
|
||||
|
||||
fun makeStatusTypeSymbol(
|
||||
iconStyle: SimpleMarkerSymbolStyle,
|
||||
backgroundFill: Color
|
||||
): Symbol {
|
||||
val white = Color.fromRgba(255, 255, 255, 255)
|
||||
|
||||
// Hintergrund: Kreis in Statusfarbe
|
||||
val background = SimpleMarkerSymbol(
|
||||
style = SimpleMarkerSymbolStyle.Circle,
|
||||
color = backgroundFill,
|
||||
size = 18f
|
||||
).apply {
|
||||
outline = SimpleLineSymbol(
|
||||
style = SimpleLineSymbolStyle.Solid,
|
||||
color = white,
|
||||
width = 1.5f
|
||||
)
|
||||
}
|
||||
|
||||
// Vordergrund: "Icon" als Outline (weiß), ohne Füllung
|
||||
val foreground = SimpleMarkerSymbol(
|
||||
style = iconStyle,
|
||||
color = Color.fromRgba(0, 0, 0, 0), // transparent => nur Outline sichtbar
|
||||
size = 10f
|
||||
).apply {
|
||||
outline = SimpleLineSymbol(
|
||||
style = SimpleLineSymbolStyle.Solid,
|
||||
color = white,
|
||||
width = 2.0f
|
||||
)
|
||||
}
|
||||
|
||||
return CompositeSymbol(listOf(background, foreground))
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ suspend fun findNearbyDamageOfSameType(
|
||||
for (feature in result) {
|
||||
val p = feature.geometry as? Point ?: continue
|
||||
|
||||
// ✅ Distanz korrekt
|
||||
val dist = GeometryEngine.distanceOrNull(pointInLayerSR, p) ?: Double.POSITIVE_INFINITY
|
||||
|
||||
val typ = (feature.attributes["typ"] as? String).orEmpty()
|
||||
|
||||
BIN
app/src/main/res/drawable/bike.png
Normal file
BIN
app/src/main/res/drawable/bike.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable/lightbulb.png
Normal file
BIN
app/src/main/res/drawable/lightbulb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
BIN
app/src/main/res/drawable/motorway.png
Normal file
BIN
app/src/main/res/drawable/motorway.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
BIN
app/src/main/res/drawable/pedestrian.png
Normal file
BIN
app/src/main/res/drawable/pedestrian.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/drawable/pin.png
Normal file
BIN
app/src/main/res/drawable/pin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Reference in New Issue
Block a user