You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Studio中用GeoTools读取ZIP格式Shapefile并导出到Google Maps

实现思路与示例代码

前置配置(GeoTools适配Android)

首先需要在项目中配置GeoTools的依赖源和排除不兼容的依赖项:

  1. 在项目的settings.gradle中添加GeoTools的官方仓库:
dependencyResolutionManagement {
    repositories {
        maven { url "https://repo.osgeo.org/repository/release/" }
        google()
        mavenCentral()
    }
}
  1. 在模块级build.gradle中添加依赖:
dependencies {
    // GeoTools 核心与Shapefile解析依赖
    implementation('org.geotools:gt-shapefile:28.2') {
        exclude group: 'javax.media', module: 'jai_core'
        exclude group: 'javax.media', module: 'jai_imageio'
        exclude group: 'javax.xml.stream', module: 'stax-api'
    }
    // Google Maps SDK
    implementation 'com.google.android.gms:play-services-maps:18.2.0'
}

核心实现代码

1. 读取ZIP格式Shapefile并转换为Google Maps多边形对象

import android.graphics.Color;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolygonOptions;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Polygon;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public List<PolygonOptions> parseShapefileZip(String zipFilePath) throws IOException {
    List<PolygonOptions> result = new ArrayList<>();
    File shapeZip = new File(zipFilePath);

    Map<String, Object> params = new HashMap<>();
    params.put("url", shapeZip.toURI().toURL());
    // 根据你的Shapefile实际编码调整,国内常用编码为GBK、UTF-8
    params.put("charset", "GBK");

    ShapefileDataStore dataStore = new ShapefileDataStore(params);
    String typeName = dataStore.getTypeNames()[0];

    try (SimpleFeatureIterator featureIterator = dataStore.getFeatureSource(typeName).getFeatures().features()) {
        while (featureIterator.hasNext()) {
            var feature = featureIterator.next();
            Polygon jtsPolygon = (Polygon) feature.getDefaultGeometry();
            List<LatLng> polygonPoints = new ArrayList<>();
            // 转换JTS坐标为Google Maps LatLng格式
            for (Coordinate coord : jtsPolygon.getCoordinates()) {
                polygonPoints.add(new LatLng(coord.y, coord.x));
            }
            // 构造地图多边形样式,可自定义调整
            PolygonOptions options = new PolygonOptions()
                    .addAll(polygonPoints)
                    .strokeWidth(4f)
                    .strokeColor(Color.RED)
                    .fillColor(0x7F3DDC84);
            result.add(options);
        }
    } finally {
        dataStore.dispose();
    }
    return result;
}

2. 将多边形加载到Google Maps

在onMapReady回调中调用解析方法,注意大文件解析需要放在子线程执行,避免阻塞主线程导致ANR:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    // 子线程执行解析逻辑
    new Thread(() -> {
        try {
            List<PolygonOptions> polygons = parseShapefileZip("本地Shapefile压缩包的绝对路径");
            // 切回主线程操作地图
            runOnUiThread(() -> {
                for (PolygonOptions option : polygons) {
                    mMap.addPolygon(option);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start();
}

替代方案(轻量无GeoTools依赖)

如果对APK包体积有要求,或者遇到GeoTools的兼容问题,可以直接手动解析Shapefile的.shp二进制结构:

  • 从ZIP包中提取后缀为.shp、.dbf的文件
  • 按照Shapefile官方格式规范读取坐标点和属性数据,直接转换为Google Maps的LatLng对象即可,整体代码量在300行以内,不需要引入第三方重型依赖

注意事项

  • 若Shapefile使用的坐标参考系不是WGS84,需要先做坐标转换,否则加载到地图上会出现偏移
  • 读取本地文件前需要先申请对应Android版本的存储权限
  • 如果需要将解析后的地块数据存储到Firebase,可以直接把每个多边形的坐标列表、属性字段转换为JSON格式存储即可

内容的提问来源于stack exchange,提问作者Teo Pal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:54:04