上一篇章我们在本地使用Geodatabase.createAsync成功在本地创建了geodatabase文件,它不仅可以添加feature要素,它还天然支持附件的增删改查,可以存放各种jpg,png只要是你想得到的文件都可以添加进来,这一篇章我们就来详解一下如果往geodatabase添加附件

看Geodatabase.createAsync创建的关键过程,在创建完geodatabase,在添加TableDescription的时候就可以选择开启tableDescription.setHasAttachments(true)附件功能,这样创建出来的table表在录入要素的时候就可以往feature中添加attachment附件了,就一行代码

前置环境我这里为各位接入了开源库io.github.lucksiege:pictureselector:v3.10.0图片选择库,这是一个非常优秀的图片选择器,安利一波!选择完图片之后点确定返回绘制面板右下角附件数量就是刚才选中的几张图片,可以反复进去重新拍照

代码在HomeViewModel中的addFeature可以看到,选择完的图片内容List<LocalMedia>放在HomeFragment.localMediaList静态对象中。所以这里添加要素直接判断这个HomeFragment.localMediaList是不是空的就表示有没有附件了。

因为程序支持geojson,shp和geodatabase三种存储模式,使用哪一种模式这取决于你在主页侧边栏选择的存储模式是什么,如果不是geodatabase存储模式那么不支持附件操作,因为我只对这个模式做了拓展,geojson和shp这两个存储模式各位如果有需要请自行编写代码进行拓展

默认用geodatabaseFeatureTable.createFeature和其他的FeatureTable创建出来的都是Feature是不支持附件操作的,需要类型向下转成ArcgisFeature调用addAttachmentAsync,第一个参数是byte[],第二个是文件的类型这个不是常量可以任意写,第三个是文件的名字例如a.jpg,最后直接get同步获取不异步等待就好了

在主页直接点击查询要素在绘制面板就可以看到要素的附件数量了,直接点击进去因为是查询要素就需要把ArcgisFeature中的attachment附件列表出来,这段代码在AttachmentActivity中可以看到,查询出来的Feature会直接放在HomeFragment.updateFeature,如果是null是添加新要素,如果不是null就表示这个操作要素是查询出来的,不是添加要素

private fun initRecycleView() {
	val recyclerView = binding.recyclerView
	val manager = FullyGridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false)
	recyclerView.layoutManager = manager
	val itemAnimator = recyclerView.itemAnimator
	if (itemAnimator != null) {
		(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
	}

	if(HomeFragment.updateFeature != null){
		val fetchAttachmentsAsync = (HomeFragment.updateFeature as ArcGISFeature).fetchAttachmentsAsync()
		fetchAttachmentsAsync.addDoneListener {
			val get = fetchAttachmentsAsync.get()
			attachmentAdapter = AttachmentAdapter(get)
			recyclerView.adapter = attachmentAdapter
		}
	} else {

		/**
		 * 如果updateFeature是空,那就是这次选择图片是新增要素,但也有可能是新增要素的时候反复打开图片选择界面选择图片
		 * 如果是新增要素,选择完图片是不会把选中的结果放到当前activity的,而是直接丢到了HomeFragment.localMediaList里面了
		 * 反复打开和选择,都是最新的结果,保存要素了就把换个HomeFragment.localMediaList清空clear掉就可以了
		 */
		localMediaAdapter = LocalMediaAdapter(HomeFragment.localMediaList)
		recyclerView.adapter = localMediaAdapter
	}

}

既然HomeFragment.updateFeature不是null,我如何把updateFeature中的附件重新列表出来呢?使用fetchAttachmentsAsync即可列表出来。因为是查询出来的要素再次拍照就没必要传给HomeFragment.localMediaList静态对象中了,直接就在这里用查询出来的updateFeature.addAttachmentAsync进行附件添加了,这里代码和HomeViewModel.addFeature附件操作代码过程是一样的,删除也是一样的,如果是添加要素那么删除的附件对象直接就在HomeFragment.localMediaList中移除,如果是查询出来的要素就直接用updateFeature.deleteAttachmentAsync了,我这里代码写得不是很好,拓展性不是很强,各位请自行优化

fun addAttachmentToFeature(list: List<LocalMedia>){
	val updateFeature = HomeFragment.updateFeature
	if(updateFeature != null){
		/**
		 * 因为是更新要素,直接在这里添加进去就行了
		 */
		val arcGISFeature = updateFeature as ArcGISFeature
		val asyncJobList = mutableListOf<Single<Any>>()
		list.forEachIndexed { index, localMedia ->
			val realPath = localMedia.realPath
			val mimeType = localMedia.mimeType
			val fileName = localMedia.fileName
			val readBytes = File(realPath).inputStream().readBytes()
			val job = Single.create<Any> { emit ->
				val addAttachmentAsync = arcGISFeature.addAttachmentAsync(readBytes, mimeType, fileName)
				addAttachmentAsync.addDoneListener {
					try {
						val get = addAttachmentAsync.get()
						emit.onSuccess(true)
					} catch (e: Exception) {
						e.printStackTrace()
					}
				}
			}
			asyncJobList.add(job)
		}
		Single.zip(asyncJobList) { objects -> objects }.subscribe({
			reloadFeatureAttachmentListToAdapter()
			showToast("添加成功")
		}, {})
	} else {
		//不是更新,是添加新的feature,将结果放到主页面,等添加要素的时候再将这些附件添加进去要素里面
		HomeFragment.localMediaList.addAll(list)
		localMediaAdapter.append(list)
	}
}

这一篇章我们学习到了如何在创建geodatabase的时候开启附件,添加附件,列表附件,和删除附件的功能,如有疑问请加我qq1330884822一起学习与交流,一起变得更强!

https://gitee.com/tanqidi/ArcgisAndroidhttps://gitee.com/tanqidi/ArcgisAndroid

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐