最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android基于Mapbox?V10?繪制LineGradient軌跡

 更新時(shí)間:2022年08月25日 08:47:07   作者:yxc???????  
這篇文章主要介紹了Android基于Mapbox?V10?繪制LineGradient軌跡,文章通告介紹一些V10上的用法,最終講下如何繪制漸變運(yùn)動(dòng)記錄軌跡,感興趣的小伙伴可以參考一下

前言

當(dāng)Mapbox升級(jí)到V10(我直接到當(dāng)前的最新V10.3)版本后,就可以就此實(shí)現(xiàn)自己想要實(shí)現(xiàn)的功能。

官方文檔 (docs.mapbox.com/android/map…)上的一些case就不在重復(fù)了

UISettings:

PreV10 通過MapView 拿到UISettings, 然后控制相關(guān)屬性,V10 UISettings已經(jīng)被移除了,不再統(tǒng)一管理,比較分散。

參見相關(guān)屬性的控制:

mMapView.compass.visibility = false
mMapView.logo.enabled = false
mMapView.attribution.enabled = false
mMapView.gestures.updateSettings { null }//控制無法觸摸

PreV10 與 V10 的Camera 相關(guān)的animation (涉及到用到的Point,PreV10 之前有LatLn, Point 兩個(gè)類,當(dāng)時(shí)還覺得為啥弄兩個(gè),比較冗余,V10里面拿掉了LatLn保留Point,注意的是Point構(gòu)造時(shí) longitude為第一個(gè)prarams. )

普通的 camera

fun moveCamera(
 ? ? ? ?mapView: MapView,
 ? ? ? ?originalList: List<Point>,
 ? ? ? ?paddingStart: Double,
 ? ? ? ?paddingTop: Double,
 ? ? ? ?paddingEnd: Double,
 ? ? ? ?paddingBottom: Double
 ?  ) {
 ? ? ? ?if (originalList.isEmpty()) {
 ? ? ? ? ? ?return
 ? ? ?  }
 ? ? ? ?val mapboxMap = mapView.getMapboxMap()
 ? ? ? ?val camera = mapboxMap.cameraForCoordinates(originalList, EdgeInsets(paddingTop, paddingStart, paddingBottom, paddingEnd))
 ? ? ? ?mapView.camera.flyTo(camera)
// ? ? ?  mapboxMap.setCamera(camera)
 ?  }

camera動(dòng)畫之后,animationEnd 后的回調(diào) 需求時(shí),傳入animationOptions給 easeTo(),如下實(shí)現(xiàn):

fun easeCamera(mapView:MapView, originalList: List<Point>,
 ? ? ? ? ? ? ? ? ? margin: Double,
 ? ? ? ? ? ? ? ? ? duration: Long,
 ? ? ? ? ? ? ? ? ? actionAfter: (() -> Unit)? = null){
 ? ? ? ?if (originalList.isEmpty()) {
 ? ? ? ? ? ?return
 ? ? ?  }
 ? ? ? ?val animationOptions = MapAnimationOptions.mapAnimationOptions {
 ? ? ? ? ? ?duration(duration)
// ? ? ? ? ?  owner(MapAnimationOwnerRegistry.GESTURES)
 ? ? ? ? ? ?animatorListener(object : AnimatorListenerAdapter() {
 ? ? ? ? ? ? ? ?override fun onAnimationEnd(animation: Animator?) {
 ? ? ? ? ? ? ? ? ? ?actionAfter?.invoke()
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  })
 ? ? ?  }
 ? ? ? ?val mapboxMap = mapView.getMapboxMap()
 ? ? ? ?val camera = mapboxMap.cameraForCoordinates(originalList, EdgeInsets(margin, margin, margin, margin))
 ? ? ? ?mapView.camera.easeTo(camera, animationOptions)
 ?  }

LatlngBounds:

Pre10 之前的類,并且可以通過 List 創(chuàng)建一個(gè) LatlngBounds, 然后 getCenter(), V10中直接拿掉了 LatLngBounds, 也就沒有獲取List 對(duì)應(yīng)的 getCenter()了,沒有仔細(xì)地去找API是否有相對(duì)應(yīng)的替代,直接自己用擴(kuò)展實(shí)現(xiàn)了一下:

@JvmStatic
fun getCenter(originalList: List<Point>): Point? {
 ?if (originalList.isEmpty()) {
 ? ?return null
  }
 ?if (originalList.size < 2) {
 ? ?return originalList[0]
  }
 ?val multiPoint = MultiPoint.fromLngLats(originalList)
 ?val boundingBox = multiPoint.createBoundingBoxFromPoints()
 ?return boundingBox?.getCenter()
}

涉及到兩個(gè)類 BoundingBox 及 MultiPoint, 在兩個(gè)類上添加擴(kuò)展方法:

/**
** 通過 southwest、northeast 兩個(gè)點(diǎn)構(gòu)建 BoundingBox 對(duì)象
**/
fun MultiPoint.createBoundingBoxFromPoints(): BoundingBox?{
 ? ?val coordinates = coordinates()
 ? ?if (coordinates.size > 1){
 ? ? ? ?var minLat: Double = MAX_LATITUDE
 ? ? ? ?var minLon: Double = MAX_LONGITUDE
 ? ? ? ?var maxLat: Double = MIN_LATITUDE
 ? ? ? ?var maxLon: Double = MIN_LONGITUDE
?
 ? ? ? ?for (gp in coordinates) {
 ? ? ? ? ? ?val latitude: Double = gp.latitude()
 ? ? ? ? ? ?val longitude: Double = gp.longitude()
 ? ? ? ? ? ?minLat = Math.min(minLat, latitude)
 ? ? ? ? ? ?minLon = Math.min(minLon, longitude)
 ? ? ? ? ? ?maxLat = Math.max(maxLat, latitude)
 ? ? ? ? ? ?maxLon = Math.max(maxLon, longitude)
 ? ? ?  }
 ? ? ? ?val southwest = Point.fromLngLat(minLon, minLat)
 ? ? ? ?val northeast = Point.fromLngLat(maxLon, maxLat)
 ? ? ? ?return BoundingBox.fromPoints(southwest, northeast)
 ?  }
 ? ?return null
}
?
/**
** 擴(kuò)展BoundingBox getCenter()方法。
**/
fun BoundingBox.getCenter(): Point {
 ? ?val centerLon = (southwest().longitude() + northeast().longitude())/2.0
 ? ?val centerLat = (southwest().latitude() + northeast().latitude())/2.0
 ? ?return Point.fromLngLat(centerLon, centerLat)
}

Style設(shè)定Layer

V10 添加了DSL build 添加 source、layer,相對(duì)而言source、layer都比較集中在builder{}的 block里,實(shí)際應(yīng)用中通常source、layer 的添加都是分離的,動(dòng)態(tài)的,通過sourceID, layerId 找到對(duì)應(yīng)的 source、layer然后修改里面的內(nèi)容, 發(fā)現(xiàn) addLayerBelow(layer, layId) 該方法不好使,Crash了,暫且不用它了。 SymbolLayer 相比之前的api接口,少了一個(gè) style.addImages(imagesMap), 不再支持一次性添加多個(gè)Image,添加一個(gè)簡(jiǎn)單的擴(kuò)展函數(shù)即可。

fun Style.addImages(imageMap: Map<String, Bitmap>) {
 ? ?imageMap.forEach { (t, u) ->
 ? ? ? ?addImage(t, u)
 ?  }
}

創(chuàng)建SymbolLayer 及 Source (Feature)的case

 private fun createSymbolLayer(
 ? ? ? ?layerId: String,
 ? ? ? ?sourceId: String,
 ? ? ? ?isChangeStyle: Boolean,
 ? ? ? ?offsetY: Float
 ?  ): SymbolLayer {
 ? ? ? ?return symbolLayer(layerId, sourceId){
 ? ? ? ? ? ?iconImage(PROPERTY_ICON_NAME_PATTERN)
 ? ? ? ? ? ?iconAllowOverlap(true)
 ? ? ? ? ? ?iconSize(if (isChangeStyle) 1.0 else 0.0)
 ? ? ? ? ? ?iconIgnorePlacement(true)
 ? ? ? ? ? ?iconOffset(listOf(0.0, offsetY.toDouble()))
 ? ? ?  }
 ?  }
// 控制iconSize 大小是方便做動(dòng)畫。
?
private fun createSymbolBitmap(latLng: Point, markerStr: String, markerParams: MarkerParams?) {
 ? ? ? ?val feature = Feature.fromGeometry(Point.fromLngLat(latLng.longitude(), latLng.latitude()))
 ? ? ? ?val bitmap = createMarkerBitmap(mContext, markerParams!!)
 ? ? ? ?feature.addStringProperty(PROPERTY_ICON_NAME, markerStr)
 ? ? ? ?imagesMap[markerStr] = bitmap
 ? ? ? ?markerCoordinates.add(feature)
 ?  }

添加對(duì)應(yīng)的 source, Layer

style.addSource(
 ? ? ? ? ? ? ? ?geoJsonSource(END_SOURCE_ID){
 ? ? ? ? ? ? ? ? ? ?featureCollection(FeatureCollection.fromFeatures(markerCoordinates))
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  )
?
style.addLayer(endSymbolLayer)

繪制軌跡LineLayer

同樣添加Layer前需要添加 source, List 構(gòu)建 FeatureCollection, 如下:

mMapView.getMapboxMap().getStyle()?.addSource(
 ? ?geoJsonSource(sourceId){
 ? ? ? ?featureCollection(
 ? ? ? ? ? ?FeatureCollection.fromFeatures(
 ? ? ? ? ? ? ? ?arrayOf(
 ? ? ? ? ? ? ? ? ? ?Feature.fromGeometry(
 ? ? ? ? ? ? ? ? ? ? ? ?LineString.fromLngLats(points)
 ? ? ? ? ? ? ? ? ?  )
 ? ? ? ? ? ? ?  )
 ? ? ? ? ?  )
 ? ? ?  )
 ? ? ? ?lineMetrics(true) // 注意這里,繪制LineGradient 需要添加這行代碼。
 ?  }
)

添加單色的 LineLayer

mMapView.getMapboxMap().getStyle()?.addLayer(
 ? ? ? ? ? ? ? ?lineLayer(layerId, sourceId){
 ? ? ? ? ? ? ? ? ? ?lineDasharray(listOf(0.01, 2.0))
 ? ? ? ? ? ? ? ? ? ?lineCap(LineCap.ROUND)
 ? ? ? ? ? ? ? ? ? ?lineJoin(LineJoin.ROUND)
 ? ? ? ? ? ? ? ? ? ?lineWidth(TRACE_WIDTH.toDouble())
 ? ? ? ? ? ? ? ? ? ?lineColor(pathColor)
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  )

繪制LineGradient, 先聊 Pre10的方案

??/**
 ? * Defines a gradient with which to color a line feature. Can only be used with GeoJSON sources that specify `"lineMetrics": true`.
 ? *
 ? * @param expression an expression statement
 ? * @return property wrapper around an expression statement
 ? */
 ?public static PropertyValue<Expression> lineGradient(Expression expression) {
 ? ?return new PaintPropertyValue<>("line-gradient", expression);
  }
?
 /**
 ?Produces continuous, smooth results by interpolating between pairs of input and output values ("stops"). The `input` may be any numeric expression (e.g., `["get", "population"]`). Stop inputs must be numeric literals in strictly ascending order. The output type must be `number`, `array<number>`, or `color`.
Example usage:
 FillLayer fillLayer = new FillLayer("layer-id", "source-id");
 fillLayer.setProperties(
 ? ? fillColor(
 ? ? ? interpolate(
 ? ? ? ? exponential(0.5f), zoom(),
 ? ? ? ? stop(1.0f, color(Color.RED)),
 ? ? ? ? stop(5.0f, color(Color.BLUE)),
 ? ? ? ? stop(10.0f, color(Color.GREEN))
 ? ? ? )
 ? ? )
 );
 
 ? ? 
Params:
interpolation – type of interpolation
number – the input expression
stops – pair of input and output values
Returns:
expression
See Also:
Style specification
 ? */
 ?public static Expression interpolate(@NonNull Interpolator interpolation,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @NonNull Expression number, Stop... stops) {
 ? ?return interpolate(interpolation, number, Stop.toExpressionArray(stops));
  }

以上只需創(chuàng)建 Expression.Stop[] stops, 根據(jù)List 中每個(gè)Point 的配速對(duì)應(yīng)的色值,傳入即可,繪制LineGradient。

V10 中不再有 Expression 下 的Stop類,所以無從談起創(chuàng)建Stop[] 了,從官方的demo里看 , 最后跟了不定的 stop{}, 可以看見是一個(gè)可變參數(shù),所以打算構(gòu)建一個(gè) stop{} 的數(shù)據(jù)。

 private fun createHeatmapLayer(): HeatmapLayer {
 ? ?return heatmapLayer(
 ? ? ?HEATMAP_LAYER_ID,
 ? ? ?EARTHQUAKE_SOURCE_ID
 ?  ) {
 ? ? ?maxZoom(9.0)
 ? ? ?sourceLayer(HEATMAP_LAYER_SOURCE)
 ? ? ?// Begin color ramp at 0-stop with a 0-transparancy color
 ? ? ?// to create a blur-like effect.
 ? ? ?heatmapColor(
 ? ? ? ?interpolate {
 ? ? ? ? ?linear()
 ? ? ? ? ?heatmapDensity()
 ? ? ? ? ?stop {
 ? ? ? ? ? ?literal(0)
 ? ? ? ? ? ?rgba(33.0, 102.0, 172.0, 0.0)
 ? ? ? ?  }
 ? ? ? ? ?stop {
 ? ? ? ? ? ?literal(0.2)
 ? ? ? ? ? ?rgb(103.0, 169.0, 207.0)
 ? ? ? ?  }
 ? ? ? ? ?stop {
 ? ? ? ? ? ?literal(0.4)
 ? ? ? ? ? ?rgb(209.0, 229.0, 240.0)
 ? ? ? ?  }
 ? ? ? ? ?stop {
 ? ? ? ? ? ?literal(0.6)
 ? ? ? ? ? ?rgb(253.0, 219.0, 240.0)
 ? ? ? ?  }
 ? ? ? ? ?stop {
 ? ? ? ? ? ?literal(0.8)
 ? ? ? ? ? ?rgb(239.0, 138.0, 98.0)
 ? ? ? ?  }
 ? ? ? ? ?stop {
 ? ? ? ? ? ?literal(1)
 ? ? ? ? ? ?rgb(178.0, 24.0, 43.0)
 ? ? ? ?  }
 ? ? ?  }
 ? ?  )
 ? ?  ...
 ? ?  ...
 ?  }
 }

其實(shí) stop{} 的源碼如下, 所以需要提供一個(gè)高階函數(shù)的數(shù)組

 ? ?fun stop(block: ExpressionBuilder.() -> Unit) {
 ? ? ?this@ExpressionBuilder.apply(block)
 ?  }
?
//給Expression.InterpolatorBuilder 添加一個(gè) stops()的擴(kuò)展方法即可
fun Expression.InterpolatorBuilder.stops(stopList:Array<(Expression.ExpressionBuilder.() -> Unit)?>){
 ? ?stopList.forEach { stop ->
 ? ? ? ?stop?.let {
 ? ? ? ? ? ?apply(it)
 ? ? ?  }
 ?  }
}
?
//將以上的擴(kuò)展方法作為參數(shù)傳入 構(gòu)建 Expression的最后一個(gè)參數(shù),
var colorExpression = Expression.interpolate{
 ? ? ? ? ? ? ? ?linear()
 ? ? ? ? ? ? ? ?lineProgress()
 ? ? ? ? ? ? ? ?stops(colorStops)
 ? ? ? ? ?  }
?
//最后將 colorExpression 應(yīng)用到構(gòu)建lineLayer的 lineGradient(colorExpression) 作為參數(shù)即可,大功告成
mMapView.getMapboxMap().getStyle()?.addLayer(
 ? ? ? ? ? ? ? ?lineLayer(layerId, sourceId){
 ? ? ? ? ? ? ? ? ? ?lineCap(LineCap.ROUND)
 ? ? ? ? ? ? ? ? ? ?lineJoin(LineJoin.ROUND)
 ? ? ? ? ? ? ? ? ? ?lineWidth(5.0)
 ? ? ? ? ? ? ? ? ?lineGradient(colorExpression)
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  )

到此這篇關(guān)于Android基于Mapbox V10 繪制LineGradient軌跡的文章就介紹到這了,更多相關(guān)Android Mapbox 繪制 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android實(shí)現(xiàn)隱私政策彈窗與鏈接功能

    Android實(shí)現(xiàn)隱私政策彈窗與鏈接功能

    現(xiàn)在幾乎所有的應(yīng)用市場(chǎng)都要求應(yīng)用上架需要用戶協(xié)議/隱私政策,本篇內(nèi)容將介紹如何在APP內(nèi)植入一個(gè)隱私政策彈窗與鏈接,對(duì)Android隱私政策彈窗實(shí)現(xiàn)代碼感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • android實(shí)現(xiàn)在圖標(biāo)上顯示數(shù)字

    android實(shí)現(xiàn)在圖標(biāo)上顯示數(shù)字

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)在圖標(biāo)上顯示數(shù)字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android Jetpack組件中LiveData的優(yōu)劣

    Android Jetpack組件中LiveData的優(yōu)劣

    LiveData是Jetpack組件的一部分,更多的時(shí)候是搭配ViewModel來使用,相對(duì)于Observable,LiveData的最大優(yōu)勢(shì)是其具有生命感知的,換句話說,LiveData可以保證只有在組件(?Activity、Fragment、Service)處于活動(dòng)生命周期狀態(tài)的時(shí)候才會(huì)更新數(shù)據(jù)
    2023-04-04
  • android下拉刷新ListView的介紹和實(shí)現(xiàn)代碼

    android下拉刷新ListView的介紹和實(shí)現(xiàn)代碼

    在當(dāng)下,列表組件不帶下拉刷新的都不好意思叫列表。第一次完成列表的下拉刷新功能的時(shí)候,直接在Activity中實(shí)現(xiàn),雖然功能上是實(shí)現(xiàn)了,總體上感覺很亂。所以第二次用到的時(shí)候,就想著封裝成一個(gè)組件,實(shí)現(xiàn)和Activity的解耦。
    2013-04-04
  • 一文深入探討Android Activity啟動(dòng)模式

    一文深入探討Android Activity啟動(dòng)模式

    在 Android 應(yīng)用開發(fā)中,Activity 是用戶界面的核心組件,而 Activity 的啟動(dòng)模式則是決定應(yīng)用界面如何在任務(wù)棧中交互、管理以及呈現(xiàn)的關(guān)鍵因素,本文將深入探討 Android 中的 Activity 啟動(dòng)模式,詳細(xì)解釋每種模式的用途、適用場(chǎng)景
    2023-08-08
  • Android中Retrofit庫的高級(jí)使用與原理

    Android中Retrofit庫的高級(jí)使用與原理

    在 Android 開發(fā)中,網(wǎng)絡(luò)請(qǐng)求是一個(gè)極為關(guān)鍵的部分,Retrofit 作為一個(gè)強(qiáng)大的網(wǎng)絡(luò)請(qǐng)求庫,能夠簡(jiǎn)化開發(fā)流程,提供高效的網(wǎng)絡(luò)請(qǐng)求能力,本文將深入介紹 Retrofit 的高級(jí)使用與原理,幫助讀者更全面地理解和應(yīng)用這一庫,需要的朋友可以參考下
    2023-08-08
  • Flutter控件之實(shí)現(xiàn)Widget基類的封裝

    Flutter控件之實(shí)現(xiàn)Widget基類的封裝

    在實(shí)際的開發(fā)中,Widget的基類還是很有必要存在的,不然就會(huì)存在很多的冗余嵌套代碼,本文為大家介紹了Flutter中基類是如何封裝的,需要的可以收藏一下
    2023-05-05
  • Android開發(fā)強(qiáng)制橫屏和強(qiáng)制豎屏設(shè)置實(shí)例代碼

    Android開發(fā)強(qiáng)制橫屏和強(qiáng)制豎屏設(shè)置實(shí)例代碼

    本篇文章主要介紹了Android開發(fā)強(qiáng)制橫屏和強(qiáng)制豎屏設(shè)置實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • arcgis android之定位功能的示例代碼

    arcgis android之定位功能的示例代碼

    這篇文章主要介紹了arcgis android之定位功能的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • Android模擬登錄評(píng)論CSDN實(shí)現(xiàn)代碼

    Android模擬登錄評(píng)論CSDN實(shí)現(xiàn)代碼

    本篇文章主要介紹了Android模擬登錄評(píng)論CSDN實(shí)現(xiàn)代碼,可以實(shí)現(xiàn)登陸發(fā)表評(píng)論到官方網(wǎng)站,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-11-11

最新評(píng)論

德化县| 时尚| 迁安市| 峨眉山市| 十堰市| 双流县| 防城港市| 鹤壁市| 东丰县| 临猗县| 嵊泗县| 镶黄旗| 宕昌县| 武隆县| 徐水县| 林周县| 呼和浩特市| 金山区| 同仁县| 余干县| 德昌县| 博罗县| 丘北县| 大厂| 吴江市| 井冈山市| 光山县| 伽师县| 花莲市| 海南省| 林口县| 额尔古纳市| 淄博市| 平度市| 巩留县| 桂平市| 太康县| 弥渡县| 平阳县| 台南县| 江山市|