Skip to content

Commit

Permalink
Update Geo Package content last change date on each tile save.
Browse files Browse the repository at this point in the history
  • Loading branch information
ComBatVision committed Dec 30, 2023
1 parent 3585089 commit 4ff8cba
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package earth.worldwind.ogc.gpkg
import android.content.ContentValues
import android.database.SQLException
import android.database.sqlite.SQLiteDatabase.*
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import java.util.concurrent.TimeUnit

// TODO parameterize column names as constants or use some ORM
Expand Down Expand Up @@ -169,14 +171,17 @@ actual open class GeoPackage actual constructor(pathName: String, isReadOnly: Bo
put("data_type", dataType)
put("identifier", identifier)
put("description", description)
put("last_change", lastChange)
put("last_change", lastChange.toString())
put("min_x", minX)
put("min_y", minY)
put("max_x", maxX)
put("max_y", maxY)
put("srs_id", srsId)
}
if (database.insert(CONTENTS, null, values) >= 0) addContent(this)
if (database.insert(CONTENTS, null, values) >= 0 ||
database.update(CONTENTS, values, "table_name=?", arrayOf(content.tableName)) > 0) {
addContent(this)
}
} }
}

Expand Down Expand Up @@ -288,6 +293,15 @@ actual open class GeoPackage actual constructor(pathName: String, isReadOnly: Bo
} }
}

override suspend fun updateContentsLastChangeDate(content: GpkgContent) {
connection.openDatabase().use { database ->
val values = ContentValues().apply {
put("last_change", content.lastChange.toString())
}
database.update(CONTENTS, values, "table_name=?", arrayOf(content.tableName))
}
}

override suspend fun readSpatialReferenceSystem() {
connection.openDatabase().use { database ->
try {
Expand Down Expand Up @@ -318,8 +332,8 @@ actual open class GeoPackage actual constructor(pathName: String, isReadOnly: Bo
while (moveToNext()) addContent(
GpkgContent(
this@GeoPackage, getString(0), getString(1), getString(2),
getString(3), getString(4), getDouble(5), getDouble(6),
getDouble(7), getDouble(8), getInt(9)
getString(3), runCatching { Instant.parse(getString(4)) }.getOrNull() ?: Clock.System.now(),
getDouble(5), getDouble(6), getDouble(7), getDouble(8), getInt(9)
)
)
} }
Expand Down Expand Up @@ -540,5 +554,4 @@ actual open class GeoPackage actual constructor(pathName: String, isReadOnly: Bo
override suspend fun dropTilesTable(tableName: String) {
connection.openDatabase().use { database -> database.execSQL("DROP TABLE IF EXISTS $tableName") }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ class GpkgContentManager(pathName: String, readOnly: Boolean = false): ContentMa
coverage.cacheSourceFactory = GpkgElevationSourceFactory(content, isFloat)
}

override fun getLastUpdateDate(contentKey: String) = geoPackage.content[contentKey]?.lastChange

override fun getBoundingSector(contentKey: String) = geoPackage.getBoundingSector(contentKey)

companion object {
private const val TOLERANCE = 1e-6
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import earth.worldwind.layer.mercator.MercatorSector
import earth.worldwind.util.LevelSet
import earth.worldwind.util.LevelSetConfig
import kotlinx.coroutines.runBlocking
import kotlinx.datetime.Clock
import kotlin.math.*

// TODO verify its a GeoPackage container
Expand Down Expand Up @@ -51,6 +52,8 @@ abstract class AbstractGeoPackage(val pathName: String, val isReadOnly: Boolean)
val tileUserData = readTileUserData(tiles.tableName, zoomLevel, tileColumn, tileRow)?.also { it.tileData = tileData }
?: GpkgTileUserData(this, -1, zoomLevel, tileColumn, tileRow, tileData)
writeTileUserData(tiles.tableName, tileUserData)
tiles.lastChange = Clock.System.now()
updateContentsLastChangeDate(tiles)
}

suspend fun readGriddedTile(tiles: GpkgContent, tileUserData: GpkgTileUserData) =
Expand Down Expand Up @@ -151,7 +154,17 @@ abstract class AbstractGeoPackage(val pathName: String, val isReadOnly: Boolean)
)
)
// Content bounding box can be smaller than matrix set bounding box and describes selected area on the lowest level
val content = GpkgContent(this, tableName, "tiles", layer.displayName ?: tableName, "", "", minX, minY, maxX, maxY, srsId)
val content = GpkgContent(
container = this,
tableName = tableName,
dataType = "tiles",
identifier = layer.displayName ?: tableName,
minX = minX,
minY = minY,
maxX = maxX,
maxY = maxY,
srsId = srsId
)
writeContent(content)
if (setupWebLayer && layer is WebImageLayer) setupWebLayer(layer, tableName)
return content
Expand Down Expand Up @@ -263,7 +276,17 @@ abstract class AbstractGeoPackage(val pathName: String, val isReadOnly: Boolean)
)
)
// Content bounding box can be smaller than matrix set bounding box and describes selected area on the lowest level
val content = GpkgContent(this, tableName, "2d-gridded-coverage", coverage.displayName ?: tableName, "", "", minX, minY, maxX, maxY, srsId)
val content = GpkgContent(
container = this,
tableName = tableName,
dataType = "2d-gridded-coverage",
identifier = coverage.displayName ?: tableName,
minX = minX,
minY = minY,
maxX = maxX,
maxY = maxY,
srsId = srsId
)
writeContent(content)
if (setupWebCoverage && coverage is WebElevationCoverage) setupWebCoverage(coverage, tableName)
return content
Expand Down Expand Up @@ -352,6 +375,16 @@ abstract class AbstractGeoPackage(val pathName: String, val isReadOnly: Boolean)
webServices.remove(tableName)?.let { deleteWebService(it) }
}

fun getBoundingSector(contentKey: String) = content[contentKey]?.let { content ->
if (content.srsId == EPSG_3857) MercatorSector.fromSector(Sector(
latFromEPSG3857(content.minY), latFromEPSG3857(content.maxY),
lonFromEPSG3857(content.minX), lonFromEPSG3857(content.maxX)
)) else Sector(
content.minY.degrees, content.maxY.degrees,
content.minX.degrees, content.maxX.degrees
)
}

/**
* Undefined cartesian and geographic SRS - Requirement 11 http://www.geopackage.org/spec131/index.html
*/
Expand Down Expand Up @@ -437,6 +470,8 @@ abstract class AbstractGeoPackage(val pathName: String, val isReadOnly: Boolean)
protected abstract suspend fun writeGriddedTile(griddedTile: GpkgGriddedTile)
protected abstract suspend fun writeTileUserData(tableName: String, userData: GpkgTileUserData)

protected abstract suspend fun updateContentsLastChangeDate(content: GpkgContent)

protected abstract suspend fun readSpatialReferenceSystem()
protected abstract suspend fun readContent()
protected abstract suspend fun readWebService()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package earth.worldwind.ogc.gpkg

import kotlinx.datetime.Clock
import kotlinx.datetime.Instant

class GpkgContent(
override val container: AbstractGeoPackage,
val tableName: String,
val dataType: String,
val identifier: String,
val description: String = "",
val lastChange: String,
val minX: Double?,
val minY: Double?,
val maxX: Double?,
val maxY: Double?,
val srsId: Int?
var description: String = "",
var lastChange: Instant = Clock.System.now(),
var minX: Double,
var minY: Double,
var maxX: Double,
var maxY: Double,
val srsId: Int
): GpkgEntry()
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package earth.worldwind.ogc.gpkg

class GpkgExtension(
override val container: AbstractGeoPackage,
val tableName: String?,
val columnName: String?,
val tableName: String? = null,
val columnName: String? = null,
val extensionName: String,
val definition: String,
val scope: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class GpkgGriddedCoverage(
val scale: Float = 1.0f,
val offset: Float = 0.0f,
val precision: Float = 1.0f,
val dataNull: Float?,
val dataNull: Float? = null,
val gridCellEncoding: String = "grid-value-is-center",
val uom: String? = null,
val fieldName: String = "Height",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class GpkgGriddedTile(
val tpudtId: Int,
var scale: Float = 1.0f,
var offset: Float = 0.0f,
var min: Float?,
var max: Float?,
var mean: Float?,
var stdDev: Float?
var min: Float? = null,
var max: Float? = null,
var mean: Float? = null,
var stdDev: Float? = null
): GpkgEntry()
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ class GpkgSpatialReferenceSystem(
val organization: String,
val organizationCoordSysId: Int,
val definition: String,
val description: String?
val description: String? = null
): GpkgEntry()
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package earth.worldwind.util

import earth.worldwind.geom.Sector
import earth.worldwind.globe.elevation.coverage.CacheableElevationCoverage
import earth.worldwind.globe.elevation.coverage.TiledElevationCoverage
import earth.worldwind.layer.CacheableImageLayer
import earth.worldwind.layer.TiledImageLayer
import kotlinx.datetime.Instant

interface ContentManager {
/**
Expand Down Expand Up @@ -44,4 +46,18 @@ interface ContentManager {
suspend fun setupElevationCoverageCache(
coverage: CacheableElevationCoverage, contentKey: String, setupWebCoverage: Boolean = true, isFloat: Boolean = false
)

/**
* Returns last update date of specified content
*
* @return Last update date or null, if content does not exist
*/
fun getLastUpdateDate(contentKey: String): Instant?

/**
* Gets bounding sector of specified content
*
* @return Bounding sector of specified content or null, if content does not exist
*/
fun getBoundingSector(contentKey: String): Sector?
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ actual open class GeoPackage actual constructor(pathName: String, isReadOnly: Bo
TODO("Not yet implemented")
}

override suspend fun updateContentLastChangedDate(content: GpkgContent) {
TODO("Not yet implemented")
}

override suspend fun readSpatialReferenceSystem() {
TODO("Not yet implemented")
}
Expand Down

0 comments on commit 4ff8cba

Please sign in to comment.