Split out Android examples to separate documentation site (#2978)

This commit is contained in:
Bart Louwers
2024-11-13 18:19:42 +01:00
committed by GitHub
parent 0bac36d8f6
commit b4b779dd29
41 changed files with 2923 additions and 1085 deletions

View File

@@ -27,7 +27,7 @@ import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Locale
/* ANCHOR: top */
// # --8<-- [start:top]
class JsonApiActivity : AppCompatActivity() {
// Declare a variable for MapView
@@ -35,7 +35,7 @@ class JsonApiActivity : AppCompatActivity() {
// Declare a variable for MapLibreMap
private lateinit var maplibreMap: MapLibreMap
/* ANCHOR_END: top */
// # --8<-- [end:top]
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -48,7 +48,7 @@ class JsonApiActivity : AppCompatActivity() {
// Init the MapView
mapView = findViewById(R.id.mapView)
/* ANCHOR: mapAsync */
// # --8<-- [start:mapAsync]
mapView.getMapAsync { map ->
maplibreMap = map
@@ -57,10 +57,10 @@ class JsonApiActivity : AppCompatActivity() {
// Fetch data from USGS
getEarthQuakeDataFromUSGS()
}
/* ANCHOR_END: mapAsync */
// # --8<-- [end:mapAsync]
}
/* ANCHOR: getEarthquakes */
// # --8<-- [start:getEarthquakes]
// Get Earthquake data from usgs.gov, read API doc at:
// https://earthquake.usgs.gov/fdsnws/event/1/
private fun getEarthQuakeDataFromUSGS() {
@@ -91,9 +91,9 @@ class JsonApiActivity : AppCompatActivity() {
}
})
}
/* ANCHOR_END: getEarthquakes */
// # --8<-- [end:getEarthquakes]
/* ANCHOR: addMarkers */
// # --8<-- [start:addMarkers]
private fun addMarkersToMap(data: FeatureCollection) {
val bounds = mutableListOf<LatLng>()
@@ -146,7 +146,7 @@ class JsonApiActivity : AppCompatActivity() {
maplibreMap.cameraPosition = newCameraPosition
}
}
/* ANCHOR_END: addMarkers */
// # --8<-- [end:addMarkers]
override fun onStart() {
super.onStart()

View File

@@ -110,6 +110,7 @@ class GestureDetectorActivity : AppCompatActivity() {
}
fun attachListeners() {
// # --8<-- [start:addOnMoveListener]
maplibreMap.addOnMoveListener(
object : OnMoveListener {
override fun onMoveBegin(detector: MoveGestureDetector) {
@@ -132,6 +133,7 @@ class GestureDetectorActivity : AppCompatActivity() {
}
}
)
// # --8<-- [end:addOnMoveListener]
maplibreMap.addOnRotateListener(
object : OnRotateListener {
override fun onRotateBegin(detector: RotateGestureDetector) {

View File

@@ -52,6 +52,7 @@ class LatLngBoundsActivity : AppCompatActivity() {
binding.mapView.getMapAsync { map ->
maplibreMap = map
// # --8<-- [start:featureCollection]
val featureCollection: FeatureCollection =
fromJson(GeoParseUtil.loadStringFromAssets(this, "points-sf.geojson"))
bounds = createBounds(featureCollection)
@@ -59,6 +60,7 @@ class LatLngBoundsActivity : AppCompatActivity() {
map.getCameraForLatLngBounds(bounds, createPadding(peekHeight))?.let {
map.cameraPosition = it
}
// # --8<-- [end:featureCollection]
try {
loadStyle(featureCollection)
@@ -71,7 +73,7 @@ class LatLngBoundsActivity : AppCompatActivity() {
private fun loadStyle(featureCollection: FeatureCollection) {
maplibreMap.setStyle(
Style.Builder()
.fromUri(TestStyles.getPredefinedStyleWithFallback("Streets"))
.fromUri(TestStyles.VERSATILES)
.withLayer(
SymbolLayer("symbol", "symbol")
.withProperties(
@@ -129,6 +131,7 @@ class LatLngBoundsActivity : AppCompatActivity() {
return intArrayOf(additionalPadding, additionalPadding, additionalPadding, bottomPadding)
}
// # --8<-- [start:createBounds]
private fun createBounds(featureCollection: FeatureCollection): LatLngBounds {
val boundsBuilder = LatLngBounds.Builder()
featureCollection.features()?.let {
@@ -139,6 +142,7 @@ class LatLngBoundsActivity : AppCompatActivity() {
}
return boundsBuilder.build()
}
// # --8<-- [end:createBounds]
override fun onStart() {
super.onStart()

View File

@@ -21,7 +21,7 @@ import org.maplibre.android.maps.Style
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
/* ANCHOR: top */
// # --8<-- [start:top]
/**
* This activity shows a basic usage of the LocationComponent's pulsing circle. There's no
* customization of the pulsing circle's color, radius, speed, etc.
@@ -43,9 +43,9 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
mapView.onCreate(savedInstanceState)
checkPermissions()
}
/* ANCHOR_END: top */
// # --8<-- [end:top]
/* ANCHOR: onMapReady */
// # --8<-- [start:onMapReady]
@SuppressLint("MissingPermission")
override fun onMapReady(maplibreMap: MapLibreMap) {
this.maplibreMap = maplibreMap
@@ -63,9 +63,9 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
locationComponent!!.forceLocationUpdate(lastLocation)
}
}
/* ANCHOR_END: onMapReady */
// # --8<-- [end:onMapReady]
/* ANCHOR: LocationComponentActivationOptions */
// # --8<-- [start:LocationComponentActivationOptions]
private fun buildLocationComponentActivationOptions(
style: Style,
locationComponentOptions: LocationComponentOptions
@@ -82,7 +82,7 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
)
.build()
}
/* ANCHOR_END: LocationComponentActivationOptions */
// # --8<-- [end:LocationComponentActivationOptions]
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_pulsing_location_mode, menu)
@@ -136,7 +136,7 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
maplibreMap.setStyle(Style.Builder().fromUri(Utils.nextStyle()))
}
/* ANCHOR: permission */
// # --8<-- [start:permission]
private fun checkPermissions() {
if (PermissionsManager.areLocationPermissionsGranted(this)) {
mapView.getMapAsync(this)
@@ -170,7 +170,7 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
/* ANCHOR_END: permission */
// # --8<-- [end:permission]
override fun onStart() {
super.onStart()

View File

@@ -22,10 +22,8 @@ import org.maplibre.android.snapshotter.MapSnapshotter
import org.maplibre.android.style.expressions.Expression
import org.maplibre.android.style.layers.Property
import org.maplibre.android.style.layers.PropertyFactory
import org.maplibre.android.style.layers.RasterLayer
import org.maplibre.android.style.layers.SymbolLayer
import org.maplibre.android.style.sources.GeoJsonSource
import org.maplibre.android.style.sources.RasterSource
import org.maplibre.android.style.sources.Source
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
@@ -35,11 +33,13 @@ import java.util.Objects
import java.util.Random
/**
* Test activity showing how to use a the [com.mapbox.mapboxsdk.snapshotter.MapSnapshotter]
* Test activity showing how to use the [MapSnapshotter]
*/
class MapSnapshotterActivity : AppCompatActivity() {
lateinit var grid: GridLayout
private val snapshotters: MutableList<MapSnapshotter> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map_snapshotter)
@@ -47,81 +47,81 @@ class MapSnapshotterActivity : AppCompatActivity() {
// Find the grid view and start snapshotting as soon
// as the view is measured
grid = findViewById(R.id.snapshot_grid)
grid.getViewTreeObserver()
.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
grid.getViewTreeObserver().removeOnGlobalLayoutListener(this)
addSnapshots()
}
})
grid.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
grid.viewTreeObserver.removeOnGlobalLayoutListener(this)
addSnapshots()
}
})
}
private fun addSnapshots() {
Timber.i("Creating snapshotters")
for (row in 0 until grid.rowCount) {
for (column in 0 until grid.columnCount) {
startSnapShot(row, column)
startSnapshot(row, column)
}
}
}
private fun startSnapShot(row: Int, column: Int) {
// Optionally the style
val builder = Style.Builder()
.fromUri(
TestStyles.getPredefinedStyleWithFallback(
if ((column + row) % 2 == 0) {
"Streets"
} else {
"Pastel"
}
)
)
// # --8<-- [start:startSnapshot]
private fun startSnapshot(row: Int, column: Int) {
// # --8<-- [start:styleBuilder]
val styles = arrayOf(
TestStyles.DEMOTILES,
TestStyles.AMERICANA,
TestStyles.OPENFREEMAP_LIBERY,
TestStyles.AWS_OPEN_DATA_STANDARD_LIGHT,
TestStyles.PROTOMAPS_LIGHT,
TestStyles.PROTOMAPS_DARK,
TestStyles.PROTOMAPS_WHITE,
TestStyles.PROTOMAPS_GRAYSCALE,
TestStyles.VERSATILES
)
val builder = Style.Builder().fromUri(
styles[(row * grid.rowCount + column) % styles.size]
)
// # --8<-- [end:styleBuilder]
// Define the dimensions
// # --8<-- [start:mapSnapShotterOptions]
val options = MapSnapshotter.Options(
grid.measuredWidth / grid.columnCount,
grid.measuredHeight / grid.rowCount
) // Optionally the pixel ratio
)
.withPixelRatio(1f)
.withLocalIdeographFontFamily(MapLibreConstants.DEFAULT_FONT)
// # --8<-- [end:mapSnapShotterOptions]
// Optionally the visible region
// # --8<-- [start:setRegion]
if (row % 2 == 0) {
options.withRegion(
LatLngBounds.Builder()
.include(
LatLng(
randomInRange(-80f, 80f).toDouble(),
randomInRange(-160f, 160f)
.toDouble()
randomInRange(-160f, 160f).toDouble()
)
)
.include(
LatLng(
randomInRange(-80f, 80f).toDouble(),
randomInRange(-160f, 160f)
.toDouble()
randomInRange(-160f, 160f).toDouble()
)
)
.build()
)
}
// # --8<-- [end:setRegion]
// Optionally the camera options
// # --8<-- [start:setCameraPosition]
if (column % 2 == 0) {
options.withCameraPosition(
CameraPosition.Builder()
.target(
if (options.region != null) {
options.region!!.center
} else {
LatLng(
randomInRange(-80f, 80f).toDouble(),
randomInRange(-160f, 160f)
.toDouble()
)
}
options.region?.center ?: LatLng(
randomInRange(-80f, 80f).toDouble(),
randomInRange(-160f, 160f).toDouble()
)
)
.bearing(randomInRange(0f, 360f).toDouble())
.tilt(randomInRange(0f, 60f).toDouble())
@@ -130,21 +130,15 @@ class MapSnapshotterActivity : AppCompatActivity() {
.build()
)
}
if (row == 0 && column == 0) {
// Add a source
val source: Source =
RasterSource("my-raster-source", "maptiler://sources/satellite", 512)
builder.withLayerAbove(
RasterLayer("satellite-layer", "my-raster-source"),
"country_1"
)
builder.withSource(source)
} else if (row == 0 && column == 2) {
// # --8<-- [end:setCameraPosition]
// # --8<-- [start:addMarkerLayer]
if (row == 0 && column == 2) {
val carBitmap = BitmapUtils.getBitmapFromDrawable(
ResourcesCompat.getDrawable(resources, R.drawable.ic_directions_car_black, theme)
)
// marker source
// Marker source
val markerCollection = FeatureCollection.fromFeatures(
arrayOf(
Feature.fromGeometry(
@@ -159,7 +153,7 @@ class MapSnapshotterActivity : AppCompatActivity() {
)
val markerSource: Source = GeoJsonSource(MARKER_SOURCE, markerCollection)
// marker layer
// Marker layer
val markerSymbolLayer = SymbolLayer(MARKER_LAYER, MARKER_SOURCE)
.withProperties(
PropertyFactory.iconImage(Expression.get(TITLE_FEATURE_PROPERTY)),
@@ -167,11 +161,7 @@ class MapSnapshotterActivity : AppCompatActivity() {
PropertyFactory.iconAllowOverlap(true),
PropertyFactory.iconSize(
Expression.switchCase(
Expression.toBool(
Expression.get(
SELECTED_FEATURE_PROPERTY
)
),
Expression.toBool(Expression.get(SELECTED_FEATURE_PROPERTY)),
Expression.literal(1.5f),
Expression.literal(1.0f)
)
@@ -187,16 +177,16 @@ class MapSnapshotterActivity : AppCompatActivity() {
.withCameraPosition(
CameraPosition.Builder()
.target(
LatLng(
5.537109374999999,
52.07950600379697
)
LatLng(5.537109374999999, 52.07950600379697)
)
.zoom(1.0)
.padding(1.0, 1.0, 1.0, 1.0)
.build()
)
}
// # --8<-- [end:addMarkerLayer]
// # --8<-- [start:startSnapshotter]
options.withStyleBuilder(builder)
val snapshotter = MapSnapshotter(this@MapSnapshotterActivity, options)
@@ -206,8 +196,9 @@ class MapSnapshotterActivity : AppCompatActivity() {
}
override fun onStyleImageMissing(imageName: String) {
val androidIcon =
BitmapUtils.getBitmapFromDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_android_2, theme))
val androidIcon = BitmapUtils.getBitmapFromDrawable(
ResourcesCompat.getDrawable(resources, R.drawable.ic_android_2, theme)
)
snapshotter.addImage(imageName, androidIcon!!, false)
}
})
@@ -225,11 +216,10 @@ class MapSnapshotterActivity : AppCompatActivity() {
}
}
)
snapshotters.add(snapshotter)
}
public override fun onPause() {
override fun onPause() {
super.onPause()
// Make sure to stop the snapshotters on pause
@@ -240,11 +230,11 @@ class MapSnapshotterActivity : AppCompatActivity() {
}
private fun featureProperties(id: String, title: String): JsonObject {
val `object` = JsonObject()
`object`.add(ID_FEATURE_PROPERTY, JsonPrimitive(id))
`object`.add(TITLE_FEATURE_PROPERTY, JsonPrimitive(title))
`object`.add(SELECTED_FEATURE_PROPERTY, JsonPrimitive(false))
return `object`
val jsonObject = JsonObject()
jsonObject.add(ID_FEATURE_PROPERTY, JsonPrimitive(id))
jsonObject.add(TITLE_FEATURE_PROPERTY, JsonPrimitive(title))
jsonObject.add(SELECTED_FEATURE_PROPERTY, JsonPrimitive(false))
return jsonObject
}
companion object {
@@ -252,7 +242,7 @@ class MapSnapshotterActivity : AppCompatActivity() {
private const val SELECTED_FEATURE_PROPERTY = "selected"
private const val TITLE_FEATURE_PROPERTY = "title"
// layer & source constants
// Layer & source constants
private const val MARKER_SOURCE = "marker-source"
private const val MARKER_LAYER = "marker-layer"
private val random = Random()
@@ -260,4 +250,4 @@ class MapSnapshotterActivity : AppCompatActivity() {
return random.nextFloat() * (max - min) + min
}
}
}
}

View File

@@ -50,7 +50,7 @@ class MapSnapshotterBitMapOverlayActivity :
Math.min(container.measuredHeight, 1024)
)
.withStyleBuilder(
Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Outdoor"))
Style.Builder().fromUri(TestStyles.AMERICANA)
)
.withCameraPosition(
CameraPosition.Builder().target(LatLng(52.090737, 5.121420))

View File

@@ -23,10 +23,15 @@ import java.net.URI
import java.net.URISyntaxException
/**
* Test activity showing how to use a the [MapSnapshotter] and heatmap layer on it.
* Test activity showing how to use the [MapSnapshotter] and heatmap layer on it.
*/
// # --8<-- [start:class_declaration]
class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.SnapshotReadyCallback {
// # --8<-- [end:class_declaration]
private var mapSnapshotter: MapSnapshotter? = null
// # --8<-- [start:onCreate]
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map_snapshotter_marker)
@@ -36,9 +41,9 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
override fun onGlobalLayout() {
container.viewTreeObserver.removeOnGlobalLayoutListener(this)
Timber.i("Starting snapshot")
val builder = Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Outdoor"))
val builder = Style.Builder().fromUri(TestStyles.AMERICANA)
.withSource(earthquakeSource!!)
.withLayerAbove(heatmapLayer, "water_intermittent")
.withLayerAbove(heatmapLayer, "water")
mapSnapshotter = MapSnapshotter(
applicationContext,
MapSnapshotter.Options(container.measuredWidth, container.measuredHeight)
@@ -55,23 +60,15 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
}
})
}
// # --8<-- [end:onCreate]
// Color ramp for heatmap. Domain is 0 (low) to 1 (high).
// Begin color ramp at 0-stop with a 0-transparency color
// to create a blur-like effect.
// Increase the heatmap weight based on frequency and property magnitude
// Increase the heatmap color weight weight by zoom level
// heatmap-intensity is a multiplier on top of heatmap-weight
// Adjust the heatmap radius by zoom level
// Transition from heatmap to circle layer by zoom level
// # --8<-- [start:heatmapLayer]
private val heatmapLayer: HeatmapLayer
private get() {
get() {
val layer = HeatmapLayer(HEATMAP_LAYER_ID, EARTHQUAKE_SOURCE_ID)
layer.maxZoom = 9f
layer.sourceLayer = HEATMAP_LAYER_SOURCE
layer.setProperties( // Color ramp for heatmap. Domain is 0 (low) to 1 (high).
// Begin color ramp at 0-stop with a 0-transparency color
// to create a blur-like effect.
layer.setProperties(
PropertyFactory.heatmapColor(
Expression.interpolate(
Expression.linear(), Expression.heatmapDensity(),
@@ -82,7 +79,7 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
Expression.literal(0.8), Expression.rgb(239, 138, 98),
Expression.literal(1), Expression.rgb(178, 24, 43)
)
), // Increase the heatmap weight based on frequency and property magnitude
),
PropertyFactory.heatmapWeight(
Expression.interpolate(
Expression.linear(),
@@ -90,8 +87,7 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
Expression.stop(0, 0),
Expression.stop(6, 1)
)
), // Increase the heatmap color weight weight by zoom level
// heatmap-intensity is a multiplier on top of heatmap-weight
),
PropertyFactory.heatmapIntensity(
Expression.interpolate(
Expression.linear(),
@@ -99,7 +95,7 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
Expression.stop(0, 1),
Expression.stop(9, 3)
)
), // Adjust the heatmap radius by zoom level
),
PropertyFactory.heatmapRadius(
Expression.interpolate(
Expression.linear(),
@@ -107,7 +103,7 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
Expression.stop(0, 2),
Expression.stop(9, 20)
)
), // Transition from heatmap to circle layer by zoom level
),
PropertyFactory.heatmapOpacity(
Expression.interpolate(
Expression.linear(),
@@ -119,33 +115,40 @@ class MapSnapshotterHeatMapActivity : AppCompatActivity(), MapSnapshotter.Snapsh
)
return layer
}
// # --8<-- [end:heatmapLayer]
override fun onStop() {
super.onStop()
mapSnapshotter!!.cancel()
}
// # --8<-- [start:onSnapshotReady]
@SuppressLint("ClickableViewAccessibility")
override fun onSnapshotReady(snapshot: MapSnapshot) {
Timber.i("Snapshot ready")
val imageView = findViewById<ImageView>(R.id.snapshot_image)
imageView.setImageBitmap(snapshot.bitmap)
}
// # --8<-- [end:onSnapshotReady]
// # --8<-- [start:onStop]
override fun onStop() {
super.onStop()
mapSnapshotter?.cancel()
}
// # --8<-- [end:onStop]
// # --8<-- [start:earthquakeSource]
private val earthquakeSource: Source?
private get() {
get() {
var source: Source? = null
try {
source = GeoJsonSource(EARTHQUAKE_SOURCE_ID, URI(EARTHQUAKE_SOURCE_URL))
} catch (uriSyntaxException: URISyntaxException) {
Timber.e(uriSyntaxException, "That's not an url... ")
Timber.e(uriSyntaxException, "That's not a valid URL.")
}
return source
}
// # --8<-- [end:earthquakeSource]
companion object {
private const val EARTHQUAKE_SOURCE_URL =
"https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
"https://maplibre.org/maplibre-gl-js/docs/assets/earthquakes.geojson"
private const val EARTHQUAKE_SOURCE_ID = "earthquakes"
private const val HEATMAP_LAYER_ID = "earthquakes-heat"
private const val HEATMAP_LAYER_SOURCE = "earthquakes"

View File

@@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import okio.ByteString.Companion.readByteString
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.Style
@@ -19,8 +20,15 @@ import java.lang.RuntimeException
/**
* Test activity showing how to use a the MapSnapshotter with a local style
*/
class MapSnapshotterLocalStyleActivity : AppCompatActivity(), MapSnapshotter.SnapshotReadyCallback {
private var mapSnapshotter: MapSnapshotter? = null
class MapSnapshotterLocalStyleActivity : AppCompatActivity() {
private lateinit var mapSnapshotter: MapSnapshotter
companion object {
private const val LATITUDE = 52.090737
private const val LONGITUDE = 5.121420
private const val ZOOM = 2.0
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map_snapshotter_marker)
@@ -29,48 +37,39 @@ class MapSnapshotterLocalStyleActivity : AppCompatActivity(), MapSnapshotter.Sna
.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
container.viewTreeObserver.removeOnGlobalLayoutListener(this)
val styleJson: String
styleJson = try {
ResourceUtils.readRawResource(
this@MapSnapshotterLocalStyleActivity,
R.raw.sat_style
)
} catch (exception: IOException) {
throw RuntimeException(exception)
}
// # --8<-- [start:readStyleJson]
val styleJson = resources.openRawResource(R.raw.demotiles).reader().readText()
// # --8<-- [end:readStyleJson]
Timber.i("Starting snapshot")
// # --8<-- [start:createMapSnapshotter]
mapSnapshotter = MapSnapshotter(
applicationContext,
MapSnapshotter.Options(
Math.min(container.measuredWidth, 1024),
Math.min(container.measuredHeight, 1024)
container.measuredWidth.coerceAtMost(1024),
container.measuredHeight.coerceAtMost(1024)
)
.withStyleBuilder(Style.Builder().fromJson(styleJson))
.withCameraPosition(
CameraPosition.Builder().target(LatLng(52.090737, 5.121420))
.zoom(18.0).build()
CameraPosition.Builder().target(LatLng(LATITUDE, LONGITUDE))
.zoom(ZOOM).build()
)
)
mapSnapshotter!!.start(
this@MapSnapshotterLocalStyleActivity,
object : MapSnapshotter.ErrorHandler {
override fun onError(error: String) {
Timber.e(error)
}
}
)
// # --8<-- [end:createMapSnapshotter]
// # --8<-- [start:createSnapshot]
mapSnapshotter.start({ snapshot ->
Timber.i("Snapshot ready")
val imageView = findViewById<View>(R.id.snapshot_image) as ImageView
imageView.setImageBitmap(snapshot.bitmap)
}) { error -> Timber.e(error )}
// # --8<-- [end:createSnapshot]
}
})
}
override fun onStop() {
super.onStop()
mapSnapshotter!!.cancel()
}
override fun onSnapshotReady(snapshot: MapSnapshot) {
Timber.i("Snapshot ready")
val imageView = findViewById<View>(R.id.snapshot_image) as ImageView
imageView.setImageBitmap(snapshot.bitmap)
if (this::mapSnapshotter.isInitialized) {
mapSnapshotter.cancel()
}
}
}

View File

@@ -202,8 +202,8 @@ class RuntimeStyleActivity : AppCompatActivity() {
true
}
R.id.action_add_satellite_layer -> {
addSatelliteLayer()
R.id.action_add_raster_source_layer -> {
addRasterSourceLayer()
true
}
@@ -501,13 +501,14 @@ class RuntimeStyleActivity : AppCompatActivity() {
).show()
}
private fun addSatelliteLayer() {
// Add a source
val source: Source = RasterSource("my-raster-source", "maptiler://sources/satellite", 512)
maplibreMap.style!!.addSource(source)
private fun addRasterSourceLayer() {
// Take note of Tile Usage Policy https://operations.osmfoundation.org/policies/tiles/
val osmTileSet = TileSet("osm", "https://tile.openstreetmap.org/{z}/{x}/{y}.png")
osmTileSet.attribution = "OSM Contributors"
val source = RasterSource("osm", osmTileSet, 128)
val layer = RasterLayer("osm-layer", "osm")
// Add a layer
maplibreMap.style!!.addLayer(RasterLayer("satellite-layer", "my-raster-source"))
maplibreMap.setStyle(Style.Builder().withSource(source).withLayer(layer))
}
private fun updateWaterColorOnZoom() {

View File

@@ -75,7 +75,7 @@ class StyleFileActivity : AppCompatActivity() {
*/
private fun loadStyleFileTask(context: Context): String =
try {
ResourceUtils.readRawResource(context, R.raw.sat_style)
ResourceUtils.readRawResource(context, R.raw.demotiles)
} catch (exception: Exception) {
Timber.e(exception, "Can't load local file style")
""

View File

@@ -3,10 +3,27 @@ package org.maplibre.android.testapp.styles
import org.maplibre.android.maps.Style
object TestStyles {
val VERSATILES = "https://tiles.versatiles.org/assets/styles/colorful.json"
const val DEMOTILES = "https://demotiles.maplibre.org/style.json"
val AMERICANA = "https://americanamap.org/style.json"
const val VERSATILES = "https://tiles.versatiles.org/assets/styles/colorful.json"
const val AMERICANA = "https://americanamap.org/style.json"
const val OPENFREEMAP_LIBERY = "https://tiles.openfreemap.org/styles/liberty"
const val AWS_OPEN_DATA_STANDARD_LIGHT = "https://maps.geo.us-east-2.amazonaws.com/maps/v0/maps/OpenDataStyle/style-descriptor?key=v1.public.eyJqdGkiOiI1NjY5ZTU4My0yNWQwLTQ5MjctODhkMS03OGUxOTY4Y2RhMzgifR_7GLT66TNRXhZJ4KyJ-GK1TPYD9DaWuc5o6YyVmlikVwMaLvEs_iqkCIydspe_vjmgUVsIQstkGoInXV_nd5CcmqRMMa-_wb66SxDdbeRDvmmkpy2Ow_LX9GJDgL2bbiCws0wupJPFDwWCWFLwpK9ICmzGvNcrPbX5uczOQL0N8V9iUvziA52a1WWkZucIf6MUViFRf3XoFkyAT15Ll0NDypAzY63Bnj8_zS8bOaCvJaQqcXM9lrbTusy8Ftq8cEbbK5aMFapXRjug7qcrzUiQ5sr0g23qdMvnKJQFfo7JuQn8vwAksxrQm6A0ByceEXSfyaBoVpFcTzEclxUomhY.NjAyMWJkZWUtMGMyOS00NmRkLThjZTMtODEyOTkzZTUyMTBi"
private fun protomaps(style: String): String {
return "https://api.protomaps.com/styles/v2/${style}.json?key=e761cc7daedf832a"
}
val PROTOMAPS_LIGHT = protomaps("light")
val PROTOMAPS_DARK = protomaps("dark")
val PROTOMAPS_GRAYSCALE = protomaps("grayscale")
val PROTOMAPS_WHITE = protomaps("white")
fun getPredefinedStyleWithFallback(name: String): String {
try {
val style = Style.getPredefinedStyle(name)

View File

@@ -43,8 +43,8 @@
android:title="@string/add_a_terrain_layer"
maplibre:showAsAction="never" />
<item
android:id="@+id/action_add_satellite_layer"
android:title="@string/add_a_satellite_layer"
android:id="@+id/action_add_raster_source_layer"
android:title="@string/set_raster_style"
maplibre:showAsAction="never" />
<item
android:id="@+id/action_update_water_color_on_zoom"

File diff suppressed because it is too large Load Diff

View File

@@ -1,766 +0,0 @@
{
"id": "hybrid",
"name": "Satellite Hybrid",
"zoom": 1,
"pitch": 0,
"center": [
0,
0
],
"glyphs": "maptiler://fonts/{fontstack}/{range}.pbf",
"layers": [
{
"id": "satellite",
"type": "raster",
"paint": {
"raster-opacity": 1
},
"filter": [
"all"
],
"layout": {
"visibility": "visible"
},
"source": "satellite",
"minzoom": 0
},
{
"id": "tunnel",
"type": "line",
"paint": {
"line-color": "rgba(255, 255, 255, 0.2)",
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
6,
0.5,
20,
30
],
"line-dasharray": [
0.28,
0.14
]
},
"filter": [
"all",
[
"==",
"$type",
"LineString"
],
[
"==",
"brunnel",
"tunnel"
],
[
"in",
"class",
"motorway",
"primary",
"secondary",
"tertiary",
"trunk"
]
],
"layout": {
"line-cap": "butt",
"line-join": "miter"
},
"source": "openmaptiles",
"source-layer": "transportation"
},
{
"id": "path",
"type": "line",
"paint": {
"line-color": "rgba(247, 247, 247, 0.33)",
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
14,
0.5,
20,
4
],
"line-dasharray": [
1,
1
]
},
"filter": [
"all",
[
"==",
"$type",
"LineString"
],
[
"in",
"class",
"path",
"track"
]
],
"layout": {
"line-cap": "square",
"line-join": "bevel"
},
"source": "openmaptiles",
"source-layer": "transportation"
},
{
"id": "road",
"type": "line",
"paint": {
"line-color": [
"interpolate",
[
"linear"
],
[
"zoom"
],
8,
"rgba(255, 255, 255, 0.2)",
14,
"rgba(255, 255, 255, 0.3)"
],
"line-width": [
"interpolate",
[
"linear"
],
[
"zoom"
],
5,
[
"match",
[
"get",
"class"
],
[
"motorway",
"motorway_link"
],
1,
0
],
7,
[
"match",
[
"get",
"class"
],
[
"motorway",
"motorway_link"
],
1.4,
0
],
8,
[
"match",
[
"get",
"class"
],
[
"motorway",
"motorway_link",
"primary",
"trunk"
],
0.75,
0
],
9,
[
"match",
[
"get",
"class"
],
[
"secondary",
"tertiary"
],
0.7,
1
],
10,
[
"match",
[
"get",
"class"
],
[
"motorway",
"motorway_link"
],
1.3,
1.3
],
14,
[
"match",
[
"get",
"class"
],
[
"minor",
"service"
],
0.5,
2.4
]
]
},
"filter": [
"all",
[
"==",
"$type",
"LineString"
],
[
"!in",
"class",
"rail",
"ferry",
"path",
"track"
],
[
"!=",
"brunnel",
"tunnel"
]
],
"layout": {
"line-cap": "butt",
"line-join": "round"
},
"source": "openmaptiles",
"minzoom": 6,
"source-layer": "transportation"
},
{
"id": "railway",
"type": "line",
"paint": {
"line-color": "rgba(179, 170, 158, 0.2)",
"line-opacity": [
"interpolate",
[
"linear"
],
[
"zoom"
],
11,
0.5,
16,
1.3
]
},
"filter": [
"==",
"class",
"rail"
],
"layout": {
"visibility": "visible"
},
"source": "openmaptiles",
"minzoom": 11,
"source-layer": "transportation"
},
{
"id": "admin_sub",
"type": "line",
"paint": {
"line-color": "rgba(194, 194, 194, 0.5)",
"line-dasharray": [
2,
1
]
},
"filter": [
"in",
"admin_level",
4,
6,
8
],
"layout": {
"visibility": "visible"
},
"source": "openmaptiles",
"minzoom": 3,
"source-layer": "boundary"
},
{
"id": "admin_country-dark",
"type": "line",
"paint": {
"line-color": "rgba(0, 0, 0, 0.51)",
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
3,
0.5,
21,
32
],
"line-offset": 1
},
"filter": [
"all",
[
"<=",
"admin_level",
2
],
[
"==",
"$type",
"LineString"
]
],
"layout": {
"line-cap": "butt",
"line-join": "round",
"visibility": "visible"
},
"source": "openmaptiles",
"source-layer": "boundary"
},
{
"id": "admin_country",
"type": "line",
"paint": {
"line-color": "rgba(226, 226, 226, 1)",
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
3,
0.5,
21,
32
]
},
"filter": [
"all",
[
"<=",
"admin_level",
2
],
[
"==",
"$type",
"LineString"
]
],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"source": "openmaptiles",
"source-layer": "boundary"
},
{
"id": "road_label",
"type": "symbol",
"paint": {
"text-color": "rgba(255, 255, 255, 1)",
"text-halo-color": "rgba(43, 43, 43, 1)",
"text-halo-width": 1
},
"filter": [
"==",
"$type",
"LineString"
],
"layout": {
"text-font": [
"Noto Sans Regular"
],
"text-size": [
"interpolate",
[
"cubic-bezier",
0.75,
1,
0.75,
1
],
[
"zoom"
],
10,
8,
15,
9
],
"text-field": "{name:latin} {name:nonlatin}",
"text-transform": "none",
"symbol-placement": "line",
"text-letter-spacing": 0.1,
"text-rotation-alignment": "map"
},
"source": "openmaptiles",
"source-layer": "transportation_name"
},
{
"id": "place_label",
"type": "symbol",
"paint": {
"text-color": "rgba(255, 255, 255, 1)",
"text-halo-blur": 0.5,
"text-halo-color": [
"match",
[
"get",
"class"
],
[
"city"
],
"rgba(0, 0, 0, 0.75)",
"rgba(43, 43, 43, 1)"
],
"text-halo-width": 1
},
"filter": [
"all",
[
"==",
"$type",
"Point"
],
[
"!in",
"class",
"country",
"state"
]
],
"layout": {
"text-font": [
"Noto Sans Regular"
],
"text-size": [
"interpolate",
[
"cubic-bezier",
0.5,
1,
0.5,
1
],
[
"zoom"
],
3,
[
"match",
[
"get",
"class"
],
"city",
11,
10
],
6,
[
"match",
[
"get",
"class"
],
"city",
14.5,
11
],
8,
[
"match",
[
"get",
"class"
],
"city",
16,
12
],
10,
[
"match",
[
"get",
"class"
],
"city",
20,
13
]
],
"text-field": "{name:latin}\n{name:nonlatin}",
"text-max-width": 10
},
"source": "openmaptiles",
"maxzoom": 16,
"minzoom": 3,
"source-layer": "place"
},
{
"id": "state_label",
"type": "symbol",
"paint": {
"text-color": "rgba(255, 255, 255, 1)",
"text-halo-blur": 1,
"text-halo-color": "rgba(0, 0, 0, 1)",
"text-halo-width": 1
},
"filter": [
"all",
[
"==",
"$type",
"Point"
],
[
"in",
"class",
"state"
]
],
"layout": {
"text-font": [
"Noto Sans Italic"
],
"text-size": [
"interpolate",
[
"cubic-bezier",
0.75,
1,
0.75,
1
],
[
"zoom"
],
1,
[
"step",
[
"get",
"rank"
],
13,
1,
12,
2,
12
],
4,
[
"step",
[
"get",
"rank"
],
15,
1,
14,
2,
14
],
6,
[
"step",
[
"get",
"rank"
],
23,
1,
18,
2,
18
],
9,
[
"step",
[
"get",
"rank"
],
27,
1,
22,
2,
22
]
],
"text-field": "{name:latin}",
"text-max-width": 10
},
"source": "openmaptiles",
"maxzoom": 12,
"minzoom": 3,
"source-layer": "place"
},
{
"id": "country_label",
"type": "symbol",
"paint": {
"text-color": "rgba(255, 255, 255, 1)",
"text-halo-blur": 1,
"text-halo-color": "rgba(0, 0, 0, 1)",
"text-halo-width": 1
},
"filter": [
"all",
[
"==",
"$type",
"Point"
],
[
"in",
"class",
"country"
]
],
"layout": {
"text-font": [
"Noto Sans Bold"
],
"text-size": [
"interpolate",
[
"cubic-bezier",
0.75,
1,
0.75,
1
],
[
"zoom"
],
1,
[
"step",
[
"get",
"rank"
],
13,
1,
12,
2,
12
],
4,
[
"step",
[
"get",
"rank"
],
15,
1,
14,
2,
14
],
6,
[
"step",
[
"get",
"rank"
],
23,
1,
18,
2,
18
],
9,
[
"step",
[
"get",
"rank"
],
27,
1,
22,
2,
22
]
],
"text-field": "{name:latin}",
"text-max-width": 10
},
"source": "openmaptiles",
"maxzoom": 12,
"source-layer": "place"
}
],
"bearing": 0,
"sources": {
"satellite": {
"url": "maptiler://sources/satellite",
"type": "raster",
"tileSize": 256
},
"openmaptiles": {
"url": "maptiler://sources/v3",
"type": "vector"
}
},
"version": 8,
"metadata": {
"maputnik:renderer": "mbgljs",
"openmaptiles:version": "3.x"
}
}

View File

@@ -73,7 +73,7 @@
<string name="add_a_dynamic_geojson_source">Add a dynamic GeoJSON source</string>
<string name="remove_buildings_layer">Remove buildings layer</string>
<string name="add_a_terrain_layer">Add a terrain layer</string>
<string name="add_a_satellite_layer">Add a satellite layer</string>
<string name="set_raster_style">Set style with raster layer</string>
<string name="change_the_water_color_on_zoom">Change the water color on zoom</string>
<string name="custom_tiles">Custom tiles</string>
<string name="apply_filtered_fill">Apply filtered fill</string>