ArcGIS Runtime SDK for Android 学习(9):通过PictureMarkerSymbol创建点符号

    本文主要简单讲解如何通过本地或在线资源的方式使用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老师的指导

猜你喜欢

转载自blog.csdn.net/smart3s/article/details/81057567
今日推荐