Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion collect_app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ dependencies {
}
implementation project(':external-app')
implementation project(':maps')
implementation project(':osmdroid')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove osmdroid from libs.versions.toml.
Osmdroid is still mentioned in a couple of places, like: STATE.md, MapFragment (in the comment) etc.

implementation project(':entities')
implementation project(':crash-handler')
implementation project(':selfie-camera')
Expand Down
1 change: 0 additions & 1 deletion collect_app/proguard-rules.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
-dontwarn com.google.**
-dontwarn au.com.bytecode.**
-dontwarn org.joda.time.**
-dontwarn org.osmdroid.**
-dontwarn org.xmlpull.v1.**
-dontwarn org.hamcrest.**
-dontwarn com.rarepebble.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import org.odk.collect.android.injection.config.CollectEntitiesDependencyModule;
import org.odk.collect.android.injection.config.CollectGeoDependencyModule;
import org.odk.collect.android.injection.config.CollectGoogleMapsDependencyModule;
import org.odk.collect.android.injection.config.CollectOsmDroidDependencyModule;
import org.odk.collect.android.injection.config.CollectProjectsDependencyModule;
import org.odk.collect.android.injection.config.CollectSelfieCameraDependencyModule;
import org.odk.collect.android.injection.config.DaggerAppDependencyComponent;
Expand Down Expand Up @@ -66,9 +65,6 @@
import org.odk.collect.location.LocationDependencyComponentProvider;
import org.odk.collect.location.LocationDependencyModule;
import org.odk.collect.maps.layers.ReferenceLayerRepository;
import org.odk.collect.osmdroid.DaggerOsmDroidDependencyComponent;
import org.odk.collect.osmdroid.OsmDroidDependencyComponent;
import org.odk.collect.osmdroid.OsmDroidDependencyComponentProvider;
import org.odk.collect.projects.DaggerProjectsDependencyComponent;
import org.odk.collect.projects.ProjectsDependencyComponent;
import org.odk.collect.projects.ProjectsDependencyComponentProvider;
Expand All @@ -92,7 +88,6 @@ public class Collect extends Application implements
AudioRecorderDependencyComponentProvider,
ProjectsDependencyComponentProvider,
GeoDependencyComponentProvider,
OsmDroidDependencyComponentProvider,
StateStore,
ObjectProviderHost,
EntitiesDependencyComponentProvider,
Expand All @@ -113,7 +108,6 @@ public class Collect extends Application implements
private AudioRecorderDependencyComponent audioRecorderDependencyComponent;
private ProjectsDependencyComponent projectsDependencyComponent;
private GeoDependencyComponent geoDependencyComponent;
private OsmDroidDependencyComponent osmDroidDependencyComponent;
private EntitiesDependencyComponent entitiesDependencyComponent;
private SelfieCameraDependencyComponent selfieCameraDependencyComponent;
private GoogleMapsDependencyComponent googleMapsDependencyComponent;
Expand Down Expand Up @@ -272,18 +266,6 @@ public GeoDependencyComponent getGeoDependencyComponent() {
return geoDependencyComponent;
}

@NonNull
@Override
public OsmDroidDependencyComponent getOsmDroidDependencyComponent() {
if (osmDroidDependencyComponent == null) {
osmDroidDependencyComponent = DaggerOsmDroidDependencyComponent.builder()
.osmDroidDependencyModule(new CollectOsmDroidDependencyModule(applicationComponent))
.build();
}

return osmDroidDependencyComponent;
}

@NonNull
@Override
public ObjectProvider getObjectProvider() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,32 @@ object MapboxClassInstanceCreator {
@JvmStatic
fun isMapboxAvailable(): Boolean {
return try {
getClass(MAP_FRAGMENT)
Class.forName(MAP_FRAGMENT)
System.loadLibrary("mapbox-common")
true
} catch (e: Throwable) {
false
}
}

fun createMapboxMapFragment(): MapFragment {
return createClassInstance(MAP_FRAGMENT)
fun createMapboxMapFragment(configuration: String): MapFragment {
return Class.forName(MAP_FRAGMENT)
.getConstructor(String::class.java)
.newInstance(configuration) as MapFragment
}

@JvmStatic
fun createMapBoxInitializationFragment(): Fragment {
return createClassInstance("org.odk.collect.mapbox.MapBoxInitializationFragment")
return Class.forName("org.odk.collect.mapbox.MapBoxInitializationFragment")
.getConstructor()
.newInstance() as Fragment
}

@JvmStatic
fun createMapboxMapConfigurator(): MapConfigurator {
return createClassInstance("org.odk.collect.mapbox.MapboxMapConfigurator")
fun createMapboxMapConfigurator(configuration: String): MapConfigurator {
return Class.forName("org.odk.collect.mapbox.MapboxMapConfigurator")
.getConstructor(String::class.java)
.newInstance(configuration) as MapConfigurator
}

private fun <T> createClassInstance(className: String): T {
return getClass(className).newInstance() as T
}

private fun getClass(className: String): Class<*> = Class.forName(className)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.Context
import android.os.Handler
import com.google.android.gms.maps.MapView
import org.odk.collect.android.geo.MapConfiguratorProvider
import org.odk.collect.osmdroid.OsmDroidInitializer
import org.odk.collect.settings.SettingsProvider
import org.odk.collect.settings.keys.ProjectKeys
import org.odk.collect.utilities.UserAgentProvider
Expand All @@ -30,7 +29,7 @@ class MapsInitializer @Inject constructor(
val availableBaseMaps = MapConfiguratorProvider.getIds()
val baseMapSetting =
settingsProvider.getUnprotectedSettings().getString(ProjectKeys.KEY_BASEMAP_SOURCE)
if (!availableBaseMaps.contains(baseMapSetting)) {
if (!availableBaseMaps.contains(baseMapSetting) && availableBaseMaps.isNotEmpty()) {
settingsProvider.getUnprotectedSettings().save(
ProjectKeys.KEY_BASEMAP_SOURCE,
availableBaseMaps[0]
Expand All @@ -54,7 +53,6 @@ class MapsInitializer @Inject constructor(
// This has to happen on the main thread but we might call `initialize` from tests
MapView(context).onCreate(null)
}
OsmDroidInitializer.initialize(userAgentProvider.userAgent)
Copy link
Copy Markdown
Member

@grzesiek2010 grzesiek2010 Jun 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove userAgentProvider from the constructor.

} catch (ignore: Exception) {
// ignored
} catch (ignore: Error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,23 @@
import static org.odk.collect.settings.keys.ProjectKeys.BASEMAP_SOURCE_OSM;
import static org.odk.collect.settings.keys.ProjectKeys.BASEMAP_SOURCE_USGS;
import static org.odk.collect.settings.keys.ProjectKeys.KEY_BASEMAP_SOURCE;
import static org.odk.collect.settings.keys.ProjectKeys.KEY_CARTO_MAP_STYLE;
import static org.odk.collect.settings.keys.ProjectKeys.KEY_GOOGLE_MAP_STYLE;
import static org.odk.collect.settings.keys.ProjectKeys.KEY_USGS_MAP_STYLE;
import static org.odk.collect.strings.localization.LocalizedApplicationKt.getLocalizedString;

import android.content.Context;

import androidx.annotation.NonNull;

import com.google.android.gms.maps.GoogleMap;

import org.odk.collect.android.application.Collect;
import org.odk.collect.android.application.MapboxClassInstanceCreator;
import org.odk.collect.googlemaps.GoogleMapConfigurator;
import org.odk.collect.googlemaps.GoogleMapConfigurator.GoogleMapTypeOption;
import org.odk.collect.android.injection.DaggerUtils;
import org.odk.collect.googlemaps.GoogleMapConfigurator;
import org.odk.collect.maps.MapConfigurator;
import org.odk.collect.osmdroid.OsmDroidMapConfigurator;
import org.odk.collect.osmdroid.OsmDroidMapConfigurator.WmsOption;
import org.odk.collect.osmdroid.WebMapService;

import java.util.ArrayList;
import java.util.List;

public class MapConfiguratorProvider {

private static SourceOption[] sourceOptions;
private static final String USGS_URL_BASE =
"https://basemap.nationalmap.gov/arcgis/rest/services";
private static final String OSM_COPYRIGHT = "© OpenStreetMap contributors";
private static final String CARTO_COPYRIGHT = "© CARTO";
private static final String CARTO_ATTRIBUTION = OSM_COPYRIGHT + ", " + CARTO_COPYRIGHT;
private static final String USGS_ATTRIBUTION = "Map services and data available from U.S. Geological Survey,\nNational Geospatial Program.";

private MapConfiguratorProvider() {

Expand All @@ -55,14 +40,7 @@ public static void initOptions(Context context) {

ArrayList<SourceOption> sourceOptions = new ArrayList<>();

GoogleMapConfigurator googleMapsConfigurator = new GoogleMapConfigurator(
KEY_GOOGLE_MAP_STYLE, org.odk.collect.strings.R.string.basemap_source_google,
new GoogleMapTypeOption(GoogleMap.MAP_TYPE_NORMAL, org.odk.collect.strings.R.string.streets),
new GoogleMapTypeOption(GoogleMap.MAP_TYPE_TERRAIN, org.odk.collect.strings.R.string.terrain),
new GoogleMapTypeOption(GoogleMap.MAP_TYPE_HYBRID, org.odk.collect.strings.R.string.hybrid),
new GoogleMapTypeOption(GoogleMap.MAP_TYPE_SATELLITE, org.odk.collect.strings.R.string.satellite)
);

GoogleMapConfigurator googleMapsConfigurator = new GoogleMapConfigurator();
if (googleMapsConfigurator.isAvailable(context)) {
sourceOptions.add(new SourceOption(BASEMAP_SOURCE_GOOGLE, org.odk.collect.strings.R.string.basemap_source_google,
googleMapsConfigurator
Expand All @@ -71,49 +49,24 @@ public static void initOptions(Context context) {

if (isMapboxSupported()) {
sourceOptions.add(new SourceOption(BASEMAP_SOURCE_MAPBOX, org.odk.collect.strings.R.string.basemap_source_mapbox,
MapboxClassInstanceCreator.createMapboxMapConfigurator()
MapboxClassInstanceCreator.createMapboxMapConfigurator(BASEMAP_SOURCE_MAPBOX)
));

sourceOptions.add(new SourceOption(BASEMAP_SOURCE_OSM, org.odk.collect.strings.R.string.basemap_source_osm,
MapboxClassInstanceCreator.createMapboxMapConfigurator(BASEMAP_SOURCE_OSM)
));
sourceOptions.add(new SourceOption(BASEMAP_SOURCE_USGS, org.odk.collect.strings.R.string.basemap_source_usgs,
MapboxClassInstanceCreator.createMapboxMapConfigurator(BASEMAP_SOURCE_USGS)
));
sourceOptions.add(new SourceOption(BASEMAP_SOURCE_CARTO, org.odk.collect.strings.R.string.basemap_source_carto,
MapboxClassInstanceCreator.createMapboxMapConfigurator(BASEMAP_SOURCE_CARTO)
));
}

sourceOptions.add(new SourceOption(BASEMAP_SOURCE_OSM, org.odk.collect.strings.R.string.basemap_source_osm,
new OsmDroidMapConfigurator(
new WebMapService(
"Mapnik", 0, 19, 256, OSM_COPYRIGHT,
"https://tile.openstreetmap.org/{z}/{x}/{y}.png"
)
)
));
sourceOptions.add(new SourceOption(BASEMAP_SOURCE_USGS, org.odk.collect.strings.R.string.basemap_source_usgs,
new OsmDroidMapConfigurator(
KEY_USGS_MAP_STYLE, org.odk.collect.strings.R.string.basemap_source_usgs,
new WmsOption("topographic", org.odk.collect.strings.R.string.topographic, new WebMapService(
getLocalizedString(getApplication(), org.odk.collect.strings.R.string.openmap_usgs_topo), 0, 18, 256, USGS_ATTRIBUTION,
USGS_URL_BASE + "/USGSTopo/MapServer/tile/{z}/{y}/{x}"
)),
new WmsOption("hybrid", org.odk.collect.strings.R.string.hybrid, new WebMapService(
getLocalizedString(getApplication(), org.odk.collect.strings.R.string.openmap_usgs_sat), 0, 18, 256, USGS_ATTRIBUTION,
USGS_URL_BASE + "/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}"
)),
new WmsOption("satellite", org.odk.collect.strings.R.string.satellite, new WebMapService(
getLocalizedString(getApplication(), org.odk.collect.strings.R.string.openmap_usgs_img), 0, 18, 256, USGS_ATTRIBUTION,
USGS_URL_BASE + "/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"
))
)
));
sourceOptions.add(new SourceOption(BASEMAP_SOURCE_CARTO, org.odk.collect.strings.R.string.basemap_source_carto,
new OsmDroidMapConfigurator(
KEY_CARTO_MAP_STYLE, org.odk.collect.strings.R.string.basemap_source_carto,
new WmsOption("positron", org.odk.collect.strings.R.string.carto_map_style_positron, new WebMapService(
getLocalizedString(getApplication(), org.odk.collect.strings.R.string.openmap_cartodb_positron), 0, 18, 256, CARTO_ATTRIBUTION,
"http://1.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"
)),
new WmsOption("dark_matter", org.odk.collect.strings.R.string.carto_map_style_dark_matter, new WebMapService(
getLocalizedString(getApplication(), org.odk.collect.strings.R.string.openmap_cartodb_darkmatter), 0, 18, 256, CARTO_ATTRIBUTION,
"http://1.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"
))
)
));
initOptions(sourceOptions);
}

public static void initOptions(List<SourceOption> sourceOptions) {
MapConfiguratorProvider.sourceOptions = sourceOptions.toArray(new SourceOption[]{});
}

Expand Down Expand Up @@ -174,12 +127,12 @@ private static Collect getApplication() {
return Collect.getInstance();
}

private static class SourceOption {
public static class SourceOption {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think longer term, we really don't want MapConfiguratorProvider to be statically accessed, but that's a rabbit hole for another time.

private final String id; // preference value to store
private final int labelId; // string resource ID
private final MapConfigurator cftor;

private SourceOption(String id, int labelId, MapConfigurator cftor) {
public SourceOption(String id, int labelId, MapConfigurator cftor) {
this.id = id;
this.labelId = labelId;
this.cftor = cftor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,31 @@ import org.odk.collect.android.application.MapboxClassInstanceCreator
import org.odk.collect.googlemaps.GoogleMapFragment
import org.odk.collect.maps.MapFragment
import org.odk.collect.maps.MapFragmentFactory
import org.odk.collect.osmdroid.OsmDroidMapFragment
import org.odk.collect.settings.SettingsProvider
import org.odk.collect.settings.keys.ProjectKeys.BASEMAP_SOURCE_CARTO
import org.odk.collect.settings.keys.ProjectKeys.BASEMAP_SOURCE_MAPBOX
import org.odk.collect.settings.keys.ProjectKeys.BASEMAP_SOURCE_OSM
import org.odk.collect.settings.keys.ProjectKeys.BASEMAP_SOURCE_USGS
import org.odk.collect.settings.keys.ProjectKeys
import org.odk.collect.settings.keys.ProjectKeys.KEY_BASEMAP_SOURCE

class MapFragmentFactoryImpl(private val settingsProvider: SettingsProvider) : MapFragmentFactory {

override fun createMapFragment(): MapFragment {
val settings = settingsProvider.getUnprotectedSettings()

return when {
isBasemapOSM(settings.getString(KEY_BASEMAP_SOURCE)) -> OsmDroidMapFragment()
settings.getString(KEY_BASEMAP_SOURCE) == BASEMAP_SOURCE_MAPBOX -> MapboxClassInstanceCreator.createMapboxMapFragment()
else -> GoogleMapFragment()
val basemapSource = settings.getString(KEY_BASEMAP_SOURCE)
return if (isMapbox(basemapSource)) {
MapboxClassInstanceCreator.createMapboxMapFragment(
basemapSource ?: ProjectKeys.BASEMAP_SOURCE_MAPBOX
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basemapSource can't be null here - isMapbox(null) returns false, so the ?: BASEMAP_SOURCE_MAPBOX fallback is unreachable.

)
} else {
GoogleMapFragment()
}
}

private fun isBasemapOSM(basemap: String?): Boolean {
return basemap == BASEMAP_SOURCE_OSM ||
basemap == BASEMAP_SOURCE_USGS ||
basemap == BASEMAP_SOURCE_CARTO
private fun isMapbox(source: String?): Boolean {
return when (source) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simplified to:

when (source) {
    ProjectKeys.BASEMAP_SOURCE_MAPBOX,
    ProjectKeys.BASEMAP_SOURCE_OSM,
    ProjectKeys.BASEMAP_SOURCE_USGS,
    ProjectKeys.BASEMAP_SOURCE_CARTO -> true
    else -> false
}

ProjectKeys.BASEMAP_SOURCE_MAPBOX -> true
ProjectKeys.BASEMAP_SOURCE_OSM -> true
ProjectKeys.BASEMAP_SOURCE_USGS -> true
ProjectKeys.BASEMAP_SOURCE_CARTO -> true
else -> false
}
}
}

This file was deleted.

Loading