Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d12ee62a authored by Ellen Poe's avatar Ellen Poe
Browse files

refactor: progress on complexity task

parent 454425ce
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -5,4 +5,8 @@ naming:

complexity:
  LongParameterList:
    active: true
    ignoreDefaultParameters: true
  CognitiveComplexMethod:
    active: true
    excludes: [ '**/cardinal/bottomsheet/**' ]
+210 −213
Original line number Diff line number Diff line
@@ -84,13 +84,54 @@ class LocalMapServer(
        // Find an available port
        val availablePort = findAvailablePort()

        server = embeddedServer(CIO, port = availablePort, host = "127.0.0.1") {
        server = createEmbeddedServer(availablePort)
        server?.start(wait = false)

        port = availablePort

        Log.d(TAG, "Tile server started on port: $port")
    }

    fun stop() {
        server?.stop(1000, 5000)
        server = null
        port = -1

        // Close the databases.
        terrainDatabase?.close()
        terrainDatabase = null
        landcoverDatabase?.close()
        landcoverDatabase = null
        basemapDatabase?.close()
        basemapDatabase = null
        offlineAreasDatabase?.close()
        offlineAreasDatabase = null

        Log.d(TAG, "Tile server stopped")
    }

    fun getPort(): Int {
        return port
    }

    private fun createEmbeddedServer(port: Int) =
        embeddedServer(CIO, port = port, host = "127.0.0.1") {
            routing {
                get("/") {
                handleRoot()
                handleStyleLight()
                handleStyleDark()
                handleRoute()
                handleTerrainTile()
                handleLandcoverTile()
                handleOpenMapTiles()
            }
        }

    private fun io.ktor.server.routing.Routing.handleRoot() = get("/") {
        call.respondText("Tile Server is running!")
    }

                get("/style_light.json") {
    private fun io.ktor.server.routing.Routing.handleStyleLight() = get("/style_light.json") {
        try {
            val styleJson = readAssetFile("style_light.json")
            val modifiedStyleJson = styleJson.replace("{port}", port.toString())
@@ -106,7 +147,7 @@ class LocalMapServer(
        }
    }

                get("/style_dark.json") {
    private fun io.ktor.server.routing.Routing.handleStyleDark() = get("/style_dark.json") {
        try {
            val styleJson = readAssetFile("style_dark.json")
            val modifiedStyleJson = styleJson.replace("{port}", port.toString())
@@ -122,8 +163,7 @@ class LocalMapServer(
        }
    }

                // Valhalla-compatible routing endpoint
                post("/route") {
    private fun io.ktor.server.routing.Routing.handleRoute() = post("/route") {
        try {
            val requestBody = call.receiveText()
            Log.d(TAG, "Received routing request: $requestBody")
@@ -145,7 +185,7 @@ class LocalMapServer(
        }
    }

                // Serve tiles from terrain.mbtiles.
    private fun io.ktor.server.routing.Routing.handleTerrainTile() =
        get("/terrain/{z}/{x}/{y}.png") {
            val terrainDatabase = terrainDatabase ?: return@get

@@ -176,8 +216,7 @@ class LocalMapServer(
            }
        }


                // Serve tiles from landcover.mbtiles.
    private fun io.ktor.server.routing.Routing.handleLandcoverTile() =
        get("/landcover/{z}/{x}/{y}.pbf") {
            val landcoverDatabase = landcoverDatabase ?: return@get

@@ -209,7 +248,7 @@ class LocalMapServer(
            }
        }

                // Serve tiles from basemap.mbtiles.
    private fun io.ktor.server.routing.Routing.handleOpenMapTiles() =
        get("/openmaptiles/{z}/{x}/{y}.pbf") {
            val z = call.parameters["z"]?.toIntOrNull()
            val x = call.parameters["x"]?.toLongOrNull()
@@ -223,33 +262,7 @@ class LocalMapServer(
                return@get
            }

                    Log.d(TAG, "Requesting tile: /openmaptiles/$z/$x/$y.pbf")

                    // MBTiles uses TMS (Tile Map Service) coordinate system where Y=0 is at the bottom
                    // Most map libraries use XYZ coordinate system where Y=0 is at the top
                    // Convert Y coordinate from XYZ to TMS: TMS_Y = 2^zoom - 1 - XYZ_Y
                    val tmsY = (2.0.pow(z.toDouble()) - 1 - y).toLong()

                    var isGzipped = true

                    val basemapDatabase = basemapDatabase

                    // First try to get tile from built-in database
                    var tileData = if (basemapDatabase != null) {
                        getTileData(basemapDatabase, z, x, tmsY)
                    } else {
                        Log.w(TAG, "Basemap database is null")
                        null
                    }

                    // If not found, try offline databases
                    if (tileData == null) {
                        Log.d(TAG, "Tile not found in basemap database, checking offline databases")
                        tileData = getTileDataFromOfflineDatabases(z, x, y)
                        isGzipped = false
                    } else {
                        Log.d(TAG, "Tile found in basemap database")
                    }
            val (tileData, isGzipped) = findTileData(z, x, y)

            if (tileData != null) {
                Log.d(
@@ -262,30 +275,6 @@ class LocalMapServer(
                }
                call.respondBytes(tileData, contentType = ContentType.Application.ProtoBuf)
            } else {
                        // Check if we should fetch from the internet (not in offline mode)
                        val isOfflineMode = isOfflineMode()
                        if (!isOfflineMode) {
                            Log.d(
                                TAG,
                                "Tile not found in local caches, attempting to fetch from internet"
                            )
                            tileData = CoroutineScope(Dispatchers.IO).async {
                                fetchTileFromInternet(
                                    z, x, y
                                )
                            }.await()
                            if (tileData != null) {
                                Log.d(
                                    TAG,
                                    "Successfully fetched tile from internet: /openmaptiles/$z/$x/$y.pbf, size: ${tileData.size} bytes"
                                )
                                call.respondBytes(
                                    tileData, contentType = ContentType.Application.ProtoBuf
                                )
                                return@get
                            }
                        }

                Log.d(TAG, "Tile not found: /openmaptiles/$z/$x/$y.pbf")
                // If we respond with NotFound here (as would make sense) it will cause maplibre to cache the
                // fact that this tile doesn't exist in this source, which we don't want because it will never
@@ -297,36 +286,6 @@ class LocalMapServer(
                )
            }
        }
            }
        }
        server?.start(wait = false)

        port = availablePort

        Log.d(TAG, "Tile server started on port: $port")
    }

    fun stop() {
        server?.stop(1000, 5000)
        server = null
        port = -1

        // Close the databases.
        terrainDatabase?.close()
        terrainDatabase = null
        landcoverDatabase?.close()
        landcoverDatabase = null
        basemapDatabase?.close()
        basemapDatabase = null
        offlineAreasDatabase?.close()
        offlineAreasDatabase = null

        Log.d(TAG, "Tile server stopped")
    }

    fun getPort(): Int {
        return port
    }

    private fun readAssetFile(fileName: String): String {
        return context.assets.open(fileName).use { inputStream ->
@@ -552,6 +511,44 @@ class LocalMapServer(
        return null
    }

    /**
     * Find tile data for given coordinates from available sources
     */
    private suspend fun findTileData(z: Int, x: Long, y: Long): Pair<ByteArray?, Boolean> {
        val tmsY = (2.0.pow(z.toDouble()) - 1 - y).toLong()

        // First try to get tile from built-in database
        val tileData = basemapDatabase?.let { getTileData(it, z, x, tmsY) }
        if (tileData != null) {
            Log.d(TAG, "Tile found in basemap database")
            return Pair(tileData, true) // gzipped
        }

        // If not found, try offline databases
        Log.d(TAG, "Tile not found in basemap database, checking offline databases")
        val offlineTileData = getTileDataFromOfflineDatabases(z, x, y)
        if (offlineTileData != null) {
            return Pair(offlineTileData, false) // not gzipped
        }

        // Check if we should fetch from the internet (not in offline mode)
        if (!isOfflineMode()) {
            Log.d(TAG, "Tile not found in local caches, attempting to fetch from internet")
            val internetTileData = CoroutineScope(Dispatchers.IO).async {
                fetchTileFromInternet(z, x, y)
            }.await()
            if (internetTileData != null) {
                Log.d(
                    TAG,
                    "Successfully fetched tile from internet: size: ${internetTileData.size} bytes"
                )
                return Pair(internetTileData, false) // not gzipped
            }
        }

        return Pair(null, false) // not found
    }

    /**
     * Check if the app is in offline mode
     */
+627 −431

File changed.

Preview size limit exceeded, changes collapsed.