ArcGIS for Android 实现加载地图
创建第一个应用
1.前期项目准备
1.1. 创建新工程
- 新建一个空活动项目
- 选择语言、平台,修改命名等
1.2. 添加ArcGIS SDK
-
build.gradle (Project: <project name>)
添加maven { url 'https://esri.jfrog.io/artifactory/arcgis' }
-
build.gradle (Module: <module name>)
添加implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0'
-
Gradle
更新:Sync Project with Gradle Files
-
AndroidManifest.xml
添加//网络权限 <uses-permission android:name="android.permission.INTERNET" /> //use a MapView (2D) require at least OpenGL ES 2.x: <uses-feature android:glEsVersion="0x00020000" android:required="true" />
-
在
appdbuild.gradle(Module:app)
的android部分指定Java版本compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }
1.3. 添加MapView
地图控件
-
修改
activity_main.xml
,替换TextView
<com.esri.arcgisruntime.mapping.view.MapView android:id="@+id/mapView" android:layout_height="fill_parent" android:layout_width="fill_parent" tools:ignore="MissingConstraints"> </com.esri.arcgisruntime.mapping.view.MapView>
2.加载在线地图
2.1.设置地图
-
添加
private MapView mMapView;
-
引用
import com.esri.arcgisruntime.mapping.view.MapView; (IDE可能会自动导入)
-
在
onCreate
事件中设置地图super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMapView=findViewById(R.id.mapView); ArcGISMap map =new ArcGISMap(Basemap.Type.TOPOGRAPHIC,34.056295,-117.195800,16); mMapView.setMap(map);
-
重载
onPause
、onResume
与onDestroy
事件@Override protected void onPause() { mMapView.pause(); super.onPause(); } @Override protected void onResume() { super.onResume(); mMapView.resume(); }
2.2. 编译运行
点击运行后,Android
模拟器中将打开生成的App
3.加载离线地图
3.1 数据准备
在IDEA
中点击菜单中的view
、tool windows
、device file explorer
,打开如下视图,找到mnt
下的sdcard
,这个就是我们的手机常用的存储位置。
在sdcard
中新建文件夹,并upload
地图文件,此处上传shape file
、TPK
、MMPK
文件
3.2.加载TPK
地图
3.2.1.设置地图
-
添加变量
private static final String TAG =MainActivity.class.getSimpleName(); private MapView mapView; private MobileMapPackage mobileMapPackage; private TileCache tileCache; private final String TPKPath=Environment.getExternalStorageDirectory()+"/EXFile/YueLuShan.tpk";
-
添加引用
package com.example.ex02; import android.Manifest; import android.content.pm.PackageManager; import android.os.Environment; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.esri.arcgisruntime.data.TileCache; import com.esri.arcgisruntime.layers.ArcGISTiledLayer; import com.esri.arcgisruntime.loadable.LoadStatus; import com.esri.arcgisruntime.mapping.ArcGISMap; import com.esri.arcgisruntime.mapping.Basemap; import com.esri.arcgisruntime.mapping.MobileMapPackage; import com.esri.arcgisruntime.mapping.view.MapView;
-
重载
onCreate
、onPause
、onResume
、onDestroy
事件@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mapView=findViewById(R.id.mapView); requestPermission(); } @Override protected void onPause() { mMapView.pause(); super.onPause(); } @Override protected void onResume() { super.onResume(); mMapView.resume(); }
-
设置权限请求
private void requestPermission() { String[] reqPermission=new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}; int reqCode=2; if (ContextCompat.checkSelfPermission(MainActivity.this,reqPermission[0])== PackageManager.PERMISSION_GRANTED){ loadTPK(TPKPath); }else { ActivityCompat.requestPermissions(MainActivity.this,reqPermission,reqCode); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull @org.jetbrains.annotations.NotNull String[] permissions, @NonNull @org.jetbrains.annotations.NotNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){ loadTPK(TPKPath); }else { Toast.makeText(MainActivity.this,"permission denied!",Toast.LENGTH_SHORT); } }
-
添加方法支持
private boolean loadTPK(String path){ try { tileCache=new TileCache(TPKPath); tileCache.loadAsync(); tileCache.addDoneLoadingListener(()->{ if (tileCache.getLoadStatus()== LoadStatus.LOADED){ Basemap basemap=new Basemap(new ArcGISTiledLayer(tileCache)); mapView.setMap(new ArcGISMap(basemap)); }else { String error ="Error loading mobile map package : " + tileCache.getLoadError().getMessage(); Log.e(TAG,error); Toast.makeText(this,error,Toast.LENGTH_SHORT); } }); return true; }catch (Exception e){ return false; } }
3.2.2.编译运行
点击运行后,Android
模拟器中将打开生成的App
3.3.加载MMPK
地图
3.3.1.设置地图
-
添加变量
private static final String TAG =MainActivity.class.getSimpleName(); private MapView mapView; private MobileMapPackage mobileMapPackage; private final String MMPKPath= Environment.getExternalStorageDirectory() +"/EXFile/Yellowstone.mmpk";
-
添加引用
package com.example.ex02; import android.Manifest; import android.content.pm.PackageManager; import android.os.Environment; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.esri.arcgisruntime.data.TileCache; import com.esri.arcgisruntime.layers.ArcGISTiledLayer; import com.esri.arcgisruntime.loadable.LoadStatus; import com.esri.arcgisruntime.mapping.ArcGISMap; import com.esri.arcgisruntime.mapping.Basemap; import com.esri.arcgisruntime.mapping.MobileMapPackage; import com.esri.arcgisruntime.mapping.view.MapView;
-
重载
onCreate
、onPause
、onResume
、onDestroy
事件@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mapView=findViewById(R.id.mapView); requestPermission(); } @Override protected void onPause() { mMapView.pause(); super.onPause(); } @Override protected void onResume() { super.onResume(); mMapView.resume(); }
-
设置权限请求
private void requestPermission() { String[] reqPermission=new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}; int reqCode=2; if (ContextCompat.checkSelfPermission(MainActivity.this,reqPermission[0])== PackageManager.PERMISSION_GRANTED){ loadMMPK(MMPKPath); }else { ActivityCompat.requestPermissions(MainActivity.this,reqPermission,reqCode); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull @org.jetbrains.annotations.NotNull String[] permissions, @NonNull @org.jetbrains.annotations.NotNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){ loadMMPK(MMPKPath); }else { Toast.makeText(MainActivity.this,"permission denied!",Toast.LENGTH_SHORT); } }
-
添加方法支持
private boolean loadMMPK(String path){ try { mobileMapPackage = new MobileMapPackage(path); mobileMapPackage.loadAsync(); mobileMapPackage.addDoneLoadingListener(()->{ if (mobileMapPackage.getLoadStatus()== LoadStatus.LOADED && !mobileMapPackage.getMaps().isEmpty()){ mapView.setMap(mobileMapPackage.getMaps().get(0)); }else { String error ="Error loading mobile map package : " + mobileMapPackage.getLoadError().getMessage(); Log.e(TAG,error); Toast.makeText(this,error,Toast.LENGTH_SHORT); } }); return true; }catch (Exception e){ return false; } }
3.3.2.编译运行
点击运行后,Android
模拟器中将打开生成的App
3.4.加载shape file
地图
3.4.1.设置地图
- 添加变量
private MapView mMapView;
private final static String TAG = MainActivity.class.getSimpleName();
-
添加引用
import android.Manifest; import android.content.pm.PackageManager; import android.os.Environment; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.esri.arcgisruntime.data.ShapefileFeatureTable; import com.esri.arcgisruntime.layers.FeatureLayer; import com.esri.arcgisruntime.loadable.LoadStatus; import com.esri.arcgisruntime.mapping.ArcGISMap; import com.esri.arcgisruntime.mapping.Basemap; import com.esri.arcgisruntime.mapping.Viewpoint; import com.esri.arcgisruntime.mapping.view.MapView; import java.io.File;
-
在
onCreate
事件中设置地图@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMapView=findViewById(R.id.mapView); ArcGISMap map =new ArcGISMap(Basemap.createStreetsVector()); mMapView.setMap(map); requestReadPermission(); }
-
重载
onPause
、onResume
与onDestroy
事件@Override protected void onPause() { mMapView.pause(); super.onPause(); } @Override protected void onResume() { super.onResume(); mMapView.resume(); }
-
添加方法支持
// 请求设备读写权限并加载数据 private void requestReadPermission() { // 定义请求权限 String[] reqPermission = new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }; int requestCode = 2; // 在API23版本以上中,权限需要在运行时进行请求 if (ContextCompat.checkSelfPermission(MainActivity.this, reqPermission[0]) == PackageManager.PERMISSION_GRANTED) { // 加载数据 featureLayerShapefile(); } else { // 请求权限 ActivityCompat.requestPermissions(MainActivity.this, reqPermission, requestCode); } } // 处理权限请求响应,用户选择完权限后响应 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 加载数据 featureLayerShapefile(); } else { // 报告给用户权限请求被拒绝 Toast.makeText(MainActivity.this, getResources().getString(R.string.arcgisruntime_error_null_value_not_allowed), Toast.LENGTH_SHORT).show(); } } // 加载shapefile private void featureLayerShapefile() { // 获取本地shapefile文件 String path = getSDCardPath()+"/EXFile/GeorgiaEduc.shp"; ShapefileFeatureTable shapefileFeatureTable = new ShapefileFeatureTable(path); shapefileFeatureTable.loadAsync(); shapefileFeatureTable.addDoneLoadingListener(() -> { if (shapefileFeatureTable.getLoadStatus() == LoadStatus.LOADED) { // 利用shapefile文件创建一个FeatureLayer文件 FeatureLayer shapefileFeatureLayer = new FeatureLayer(shapefileFeatureTable); // 将shapefile图层添加到业务图层 mMapView.getMap().getOperationalLayers().add(shapefileFeatureLayer); // 缩放到shapefile范围 mMapView.setViewpointAsync(new Viewpoint(shapefileFeatureLayer.getFullExtent())); } else { String error = "Shapefile feature table failed to load: " + shapefileFeatureTable.getLoadError().toString(); Toast.makeText(MainActivity.this, error, Toast.LENGTH_LONG).show(); Log.e(TAG, error); } }); } // 获取SD卡路径 public String getSDCardPath() { return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator; }
3.4.2.编译运行
点击运行后,Android
模拟器中将打开生成的App