Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kujaku migration to V10.19 #383

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
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
Kujaku migration
Aleem92 committed Jan 31, 2025
commit fc1c57108f8bdeb1132ea017a6c36df09da49f22
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ The library offers a view `KujakuMapView` that provides more functionality than

## `Unable to resolve artifact: Missing` while running tests

This is encountered when Robolectric has problems downloading the jars it needs for different Android SDK levels. If you keep running into this you can download the JARs locally and point Robolectric to them by doing:
This is encountered when Robolectric has problems downloading the jars it needs for different Android SDK levels. If you keep running into this you can download the JARs locally and pointModel Robolectric to them by doing:

```
./download-robolectric-deps.sh
10 changes: 5 additions & 5 deletions SPECIFICATION.md
Original file line number Diff line number Diff line change
@@ -129,7 +129,7 @@ Steps for creating the mapbox style with Kujaku configuration:
3. Add the Kujaku config

The Kujaku config is a JSON Object with the following:
1. `data_sources` JSON Array of `name`-only JSON Objects - The name points to the data source name in the style
1. `data_sources` JSON Array of `name`-only JSON Objects - The name pointModels to the data source name in the style
```json
"data_sources": [
{
@@ -238,7 +238,7 @@ public void addWmtsLayer(WmtsCapabilities capabilities, String layerIdentifier,

## 2. Using Tracking Service

The Tracking Service is a foreground service providing Locations points regarding some options.
The Tracking Service is a foreground service providing Locations pointModels regarding some options.
The application needs to register the TrackingService listener to be able to receive notifications when :
- First location as been received
- A new location has been recorded
@@ -351,7 +351,7 @@ The **MapActivity** will request some permissions(during runtime & in the manife
The `KujakuMapView` enables a developer to have low level access to the geo-spatial widget. The developer can access the Mapbox APIs exposed on the mapbox `MapView` and have the flexibility to implement the widget in whatever view they want.

Example usage:
1. Add point without GPS
1. Add pointModel without GPS

```java
kujakuMapView.addPoint(false, new AddPointCallback() {
@@ -369,7 +369,7 @@ Example usage:
});
```

2. Add point with GPS
2. Add pointModel with GPS

```java
kujakuMapView.addPoint(true, new AddPointCallback() {
@@ -382,7 +382,7 @@ Example usage:
public void onCancel() {
// Do something here -->
// 1. Explain to the user that a location is required
// 2. Give them the option of manually locating the point
// 2. Give them the option of manually locating the pointModel
}
});

17 changes: 8 additions & 9 deletions configs.gradle
Original file line number Diff line number Diff line change
@@ -101,26 +101,26 @@ ext.localProperties = properties
*/

ext {

// Dependency and other versions
androidxTestCoreVersion = "1.4.0"
compileSdkVersion = 34
jacocoVersion = "0.8.11"
junitVersion = "4.13.2"
mapboxAnnotationPluginVersion = "0.9.0"
mapboxSdkVersion = "9.7.1"
mapboxSdkTurfVersion = "7.2.0"
mapboxVersion = "10.19.0"
mapboxServicesVersion = "5.4.1" // For Services, GeoJSON, and Turf
robolectricVersion = "4.13"
supportVersion = "1.0.0"
volleyVersion = "1.2.1"
targetSdkVersion = 34

// Dependency names
androidxTestCore = "androidx.test:core:$androidxTestCoreVersion"
junit = "junit:junit:$junitVersion"
mapboxSDK = "com.mapbox.mapboxsdk:mapbox-android-sdk:$mapboxSdkVersion"
mapboxSDKTurf = "com.mapbox.mapboxsdk:mapbox-sdk-turf:$mapboxSdkTurfVersion"
mapboxAnnotationPlugin = "com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:$mapboxAnnotationPluginVersion"

mapboxSDK = "com.mapbox.maps:android:$mapboxVersion"
mapboxLocation = "com.mapbox.maps:plugin-locationcomponent:$mapboxVersion"
mapboxGestures = "com.mapbox.maps:plugin-gestures:$mapboxVersion"
mapboxStyleEx = "com.mapbox.maps:android-plugin-style-extension:$mapboxVersion"
mapboxSDKTurf = "com.mapbox.mapboxsdk:mapbox-sdk-turf:$mapboxServicesVersion"
robolectric = "org.robolectric:robolectric:$robolectricVersion"
}

@@ -138,7 +138,6 @@ ext.mapboxDependencies = { instance, configuration ->
// is a dependency of the mapbox-android-sdk. The mapbox-sdk-turf is declared as
// a runtime dependency
configuration.implementation "com.mapbox.mapboxsdk:mapbox-sdk-turf:$instance.mapboxSdkTurfVersion"
configuration.implementation "com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v7:${instance.mapboxAnnotationPluginVersion}"

}

5 changes: 4 additions & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
@@ -116,7 +116,10 @@ dependencies { configuration ->
// is a dependency of the mapbox-android-sdk. The mapbox-sdk-turf is declared as
// a runtime dependency
implementation mapboxSDKTurf
implementation mapboxAnnotationPlugin
implementation mapboxStyleEx
implementation mapboxLocation
implementation mapboxGestures
// implementation mapboxAnnotationPlugin

// Comment the line below when creating releases - The line is for development of the library & utils
implementation (project(":utils")) {
6 changes: 3 additions & 3 deletions library/src/main/java/io/ona/kujaku/KujakuLibrary.java
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@
import java.util.List;

import io.ona.kujaku.data.realm.RealmDatabase;
import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.exceptions.KujakuLibraryInitializationException;
import io.ona.kujaku.helpers.ActivityLauncherHelper;
import io.ona.kujaku.receivers.KujakuNetworkChangeReceiver;
@@ -87,8 +87,8 @@ public static void setEnableMapDownloadResume(boolean isEnableMapDownloadResume)
}

public void launchMapActivity(@NonNull Activity hostActivity, @NonNull String mapboxAccessToken
, @Nullable List<Point> points, boolean enableDropPoint) {
ActivityLauncherHelper.launchMapActivity(hostActivity, mapboxAccessToken, points, enableDropPoint);
, @Nullable List<PointModel> pointModels, boolean enableDropPoint) {
ActivityLauncherHelper.launchMapActivity(hostActivity, mapboxAccessToken, pointModels, enableDropPoint);
}

public void showToast(@NonNull String text) {
23 changes: 8 additions & 15 deletions library/src/main/java/io/ona/kujaku/activities/MapActivity.java
Original file line number Diff line number Diff line change
@@ -24,12 +24,7 @@
import android.widget.RelativeLayout;

import com.mapbox.geojson.Feature;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.maps.MapboxMap;

import org.json.JSONArray;
import org.json.JSONException;
@@ -44,7 +39,7 @@
import io.ona.kujaku.adapters.InfoWindowAdapter;
import io.ona.kujaku.adapters.InfoWindowObject;
import io.ona.kujaku.adapters.holders.InfoWindowViewHolder;
import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.helpers.storage.MapBoxStyleStorage;
import io.ona.kujaku.sorting.Sorter;
import io.ona.kujaku.utils.Constants;
@@ -76,7 +71,7 @@
* <p>
* Created by Ephraim Kigamba - ekigamba@ona.io
*/
public class MapActivity extends AppCompatActivity implements MapboxMap.OnMapClickListener {
public class MapActivity extends AppCompatActivity {
private static final int PERMISSIONS_REQUEST_CODE = 342;
private KujakuMapView kujakuMapView;
private String currentStylePath;
@@ -127,13 +122,11 @@ protected void onCreate(Bundle savedInstanceState) {
if (bundle != null
&& bundle.containsKey(Constants.PARCELABLE_KEY_MAPBOX_ACCESS_TOKEN)
&& bundle.getString(Constants.PARCELABLE_KEY_MAPBOX_ACCESS_TOKEN) != null) {
String mapBoxAccessToken = bundle.getString(Constants.PARCELABLE_KEY_MAPBOX_ACCESS_TOKEN);
Mapbox.getInstance(this, mapBoxAccessToken);
List<Point> points = bundle.getParcelableArrayList(PARCELABLE_POINTS_LIST);
List<PointModel> pointModels = bundle.getParcelableArrayList(PARCELABLE_POINTS_LIST);
enableDropPoint = bundle.getBoolean(ENABLE_DROP_POINT_BUTTON, false);

setContentView(R.layout.activity_map);
initializeViews(points, enableDropPoint);
initializeViews(pointModels, enableDropPoint);
checkPermissions(savedInstanceState);
} else {
finish();
@@ -270,7 +263,7 @@ private LatLng getBoundsCenter(LatLng topLeftBound, LatLng bottomRightBound) {
);
}

private void initializeViews(List<Point> points, boolean enableDropPoint) {
private void initializeViews(List<PointModel> pointModels, boolean enableDropPoint) {
dismissAllDialogs();
alertDialogs = new HashMap<>();
infoWindowsRecyclerView = findViewById(R.id.rv_mapActivity_infoWindow);
@@ -309,8 +302,8 @@ public void onClick(View v) {
});
btnDone.setVisibility(View.VISIBLE);

if (points != null) {
kujakuMapView.updateDroppedPoints(new ArrayList<>(points));
if (pointModels != null) {
kujakuMapView.updateDroppedPoints(new ArrayList<>(pointModels));
}
}
}
Original file line number Diff line number Diff line change
@@ -8,14 +8,14 @@
/**
* @author Vincent Karuri
*/
public class Point implements Parcelable {
public class PointModel implements Parcelable {

private Integer id;
private double lat;
private double lng;
private Long dateUpdated;

public Point(Integer id, double lat, double lng) {
public PointModel(Integer id, double lat, double lng) {
this.id = id;
this.lat = lat;
this.lng = lng;
@@ -55,12 +55,12 @@ public void setDateUpdated(Long dateUpdated) {

@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof Point)) {
if (o == null || !(o instanceof PointModel)) {
return false;
}
Point point = (Point) o;
return Double.compare(point.getLat(), getLat()) == 0 &&
Double.compare(point.getLng(), getLng()) == 0;
PointModel pointModel = (PointModel) o;
return Double.compare(pointModel.getLat(), getLat()) == 0 &&
Double.compare(pointModel.getLng(), getLng()) == 0;
}

@Override
@@ -69,19 +69,19 @@ public int hashCode() {
}

// Parcelable methods
public Point(Parcel in) {
public PointModel(Parcel in) {
this.id = in.readInt();
this.lat = in.readDouble();
this.lng = in.readDouble();
}

public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Point createFromParcel(Parcel in) {
return new Point(in);
public PointModel createFromParcel(Parcel in) {
return new PointModel(in);
}

public Point[] newArray(int size) {
return new Point[size];
public PointModel[] newArray(int size) {
return new PointModel[size];
}
};

Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -16,7 +15,7 @@

import io.ona.kujaku.activities.MapActivity;
import io.ona.kujaku.callables.AsyncTaskCallable;
import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.listeners.OnFinishedListener;
import io.ona.kujaku.tasks.GenericAsyncTask;
import io.ona.kujaku.utils.Constants;
@@ -35,7 +34,7 @@ public class ActivityLauncherHelper {
public static final String TAG = ActivityLauncherHelper.class.getName();

public static void launchMapActivity(@NonNull Activity hostActivity, @NonNull String mapboxAccessToken
, @Nullable List<Point> points, boolean enableDropPoint) {
, @Nullable List<PointModel> pointModels, boolean enableDropPoint) {
Intent intent = new Intent(hostActivity, MapActivity.class);
createCustomStyleLayer(hostActivity.getApplicationContext(), new OnFinishedListener() {
@Override
@@ -48,7 +47,7 @@ public void onSuccess(Object[] objects) {

intent.putExtra(Constants.PARCELABLE_KEY_MAPBOX_ACCESS_TOKEN, mapboxAccessToken);
intent.putExtra(ENABLE_DROP_POINT_BUTTON, enableDropPoint);
intent.putParcelableArrayListExtra(PARCELABLE_POINTS_LIST, (ArrayList<? extends Parcelable>) points);
intent.putParcelableArrayListExtra(PARCELABLE_POINTS_LIST, (ArrayList<? extends Parcelable>) pointModels);

hostActivity.startActivityForResult(intent, MAP_ACTIVITY_REQUEST_CODE);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package io.ona.kujaku.helpers;

import static com.mapbox.maps.plugin.Plugin.MAPBOX_LOCATION_COMPONENT_PLUGIN_ID;

import android.content.Context;
import android.content.pm.PackageManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.maps.MapView;
import com.mapbox.maps.plugin.LocationPuck2D;
import com.mapbox.maps.plugin.locationcomponent.LocationComponentPlugin;

import io.ona.kujaku.callbacks.OnLocationComponentInitializedCallback;

@@ -17,43 +19,51 @@
*/
public class MapboxLocationComponentWrapper {

private LocationComponent locationComponent;

private LocationComponentPlugin locationComponent;
private OnLocationComponentInitializedCallback onLocationComponentInitializedCallback;

/**
* Init Location Component Wrapper
*
* @param mapboxMap {@link MapboxMap}
* @param mapView {@link MapView}
* @param context
* @param locationRenderMode {@link RenderMode}
* @param showBearing whether to show bearing indicator
*/
@SuppressWarnings( {"MissingPermission"})
public void init(@NonNull MapboxMap mapboxMap, @NonNull Context context, int locationRenderMode) {
locationComponent = mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(context, mapboxMap.getStyle(), false);
locationComponent.setLocationComponentEnabled(true);
locationComponent.setCameraMode(CameraMode.NONE);
@SuppressWarnings({"MissingPermission"})
public void init(@NonNull MapView mapView, @NonNull Context context, boolean showBearing) {
locationComponent = mapView.getPlugin(MAPBOX_LOCATION_COMPONENT_PLUGIN_ID);

LocationPuck2D locationPuck = new LocationPuck2D();

PackageManager pm = context.getPackageManager();
if (pm != null && !pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS)) {
// This device does not have a compass, turn off the compass feature
locationComponent.setRenderMode(RenderMode.NORMAL);
} else {
locationComponent.setRenderMode(locationRenderMode);
boolean hasCompass = pm != null && pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS);

locationComponent.setLocationPuck(locationPuck);
locationComponent.setEnabled(true);

if (hasCompass && showBearing) {
locationPuck.setBearingImage(null);
locationComponent.setPulsingEnabled(true);
}

if (onLocationComponentInitializedCallback != null) {
onLocationComponentInitializedCallback.onLocationComponentInitialized();
}
}

/**
* Get the location component
* @return LocationComponentPlugin instance
*/
@Nullable
public LocationComponent getLocationComponent() {
return locationComponent;
public LocationComponentPlugin getLocationComponent() {
return locationComponent;
}

public void setOnLocationComponentInitializedCallback(OnLocationComponentInitializedCallback onLocationComponentInitializedCallback) {
this.onLocationComponentInitializedCallback = onLocationComponentInitializedCallback;
/**
* Set callback for when location component is initialized
* @param callback OnLocationComponentInitializedCallback
*/
public void setOnLocationComponentInitializedCallback(OnLocationComponentInitializedCallback callback) {
this.onLocationComponentInitializedCallback = callback;
}
}
}
40 changes: 21 additions & 19 deletions library/src/main/java/io/ona/kujaku/helpers/wmts/WmtsHelper.java
Original file line number Diff line number Diff line change
@@ -3,11 +3,11 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
import com.mapbox.mapboxsdk.style.sources.RasterSource;
import com.mapbox.mapboxsdk.style.sources.TileSet;
import com.mapbox.bindgen.Value;
import com.mapbox.maps.Style;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;

import io.ona.kujaku.exceptions.WmtsCapabilitiesException;
@@ -88,24 +88,26 @@ private static void setTilesSize(@NonNull WmtsLayer layer, @NonNull WmtsCapabili
/**
* Add all Wmts Layers in wmtsLayers on the map
*/
public static void addWmtsLayers(@Nullable Set<WmtsLayer> wmtsLayers,@NonNull Style style) {
// Add WmtsLayers
public static void addWmtsLayers(@Nullable Set<WmtsLayer> wmtsLayers, @NonNull Style style) {
if (wmtsLayers != null) {
for (WmtsLayer layer : wmtsLayers) {
if (style.getSource(layer.getIdentifier()) == null) {

TileSet tileSet = new TileSet("tileset", layer.getTemplateUrl("tile"));
tileSet.setMaxZoom(layer.getMaximumZoom());
tileSet.setMinZoom(layer.getMinimumZoom());

RasterSource webMapSource = new RasterSource(
layer.getIdentifier(),
tileSet, layer.getTilesSize());
style.addSource(webMapSource);

RasterLayer webMapLayer = new RasterLayer(layer.getIdentifier(), layer.getIdentifier());
style.addLayer(webMapLayer);
}
HashMap<String, Value> tilesetProperties = new HashMap<>();
tilesetProperties.put("type", Value.valueOf("raster"));
tilesetProperties.put("tiles", Value.valueOf(Arrays.toString(new String[]{layer.getTemplateUrl("tile")})));
tilesetProperties.put("maxzoom", Value.valueOf(layer.getMaximumZoom()));
tilesetProperties.put("minzoom", Value.valueOf(layer.getMinimumZoom()));
tilesetProperties.put("tileSize", Value.valueOf(layer.getTilesSize()));

style.addStyleSource(layer.getIdentifier(), Value.valueOf(tilesetProperties));

// Create raster layer properties
HashMap<String, Value> layerProperties = new HashMap<>();
layerProperties.put("id", Value.valueOf(layer.getIdentifier()));
layerProperties.put("type", Value.valueOf("raster"));
layerProperties.put("source", Value.valueOf(layer.getIdentifier()));
// Add layer
style.addStyleLayer(Value.valueOf(layerProperties),null);
}
}
}
17 changes: 7 additions & 10 deletions library/src/main/java/io/ona/kujaku/interfaces/IKujakuMapView.java
Original file line number Diff line number Diff line change
@@ -8,18 +8,15 @@
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.mapbox.geojson.FeatureCollection;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.maps.plugin.annotation.generated.PointAnnotationOptions;

import org.json.JSONException;

import java.util.List;

import io.ona.kujaku.callbacks.AddPointCallback;
import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.exceptions.TrackingServiceNotInitializedException;
import io.ona.kujaku.exceptions.WmtsCapabilitiesException;
import io.ona.kujaku.layers.ArrowLineLayer;
@@ -56,9 +53,9 @@ public interface IKujakuMapView extends IKujakuMapViewLowLevel {
* @param useGPS
* @param addPointCallback returns the location chosen by user from GPS or calls {@link AddPointCallback#onCancel()}
* if the user cancels the operation
* @param markerOptions Specifies the marker properties
* @param pointAnnotationOptions Specifies the marker properties
*/
void addPoint(boolean useGPS, @NonNull AddPointCallback addPointCallback, @Nullable MarkerOptions markerOptions);
void addPoint(boolean useGPS, @NonNull AddPointCallback addPointCallback, @Nullable PointAnnotationOptions pointAnnotationOptions);


/**
@@ -164,11 +161,11 @@ public interface IKujakuMapView extends IKujakuMapViewLowLevel {
/**
* This function updates the list of points displayed in KujakuMapView
* <p>
* This is done both in the internal {@link List<Point>} data structure and visually on the map using location markers defined by the user
* This is done both in the internal {@link List< PointModel >} data structure and visually on the map using location markers defined by the user
*
* @param points A list of {@link Point}
* @param pointModels A list of {@link PointModel}
*/
void updateDroppedPoints(List<Point> points);
void updateDroppedPoints(List<PointModel> pointModels);

/**
* Sets an {@link OnFeatureClickListener} which will be fired when a feature on the map in either of the {@code layerIds}
Original file line number Diff line number Diff line change
@@ -3,12 +3,9 @@
import androidx.annotation.DrawableRes;
import androidx.annotation.IntegerRes;
import androidx.annotation.Nullable;

import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;

import com.mapbox.maps.plugin.annotation.generated.PointAnnotationOptions;
import org.json.JSONObject;

import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.listeners.OnLocationChanged;

/**
@@ -52,11 +49,11 @@ public interface IKujakuMapViewLowLevel {
* disabling the marker layout, disabling GPS location updates, adding a point at @param latLng & returns a geoJSON
* feature at @param latLng
*
* @param markerOptions This specifies how the marker should look like
* @param pointAnnotationOptions This specifies how the marker should look like
*
* @return
*/
@Nullable JSONObject dropPoint(@Nullable MarkerOptions markerOptions);
@Nullable JSONObject dropPoint(@Nullable PointAnnotationOptions pointAnnotationOptions);

/**
* This should be called after calling {@link #enableAddPoint(boolean)} with {@code true} thus
@@ -74,21 +71,21 @@ public interface IKujakuMapViewLowLevel {
* disabling the marker layout, disabling GPS location updates, adding a point at @param latLng & returns a geoJSON
* feature at @param latLng
*
* @param latLng
* @param pointModel
*
* @return
*/
@Nullable JSONObject dropPoint(@Nullable LatLng latLng);
@Nullable JSONObject dropPoint(@Nullable PointModel pointModel);

/**
* This should be called after calling {@link #enableAddPoint(boolean, OnLocationChanged)} with {@code true} thus
* disabling the marker layout, disabling GPS location updates, adding a point at @param latLng & returns a geoJSON
* feature at @param latLng
*
* @param latLng
* @param pointModel
* @param markerResourceId This is the resource that should be shown as the marker
*
* @return
*/
@Nullable JSONObject dropPoint(@Nullable LatLng latLng, @DrawableRes int markerResourceId);
@Nullable JSONObject dropPoint(@Nullable PointModel pointModel, @DrawableRes int markerResourceId);
}
287 changes: 151 additions & 136 deletions library/src/main/java/io/ona/kujaku/views/KujakuMapView.java

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions library/src/main/res/layout/mapbox_mapview_internal.xml
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
android:background="@android:color/transparent"
android:contentDescription="@null"/>

<com.mapbox.mapboxsdk.maps.widgets.CompassView
<com.mapbox.maps.plugin.compass.CompassViewImpl
android:id="@+id/compassView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -38,7 +38,7 @@
<!-- END OF MAPBOX VIEW XML -->

<!-- START OF CUSTOM VIEWS ADDED TO KujakuMapView -->
<!-- This is the drop point layout used to simulate the position on which the user wants to drop a point -->
<!-- This is the drop pointModel layout used to simulate the position on which the user wants to drop a pointModel -->
<ImageView
android:id="@+id/iv_mapview_locationSelectionMarker"
android:layout_width="wrap_content"
2 changes: 1 addition & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ private static void libraryModuleDevelopment(instance, configuration) {

configuration.implementation instance.mapboxSDKTurf

configuration.implementation instance.mapboxAnnotationPlugin
// configuration.implementation instance.mapboxAnnotationPlugin
}

// This is used when making a release and you need to test that the published artifacts work in host applications OK
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
import org.junit.Before;
import org.junit.Test;

import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.sample.repository.PointsRepository;

import static io.ona.kujaku.sample.util.Constants.DATABASE_NAME;
@@ -30,35 +30,35 @@ public void tearDown() {

@Test
public void testAddOrUpdateShouldAddNewPoint() {
Point point = new Point(null, 1, 3);
database.addOrUpdate(point);
PointModel pointModel = new PointModel(null, 1, 3);
database.addOrUpdate(pointModel);
assertEquals(1, database.getAllPoints().size());
}

@Test
public void testGetAllPointsShouldGetAllAddedPoints() {
Point point = new Point(null, 1, 3);
database.addOrUpdate(point);
point = new Point(null, 4, 7);
database.addOrUpdate(point);
point = new Point(null, 9, 10);
database.addOrUpdate(point);
PointModel pointModel = new PointModel(null, 1, 3);
database.addOrUpdate(pointModel);
pointModel = new PointModel(null, 4, 7);
database.addOrUpdate(pointModel);
pointModel = new PointModel(null, 9, 10);
database.addOrUpdate(pointModel);
assertEquals(3, database.getAllPoints().size());
}

@Test
public void testGetPointByIdShouldGetAddedPointById() {
Point expectedPoint = new Point(null, 1, 3);
database.addOrUpdate(expectedPoint);
PointModel expectedPointModel = new PointModel(null, 1, 3);
database.addOrUpdate(expectedPointModel);

Point point = new Point(null, 4, 7);
database.addOrUpdate(point);
point = new Point(null, 9, 10);
database.addOrUpdate(point);
PointModel pointModel = new PointModel(null, 4, 7);
database.addOrUpdate(pointModel);
pointModel = new PointModel(null, 9, 10);
database.addOrUpdate(pointModel);

Point actualPoint = database.getPoint("1");
assertEquals((int) actualPoint.getId(), 1);
assertEquals(actualPoint.getLat(), expectedPoint.getLat());
assertEquals(actualPoint.getLng(), expectedPoint.getLng());
PointModel actualPointModel = database.getPoint("1");
assertEquals((int) actualPointModel.getId(), 1);
assertEquals(actualPointModel.getLat(), expectedPointModel.getLat());
assertEquals(actualPointModel.getLng(), expectedPointModel.getLng());
}
}
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ private void initializeFromGenericLayer() {
.target(new LatLng(-1.284956, 36.768831))
.zoom(16)
.build();
kujakuMapView.setCameraPosition(cameraPosition);
kujakuMapView.setCameraState(cameraPosition);
}

private void initializeFromStyleSource() {
@@ -82,7 +82,7 @@ private void initializeFromStyleSource() {
.target(new LatLng(-14.1706623, 32.5987837))
.zoom(16)
.build();
kujakuMapView.setCameraPosition(cameraPosition);
kujakuMapView.setCameraState(cameraPosition);
File mbFilesDir = new File(Environment.getExternalStorageDirectory().getPath() + MBTilesHelper.MB_TILES_DIRECTORY);
kujakuMapView.getMapAsync(new OnMapReadyCallback() {
@Override
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ private void initializeGenericLayer() {
.target(new LatLng(-1.284956, 36.768831))
.zoom(16)
.build();
kujakuMapView.setCameraPosition(cameraPosition);
kujakuMapView.setCameraState(cameraPosition);
}

private void addPointsToMap(LatLng latLng) {
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
@@ -35,7 +34,7 @@
import es.dmoral.toasty.Toasty;
import io.ona.kujaku.KujakuLibrary;
import io.ona.kujaku.callables.AsyncTaskCallable;
import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.helpers.storage.MapBoxStyleStorage;
import io.ona.kujaku.helpers.MapBoxWebServiceApi;
import io.ona.kujaku.helpers.OfflineServiceHelper;
@@ -47,7 +46,6 @@
import io.ona.kujaku.tasks.GenericAsyncTask;
import io.ona.kujaku.utils.Constants;
import io.ona.kujaku.utils.Permissions;
import timber.log.Timber;

import static io.ona.kujaku.utils.Constants.MAP_ACTIVITY_REQUEST_CODE;
import static io.ona.kujaku.utils.Constants.NEW_FEATURE_POINTS_JSON;
@@ -74,7 +72,7 @@ public class MainActivity extends BaseNavigationDrawerActivity {
private int lastNotificationId = 2081;
private final static String TAG = MainActivity.class.getSimpleName();

private List<Point> points;
private List<PointModel> pointModels;

private Activity mainActivity = this;

@@ -153,8 +151,8 @@ public void onClick(View v) {
final OnFinishedListener onPointsFetchFinishedListener = new OnFinishedListener() {
@Override
public void onSuccess(Object[] objects) {
points = (List<Point>) objects[0];
KujakuLibrary.getInstance().launchMapActivity(mainActivity, BuildConfig.MAPBOX_SDK_ACCESS_TOKEN, points, true);
pointModels = (List<PointModel>) objects[0];
KujakuLibrary.getInstance().launchMapActivity(mainActivity, BuildConfig.MAPBOX_SDK_ACCESS_TOKEN, pointModels, true);
}
@Override
public void onError(Exception e) {
@@ -167,10 +165,10 @@ public void onError(Exception e) {
@Override
public void onClick(View v) {
// TODO: will need to figure out how to get new points added after initial MainActivity instantiation
if (points == null || points.size() == 0) {
if (pointModels == null || pointModels.size() == 0) {
fetchDroppedPoints(onPointsFetchFinishedListener);
} else {
KujakuLibrary.getInstance().launchMapActivity(mainActivity, BuildConfig.MAPBOX_SDK_ACCESS_TOKEN, points, true);
KujakuLibrary.getInstance().launchMapActivity(mainActivity, BuildConfig.MAPBOX_SDK_ACCESS_TOKEN, pointModels, true);
}
}
});
@@ -181,10 +179,10 @@ public void onClick(View v) {
@Override
public void onClick(View v) {
// TODO: will need to figure out how to get new points added after initial MainActivity instantiation
if (points == null || points.size() == 0) {
if (pointModels == null || pointModels.size() == 0) {
fetchDroppedPoints(onPointsFetchFinishedListener);
} else {
KujakuLibrary.getInstance().launchMapActivity(mainActivity, BuildConfig.MAPBOX_SDK_ACCESS_TOKEN, points, true);
KujakuLibrary.getInstance().launchMapActivity(mainActivity, BuildConfig.MAPBOX_SDK_ACCESS_TOKEN, pointModels, true);
}
}
});
@@ -194,8 +192,8 @@ private void fetchDroppedPoints(OnFinishedListener onFinishedListener) {
GenericAsyncTask genericAsyncTask = new GenericAsyncTask(new AsyncTaskCallable() {
@Override
public Object[] call() throws Exception {
List<Point> droppedPoints = MyApplication.getInstance().getPointsRepository().getAllPoints();
return new Object[]{droppedPoints};
List<PointModel> droppedPointModels = MyApplication.getInstance().getPointsRepository().getAllPoints();
return new Object[]{droppedPointModels};
}
});
genericAsyncTask.setOnFinishedListener(onFinishedListener);
@@ -443,10 +441,10 @@ public Object[] call() throws Exception {
try {
JSONObject featurePoint = new JSONObject(geoJSONFeature);
JSONArray coordinates = featurePoint.getJSONObject("geometry").getJSONArray("coordinates");
Point newPoint = new Point(null, (double) coordinates.get(1), (double) coordinates.get(0));
MyApplication.getInstance().getPointsRepository().addOrUpdate(newPoint);
newPoint.setId((int) (Math.random() * Integer.MAX_VALUE));
points.add(newPoint);
PointModel newPointModel = new PointModel(null, (double) coordinates.get(1), (double) coordinates.get(0));
MyApplication.getInstance().getPointsRepository().addOrUpdate(newPointModel);
newPointModel.setId((int) (Math.random() * Integer.MAX_VALUE));
pointModels.add(newPointModel);
} catch (Exception e) {
Log.e(TAG, "JsonArray parse error occured");
}
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
import java.util.List;

import io.ona.kujaku.callbacks.OnLocationServicesEnabledCallBack;
import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;
import io.ona.kujaku.exceptions.TrackingServiceNotInitializedException;
import io.ona.kujaku.listeners.TrackingServiceListener;
import io.ona.kujaku.location.KujakuLocation;
@@ -116,11 +116,11 @@ private void InitRecordingButton() {
}

private void displayTracksRecorded(List<KujakuLocation> locations) {
List<Point> points = new ArrayList<>();
List<PointModel> pointModels = new ArrayList<>();
for (KujakuLocation location: locations) {
points.add(new Point(location.hashCode(), location.getLatitude(), location.getLongitude()));
pointModels.add(new PointModel(location.hashCode(), location.getLatitude(), location.getLongitude()));
}
kujakuMapView.updateDroppedPoints(points);
kujakuMapView.updateDroppedPoints(pointModels);
}

/**** TrackingServiceListener ****/
@@ -146,9 +146,9 @@ public void onFirstLocationReceived(KujakuLocation location) {
@Override
public void onNewLocationReceived(KujakuLocation location) {
Toast.makeText(getApplicationContext(), "New Location received", Toast.LENGTH_SHORT).show();
List<Point> points = new ArrayList<>();
points.add(new Point(location.hashCode(), location.getLatitude(), location.getLongitude()));
kujakuMapView.updateDroppedPoints(points);
List<PointModel> pointModels = new ArrayList<>();
pointModels.add(new PointModel(location.hashCode(), location.getLatitude(), location.getLongitude()));
kujakuMapView.updateDroppedPoints(pointModels);
}

@Override
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
import java.util.Calendar;
import java.util.List;

import io.ona.kujaku.domain.Point;
import io.ona.kujaku.domain.PointModel;

import static io.ona.kujaku.sample.util.Constants.INSERT_OR_REPLACE;

@@ -47,68 +47,68 @@ public static void createTable(SQLiteDatabase database) {
database.execSQL(CREATE_POINTS_TABLE);
}

public void addOrUpdate(Point point) {
public void addOrUpdate(PointModel pointModel) {

if (point == null) {
if (pointModel == null) {
return;
}

if (point.getDateUpdated() == null) {
point.setDateUpdated(Calendar.getInstance().getTimeInMillis());
if (pointModel.getDateUpdated() == null) {
pointModel.setDateUpdated(Calendar.getInstance().getTimeInMillis());
}

try {
SQLiteDatabase database = getWritableDatabase();

String query = String.format(INSERT_OR_REPLACE, POINTS_TABLE);
query += "(" + StringUtils.repeat("?", ",", POINTS_TABLE_COLUMNS.length) + ")";
database.execSQL(query, createQueryValues(point));
database.execSQL(query, createQueryValues(pointModel));
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}

public List<Point> getAllPoints() {
public List<PointModel> getAllPoints() {

List<Point> points = new ArrayList<>();
List<PointModel> pointModels = new ArrayList<>();
Cursor cursor = null;
try {
cursor = getReadableDatabase().rawQuery("SELECT * " + " FROM " + POINTS_TABLE, null);
points = readPoints(cursor);
pointModels = readPoints(cursor);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
} finally {
if (cursor != null) {
cursor.close();
}
}
return points;
return pointModels;
}

public Point getPoint(String id) {
Point point = null;
public PointModel getPoint(String id) {
PointModel pointModel = null;
Cursor cursor = null;
try {
cursor = getReadableDatabase().rawQuery("SELECT * " + " FROM " + POINTS_TABLE + " WHERE " + ID + "=?", new String[]{id});
List<Point> points = readPoints(cursor);
point = points.size() > 0 ? points.get(0) : null;
List<PointModel> pointModels = readPoints(cursor);
pointModel = pointModels.size() > 0 ? pointModels.get(0) : null;
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
} finally {
if (cursor != null) {
cursor.close();
}
}
return point;
return pointModel;
}

private List<Point> readPoints(Cursor cursor) {
private List<PointModel> readPoints(Cursor cursor) {

List<Point> points = new ArrayList<>();
List<PointModel> pointModels = new ArrayList<>();
try {
if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
points.add(createPoint(cursor));
pointModels.add(createPoint(cursor));
cursor.moveToNext();
}
}
@@ -119,24 +119,24 @@ private List<Point> readPoints(Cursor cursor) {
cursor.close();
}
}
return points;
return pointModels;
}

@SuppressLint("Range")
private Point createPoint(Cursor cursor) {
return new Point(
private PointModel createPoint(Cursor cursor) {
return new PointModel(
cursor.getInt(cursor.getColumnIndex(ID)),
cursor.getDouble(cursor.getColumnIndex(LAT)),
cursor.getDouble(cursor.getColumnIndex(LNG))
);
}

private Object[] createQueryValues(Point point) {
private Object[] createQueryValues(PointModel pointModel) {
Object[] values = new Object[]{
point.getId(),
point.getLat(),
point.getLng(),
point.getDateUpdated()
pointModel.getId(),
pointModel.getLat(),
pointModel.getLng(),
pointModel.getDateUpdated()
};
return values;
}
2 changes: 1 addition & 1 deletion sample/src/main/res/layout/mapbox_mapview_internal.xml
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@
<!-- END OF MAPBOX VIEW XML -->

<!-- START OF CUSTOM VIEWS ADDED TO KujakuMapView -->
<!-- This is the drop point layout used to simulate the position on which the user wants to drop a point -->
<!-- This is the drop pointModel layout used to simulate the position on which the user wants to drop a pointModel -->
<ImageView
android:id="@+id/iv_mapview_locationSelectionMarker"
android:layout_width="wrap_content"
2 changes: 1 addition & 1 deletion sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@
<string name="padded_bbox_calculator">Padded Bbox Calculator</string>
<string name="drop_point">Drop Point</string>
<string name="generate_padded_bbox">Generate Padded Bbox</string>
<string name="first_add_some_points">First add some points</string>
<string name="first_add_some_points">First add some pointModels</string>
<string name="start_offline_downloading_using_helper">Start Offline Downloading Using Helper</string>
<string name="stop_offline_download_using_helper">Stop Offline Download Using Helper</string>
<string name="delete_offline_map_using_helper">Delete Offline Map Using Helper</string>
3 changes: 3 additions & 0 deletions utils/build.gradle
Original file line number Diff line number Diff line change
@@ -62,6 +62,9 @@ dependencies {
// is a dependency of the mapbox-android-sdk. The mapbox-sdk-turf is declared as
// a runtime dependency
implementation mapboxSDKTurf
implementation mapboxStyleEx
implementation mapboxLocation
implementation mapboxGestures
//implementation mapboxAnnotationPlugin

testImplementation junit