OpenStreetMap API: implement some first filters

This commit is contained in:
johan12345
2023-07-09 16:53:25 +02:00
parent f1bb37ea68
commit 1fee260d1c
2 changed files with 112 additions and 4 deletions

View File

@@ -1,20 +1,34 @@
package net.vonforst.evmap.api.openstreetmap
import android.database.DatabaseUtils
import com.car2go.maps.model.LatLng
import com.car2go.maps.model.LatLngBounds
import com.squareup.moshi.Moshi
import net.vonforst.evmap.BuildConfig
import net.vonforst.evmap.R
import net.vonforst.evmap.addDebugInterceptors
import net.vonforst.evmap.api.ChargepointApi
import net.vonforst.evmap.api.ChargepointList
import net.vonforst.evmap.api.FiltersSQLQuery
import net.vonforst.evmap.api.StringProvider
import net.vonforst.evmap.api.goingelectric.GEChargepoint
import net.vonforst.evmap.api.mapPower
import net.vonforst.evmap.api.mapPowerInverse
import net.vonforst.evmap.api.nameForPlugType
import net.vonforst.evmap.api.openchargemap.ZonedDateTimeAdapter
import net.vonforst.evmap.api.powerSteps
import net.vonforst.evmap.model.BooleanFilter
import net.vonforst.evmap.model.ChargeLocation
import net.vonforst.evmap.model.Chargepoint
import net.vonforst.evmap.model.Filter
import net.vonforst.evmap.model.FilterValue
import net.vonforst.evmap.model.FilterValues
import net.vonforst.evmap.model.MultipleChoiceFilter
import net.vonforst.evmap.model.ReferenceData
import net.vonforst.evmap.model.SliderFilter
import net.vonforst.evmap.model.getBooleanValue
import net.vonforst.evmap.model.getMultipleChoiceValue
import net.vonforst.evmap.model.getSliderValue
import net.vonforst.evmap.viewmodel.Resource
import okhttp3.OkHttpClient
import retrofit2.Response
@@ -99,14 +113,100 @@ class OpenStreetMapApiWrapper(baseurl: String = "https://evmap-dev.vonforst.net"
referenceData: ReferenceData,
sp: StringProvider
): List<Filter<FilterValue>> {
return emptyList()
val plugs = listOf(
Chargepoint.TYPE_1,
Chargepoint.CCS_TYPE_1,
Chargepoint.TYPE_2_SOCKET,
Chargepoint.TYPE_2_PLUG,
Chargepoint.CCS_TYPE_2,
Chargepoint.CHADEMO,
Chargepoint.SUPERCHARGER,
Chargepoint.CEE_BLAU,
Chargepoint.CEE_ROT,
Chargepoint.SCHUKO
)
val plugMap = plugs.associateWith { plug ->
nameForPlugType(sp, plug)
}
return listOf(
BooleanFilter(sp.getString(R.string.filter_free), "freecharging"),
BooleanFilter(sp.getString(R.string.filter_free_parking), "freeparking"),
BooleanFilter(sp.getString(R.string.filter_open_247), "open_247"),
SliderFilter(
sp.getString(R.string.filter_min_power), "min_power",
powerSteps.size - 1,
mapping = ::mapPower,
inverseMapping = ::mapPowerInverse,
unit = "kW"
),
MultipleChoiceFilter(
sp.getString(R.string.filter_connectors), "connectors",
plugMap,
commonChoices = setOf(
Chargepoint.TYPE_1,
Chargepoint.TYPE_2_SOCKET,
Chargepoint.TYPE_2_PLUG,
Chargepoint.CCS_TYPE_1,
Chargepoint.CCS_TYPE_2,
Chargepoint.CHADEMO
),
manyChoices = true
),
SliderFilter(
sp.getString(R.string.filter_min_connectors),
"min_connectors",
10,
min = 1
)
)
}
override fun convertFiltersToSQL(
filters: FilterValues,
referenceData: ReferenceData
): FiltersSQLQuery {
TODO("Not yet implemented")
if (filters.isEmpty()) return FiltersSQLQuery("", false, false)
var requiresChargepointQuery = false
val result = StringBuilder()
if (filters.getBooleanValue("freecharging") == true) {
result.append(" AND freecharging IS 1")
}
if (filters.getBooleanValue("freeparking") == true) {
result.append(" AND freeparking IS 1")
}
if (filters.getBooleanValue("open_247") == true) {
result.append(" AND twentyfourSeven IS 1")
}
val minPower = filters.getSliderValue("min_power")
if (minPower != null && minPower > 0) {
result.append(" AND json_extract(cp.value, '$.power') >= ${minPower}")
requiresChargepointQuery = true
}
val connectors = filters.getMultipleChoiceValue("connectors")
if (connectors != null && !connectors.all) {
val connectorsList = if (connectors.values.size == 0) {
""
} else {
connectors.values.joinToString(",") {
DatabaseUtils.sqlEscapeString(it)
}
}
result.append(" AND json_extract(cp.value, '$.type') IN (${connectorsList})")
requiresChargepointQuery = true
}
val minConnectors = filters.getSliderValue("min_connectors")
if (minConnectors != null && minConnectors > 1) {
result.append(" GROUP BY ChargeLocation.id HAVING COUNT(1) >= $minConnectors")
requiresChargepointQuery = true
}
return FiltersSQLQuery(result.toString(), requiresChargepointQuery, false)
}
override fun filteringInSQLRequiresDetails(filters: FilterValues): Boolean {

View File

@@ -34,7 +34,7 @@ import net.vonforst.evmap.model.*
OCMCountry::class,
OCMOperator::class,
SavedRegion::class
], version = 22
], version = 23
)
@TypeConverters(Converters::class, GeometryConverters::class)
abstract class AppDatabase : RoomDatabase() {
@@ -75,13 +75,14 @@ abstract class AppDatabase : RoomDatabase() {
MIGRATION_7, MIGRATION_8, MIGRATION_9, MIGRATION_10, MIGRATION_11,
MIGRATION_12, MIGRATION_13, MIGRATION_14, MIGRATION_15, MIGRATION_16,
MIGRATION_17, MIGRATION_18, MIGRATION_19, MIGRATION_20, MIGRATION_21,
MIGRATION_22
MIGRATION_22, MIGRATION_23
)
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
// create default filter profile for each data source
db.execSQL("INSERT INTO `FilterProfile` (`dataSource`, `name`, `id`, `order`) VALUES ('goingelectric', 'FILTERS_CUSTOM', $FILTERS_CUSTOM, 0)")
db.execSQL("INSERT INTO `FilterProfile` (`dataSource`, `name`, `id`, `order`) VALUES ('openchargemap', 'FILTERS_CUSTOM', $FILTERS_CUSTOM, 0)")
db.execSQL("INSERT INTO `FilterProfile` (`dataSource`, `name`, `id`, `order`) VALUES ('openstreetmap', 'FILTERS_CUSTOM', $FILTERS_CUSTOM, 0)")
// initialize spatialite columns
db.query("SELECT RecoverGeometryColumn('ChargeLocation', 'coordinates', 4326, 'POINT', 'XY');")
.moveToNext()
@@ -459,6 +460,13 @@ abstract class AppDatabase : RoomDatabase() {
db.execSQL("DELETE FROM savedregion")
}
}
private val MIGRATION_23 = object : Migration(22, 23) {
override fun migrate(db: SupportSQLiteDatabase) {
// API openstreetmap added
db.execSQL("INSERT INTO `FilterProfile` (`dataSource`, `name`, `id`, `order`) VALUES ('openstreetmap', 'FILTERS_CUSTOM', $FILTERS_CUSTOM, 0)")
}
}
}
/**