这一章节我们来实现如何在要素上显示标注和各种酷炫图标,不然单单只是一个红色的点和一根有颜色的线不太美观和不够见名知意。图标资源读者可以在ArcgisAndroid源码主目录可以看到,在程序启动的时候在文件管理器ArcgisAndroid中会生成一个叫 图标资源 目录,你需要把这些图标资源复制进去就可以进行下一步操作了。
首先回到图层配置中可以看到新增了两个可以下拉的选项,标注字段就是把选中的字段作为该图层的标注字段,例如我选中的是名称字段,我在录入要素的时候输入的是 红绿灯 它就会把这个红绿灯内容作为标签显示在要素上面。
图标字段我也选中的是名称,因为图标符号化使用的是 UniqueValueRenderer 唯一值渲染,需要在图标资源名字和要素字段内容建立一个唯一值匹配,匹配上了就显示这个图标。如果你输入的和唯一值渲染匹配不上就会显示默认的红色点点。这样就算有再多的要素他也能快速将匹配上的要素进行图标符号化,而不是(Graphic,GraphicsOverlay,PictureMarkerSymbol)一个一个的根据要素坐标来手动添加图标,这样会导致内存溢出从而引起程序崩溃,代码都在SymbolUtils类中
可以看到在参数只有两个,一个是我们的图层配置对象里面存放了线的宽度,标注的字段,图标的字段和边框色还有内容色,另外一个就是(GeodatabaseFeatureTable,ServiceFeatureTable,ShapefileFeatureTable)要素表实例化完毕后交给FeatureLayer,这个对象就是它
LabelingPlacement对象是用来控制标注在要素的哪个方向上,如果是点我使用的是POINT_ABOVE_CENTER在点的上面中间,线我使用的是LINE_ABOVE_ALON在线的上面沿着进行显示。offsetDistance是用来控制标注距离偏移量的,不然标注和符号化样式离得太近了稍微离远一点显示会更合适。
标注对象有两个一个是ArcadeLabelExpression或SimpleLabelExpression("[Objectid]"),如果像本章一样单字段显示可以直接用SimpleLabelExpression,如果你想显示多字段并且还想拼接字符串可以使用ArcadeLabelExpression,例如ArcadeLabelExpression("\$feature.${layer.name} + ' 今年 ' + \$feature.${layer.age}+' 岁了'")
看到featureLayer.labelDefinitions.add(labelDefinition)了吗?它居然可以add,那也就是说可以添加多个标注表达式了,只需要改成你想显示的标注字段和LabelingPlacement显示位置即可,例如我创建4个LabelDefinition标注表达式利用LabelingPlacement分别设置上下左右显示 。无论是点,线,面,都是一样的,各位可以利用这个效果来发散思维应用在你们的程序中
这里稍微复杂的就是UniqueValueRenderer唯一值渲染器了,fieldNames.add(layer.icon) 初始化的时候需要给他设置一个字段,表示用哪个字段的内容来进行接下来的唯一值匹配,直接读取 图标资源 里面的所有小图标循环创建UniqueValueRenderer.UniqueValue添加进来即可
最重要的是开启标注 featureLayer.isLabelsEnabled = true,不然你搞了那么多代码死活显示不出来得注意看看是否忘记开启了
fun symbol(layer: LayerConfig, featureLayer: FeatureLayer){
// val labelDefinition = LabelDefinition(ArcadeLabelExpression("\$feature.${layer.label} + ' 拼接内容, ' + \$feature.${layer.label}"), textSymbol)
// val labelDefinition = LabelDefinition(ArcadeLabelExpression("\$feature.${layer.label}"), textSymbol)
val labelDefinition = LabelDefinition(SimpleLabelExpression("[${layer.label}]"), textSymbol).apply {
when(featureLayer.featureTable.geometryType) {
GeometryType.POINT -> {
//在点的上方中间
placement = LabelingPlacement.POINT_ABOVE_CENTER
offsetDistance = layer.width.toDouble() * 1.5
}
GeometryType.POLYLINE -> {
//设置一下偏移量,标注和符号化样式离得太近了,稍微离远一点显示标注
offsetDistance = layer.width.toDouble() * 1.5
placement = LabelingPlacement.LINE_ABOVE_ALONG
}
GeometryType.POLYGON ->{
//默认的显示方式就是 AUTOMATIC
placement = LabelingPlacement.AUTOMATIC
}
else -> {}
}
overrunStrategy = LabelOverrunStrategy.ALLOW
}
featureLayer.labelDefinitions.add(labelDefinition)
//开启标注和添加标注表达式
featureLayer.isLabelsEnabled = true
when(featureLayer.featureTable.geometryType){
GeometryType.POINT -> {
//唯一值渲染器
val symbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.RED, 12F)
val uniqueValueRenderer = UniqueValueRenderer().apply {
fieldNames.add(layer.icon)
}
uniqueValueRenderer.defaultSymbol = symbol
val iconResourceFolder = Environment.getExternalStorageDirectory().absolutePath + File.separator + getString(R.string.app_name) + File.separator + getString(R.string.icon_resource)
File(iconResourceFolder).listFiles()?.forEachIndexed { index, file ->
val iconName = file.name.split(".")[0]
val iconResourcePath = iconResourceFolder + File.separator + file.name
val bitmap = BitmapFactory.decodeFile(iconResourcePath)
val drawable = BitmapDrawable(bitmap)
//val iconSymbol = PictureMarkerSymbol("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Recreation/FeatureServer/0/images/e82f744ebb069bb35b234b3fea46deae")
val iconSymbol = PictureMarkerSymbol(drawable)
iconSymbol.height = 30F
iconSymbol.width = 30F
// create a unique value for each category
val iconUniqueValue = UniqueValueRenderer.UniqueValue("", iconName, iconSymbol, listOf(iconName))
uniqueValueRenderer.uniqueValues.add(iconUniqueValue)
}
featureLayer.renderer = uniqueValueRenderer
}
GeometryType.POLYLINE -> {
val lineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, layer.color, layer.width.toFloat())
featureLayer.renderer = SimpleRenderer(lineSymbol)
}
GeometryType.POLYGON -> {
//设置面样式
val lineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, layer.borderColor, layer.width.toFloat())
val fillSymbol = SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, layer.color, lineSymbol)
featureLayer.renderer = SimpleRenderer(fillSymbol)
}
else -> {}
}
}
https://gitee.com/tanqidi/ArcgisAndroidhttps://gitee.com/tanqidi/ArcgisAndroid