【问题标题】:How to Draw Many Polylines in Google Map Efficiently?如何在谷歌地图中高效地绘制多条折线?
【发布时间】:2015-07-08 04:54:26
【问题描述】:

我目前正在学习制作一个使用谷歌地图向用户显示数据的安卓应用。目前我正在使用折线画出我想在地图上显示的所有“数据/线”,但我直接在谷歌地图上绘制它,比如 mMap.addPolyline(...)。 (我希望我可以发布截图,但我没有至少 10 个声望 :-( )。

但是我在地图上绘制所有这些线时遇到了一些性能问题,因为它们在那里的一个小区域内由大约 500 到 900 条线组成(通过放大)。问题是,当应用程序绘制所有这些数据时,应用程序会挂起/停止一秒钟,就像冻结一样,然后一旦完成绘制,应用程序就会继续工作。

所以我的问题是,如何在地图上绘制时不让应用挂起/停止一秒钟的情况下顺利绘制那么多折线?比如用户可以在地图上绘制折线的同时在地图上移动?

我曾尝试在不同的线程中在地图上绘制折线,但我遇到了一个错误,例如必须在主线程上绘制(不记得确切的异常错误)。除此之外,我还在互联网上搜索过这样的例子,但我只找到了带有 Overlay 或 ItemizedOverlay 东西的例子,但据我所知,这些已经被弃用了。还有其他选择吗?你能给我一些例子或指导我找到正确的资源吗?给我看一些代码会很有帮助。

谢谢

更新: 忘记在这里包含我的代码,这是我绘制折线的代码:

private class LoadDataTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        // Show a message saying this app is fetching data
        Toast.makeText(mMainActivity,
                "Fetching data ...",
                Toast.LENGTH_SHORT)
                .show();
    }

    @Override
    protected Void doInBackground(String... urls) {
        // Load then read the data from a url in the background
        loadData();

        readData();

        return null;
    }

    @Override
    protected void onPostExecute(Void unused) {

        // draw lines here
        PolylineOptions lineOptions = new PolylineOptions()
                .add(new LatLng(locations[0].getLatitude(), locations[0].getLongitude()))
                .add(new LatLng(locations[1].getLatitude(), locations[1].getLongitude()))
                .color(Color.GREEN)
                .width(5f);

        Polyline polyline = mMap.addPolyline(lineOptions);
        lineList.add(polyline);

    }
}

【问题讨论】:

    标签: android google-maps


    【解决方案1】:

    运行获取数据以在后台线程上绘制并仅在主线程上绘制线条,使用下面的代码我们正在绘制 3000 条线

    Set<String> routeNames=cordinatePojos.keySet();
                arrayList=new ArrayList<String>();
                arrayList.addAll(routeNames);
                iterator=routeNames.iterator();
                color[0]=Color.BLUE;
                color[1]=Color.GREEN;
                color[2]=Color.RED;
                color[3]=Color.CYAN;
                conuter=0;    
    
    Thread thread=new Thread(new Runnable() {
    
                            @Override
                            public void run() {
                                // TODO Auto-generated method stub
                                while (iterator.hasNext()) {
    
                                latLngs = cordinatePojos.get(iterator.next());
                                sortLocations(latLngs, latLngs.get(0).latitude, latLngs.get(0).longitude);
                                Log.d("test on background======",""+latLngs.get(0)+"======"+conuter);
                                final PolylineOptions polyLineOptions = new PolylineOptions();
                                polyLineOptions.addAll(latLngs);
                                polyLineOptions.width(15-i-i);
                                polyLineOptions.color(color[i]);
                                float[] result1 = new float[3];
    
    
                                android.location.Location.distanceBetween(latLngs.get(0).latitude,latLngs.get(0).longitude, latLngs.get(latLngs.size()-1).latitude, latLngs.get(latLngs.size()-1).longitude, result1);
                                Float distance1 = result1[0];
                                totalDistance=totalDistance+distance1;
        //                      final MarkerOptions markerOptions=new MarkerOptions().position(latLngs.get(0)).title(arrayList.get(conuter)+"==distance between this road is "+ distance1/1000 + " Km");
        //                      final MarkerOptions lastMarkerOptions=new MarkerOptions().position(latLngs.get(latLngs.size()-1)).title(arrayList.get(conuter)+"==distance between this road is "+distance1/1000+ " Km");
                                 runOnUiThread(new Runnable() {
    
                                        @Override
                                        public void run() {
                                            // TODO Auto-generated method stub
                                                /*googleMap.addMarker(markerOptions);
                                                googleMap.addMarker(lastMarkerOptions);*/
                                                googleMap.addPolyline(polyLineOptions);
                                                if (i>2) {                                                                                                                                                                                            
                                                    i=0;
                                                }
                                                i++;
    
                                        }
                                    });
                                 if (conuter>3000) {
                                    break;
                                }
                                 conuter++;
    
                            }   
    

    【讨论】:

    • 谢谢你,有机会我会试一试的。但只是另一个问题,所以我创建了这个新线程并在我想绘制我的折线时执行它?
    【解决方案2】:

    试试这个::

    GoogleMap mMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
    
    List<Polyline> mPolylines = new ArrayList<Polyline>();
    // Add polylines to the map and the list
    mPolylines.add(mMap.addPolyline(polyOpts));
    ...
    mPolylines.add(mMap.addPolyline(polyOpts));
    
    
    mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng clickCoords) {
            for (PolylineOptions polyline : mPolylines) {
                for (LatLng polyCoords : polyline.getPoints()) {
                    float[] results = new float[1];
                    Location.distanceBetween(clickCoords.latitude, clickCoords.longitude,
                            polyCoords.latitude, polyCoords.longitude, results);
    
                    if (results[0] < 100) {
                        polyline.setVisible(false);
                        Log.e(TAG, "Found @ "+clickCoords.latitude+" "+clickCoords.longitude);
                        return;
                    }
                }
            }
        }
    });
    

    【讨论】:

    • 感谢您的回答,但我已经尝试过您的做法,这就是我现在仍然面临的问题(在地图上绘制数据时缓慢/挂起/停止)。
    • 我在Note2、Note3、三星平板、nexus、中国品牌手机等7种不同的设备上进行了测试。它们都有相同的问题,所以我确定不是我的设备的问题。
    【解决方案3】:

    你应该使用 asynclass 并显示进度对话框

     private class ShowPolyLine extends
                    AsyncTask<Void, Void, Void> {
        ProgressDialog pdDialog;
                @Override
                protected void onPreExecute() {
                    try {
            pdDialog = new ProgressDialog(YourActivity.this);
                        pdDialog.show();
                        pdDialog.setCancelable(false);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                protected TicketTemplate doInBackground(Void... params) {
                    try {
                        // show pollyline code
                    } catch (Exception e) {
                        Log.d("exception", ".........................." + e);
                        return null;
                    }
                }
    
                @Override
                protected void onPostExecute(Void result) {
    
                        super.onPostExecute(result);
                         pdDialog.dismiss();
    
    
    
    
                }
    
            }
    

    并将其称为ShowPolyLine().execute();

    【讨论】:

    • 绘制所有线条时,是不是还是会导致app/map暂时停止响应?
    • 是的,这肯定会花费一些时间,但它不会挂起您的 UI,并且用户会知道正在进行一些工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    相关资源
    最近更新 更多