Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[ios][android] SDK Bindings for Image Sources #9110

Merged
merged 5 commits into from
Jun 19, 2017
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions platform/android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started.

## master
* Add support for ImageSource [#9110](https://github.com/mapbox/mapbox-gl-native/pull/9110)

## 5.1.0 - TBA
* Fix tracking mode + camera race condition [#9133](https://github.com/mapbox/mapbox-gl-native/pull/9133)
* Harden orientation changes [#9128](https://github.com/mapbox/mapbox-gl-native/pull/9128)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.mapbox.mapboxsdk.geometry;

import android.os.Parcel;
import android.os.Parcelable;

/**
* A geographical area representing a non-aligned quadrilateral
* <p>
* This class does not wrap values to the world bounds
* </p>
*/
public class LatLngQuad implements Parcelable {

private final LatLng topLeft;
private final LatLng topRight;
private final LatLng bottomRight;
private final LatLng bottomLeft;

/**
* Construct a new LatLngQuad based on its corners,
* in order top left, top right, bottom left, bottom right
*/
public LatLngQuad(final LatLng topLeft, final LatLng topRight, final LatLng bottomRight, final LatLng bottomLeft) {
this.topLeft = topLeft;
this.topRight = topRight;
this.bottomRight = bottomRight;
this.bottomLeft = bottomLeft;
}

public LatLng getTopLeft() {
return this.topLeft;
}

public LatLng getTopRight() {
return this.topRight;
}

public LatLng getBottomRight() {
return this.bottomRight;
}

public LatLng getBottomLeft() {
return this.bottomLeft;
}

public static final Parcelable.Creator<LatLngQuad> CREATOR = new Parcelable.Creator<LatLngQuad>() {
@Override
public LatLngQuad createFromParcel(final Parcel in) {
return readFromParcel(in);
}

@Override
public LatLngQuad[] newArray(final int size) {
return new LatLngQuad[size];
}
};

@Override
public int hashCode() {
int code = topLeft.hashCode();
code = (code ^ code >>> 31) + topRight.hashCode();
code = (code ^ code >>> 31) + bottomRight.hashCode();
code = (code ^ code >>> 31) + bottomLeft.hashCode();
return code;
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(final Parcel out, final int arg1) {
topLeft.writeToParcel(out, arg1);
topRight.writeToParcel(out, arg1);
bottomRight.writeToParcel(out, arg1);
bottomLeft.writeToParcel(out, arg1);
}

private static LatLngQuad readFromParcel(final Parcel in) {
final LatLng topLeft = new LatLng(in);
final LatLng topRight = new LatLng(in);
final LatLng bottomRight = new LatLng(in);
final LatLng bottomLeft = new LatLng(in);
return new LatLngQuad(topLeft, topRight, bottomRight, bottomLeft);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package com.mapbox.mapboxsdk.style.sources;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.v4.content.ContextCompat;

import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.geometry.LatLngQuad;

import java.net.URL;


/**
* Image source, allows a georeferenced raster image to be shown on the map.
* <p>
* The georeferenced image scales and rotates as the user zooms and rotates the map.
* The geographic location of the raster image content, supplied with `LatLngQuad`,
* can be non-axis aligned.
* </p>
* * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-image">the style specification</a>
*/
@UiThread
public class ImageSource extends Source {

/**
* Internal use
*
* @param nativePtr - pointer to native peer
*/
public ImageSource(long nativePtr) {
super(nativePtr);
}

/**
* Create an ImageSource from coordinates and an image URL
*
* @param id The source id
* @param coordinates The Latitude and Longitude of the four corners of the image
* @param url remote json file
*/
public ImageSource(String id, LatLngQuad coordinates, URL url) {
initialize(id, coordinates);
setUrl(url);
}

/**
* Create an ImageSource from coordinates and a bitmap image
*
* @param id The source id
* @param coordinates The Latitude and Longitude of the four corners of the image
* @param bitmap A Bitmap image
*/
public ImageSource(String id, LatLngQuad coordinates, @NonNull android.graphics.Bitmap bitmap) {
initialize(id, coordinates);
setImage(bitmap);
}

/**
* Create an ImageSource from coordinates and a bitmap image resource
*
* @param id The source id
* @param coordinates The Latitude and Longitude of the four corners of the image
* @param resourceId The resource ID of a Bitmap image
*/
public ImageSource(String id, LatLngQuad coordinates, @DrawableRes int resourceId) {
initialize(id, coordinates);
setImage(resourceId);
}

/**
* Updates the source image url
*
* @param url An Image url
*/
public void setUrl(URL url) {
setUrl(url.toExternalForm());
}

/**
* Updates the source image url
*
* @param url An image url
*/
public void setUrl(String url) {
nativeSetUrl(url);
}

/**
* Updates the source image to a bitmap
*
* @param bitmap A Bitmap image
*/
public void setImage(@NonNull android.graphics.Bitmap bitmap) {
nativeSetImage(bitmap);
}

/**
* Updates the source image to a bitmap image resource
*
* @param resourceId The resource ID of a Bitmap image
*/
public void setImage(@DrawableRes int resourceId) throws IllegalArgumentException {
Context context = Mapbox.getApplicationContext();
Drawable drawable = ContextCompat.getDrawable(context, resourceId);
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
nativeSetImage(bitmapDrawable.getBitmap());
} else {
throw new IllegalArgumentException("Failed to decode image. The resource provided must be a Bitmap.");
}
}

/**
* @return The url or null
*/
@Nullable
public String getUrl() {
return nativeGetUrl();
}

protected native void initialize(String layerId, LatLngQuad payload);

protected native void nativeSetUrl(String url);

protected native String nativeGetUrl();

protected native void nativeSetImage(Bitmap bitmap);

@Override
protected native void finalize() throws Throwable;
}
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,17 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity"/>
</activity>
<activity
android:name=".activity.style.AnimatedImageSourceActivity"
android:label="@string/activity_animated_image_source"
android:description="@string/description_animated_image_source">
<meta-data
android:name="@string/category"
android:value="@string/category_style"/>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity"/>
</activity>

<!-- Features -->
<activity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.mapbox.mapboxsdk.testapp.activity.style;

import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;

import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngQuad;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
import com.mapbox.mapboxsdk.style.sources.ImageSource;

import com.mapbox.mapboxsdk.testapp.R;

/**
* Test activity showing how to use a series of images to create an animation
* with an ImageSource
* <p>
* GL-native equivalent of https://www.mapbox.com/mapbox-gl-js/example/animate-images/
* </p>
*/
public class AnimatedImageSourceActivity extends AppCompatActivity implements OnMapReadyCallback {

private static final String ID_IMAGE_SOURCE = "animated_image_source";
private static final String ID_IMAGE_LAYER = "animated_image_layer";

private MapView mapView;
private MapboxMap mapboxMap;

private Handler handler;
private Runnable runnable;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animated_image_source);

mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}

@Override
public void onMapReady(@NonNull final MapboxMap map) {
mapboxMap = map;

// add source
LatLngQuad quad = new LatLngQuad(
new LatLng(46.437, -80.425),
new LatLng(46.437, -71.516),
new LatLng(37.936, -71.516),
new LatLng(37.936, -80.425));
mapboxMap.addSource(new ImageSource(ID_IMAGE_SOURCE, quad, R.drawable.southeast_radar_0));

// add layer
RasterLayer layer = new RasterLayer(ID_IMAGE_LAYER, ID_IMAGE_SOURCE);
mapboxMap.addLayer(layer);

// loop refresh geojson
handler = new Handler();
runnable = new RefreshImageRunnable(mapboxMap, handler);
handler.postDelayed(runnable, 100);
}

@Override
protected void onStart() {
super.onStart();
mapView.onStart();
}

@Override
public void onResume() {
super.onResume();
mapView.onResume();
}

@Override
public void onPause() {
super.onPause();
mapView.onPause();
}

@Override
protected void onStop() {
super.onStop();
mapView.onStop();
handler.removeCallbacks(runnable);
}

@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}

private static class RefreshImageRunnable implements Runnable {

private MapboxMap mapboxMap;
private Handler handler;
private int[] drawables;
private int drawableIndex;

RefreshImageRunnable(MapboxMap mapboxMap, Handler handler) {
this.mapboxMap = mapboxMap;
this.handler = handler;
drawables = new int[4];
drawables[0] = R.drawable.southeast_radar_0;
drawables[1] = R.drawable.southeast_radar_1;
drawables[2] = R.drawable.southeast_radar_2;
drawables[3] = R.drawable.southeast_radar_3;
drawableIndex = 1;
}

@Override
public void run() {
((ImageSource) mapboxMap.getSource(ID_IMAGE_SOURCE)).setImage(drawables[drawableIndex++]);
if (drawableIndex > 3) {
drawableIndex = 0;
}
handler.postDelayed(this, 1000);
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading