地圖基本操作
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>
1.4 數據准備
在IDEA
中點擊菜單中的view
、tool windows
、device file explorer
,打開如下視圖,找到mnt
下的sdcard
,這個就是我們的手機常用的存儲位置。
在sdcard
中新建文件夾,並upload
地圖文件,此處上傳shape file
、TPK
、MMPK
文件
2.添加界面操作
2.1 定義文本
在strings.xml
中完成文本的定義(規范化做法,其實也不是必須這樣,這樣可便於日后維護,比如更換界面語言)
<resources>
<string name="app_name">EX03</string>
<string name="btnZoomIn">放大</string>
<string name="btnZoomOut">縮小</string>
<string name="btnRotation">旋轉</string>
<string name="btnScale">縮放</string>
<string name="btnLayers">圖層</string>
</resources>
2.2 設計界面
打開activity_main.xml
,可切換設計界面和代碼界面進行設計。此處先在mapView
中添加一個LinearLayout horizontal
,再在LinearLayout horizontal
中添加button
,並修改屬性。
xml
文件如下:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="@string/btnZoomIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1" tools:ignore="ButtonStyle"
android:id="@+id/buttonZoomIn"/>
<Button
android:text="@string/btnZoomOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/buttonZoomOut" android:layout_weight="1"
tools:ignore="ButtonStyle"/>
<Button
android:text="@string/btnRotation"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/buttonRotation" android:layout_weight="1"
tools:ignore="ButtonStyle"/>
<Button
android:text="@string/btnScale"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/buttonScale" android:layout_weight="1"
tools:ignore="ButtonStyle"/>
<Button
android:text="@string/btnLayers"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/buttonLayers" android:layout_weight="1"
tools:ignore="ButtonStyle"/>
</LinearLayout>
3. 添加方法支持
3.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(); } @Override protected void onDestroy() { mMapView.dispose(); super.onDestroy(); }
3.2 完善放大方法
-
添加函數
protected void registerButtonClick()
-
在
protected void registerButtonClick()
中添加代碼Button buttonZoomIn=(Button)findViewById(R.id.buttonZoomIn); buttonZoomIn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mMapView.setViewpointScaleAsync(mMapView.getMapScale()*0.5); } });
-
在
onCreate
函數中添加registerButtonClick()
調用
3.3 完善縮小方法
-
在
protected void registerButtonClick()
中添加代碼Button buttonZoomOut=(Button)findViewById(R.id.buttonZoomOut); buttonZoomOut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mMapView.setViewpointScaleAsync(mMapView.getMapScale()*2.0); } });
3.4 完善旋轉方法
-
在
protected void registerButtonClick()
中添加代碼Button buttonRotation=(Button)findViewById(R.id.buttonRotation); buttonRotation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mMapView.setViewpointRotationAsync(mMapView.getMapRotation()+10.0); } });
3.5 完善圖層管理方法
-
由於上述在線加載的地圖沒有多圖層,此處加載離線多圖層地圖
-
添加變量
private static final String TAG =MainActivity.class.getSimpleName(); 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;
-
設置權限請求
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(); Toast.makeText(this,error,Toast.LENGTH_SHORT); } }); return true; }catch (Exception e){ return false; } }
-
在
onCreate
中添加requestPermission()
調用
-
-
運行測試
點擊運行后,Android
模擬器中將打開生成的App
-
在
protected void registerButtonClick()
中添加代碼Button buttonLayers=(Button)findViewById(R.id.buttonLayers); buttonLayers.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int size=mMapView.getMap().getOperationalLayers().size(); final String[] names=new String[size]; for (int i=0;i<size;i++){ names[i]=mMapView.getMap().getOperationalLayers().get(i).getName(); } AlertDialog alertDialog=new AlertDialog.Builder(MainActivity.this) .setTitle("請選擇圖層") .setItems(names, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //設置圖層操作代碼,此處只是簡單的移除圖層 mMapView.getMap().getOperationalLayers().remove(which); } }) .show(); } });
3.6 完善比例尺方法
-
在
protected void registerButtonClick()
中添加代碼Button buttonScale=(Button)findViewById(R.id.buttonScale); buttonScale.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String[] scale=new String[]{"100000","50000","10000","5000"}; final int[] scales=new int[] {100000,50000,10000,5000}; AlertDialog alertDialog=new AlertDialog.Builder(MainActivity.this) .setTitle("請選擇比例尺") .setItems(scale, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mMapView.setViewpointScaleAsync(scales[which]); } }) .show(); } });