本文主要简单讲解如何通过本地或在线资源的方式使用SimpleMarkerSymbol创建简单的图片点符号。
实现步骤:
1.创建Android项目
2.添加Runtime SDK依赖
3.添加权限及OpenGL ES支持
前三步本文省略,初学者可参照ArcGIS Runtime SDK for Android 学习笔记(1):第一个地图应用程序(二维)
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老师的指导