# dppmap
**Repository Path**: gzlpsdp/dppmap
## Basic Information
- **Project Name**: dppmap
- **Description**: 封装整合maplibre+jts+geopackage+proj4j开源地图应用
- **Primary Language**: Android
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2026-04-24
- **Last Updated**: 2026-05-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## gis-map-dpp
[](https://jitpack.io/#com.gitee.gzlpsdp/dppmap)
gis-map-dpp 是一个基于 MapLibre Android 的高性能 GIS 地图 SDK,集成了 GeoPackage、JTS 几何运算、proj4j 坐标转换等功能。提供地图显示、矢量数据管理、绘制、编辑、查询、动态样式、标注过滤等一站式能力,帮助 Android 开发者快速构建 GIS 应用。
## 功能特性
- **地图引擎:** 基于 MapLibre,支持矢量/栅格底图、自定义瓦片(WMS/WMTS)。
- **矢量数据:** 无缝加载 .gpkg 文件,支持点、线、面图层。
- **CRUD 操作:** 对要素进行增、删、改、查。
- **绘制:** 点、线、面(点状模式 + 自由绘制模式)。
- **几何编辑:** 线/面顶点拖拽、添加、删除,保存/取消修改。
- **动态样式:** 根据属性字段值动态设置点/线/面的颜色、半径等。
- **文本标注:** 支持点、线、面的字段标注,样式可自定义。
- **要素点击 & 高亮:** 支持单个/多个要素高亮,高亮颜色可配置。
- **属性过滤:** 通过表达式按字段条件动态显示/隐藏要素(支持等值、比较、逻辑组合)。
- **图层控制:** 独立控制每个矢量图层的显隐。
- **坐标转换:** 集成 WGS84 → GCJ02 / BD09 / CGCS2000 等(CoordinateConverter类)
## 快速开始
**1. 添加依赖**
***Step 1.*** 在项目根目录的 build.gradle 中添加 JitPack 仓库:
```groovy
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
```
在最新版本android studio中增加settings.gradle
```groovy
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
***Step 2.*** 在 app 模块的 build.gradle 中添加依赖:
```groovy
dependencies {
implementation 'com.gitee.gzlpsdp:dppmap:Tag' // 替换为最新版本
}
```
**2. 权限配置**
在 AndroidManifest.xml 中添加存储权限(用于读取 GeoPackage 文件):
```xml
```
**3. 布局文件**
在 Activity 布局中添加 GisMapView:
```xml
```
**初始化地图**
```java
public class MainActivity extends AppCompatActivity {
private GisMapView gisMapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gisMapView = findViewById(R.id.gisMapView);
// 配置地图选项
GisMapOptions options = new GisMapOptions.Builder()
.setTianDiTuKey("您的天地图KEY") // 天地图密钥
.setBaseMapType(GisMapOptions.BaseMapType.TIANDITU_IMAGE)
.setCenter(26.9, 106.7) // 中心点(纬度, 经度)
.setZoom(7.0f)
.build();
gisMapView.setOptions(options);
gisMapView.setCallback(() -> {
// 地图准备就绪,开始加载数据
loadGeoPackage();
});
}
}
```
## 核心功能
**在地图加载完成后执行**
```
//在onMapReady中加载gpkg确保地图初始化完成
getGisMapView().setCallback(new GisMapCallback() {
@Override
public void onMapReady() {
}
});
```
### 地图配置选项(GisMapOptions)
`GisMapOptions` 用于在地图初始化时配置地图的初始状态、底图类型、手势、指北针等。通过 Builder 模式链式调用。
**参数总览**
|方法| 说明| 默认值|
|----|-----|-----|
***底图相关***
|`setBaseMapType(BaseMapType)`| 底图类型:NONE, TIANDITU_VECTOR, TIANDITU_IMAGE, CUSTOM| NONE
|`setTianDiTuKey(String)`| 天地图密钥(仅当底图为天地图时有效) |""
|`setCustomTileUrl(String)`| 自定义瓦片 URL 模板(仅当底图为 CUSTOM 时有效)| ""
***地图视口***
|`setCenter(LatLng) / setCenter(lat, lon)`| 初始中心点(纬度, 经度) |(39.9, 116.4)
|`setZoom(float)`| 初始缩放级别(通常 3~18) |7.0f
|`setMinZoom(double)`| 最小缩放级别 |3.0
|`setMaxZoom(double)`| 最大缩放级别 |18.0
***手势控制***
|`setEnableRotateGesture(boolean)`| 是否允许双指旋转地图手势| false
|`setEnableTiltGesture(boolean)`| 是否允许双指倾斜地图手势 |false
***指北针***
|`setCompassEnabled(boolean)` |是否启用指北针 |true
|`setCompassFadeWhenFacingNorth(boolean)` |false = 一直显示;true = 仅在非正北时显示(默认行为)| false
|`setCompassGravity(int)`| 指北针位置(Gravity 常量组合,如 Gravity.TOP | Gravity.END)| Gravity.TOP | Gravity.END
|`setCompassMargins(int left, int top, int right, int bottom)`| 指北针到地图四边的距离(像素)| (0,0,0,0)
|`setCompassImage(int drawableRes)`| 自定义指北针图标资源 ID(0 表示使用默认图标) |0
**使用示例**
```java
GisMapOptions options = new GisMapOptions.Builder()
// 天地图影像底图
.setBaseMapType(GisMapOptions.BaseMapType.TIANDITU_IMAGE)
.setTianDiTuKey("your_tianditu_key")
// 初始中心点(贵阳)
.setCenter(26.9, 106.7)
.setZoom(8.0f)
// 手势
.setEnableRotateGesture(true)
.setEnableTiltGesture(true)
// 指北针:一直显示,放在左上角,边距20像素,自定义图标
.setCompassEnabled(true)
.setCompassFadeWhenFacingNorth(false) // 关键:一直显示
.setCompassGravity(Gravity.LEFT | Gravity.TOP)
.setCompassMargins(20, 20, 20, 20)
.setCompassImage(R.drawable.my_compass)
.build();
gisMapView.setOptions(options);
```
**详细说明**
***1. 底图类型(BaseMapType)***
|枚举值 |说明|
|-----|----|
|NONE |无底图(透明背景)
|TIANDITU_VECTOR| 天地图矢量底图(需要密钥)
|TIANDITU_IMAGE |天地图影像底图(需要密钥)
|CUSTOM| 自定义瓦片服务(需要提供 URL 模板)
自定义瓦片 URL 模板示例:
```java
.setCustomTileUrl("https://tile.example.com/{z}/{x}/{y}.png")
```
***2. 指北针常驻与自定义图标***
- 默认情况下,指北针只在用户旋转地图后短暂出现,点击复位后自动消失。
- 设置 setCompassFadeWhenFacingNorth(false) 可使其一直显示,无论地图是否朝北。
- 自定义图标建议使用 24dp~32dp 的矢量图或 PNG,过大可能影响点击区域。
***3. 手势启用建议***
- 若需要用户自由旋转地图,请设置 setEnableRotateGesture(true)。
- 倾斜手势(setEnableTiltGesture)允许双指上下滑动改变俯仰角,默认禁用。
- 平移和缩放手势始终可用,无需配置。
***4. 注意事项***
- 天地图密钥需自行申请(天地图官网)。
- 自定义瓦片 URL 需包含 {z}, {x}, {y} 占位符。
- 指北针的 compassMargins 单位为像素,建议根据屏幕密度转换(如 dp2px)。
- 所有配置仅在地图初始化前有效;地图加载后可通过 GisMapView 的动态方法修改(如 setCompassEnabled、setBearing 等)。
### 加载 GeoPackage
```java
private void loadGeoPackage() {
File gpkgFile = new File(getExternalFilesDir(null), "sample.gpkg");
// 如果文件不存在则从 assets 复制(略)
gisMapView.loadGeoPackage(gpkgFile.getAbsolutePath(), new GeoPackageCallback() {
@Override
public void onSuccess(List tableNames) {
Toast.makeText(MainActivity.this, "加载成功,表:" + tableNames, Toast.LENGTH_SHORT).show();
// 获取各矢量表
FeatureTable pointTable = gisMapView.getFeatureTable("points");
FeatureTable lineTable = gisMapView.getFeatureTable("lines");
FeatureTable polygonTable = gisMapView.getFeatureTable("polygons");
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "加载失败:" + error, Toast.LENGTH_LONG).show();
}
});
}
```
### 绘制图形
支持点、线、面两种绘制模式:点状(单击添加点/顶点,长按完成)和 自由绘制(滑动绘制,松手完成)。
|功能| 方法|
|----|----|
|绘制点 |`gisMapView.startDrawPoint()`
|点状线 |`gisMapView.startDrawLineByPoint()`
|自由线 |`gisMapView.startDrawFreehandLine()`
|点状面 |`gisMapView.startDrawPolygonByPoint()`
|自由面 |`gisMapView.startDrawFreehandPolygon()`
|退出绘制 |`gisMapView.stopDraw()`
|完成并获取结果 |`gisMapView.finishDraw() + getLastDrawResult()`
|撤销上一次添加的顶点(仅在点状绘制模式下有效)|`gisMapView.undoDraw()`
|重做上一次撤销的顶点|`gisMapView.redoDraw()`
***绘制后保存示例:***
```java
DrawResult result = gisMapView.getLastDrawResult();
if (result == null) {
Toast.makeText(this, "未绘制图形", Toast.LENGTH_SHORT).show();
return;
}
Map attrs = new HashMap<>();
attrs.put("name", "dengpp新鲜");
attrs.put("upload", 2);
String tableName;
if(type==1){
tableName = "points";
}else if(type==2){
tableName = "lines";
}else{
tableName = "polygons";
}
// 直接使用自定义几何对象插入
gisMapView.insertFeature("lines", attrs, result.getGeometry(), new InsertCallback() {
@Override
public void onSuccess(long featureId) {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "保存成功,ID=" + featureId, Toast.LENGTH_SHORT).show();
});
}
@Override
public void onError(String error) {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "保存失败: " + error, Toast.LENGTH_SHORT).show();
});
}
});
gisMapView.finishDraw();
}
```
### 图形编辑(线/面顶点编辑)
```java
// 从点击或查询获得 Feature 后进入编辑模式
gisMapView.startEdit(feature);
// 编辑完成后保存或取消
gisMapView.saveCurrentEdit(); // 保存修改并退出
gisMapView.cancelCurrentEdit(); // 丢弃修改
gisMapView.undoEdit() //撤销上一次顶点操作(移动、添加、删除)
gisMapView.redoEdit() //重做上一次撤销的顶点操作
```
***编辑交互说明:***
***移动顶点:*** 触摸并拖动顶点的黄色圆点。
***删除顶点:*** 单击顶点(短按)后确认对话框。
***添加顶点:*** 在线段上单击即可插入新顶点。
### 要素点击与高亮
```java
//点击事件 point:点击的位置坐标
gisMapView.setOnMapClickListener(new OnMapClickListener() {
@Override
public void onClick(DPPLatLng point) {
/**
* 未点击到任何内容
*/
Log.d("Click","no click");
}
@Override
public void onVectorFeaturesClicked(DPPLatLng point,List features) {
if (features.size() == 1) {
// 高亮单个要素
gisMapView.highlightFeature(features.get(0));
} else if (features.size() > 1) {
// 多个要素时弹出选择框
String[] names = new String[features.size()];
for (int i = 0; i < features.size(); i++) {
names[i] = features.get(i).properties().get("name").getAsString();
}
new AlertDialog.Builder(context)
.setTitle("请选择")
.setItems(names, (d, which) -> gisMapView.highlightFeature(features.get(which)))
.show();
}
}
@Override
public void onServiceFeaturesClicked(DPPLatLng point,List features) { /* WMS/WFS 结果 */ }
@Override
public void onError(String error) { /* 错误信息 */ }
});
//长安事件
gisMapView.setOnMapLongClickListener((point, features) -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "长按位置: " + point.getLatitude() + "," + point.getLongitude(), Toast.LENGTH_SHORT).show();
if (!features.isEmpty()) {
gisMapView.highlightFeature(features.get(0));
}
});
});
// 清除高亮
gisMapView.clearHighlight();
// 自定义高亮样式
gisMapView.setHighlightStyle(Color.MAGENTA, 0.5f, // 面填充色+透明度
Color.CYAN, 6f, // 线颜色+宽度
Color.YELLOW, 14f); // 点颜色+半径
```
**临时高亮(临时图形层)**
除了高亮数据库中的要素外,SDK 还支持在地图上**临时显示**任意几何对象(点、线、面、多线、多面),例如缓冲区预览、裁剪结果预览、临时绘制的图形等。这些图形不会保存到数据库,可通过 `GraphicsOverlay` 管理。
***使用 GraphicsOverlay 显示临时图形***
```java
// 获取或创建一个覆盖层(每个 ID 独立)
GraphicsOverlay overlay = gisMapView.getGraphicsOverlay("myTempLayer");
// 清除旧内容
overlay.clear();
// 创建一个几何对象(例如缓冲结果、裁剪结果)
DPPPolygon bufferGeometry = ...; // 从 createBuffer 回调获得
// 设置样式属性
Map attrs = new HashMap<>();
attrs.put("fillColor", "#FFFF00"); // 黄色填充
attrs.put("fillOpacity", 0.4f); // 填充透明度
attrs.put("strokeColor", "#FF0000"); // 红色边框
attrs.put("strokeWidth", 3f); // 边框宽度
Graphic graphic = new Graphic(bufferGeometry, attrs);
overlay.addGraphic(graphic);
```
***高亮图形***
```java
Map attrs = new HashMap<>();
attrs.put("fillColor", "#FFFF00"); // 黄色填充
attrs.put("fillOpacity", 0.3f);
attrs.put("strokeColor", "#FF0000"); // 红色边框
attrs.put("strokeWidth", 3f);
gisMapView.showTemporaryGeometry(bufferGeometry, attrs);
//清除临时图形
gisMapView.clearTemporaryGeometry();
```
***支持的几何类型及样式属性***
|几何类型| 支持的属性键|
|-------|---------|
|点(圆点) |color(颜色值如 "#FF0000")、radius(半径像素)
|点(图标)| iconId(图片ID)、iconSize(缩放比例)
|线| color、width(线宽像素)
|面| fillColor、fillOpacity、strokeColor、strokeWidth、dashArray(虚线数组)
|多线、多面 |自动遍历所有子要素,样式继承
***注意事项***
- 临时图形不会影响数据库中的要素,也不会影响原有高亮图层。
- 每个 GraphicsOverlay 可包含多个图形,但过多图形会生成大量地图源和图层,建议单次显示不超过 100 个。
- 显示前建议调用 clear() 清除上一次的临时图形,避免重叠。
- 如果几何来自数据库(坐标系为 CGCS2000),必须先转换为 WGS84 才能正确显示,推荐使用 showTemporaryGeometry 方法自动处理。
### 图形样式
**静态样式(普通样式)**
***点图层样式***
```java
// 设置点的颜色和半径(单位:像素)
gisMapView.setPointStyle(Color.RED, 12f);
```
***线图层样式***
```java
// 设置线的颜色和宽度(单位:像素)
gisMapView.setLineStyle(Color.BLUE, 3f);
```
***面图层样式***
```java
// 设置面的填充色、边框色、边框宽度、虚线数组
Float[] dashArray = new Float[]{5f, 3f}; // 实线长度5,间隔3
gisMapView.setPolygonStyle(Color.parseColor("#00FF00"), Color.BLACK, 2f, dashArray);
```
***说明:***
- 静态样式是对整个图层生效的默认样式。
- 如果后续调用了动态样式(如 setDynamicPointStyle),动态样式会覆盖静态样式,直到调用 clearDynamicStyle(tableName) 恢复静态样式。
- 虚线数组可选,若不传则绘制实线。
**恢复默认样式**
```java
// 恢复该表的样式为 SDK 默认值(点红色、线红色、面绿色半透明等)
gisMapView.getFeatureTable("points").resetStyle();
```
**动态样式(按属性值渲染)**
根据要素的字段值动态改变点/线/面的颜色。
***点样式:***
```java
Map