ArcGIS Runtime SDK for Android 100 弹窗显示三维场景图层属性信息

该博客介绍了如何使用ArcGISRuntimeSDK for Android 100在场景视图中实现点击3D模型并弹窗展示其属性信息。通过监听触摸事件,识别点击的特征并展示其详细属性,提供了一种交互式的地图体验。代码示例展示了具体的实现步骤,包括设置场景、添加地形数据、加载3D场景图层以及处理点击事件来获取和显示特征属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

ArcGIS Runtime SDK for Android 100在场景视图中点击模型,如何弹窗显示模型的属性信息

最终效果图:

仅演示了属性弹窗显示,如果觉得弹窗的界面丑,请自行调整UI样式。

测试版本:

arcgis runtime for android100.10

思路:

1、ArcGIS SceneServices有7种不同的数据类型, 但是ArcGIS Runtime只支持4种,如下:

其中如果是3d object(传统建模数据)或者点要素生成的三维场景服务,则可以支持点击查询对应要素的属性信息。

链接:https://developers.arcgis.com/android/api-reference/reference/com/esri/arcgisruntime/layers/ArcGISSceneLayer.html

2、代码思路:通过点击场景视图中的模型,弹窗显示模型的属性信息。



package com.esri.arcgisruntime.scenelayerselection;

import java.util.List;
import java.util.concurrent.ExecutionException;

import android.os.Bundle;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.Toast;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.layers.ArcGISSceneLayer;
import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.mapping.ArcGISScene;
import com.esri.arcgisruntime.mapping.ArcGISTiledElevationSource;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.GeoElement;
import com.esri.arcgisruntime.mapping.Surface;
import com.esri.arcgisruntime.mapping.view.Camera;
import com.esri.arcgisruntime.mapping.view.DefaultSceneViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.IdentifyLayerResult;
import com.esri.arcgisruntime.mapping.view.SceneView;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private SceneView mSceneView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // create a scene and add a basemap to it
        ArcGISScene scene = new ArcGISScene();
        scene.setBasemap(Basemap.createImagery());

        // set the scene to the scene view
        mSceneView = findViewById(R.id.sceneView);
        mSceneView.setScene(scene);

        // add base surface with elevation data
        Surface surface = new Surface();
        final String elevationService = getString(R.string.world_elevation_url);
        surface.getElevationSources().add(new ArcGISTiledElevationSource(elevationService));
        scene.setBaseSurface(surface);

        // add a scene layer of Harvard buildings to the scene
        final String buildings = getString(R.string.brest_buildings);
        ArcGISSceneLayer sceneLayer = new ArcGISSceneLayer(buildings);
        scene.getOperationalLayers().add(sceneLayer);

        // add a camera and initial camera position
        Camera camera = new Camera(48.378, -4.494, 200, 345, 65, 0);
        mSceneView.setViewpointCamera(camera);


        // zoom to the layer's extent when loaded
        sceneLayer.addDoneLoadingListener(() -> {
            if (sceneLayer.getLoadStatus() == LoadStatus.LOADED) {

                // when the scene is clicked, identify the clicked feature and select it
                mSceneView.setOnTouchListener(new DefaultSceneViewOnTouchListener(mSceneView) {

                    @Override
                    public boolean onSingleTapConfirmed(MotionEvent motionEvent) {

                        // clear any previous selection
                        sceneLayer.clearSelection();

                        android.graphics.Point screenPoint = new android.graphics.Point(Math.round(motionEvent.getX()),
                                Math.round(motionEvent.getY()));
                        // identify clicked feature
                        ListenableFuture<IdentifyLayerResult> identify = mSceneView
                                .identifyLayerAsync(sceneLayer, screenPoint, 10, false, 1);
                        identify.addDoneListener(() -> {
                            try {
                                // get the identified result and check that it is a feature
                                IdentifyLayerResult result = identify.get();
                                List<GeoElement> geoElements = result.getElements();
                                if (!geoElements.isEmpty()) {
                                    Log.d(TAG, "geoelement not empty");
                                    GeoElement geoElement = geoElements.get(0);
                                    if (geoElement instanceof Feature) {
                                        // select the feature
                                        sceneLayer.selectFeature((Feature) geoElement);
                                        Log.d("attributes", geoElement.getAttributes().toString());

                                        AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                                        dialog.setMessage(geoElement.getAttributes().toString());
                                        dialog.show();
                                    }
                                }
                            } catch (InterruptedException | ExecutionException e) {
                                String error = "Error while identifying layer result: " + e.getMessage();
                                Log.e(TAG, error);
                                Toast.makeText(MainActivity.this, error, Toast.LENGTH_LONG).show();
                            }
                        });
                        return true;
                    }
                });
            } else if (sceneLayer.getLoadStatus() == LoadStatus.FAILED_TO_LOAD) {
                String error = "Error loading scene layer " + sceneLayer.getLoadStatus();
                Log.e(TAG, error);
                Toast.makeText(this, error, Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        mSceneView.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mSceneView.resume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mSceneView.dispose();
    }
}

其实就是官网的这个代码,只是我加了一个以对话框的方式弹窗显示。

官网链接:https://developers.arcgis.com/android/java/sample-code/scene-layer-selection/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值