如何在Kotlin中创建GeoJSON文件并实现点击按钮下载?
生成农场多边形GeoJSON并实现Android按钮下载功能
一、构建符合规范的GeoJSON数据
注意GeoJSON的坐标格式为[经度, 纬度],你提供的坐标需要调换经纬度顺序;同时Polygon的线性环必须闭合(最后一个点与第一个点重合),整理后的GeoJSON结构如下:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "农场区域" }, "geometry": { "type": "Polygon", "coordinates": [ [ [99.651681683, 4.5165132153], [99.878981683, 4.5163152153], [99.021481683, 4.3584532153], [99.698781683, 4.1578132153], [99.321481683, 4.3655132153], [99.874581683, 4.8795132153], [99.651681683, 4.5165132153] ] ] } } ] }
二、实现按钮点击下载逻辑
在按钮点击事件中完成GeoJSON生成、文件写入、权限处理等操作,完整代码示例如下:
binding.downloadGeojsonFileButton.setOnClickListener { // 1. 生成GeoJSON字符串 val geoJsonStr = """ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "农场区域" }, "geometry": { "type": "Polygon", "coordinates": [ [ [99.651681683, 4.5165132153], [99.878981683, 4.5163152153], [99.021481683, 4.3584532153], [99.698781683, 4.1578132153], [99.321481683, 4.3655132153], [99.874581683, 4.8795132153], [99.651681683, 4.5165132153] ] ] } } ] } """.trimIndent() // 2. 动态申请存储权限(Android 6.0+必需) if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1001) return@setOnClickListener } // 3. 创建文件并写入内容 try { // 指定存储到系统公共下载目录 val downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) val geoJsonFile = File(downloadDir, "farm_area.geojson") // 写入GeoJSON内容 FileWriter(geoJsonFile).use { writer -> writer.write(geoJsonStr) } // 4. 通知系统刷新媒体库,确保文件可在文件管理器中找到 MediaScannerConnection.scanFile(this, arrayOf(geoJsonFile.path), null) { _, _ -> Toast.makeText(this, "GeoJSON文件已保存到下载目录", Toast.LENGTH_SHORT).show() } } catch (e: IOException) { e.printStackTrace() Toast.makeText(this, "文件保存失败:${e.message}", Toast.LENGTH_SHORT).show() } } // 处理权限申请结果回调 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 1001) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过后重新触发下载 binding.downloadGeojsonFileButton.performClick() } else { Toast.makeText(this, "需要存储权限才能保存文件", Toast.LENGTH_SHORT).show() } } }
关键注意事项
- 坐标顺序:GeoJSON严格遵循
[经度, 纬度],不要与常用的[纬度, 经度]混淆,否则图形会显示异常。 - 存储适配:Android 10及以上版本推荐使用
MediaStore或应用私有外部存储(getExternalFilesDir),无需申请WRITE_EXTERNAL_STORAGE权限,避免权限兼容问题。 - 环闭合要求:Polygon的坐标数组必须是闭合线性环,即最后一个点与第一个点完全一致,否则不符合GeoJSON规范。
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

