首页 / 浏览问题 / 移动GIS / 问题详情
iMobile如何根据已知点数据实现动态绘制轨迹
6EXP 2024年02月02日

使用产品:iMobile 10i

问题详细描述:

我从udb数据集中获取点数据,调用geoline绘制出线,并通过gettrackinglayer.add将其显示在三维底图上,但是无法实现动态绘制,类似轨迹回放那种效果,我尝试使用timer进行控制,但好像没起作用。

我想请问一下,这个timer可以实现我想要的效果嘛,麻烦可以给个相关timer调用控制点的显示的参考吗?

或者有没有其他的方法可以实现我想要的效果,我之前看itinerary的有关示例,感觉也可以实现,但是我不太懂那个re-play是怎样调用的,可以麻烦指导下嘛?

代码:

  DatasourceConnectionInfo dinfo =new DatasourceConnectionInfo();
                    dinfo.setServer(sdcard+"/SampleData/Journey/Point.udb");
                    dinfo.setEngineType(EngineType.UDB);
                    dinfo.setAlias("UDB");
                    Datasource datasource = workspace.getDatasources().open(dinfo);
                    if (datasource == null) {
                        System.out.println("打开数据源失败");
                        return;
                    }
                    else {
                        //System.out.println("数据源打开成功!");
                         Dataset dataset = (Dataset) datasource.getDatasets().get(0);
                                //获取名为Point3d的矢量数据集
                      DatasetVector datasetVector = (DatasetVector) datasource.getDatasets().get("Point3d");
                        //得到Point对应的所有记录集
                       Recordset recordset = datasetVector.getRecordset(false, CursorType.DYNAMIC);
                       if(recordset != null){
                           // System.out.print("获取点数据集成功");
                                //设置线的样式
                                GeoStyle geoStyle_L = new GeoStyle();
                                geoStyle_L.setLineColor(new com.supermap.data.Color(4514087));//设置颜色
                                geoStyle_L.setLineSymbolID(2);//设置线状符号的编码
                                geoStyle_L.setLineWidth(10);
                                //获取点串
                                Point3Ds p1 = new Point3Ds();
                                Geometry geometry = recordset.getGeometry();
                               GeoPoint3D start_geoPoint3D = new GeoPoint3D((GeoPoint3D) geometry);
                               double a = start_geoPoint3D.getX();
                               double b = start_geoPoint3D.getY();
                               double c = start_geoPoint3D.getZ();
                               Point3D startPoint = new Point3D(a, b, c);
                               Point3D[] Point3D = {startPoint};
                               p1.addRange(Point3D);
                               Timer timer = new Timer();
                                for(int i=0;i<recordset.getRecordCount();i++){
                                    //timer定时器控制点的速度
                                    recordset.moveNext();
                                    Geometry geometry_next = recordset.getGeometry();
                                    if(geometry_next != null) {
                                        GeoPoint3D geoPoint3D = new GeoPoint3D((GeoPoint3D) geometry_next);
                                        double x = geoPoint3D.getX();
                                        double y = geoPoint3D.getY();
                                        double z = geoPoint3D.getZ();
                                        Point3D point = new Point3D(x, y, z);
                                        Point3D[] point3DArray = {point};
                                        p1.addRange(point3DArray);
                                        GeoLine3D gl =new GeoLine3D(p1);
                                        gl.setStyle(geoStyle_L);
                                        scene.getTrackingLayer().add(gl,"line");
                                        /*timer.scheduleAtFixedRate(new TimerTask() {
                                            @Override
                                            public void run() {
                                                scene.getTrackingLayer().add(gl,"line");
                                            }
                                        }, 2000,2000);*/

                                    }
                                    else{
                                        break;
                                    }

麻烦了!!!

1个回答

您好,timer也是可以实现的,具体实现思路就是比如500ms添加一个点,使用新的坐标点串构造新的几何对象添加到跟踪图层中。添加完后可以把上一次的线清除掉。这样以免跟踪图层上对象过多导致卡顿
9,127EXP 2024年02月04日

您好,根据您的思路进行了修改,但是我并未实现,绘制出来的轨迹变得不流畅了,出现以下情况

而且还出现了另一个问题,就是缩放会影响天地图底图的加载,从而会影响轨迹的显示,请问这种情况该如何处理?

代码

public void onClick(View v) {
               //打开一个工作空间
               Workspace workspace = new Workspace();
               WorkspaceConnectionInfo minfo = new WorkspaceConnectionInfo();
               minfo.setServer(sdcard + "/SampleData/Journey/journey.smwu");
               //minfo.setServer(sdcard + "/SampleData/Journey/point3d/point3d.sxwu");
               minfo.setType(WorkspaceType.SMWU);
               boolean openSuccess = workspace.open(minfo);
               if (openSuccess) {
                   //System.out.print("打开工作空间成功");
                   SceneControl sceneControl = (SceneControl) findViewById(R.id.SceneControl);
                   Scene scene = sceneControl.getScene();
                   scene.setWorkspace(workspace);
                   String tiandiduURl = "http://t0.tianditu.gov.cn/img_c/wmts?tk=22f8a846ef9e3becd95a25b08bde8f36";
                   scene.getLayers().add(tiandiduURl, Layer3DType.WMTS, "img",
                           ImageFormatType.JPG_PNG, 96.0, false);
                   Button btnline = (Button)findViewById(R.id.btn_line);
                   btnline.setOnClickListener(new OnClickListener() {
                       public void onClick(View v) {
                           DatasourceConnectionInfo dinfo = new DatasourceConnectionInfo();
                           dinfo.setServer(sdcard + "/SampleData/Journey/Point.udb");
                           dinfo.setEngineType(EngineType.UDB);
                           dinfo.setAlias("UDB");
                           Datasource datasource = workspace.getDatasources().open(dinfo);
                           if (datasource == null) {
                               System.out.println("打开数据源失败");
                               return;
                           } else {
                               //System.out.println("数据源打开成功!");
                               Dataset dataset = (Dataset) datasource.getDatasets().get(0);
                               //获取名为Point3d的矢量数据集
                               DatasetVector datasetVector = (DatasetVector) datasource.getDatasets().get("Point3d");
                               //得到Point对应的所有记录集
                               Recordset recordset = datasetVector.getRecordset(false, CursorType.DYNAMIC);
                               if (recordset != null) {
                                   // System.out.print("获取点数据集成功");
                                   //设置线的样式
                                   GeoStyle geoStyle_L = new GeoStyle();
                                   geoStyle_L.setLineColor(new com.supermap.data.Color(4514087));//设置颜色
                                   geoStyle_L.setLineSymbolID(2);//设置线状符号的编码
                                   geoStyle_L.setLineWidth(10);
                                   //获取点串
                                   Point3Ds p1 = new Point3Ds();
                                   Geometry geometry = recordset.getGeometry();
                                   GeoPoint3D start_geoPoint3D = new GeoPoint3D((GeoPoint3D) geometry);
                                   double a = start_geoPoint3D.getX();
                                   double b = start_geoPoint3D.getY();
                                   double c = start_geoPoint3D.getZ();
                                   Point3D startPoint = new Point3D(a, b, c);
                                   Point3D[] Point3D = {startPoint};
                                   p1.addRange(Point3D);
                                   recordset.moveNext();
                                
                                   Timer timer = new Timer();
                                   for (int i = 1; i <= recordset.getRecordCount(); i++) {
                                       //timer定时器控制点的速度
                                       scene.getTrackingLayer().clear();
                                       Geometry geometry_next = recordset.getGeometry();
                                       if (geometry_next != null) {
                                           TimerTask task = new TimerTask() {
                                               @Override
                                               public void run() {
                                                  GeoPoint3D geoPoint3D = new GeoPoint3D((GeoPoint3D) geometry_next);
                                                   double x = geoPoint3D.getX();
                                                   double y = geoPoint3D.getY();
                                                   double z = geoPoint3D.getZ()+100;
                                                   Point3D point = new Point3D(x, y, z);
                                                   Point3D[] point3DArray = {point};
                                                   p1.addRange(point3DArray);
                                                   GeoLine3D gl = new GeoLine3D(p1);
                                                   gl.setStyle(geoStyle_L);
                                                   scene.getTrackingLayer().add(gl, "line");
                                                   //scene.refresh();
                                               }
                                           };
                                           timer.schedule(task, 10000);
                                           //scene.getTrackingLayer().add(gl, "line");
                                           recordset.moveNext();
                                       } else {
                                           break;
                                       }
                                   }

劳烦请您帮我看一下是哪里出了问题,感谢!!!

您那边把绘制轨迹的代码放在子线程去操作呢,timer时间可以设置长一点, 刷新太多会导致资源占用过多,场景卡顿

您好,我将绘制轨迹的代码放进子线程,还是会有问题

1.在绘制轨迹时,必须要放大一下,才能显示出绘制的轨迹

2.读取的点偶尔会有几个点不按顺序获取

3.我的代码中scene.getTrackingLayer().clear();是清除跟踪图层上的所有内容,这个有影响吗?怎样才能只清除跟踪图层上一次绘制的线

请问一下,我应该如何处理以上情况,劳烦您指导

以下是我改成子线程的代码

Thread thread = new Thread(() -> {
                                       for (int i = 1; i <= recordset.getRecordCount(); i++) {
                                           //清除跟踪图层上所有内容
                                           scene.getTrackingLayer().clear();
                                           // 获取几何对象
                                           Geometry geometry_next = recordset.getGeometry();
                                           // 如果几何对象不为null
                                           if (geometry_next != null) {
                                               // 创建TimerTask任务
                                               int finalI = i+1;
                                               TimerTask task = new TimerTask() {
                                                   @Override
                                                   public void run() {

                                                       // 创建GeoPoint3D对象
                                                       GeoPoint3D geoPoint3D = new GeoPoint3D((GeoPoint3D) geometry_next);
                                                       double x = geoPoint3D.getX();
                                                       double y = geoPoint3D.getY();
                                                       double z = geoPoint3D.getZ();
                                                       //测试是否运行正常
                                                       System.out.println("当前第:"+ finalI +"个点的坐标"+x+","+y+","+z);
                                                       Point3D point = new Point3D(x, y, z);
                                                       Point3D[] point3DArray = {point};
                                                       p1.addRange(point3DArray);
                                                       GeoLine3D gl = new GeoLine3D(p1);
                                                       gl.setStyle(geoStyle_L);
                                                       //跟踪图层绘制轨迹线
                                                       scene.getTrackingLayer().add(gl, "line");

                                                       // 添加下一个点前的延迟
                                                       try {
                                                           Thread.sleep(1000); // 延迟50秒
                                                       } catch (InterruptedException e) {
                                                           e.printStackTrace();
                                                       }
                                                   }
                                               };
                                               // 计划在10秒后执行TimerTask任务
                                               timer.schedule(task, 5000);
                                               //获取下一个记录点
                                               recordset.moveNext();
                                           } else {
                                               System.out.println("无几何对象");
                                              // break; // 如果几何对象为null,跳出循环
                                           }
                                       }
                                   });
                                   thread.start();

1.需要放大才能显示轨迹,在子线程中使用scene.refresh方法强制刷新场景。

2.点不按顺序获取看看你那边是怎么获取的?代码怎么写的

3.通过trackingLayer3D.remove()方法可以移除某个ID的几何对象。
...