westnordost / osmfeatures

A dictionary of OSM map features, accessible by terms and by tags, for Java and Android.
Apache License 2.0
18 stars 9 forks source link

Initialize dictionary with data in multiplatform compose resources #27

Open michalgwo opened 2 weeks ago

michalgwo commented 2 weeks ago

Currently, there are 2 options to initialize the dictionary, either by providing FileSystem or AssetManager, but only FileSystem is available in the common source set of the Kotlin Multiplatform project. In case when we keep our presets data in compose resources, they are not available from FileSystem, they are bundled into apk, thus right now it's not possible to get them with osmfeatures library in the common source set.

To get a raw file from compose resources we can use Res.readBytes("files/presets/preset.json") (reference).

To solve this issue, I propose to make FeatureDictionary.create() accept a Res object as a parameter and read presets from compose resources by Res.readBytes()

westnordost commented 2 weeks ago

I see. Res is compose-specific, so would add a dependency, that's a no-no.

But you can just use the regular constructor of the FeatureDictionary.

Adding a function like

fun createFeatureDictionary(
    featuresAccess: ResourceAccessAdapter,
    brandFeaturesAccess: ResourceAccessAdapter?,
) = FeatureDictionary(
    featureCollection = IDLocalizedFeatureCollection(featuresAccess),
    brandFeatureCollection = brandFeaturesAccess?.let { IDBrandPresetsFeatureCollection(it) }
)

Then, you just need to implement a ResourceAccessAdapter that uses the functions from KMP Compose Resources to access the resources.

westnordost commented 2 weeks ago

It took way too long to find this out, but you can use

val buffer = Buffer()
UnsafeBufferOperations.moveToTail(buffer, byteArray)

to wrap a ByteArray into a Buffer (without copying it). A Buffer implements Source. Maybe one day KMP Compose Resources will also directly offer a function like Res.readSource.

westnordost commented 2 weeks ago

Is there a method like Res.exists at all, though?

michalgwo commented 2 weeks ago

Is there a method like Res.exists at all, though?

Not exactly, but it can be checked with Res.getUri() which returns MissingResourceException when the file doesn't exist.