上述就是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