symbole angepasst
unused fun gelöscht
This commit is contained in:
@@ -26,7 +26,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
SnapAndSolveTheme {
|
SnapAndSolveTheme {
|
||||||
MainScreen(application=application)
|
MainScreen(application=application, context=this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import DamageFilterDialog
|
|||||||
import DamageListDialog
|
import DamageListDialog
|
||||||
import MapViewModel
|
import MapViewModel
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
@@ -37,12 +38,12 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScreen(modifier: Modifier = Modifier, application: Application) {
|
fun MainScreen(modifier: Modifier = Modifier, application: Application, context: Context) {
|
||||||
var showReport by rememberSaveable { mutableStateOf(false) }
|
var showReport by rememberSaveable { mutableStateOf(false) }
|
||||||
var sliderOpen by rememberSaveable { mutableStateOf(false) }
|
var sliderOpen by rememberSaveable { mutableStateOf(false) }
|
||||||
var showSettings 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) }
|
val albumViewModel = remember { AlbumViewModel(Dispatchers.Default) }
|
||||||
|
|
||||||
fun openReport() {
|
fun openReport() {
|
||||||
@@ -196,19 +197,16 @@ fun ContentScreen(
|
|||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
modifier = Modifier.padding(bottom = 12.dp)
|
modifier = Modifier.padding(bottom = 12.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
SliderMenuItem(
|
SliderMenuItem(
|
||||||
text = "Einstellungen",
|
text = "Einstellungen",
|
||||||
icon = Icons.Default.Settings,
|
icon = Icons.Default.Settings,
|
||||||
onClick = onOpenSettings
|
onClick = onOpenSettings
|
||||||
)
|
)
|
||||||
|
|
||||||
SliderMenuItem(
|
SliderMenuItem(
|
||||||
text = "Schäden filtern",
|
text = "Schäden filtern",
|
||||||
icon = Icons.Default.FilterAlt,
|
icon = Icons.Default.FilterAlt,
|
||||||
onClick = { showFilterDialog = true }
|
onClick = { showFilterDialog = true }
|
||||||
)
|
)
|
||||||
|
|
||||||
SliderMenuItem(
|
SliderMenuItem(
|
||||||
text = "Schadensliste",
|
text = "Schadensliste",
|
||||||
icon = Icons.Default.FormatListNumbered,
|
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.app.Application
|
||||||
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
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 {
|
companion object {
|
||||||
// Zentrale Definition der Schadenstypen
|
// Zentrale Definition der Schadenstypen
|
||||||
@@ -99,7 +100,7 @@ class MapViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
println("DEBUG: Fehler beim Laden der Tabelle: ${it.message}")
|
println("DEBUG: Fehler beim Laden der Tabelle: ${it.message}")
|
||||||
}
|
}
|
||||||
featureLayer = FeatureLayer.createWithFeatureTable(serviceFeatureTable)
|
featureLayer = FeatureLayer.createWithFeatureTable(serviceFeatureTable)
|
||||||
featureLayer.renderer = createTypStatusRenderer()
|
featureLayer.renderer = createTypStatusRenderer(context)
|
||||||
map.operationalLayers.add(featureLayer)
|
map.operationalLayers.add(featureLayer)
|
||||||
|
|
||||||
// ===== DEBUG: Felder nach dem Hinzufügen zur Map =====
|
// ===== DEBUG: Felder nach dem Hinzufügen zur Map =====
|
||||||
@@ -219,27 +220,9 @@ class MapViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
|
|
||||||
when (selectedOperation) {
|
when (selectedOperation) {
|
||||||
FeatureOperationType.DEFAULT -> selectFeatureAt(singleTapConfirmedEvent.screenCoordinate)
|
FeatureOperationType.DEFAULT -> selectFeatureAt(singleTapConfirmedEvent.screenCoordinate)
|
||||||
FeatureOperationType.DELETE -> deleteFeatureAt(singleTapConfirmedEvent.screenCoordinate)
|
|
||||||
FeatureOperationType.UPDATE_ATTRIBUTE -> selectFeatureForAttributeEditAt(singleTapConfirmedEvent.screenCoordinate)
|
FeatureOperationType.UPDATE_ATTRIBUTE -> selectFeatureForAttributeEditAt(singleTapConfirmedEvent.screenCoordinate)
|
||||||
FeatureOperationType.UPDATE_GEOMETRY -> updateFeatureGeometryAt(singleTapConfirmedEvent.screenCoordinate)
|
FeatureOperationType.UPDATE_GEOMETRY -> updateFeatureGeometryAt(singleTapConfirmedEvent.screenCoordinate)
|
||||||
FeatureOperationType.PICK_REPORT_LOCATION -> pickReportLocation(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) {
|
enum class FeatureOperationType(val operationName: String, val instruction: String) {
|
||||||
DEFAULT("Default", ""),
|
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_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."),
|
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."),
|
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 MapViewModel.Companion.DAMAGE_TYPES
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
@@ -148,14 +147,7 @@ fun DamageFilterDialog(
|
|||||||
selectedFilters - type
|
selectedFilters - type
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emoji = when (type) {
|
emoji = getEmojiForType(type)
|
||||||
"Straße" -> "🛣️"
|
|
||||||
"Gehweg" -> "🚶"
|
|
||||||
"Fahrradweg" -> "🚴"
|
|
||||||
"Beleuchtung" -> "💡"
|
|
||||||
"Sonstiges" -> "📍"
|
|
||||||
else -> "•"
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -645,11 +645,11 @@ fun formatDistance(meters: Double?): String {
|
|||||||
|
|
||||||
fun getEmojiForType(typ: String): String {
|
fun getEmojiForType(typ: String): String {
|
||||||
return when (typ) {
|
return when (typ) {
|
||||||
"Straße" -> "🛣️"
|
"Straße" -> String(Character.toChars(0x1F6E3))
|
||||||
"Gehweg" -> "🚶"
|
"Gehweg" -> String(Character.toChars(0x1F6B5))
|
||||||
"Fahrradweg" -> "🚴"
|
"Fahrradweg" -> String(Character.toChars(0x1F6B2))
|
||||||
"Beleuchtung" -> "💡"
|
"Beleuchtung" -> String(Character.toChars(0x1F4A1))
|
||||||
"Sonstiges" -> "📍"
|
"Sonstiges" -> String(Character.toChars(0x1F4CC))
|
||||||
else -> "•"
|
else -> "•"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,108 @@
|
|||||||
package com.example.snapandsolve.view
|
package com.example.snapandsolve.view
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import com.arcgismaps.Color
|
import com.arcgismaps.Color
|
||||||
import com.arcgismaps.mapping.symbology.*
|
import com.arcgismaps.mapping.symbology.*
|
||||||
import kotlin.collections.iterator
|
import com.example.snapandsolve.R
|
||||||
|
|
||||||
fun createTypStatusRenderer(): UniqueValueRenderer {
|
|
||||||
|
|
||||||
// Status -> Hintergrundfarbe
|
import android.graphics.Bitmap
|
||||||
val statusColor = mapOf(
|
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),
|
"neu" to Color.fromRgba(220, 50, 50, 255),
|
||||||
"in Bearbeitung" to Color.fromRgba(255, 180, 0, 255),
|
"in Bearbeitung" to Color.fromRgba(255, 180, 0, 255),
|
||||||
"Schaden behoben" to Color.fromRgba(60, 180, 75, 255)
|
"Schaden behoben" to Color.fromRgba(60, 180, 75, 255)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Typ -> Icon-Style (aus Standardbibliothek)
|
val typeIconRes = mapOf(
|
||||||
val typeIcon = mapOf(
|
"Straße" to R.drawable.motorway,
|
||||||
"Straße" to SimpleMarkerSymbolStyle.Square,
|
"Gehweg" to R.drawable.pedestrian,
|
||||||
"Gehweg" to SimpleMarkerSymbolStyle.Triangle,
|
"Fahrradweg" to R.drawable.bike,
|
||||||
"Fahrradweg" to SimpleMarkerSymbolStyle.Diamond,
|
"Beleuchtung" to R.drawable.lightbulb,
|
||||||
"Beleuchtung" to SimpleMarkerSymbolStyle.X,
|
"Sonstiges" to R.drawable.pin
|
||||||
"Sonstiges" to SimpleMarkerSymbolStyle.Cross
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val renderer = UniqueValueRenderer().apply {
|
val renderer = UniqueValueRenderer().apply {
|
||||||
fieldNames.addAll(listOf("typ", "status"))
|
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 ((typ, iconRes) in typeIconRes) {
|
||||||
for ((status, bgColor) in statusColor) {
|
for ((status, outlineColor) in statusColorByName) {
|
||||||
val label = "$typ • $status"
|
val label = "$typ • $status"
|
||||||
|
|
||||||
renderer.uniqueValues.add(
|
renderer.uniqueValues.add(
|
||||||
UniqueValue(
|
UniqueValue(
|
||||||
label = label,
|
label = label,
|
||||||
description = label,
|
description = label,
|
||||||
symbol = makeStatusTypeSymbol(iconStyle, bgColor),
|
symbol = makeStatusTypeSymbol(
|
||||||
|
context = context,
|
||||||
|
foregroundDrawableRes = iconRes,
|
||||||
|
statusColor = outlineColor
|
||||||
|
),
|
||||||
values = listOf(typ, status)
|
values = listOf(typ, status)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -49,38 +112,3 @@ fun createTypStatusRenderer(): UniqueValueRenderer {
|
|||||||
return renderer
|
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) {
|
for (feature in result) {
|
||||||
val p = feature.geometry as? Point ?: continue
|
val p = feature.geometry as? Point ?: continue
|
||||||
|
|
||||||
// ✅ Distanz korrekt
|
|
||||||
val dist = GeometryEngine.distanceOrNull(pointInLayerSR, p) ?: Double.POSITIVE_INFINITY
|
val dist = GeometryEngine.distanceOrNull(pointInLayerSR, p) ?: Double.POSITIVE_INFINITY
|
||||||
|
|
||||||
val typ = (feature.attributes["typ"] as? String).orEmpty()
|
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