android开发分享Android基于Mapbox V10 绘制LineGradient轨迹

前言当mapbox升级到v10(我直接到当前的最新v10.3)版本后,就可以就此实现自己想要实现的功能。官方文档 (docs.mapbox.com/android/map…)上的一些ca

上述就是android开发分享Android基于Mapbox V10 绘制LineGradient轨迹的全部内容,如果对大家有所用处且需要了解更多关于Android学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

前言

当mapbox升级到v10(我直接到当前的最新v10.3)版本后,就可以就此实现自己想要实现的功能。

官方文档 (docs.mapbox.com/android/map…)上的一些case就不在重复了

uisettings:

prev10 通过mapview 拿到uisettings, 然后控制相关属性,v10 uisettings已经被移除了,不再统一管理,比较分散。

参见相关属性的控制:

mmapview.compass.visibility = false  mmapview.logo.enabled = false  mmapview.attribution.enabled = false  mmapview.gestures.updatesettings { null }//控制无法触摸

prev10 与 v10 的camera 相关的animation (涉及到用到的point,prev10 之前有latln, point 两个类,当时还觉得为啥弄两个,比较冗余,v10里面拿掉了latln保留point,注意的是point构造时 longitude为第一个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动画之后,animationend 后的回调 需求时,传入animationoptions给 easeto(),如下实现:

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 创建一个 latlngbounds, 然后 getcenter(), v10中直接拿掉了 latlngbounds, 也就没有获取list 对应的 getcenter()了,没有仔细地去找api是否有相对应的替代,直接自己用扩展实现了一下:

@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()  }

涉及到两个类 boundingbox 及 multipoint, 在两个类上添加扩展方法:

/**  ** 通过 southwest、northeast 两个点构建 boundingbox 对象  **/  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  }  ​  /**  ** 扩展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设定layer

v10 添加了dsl build 添加 source、layer,相对而言source、layer都比较集中在builder{}的 block里,实际应用中通常source、layer 的添加都是分离的,动态的,通过sourceid, layerid 找到对应的 source、layer然后修改里面的内容, 发现 addlayerbelow(layer, layid) 该方法不好使,crash了,暂且不用它了。 symbollayer 相比之前的api接口,少了一个 style.addimages(imagesmap), 不再支持一次性添加多个image,添加一个简单的扩展函数即可。

fun style.addimages(imagemap: map<string, bitmap>) {      imagemap.foreach { (t, u) ->          addimage(t, u)      }  }

创建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 大小是方便做动画。  ​  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)      }

添加对应的 source, layer

style.addsource(                  geojsonsource(end_source_id){                      featurecollection(featurecollection.fromfeatures(markercoordinates))                  }              )  ​  style.addlayer(endsymbollayer)

绘制轨迹linelayer

同样添加layer前需要添加 source, list 构建 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));    }

以上只需创建 expression.stop[] stops, 根据list 中每个point 的配速对应的色值,传入即可,绘制linegradient。

v10 中不再有 expression 下 的stop类,所以无从谈起创建stop[] 了,从官方的demo里看 , 最后跟了不定的 stop{}, 可以看见是一个可变参数,所以打算构建一个 stop{} 的数据。

 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)            }          }        )        ...        ...      }   }

其实 stop{} 的源码如下, 所以需要提供一个高阶函数的数组

    fun stop(block: expressionbuilder.() -> unit) {        this@expressionbuilder.apply(block)      }  ​  //给expression.interpolatorbuilder 添加一个 stops()的扩展方法即可  fun expression.interpolatorbuilder.stops(stoplist:array<(expression.expressionbuilder.() -> unit)?>){      stoplist.foreach { stop ->          stop?.let {              apply(it)          }      }  }  ​  //将以上的扩展方法作为参数传入 构建 expression的最后一个参数,  var colorexpression = expression.interpolate{                  linear()                  lineprogress()                  stops(colorstops)              }  ​  //最后将 colorexpression 应用到构建linelayer的 linegradient(colorexpression) 作为参数即可,大功告成  mmapview.getmapboxmap().getstyle()?.addlayer(                  linelayer(layerid, sourceid){                      linecap(linecap.round)                      linejoin(linejoin.round)                      linewidth(5.0)                    linegradient(colorexpression)                  }              )

到此这篇关于android基于mapbox v10 绘制linegradient轨迹的文章就介绍到这了,更多相关android mapbox 绘制 内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/1209181.html

(0)
上一篇 2022年8月30日
下一篇 2022年8月30日

精彩推荐