ArcGIS Runtime SDK for Android 入門(9):通過PictureMarkerSymbol建立點符號
阿新 • • 發佈:2019-02-02
本文主要簡單講解如何通過本地或線上資源的方式使用SimpleMarkerSymbol建立簡單的圖片點符號。
實現步驟:
1.建立Android專案
2.新增Runtime SDK依賴
3.新增許可權及OpenGL ES支援
在AndroidManifest.xml中新增:
<!--聯網許可權--> <uses-permission android:name="android.permission.INTERNET" /> <!--寫入外部儲存許可權--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--OpenGL ES支援 --> <uses-feature android:glEsVersion="0x00020000" android:required="true" />
4.資源準備:
(1)在res-->values-->strings.xml中新增:
<resources>
<!--新增的內容-->
<string name="pin_blank_orange_folder_name">ArcGISTemp</string>
<string name="pin_blank_orange_file_name">pin_blank_orange.png</string>
</resources>
(2)在res-->drawable中新增兩個符號圖片:
5.設定介面佈局
在layout中的佈局XML中新增:
<!-- MapView控制元件 --> <com.esri.arcgisruntime.mapping.view.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent"> </com.esri.arcgisruntime.mapping.view.MapView>
6.編寫程式碼
在Activity中:
(1)變數準備:
//MapView控制元件變數
MapView mMapView;
//GraphicsOverlay變數
GraphicsOverlay mGraphicsOverlay;
//檔案地址
String mArcGISTempFolderPath;
String mPinBlankOrangeFilePath;
//用於設定“讀取檔案”許可權的變數
private final static int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 101;
//用來提示的標籤
private static final String TAG = "PictureMarkerSymbols";
(2)onCreate方法:
//從layout中獲取MapView控制元件
mMapView = (MapView) findViewById(R.id.mapView);
// 以影像為地圖建立地圖變數
ArcGISMap map = new ArcGISMap(Basemap.createTopographic());
// 設定地圖在MapView控制元件中被顯示
mMapView.setMap(map);
//通過一個外接矩形(藉助左下和右上兩個點形成)建立一個初始化視點
Envelope envelope = new Envelope(new Point(-228835, 6550763, SpatialReferences.getWebMercator()),
new Point(-223560, 6552021, SpatialReferences.getWebMercator()));
//在MapView中設定視點
mMapView.setViewpointGeometryAsync(envelope, 100.0);
// 建立一個新GraphicsOverlay並把它新增到MapView
mGraphicsOverlay = new GraphicsOverlay();
mMapView.getGraphicsOverlays().add(mGraphicsOverlay);
//通過一個URL資料來源建立一個picture marker symbol
//當使用URL時,你需要獲取遠端資源去裝載
final PictureMarkerSymbol campsiteSymbol = new PictureMarkerSymbol(
"http://sampleserver6.arcgisonline.com/arcgis/rest/services/Recreation/FeatureServer/0/images/e82f744ebb069bb35b234b3fea46deae");
//可以設定圖片大小,如果沒有設定,圖片將自動設定為其自身預設的畫素大小
//它的外觀會因不同解析度的裝置而異。
campsiteSymbol.setHeight(18);
campsiteSymbol.setWidth(18);
campsiteSymbol.loadAsync();
campsiteSymbol.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
//一旦符號被裝載,在GraphicOverlay中新增一個新的Graphic
Point campsitePoint = new Point(-223560, 6552021, SpatialReferences.getWebMercator());
Graphic campsiteGraphic = new Graphic(campsitePoint, campsiteSymbol);
mGraphicsOverlay.getGraphics().add(campsiteGraphic);
}
});
//通過APP資源建立picture marker symbol
BitmapDrawable pinStarBlueDrawable = (BitmapDrawable) ContextCompat.getDrawable(this, R.drawable.pin_star_blue);
final PictureMarkerSymbol pinStarBlueSymbol = new PictureMarkerSymbol(pinStarBlueDrawable);
//可以設定圖片大小,如果沒有設定,圖片將自動設定為其自身預設的畫素大小
//它的外觀會因不同解析度的裝置而異。
pinStarBlueSymbol.setHeight(40);
pinStarBlueSymbol.setWidth(40);
//Optionally set the offset, to align the base of the symbol aligns with the point geometry
//可以設定圖片的偏移,使圖片符號的基點與幾何點對齊
pinStarBlueSymbol.setOffsetY(
11); //符號使用的影象周圍有一個透明的緩衝區,因此偏移量不僅僅是高度的1/2
pinStarBlueSymbol.loadAsync();
pinStarBlueSymbol.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
//一旦符號被裝載,在GraphicOverlay中新增一個新的Graphic
//通過與初始化視點相同的位置的建立一個新的Graphic
Point pinStarBluePoint = new Point(-226773, 6550477, SpatialReferences.getWebMercator());
Graphic pinStarBlueGraphic = new Graphic(pinStarBluePoint, pinStarBlueSymbol);
mGraphicsOverlay.getGraphics().add(pinStarBlueGraphic);
}
});
//請參閱createpicturelkersymbolfromfile()方法實現。
//首次執行檢查讀取外儲存器許可權
checkSaveResourceToExternalStorage();
(3)方法支援:
private void createPictureMarkerSymbolFromFile() {
//通過本地磁碟檔案建立一個PictureMarkerSymbol
BitmapDrawable pinBlankOrangeDrawable = (BitmapDrawable) Drawable.createFromPath(mPinBlankOrangeFilePath);
final PictureMarkerSymbol pinBlankOrangeSymbol = new PictureMarkerSymbol(pinBlankOrangeDrawable);
//可以設定圖片大小,如果沒有設定,圖片將自動設定為其自身預設的畫素大小
//它的外觀會因不同解析度的裝置而異。
pinBlankOrangeSymbol.setHeight(20);
pinBlankOrangeSymbol.setWidth(20);
//可以設定圖片的偏移,使圖片符號的基點與幾何點對齊
pinBlankOrangeSymbol.setOffsetY(10); //The image used has not buffer and therefore the Y offset is height/2
pinBlankOrangeSymbol.loadAsync();
//[DocRef: END]
pinBlankOrangeSymbol.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
//通過與初始化視點相同的位置新增一個新的Graphic
Point pinBlankOrangePoint = new Point(-228835, 6550763, SpatialReferences.getWebMercator());
Graphic pinBlankOrangeGraphic = new Graphic(pinBlankOrangePoint, pinBlankOrangeSymbol);
mGraphicsOverlay.getGraphics().add(pinBlankOrangeGraphic);
}
});
}
private void checkSaveResourceToExternalStorage() {
//首先,檢查是否沒有SD卡
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
// 沒有安裝的磁碟,程式不能繼續執行
return;
}
//檢查儲存磁碟需要的許可權(安卓6.0需要在Manifest中設定而且應該被授予)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//no permission, need to task, onRequestPermissionsResult will handle the result
//若沒有許可權,則需要動態獲取許可權,onRequestPermissionsResult方法可以解決這個問題
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
//許可權已經被授予則繼續執行
//將orange marker儲存到磁碟APP資原始檔
if (saveFileToExternalStorage()) {
createPictureMarkerSymbolFromFile();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
//如果請求被拒絕,則結果陣列為空
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//許可權授予
if (saveFileToExternalStorage()) {
createPictureMarkerSymbolFromFile();
}
}
}
}
}
private boolean saveFileToExternalStorage() {
//建立路徑
mArcGISTempFolderPath = Environment.getExternalStorageDirectory() + File.separator + this.getResources()
.getString(R.string.pin_blank_orange_folder_name);
mPinBlankOrangeFilePath =
mArcGISTempFolderPath + File.separator + this.getResources().getString(R.string.pin_blank_orange_file_name);
//獲取drawable資源
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.pin_blank_orange);
//建立ArcGIS臨時資料夾
File folder = new File(mArcGISTempFolderPath);
if(folder.mkdirs()){
Log.d(TAG, "Temp folder created");
}else{
Toast.makeText(MainActivity.this, "Could not create temp folder", Toast.LENGTH_LONG).show();
}
//建立磁碟上的檔案
File file = new File(mPinBlankOrangeFilePath);
try {
OutputStream outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
return true;
} catch (Exception e) {
Log.e("picture-marker-symbol", "Failed to write image to external directory: message = " + e.getMessage());
return false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
//清空我們儲存在磁碟上的檔案和資料夾
try {
File file = new File(mPinBlankOrangeFilePath);
if(file.delete()){
Log.d(TAG, "Temp folder created");
}else{
Toast.makeText(MainActivity.this, "Could not create temp folder", Toast.LENGTH_LONG).show();
}
File tempFolder = new File(mArcGISTempFolderPath);
if(tempFolder.delete()){
Log.d(TAG, "Temp folder created");
}else{
Toast.makeText(MainActivity.this, "Could not create temp folder", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Log.e("picture-marker-symbol",
"Failed to delete temp files and directory written to external storage: message = " + e.getMessage());
}
}
6.執行APP:可以對建立的符號進行瀏覽
感謝luq老師的指導