Как управлять более чем 1000 пользовательскими маркерами на карте Google с ограничением ограничивающей рамки, чтобы избежать исключения нехватки памяти?

Я использую карту Google с пользовательскими маркерами в своем проекте, где каждый маркер необходимо установить с пользовательским представлением для разных целей, таких как путевые точки с полилиниями и маркерами для их идентификации, полигоны с маркерами и т. д. Теперь, когда этих маркеров более 1000, растровое изображение не загружается в карту, и выдается OOM.

Я использовал векторные рисунки в качестве идентификатора маркера и обычный текстовый вид для их выравнивания, создание растрового изображения занимает изображение 180 * 210,

Как я могу эффективно управлять этим без задержек и проблем с OOM?

вот код: это нужно для чтения местоположения из массива allGlobalPoints, их различения и построения графика.

mMap.clear();
    allpointPlotterThreadRunning = true;
    switchTospecific = true;
    final String POINTS = "points";
    final String POIS = "pois";
    final String FAILSAFE = "failsafe";
    final String POLYGON = "polygon";
    final String LASTPOLYGON = "lastpolygon";

    allMapPointPlotter = new AsyncTask<Void, Object, Void>() {
        ProgressDialog pgbarLoading;
        PolylineOptions polyline;
        PolygonOptions plogon;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            final View tiltleView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.progress_dialog_title_background, null);
            OpenSansRegularTextView tiltle = (OpenSansRegularTextView) tiltleView.findViewById(R.id.title_text);
            tiltle.setText("UAV Editor");

            pgbarLoading = new ProgressDialog(getActivity());
            pgbarLoading.setCancelable(false);
            pgbarLoading.setMessage("" + getActivity().getString(R.string.please_wait));
            pgbarLoading.setCustomTitle(tiltleView);
            pgbarLoading.show();
            markerPlottedList = new ArrayList<>();
            markerOnQueue = new ArrayList<>();

            ((DashboardActivity) getActivity()).setZoomOut();
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            allpointPlotterThreadRunning = false;
        }


        @Override
        protected Void doInBackground(Void... voids) {
            try {
                if (allpointPlotterThreadRunning) {
                    if (allGlobalPoints.size() > 0) {


                        for (int global = 0; global < allGlobalPoints.size(); global++) {
                            if (allpointPlotterThreadRunning) {
                                //getting first object containing all points data
                                AllGlobalPointsArrayData globalDataObject = allGlobalPoints.get(global);  //This is the object of the position that contains all 5 data

                                if (globalDataObject.getPointsDataArray() != null && globalDataObject.getPointsDataArray().size() > 0) {

                                    ArrayList<RoutePointCoordinatesDataType> innerarraylist = globalDataObject.getPointsDataArray();

                                    for (int i = 0; i < innerarraylist.size(); i++) {
                                        if (allpointPlotterThreadRunning) {

                                            if (i == (innerarraylist.size() - 1)) {
                                                publishProgress(
                                                        POINTS,
                                                        Double.parseDouble(innerarraylist.get(i).getCoordinatesLatitude()),
                                                        Double.parseDouble(innerarraylist.get(i).getCoordinatesLongitude()),
                                                        i,
                                                        "" + innerarraylist.get(i).getTag(),
                                                        innerarraylist.get(i).getHeadingAngle(),
                                                        true
                                                );
                                            } else {
                                                publishProgress(
                                                        POINTS,
                                                        Double.parseDouble(innerarraylist.get(i).getCoordinatesLatitude()),
                                                        Double.parseDouble(innerarraylist.get(i).getCoordinatesLongitude()),
                                                        i,
                                                        "" + innerarraylist.get(i).getTag(),
                                                        innerarraylist.get(i).getHeadingAngle(),
                                                        false
                                                );
                                            }

                                        } else {
                                            break;
                                        }


                                    }
                                }
                                if (globalDataObject.getPoiDataArray() != null && globalDataObject.getPoiDataArray().size() > 0) {
                                    ArrayList<RoutePointCoordinatesDataType> innerList = globalDataObject.getPoiDataArray();

                                    if (innerList != null && innerList.size() > 0) {

                                        for (int i = 0; i < innerList.size(); i++) {
                                            if (allpointPlotterThreadRunning) {

                                                publishProgress(
                                                        POIS,
                                                        Double.parseDouble(innerList.get(i).getCoordinatesLatitude()),
                                                        Double.parseDouble(innerList.get(i).getCoordinatesLongitude()),
                                                        i,
                                                        "" + innerList.get(i).getTag()
                                                );

                                            } else {
                                                break;
                                            }

                                        }
                                    }
                                }

                                if (globalDataObject.getFailsafeDataArray() != null && globalDataObject.getFailsafeDataArray().size() > 0) {

                                    ArrayList<RoutePointCoordinatesDataType> innerArray = globalDataObject.getFailsafeDataArray();
                                    if (innerArray != null && innerArray.size() > 0) {
                                        for (int i = 0; i < innerArray.size(); i++) {
                                            if (allpointPlotterThreadRunning) {

                                                publishProgress(
                                                        FAILSAFE,
                                                        Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
                                                        Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
                                                        i,
                                                        "" + innerArray.get(i).getTag()
                                                );

                                            } else {
                                                break;
                                            }

                                        }
                                    }
                                }

                                if (globalDataObject.getPolygonLastUsedDataArray() != null && globalDataObject.getPolygonLastUsedDataArray().size() > 0) {
                                    ArrayList<RoutePointCoordinatesDataType> innerArray = globalDataObject.getPolygonLastUsedDataArray();
                                    if (innerArray != null && innerArray.size() > 0) {

                                        for (int i = 0; i < innerArray.size(); i++) {
                                            if (allpointPlotterThreadRunning) {


                                                if (i == (innerArray.size() - 1)) {
                                                    publishProgress(
                                                            LASTPOLYGON,
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
                                                            i,
                                                            "" + innerArray.get(i).getTag(),
                                                            true
                                                    );
                                                } else {
                                                    publishProgress(
                                                            LASTPOLYGON,
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
                                                            i,
                                                            "" + innerArray.get(i).getTag(),
                                                            false
                                                    );
                                                }

                                            } else {
                                                break;
                                            }


                                        }
                                    }
                                }

                                if (globalDataObject.getPolygonLastUsedDataArray() == null || globalDataObject.getPolygonLastUsedDataArray().size() == 0) {
                                    ArrayList<RoutePointCoordinatesDataType> innerArray = globalDataObject.getPolygonDataArray();
                                    if (innerArray != null && innerArray.size() > 0) {

                                        for (int i = 0; i < innerArray.size(); i++) {
                                            if (allpointPlotterThreadRunning) {


                                                if (i == (innerArray.size() - 1)) {
                                                    publishProgress(
                                                            POLYGON,
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
                                                            i,
                                                            "" + innerArray.get(i).getTag(),
                                                            true
                                                    );
                                                } else {
                                                    publishProgress(
                                                            POLYGON,
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
                                                            Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
                                                            i,
                                                            "" + innerArray.get(i).getTag(),
                                                            false
                                                    );
                                                }

                                            } else {
                                                break;
                                            }

                                        }

                                    }
                                }
                            } else {
                                break;
                            }
                        }

                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Object... values) {
            super.onProgressUpdate(values);
            if (allpointPlotterThreadRunning) {
                String tagmarker = (String) values[0];
                int innerCounter = (Integer) values[3];

                if (tagmarker.equalsIgnoreCase(POINTS)) {
                    if (innerCounter == 0) {
                        polyline = new PolylineOptions();
                        polyline.width(4);
                        polyline.color(Color.parseColor("#425fa9"));
                        polyline.geodesic(true);
                    }

                    polyline.add(
                            new LatLng(
                                    (Double) values[1],
                                    (Double) values[2]
                            )
                    );
                    if ((Double) values[5] != 400) {
                        createMarker(
                                mMap,
                                (Double) values[1],
                                (Double) values[2],
                                innerCounter,
                                (String) values[4],
                                (Double) values[5]

                        );


                    } else {
                        createMarker(
                                mMap,
                                (Double) values[1],
                                (Double) values[2],
                                innerCounter,
                                (String) values[4],
                                400
                        );
                    }


                    if ((Boolean) values[6]) {
                        mMap.addPolyline(polyline);
                    }

                } else if (tagmarker.equalsIgnoreCase(POIS)) {

                    createMarkerPoi(
                            mMap,
                            (Double) values[1],
                            (Double) values[2],
                            innerCounter,
                            (String) values[4]
                    );


                } else if (tagmarker.equalsIgnoreCase(FAILSAFE)) {

                    createMarkerFailsafe(
                            mMap,
                            (Double) values[1],
                            (Double) values[2],
                            innerCounter,
                            (String) values[4]
                    );

                } else if (tagmarker.equalsIgnoreCase(POLYGON)) {
                    if (innerCounter == 0) {
                        plogon = new PolygonOptions();
                        plogon.fillColor(Color.parseColor("#20ff1a1a"));

                        plogon.strokeWidth((float) 5.1)
                                .strokeColor(Color.parseColor("#30ff1a1a"));
                    }
                    createMarkerPolygon(
                            mMap,
                            (Double) values[1],
                            (Double) values[2],
                            innerCounter,
                            (String) values[4]
                    );

                    plogon.add(new LatLng(
                            (Double) values[1],
                            (Double) values[2]
                    ));
                    if ((Boolean) values[5]) {
                        mMap.addPolygon(plogon);
                    }

                } else if (tagmarker.equalsIgnoreCase(LASTPOLYGON)) {
                    if (innerCounter == 0) {
                        plogon = new PolygonOptions();
                        plogon.fillColor(Color.parseColor("#20ff1a1a"));

                        plogon.strokeWidth((float) 5.1)
                                .strokeColor(Color.parseColor("#30ff1a1a"));
                    }

                    createMarkerPolygon(
                            mMap,
                            (Double) values[1],
                            (Double) values[2],
                            innerCounter,
                            (String) values[4]
                    );

                    plogon.add(new LatLng(
                            (Double) values[1],
                            (Double) values[2]
                    ));
                    if ((Boolean) values[5]) {
                        mMap.addPolygon(plogon);
                    }
                }
            }

        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            pgbarLoading.dismiss();
            allpointPlotterThreadRunning = false;

        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Для создания маркеров и растровых изображений используются следующие функции:-> memoryCacheData используется как список lrucache для быстрого доступа к растровому изображению.

    protected void createMarker(GoogleMap map, double latitude, double longitude, int inner, String outer, double angle) {
    try {
        Bitmap resultantBitmap = null;
        if (((DashboardActivity) getActivity()).memoryCacheData != null && ((DashboardActivity) getActivity()).memoryCacheData.size() > 0) {
            resultantBitmap = ((DashboardActivity) getActivity()).memoryCacheData.get(latitude + "/" + longitude + "-OwnTab-" + inner + "|" + outer);
            if (resultantBitmap == null) {
                resultantBitmap = getMarkerBitmapFromView("P" + (inner + 1), "P", angle);
                ((DashboardActivity) getActivity()).memoryCacheData.put(latitude + "/" + longitude + "-OwnTabMarker-" + inner + "|" + outer, resultantBitmap);
            }
        } else {
            resultantBitmap = getMarkerBitmapFromView("P" + (inner + 1), "P", angle);
            ((DashboardActivity) getActivity()).memoryCacheData.put(latitude + "/" + longitude + "-OwnTabMarker-" + inner + "|" + outer, resultantBitmap);
        }

        map.addMarker(new MarkerOptions()
                .position(new LatLng(latitude, longitude))
                .anchor(0.5f, 0.5f)
                .title("" + outer)
                .icon(BitmapDescriptorFactory.fromBitmap(resultantBitmap))
        );


    } catch (Exception e) {
        e.printStackTrace();
    }

}

Пожалуйста, помогите мне, как управлять растровым изображением, не замораживая приложение и избегая исключения «Недостаточно памяти», и как я могу управлять таким количеством маркеров с помощью пользовательского представления.


person bodhidipta    schedule 14.11.2016    source источник
comment
Не возможно... 180*210*4*1000 = 151 МБ только для ваших растровых изображений...   -  person Selvin    schedule 14.11.2016
comment
Если я использую холст для рисования маркеров вместо создания растрового изображения из кеша XML, помогает ли это уменьшить размер растрового изображения?   -  person bodhidipta    schedule 16.11.2016


Ответы (2)


Я знаю, что уже слишком поздно отвечать на этот вопрос, но вы можете использовать ClusterManager для эффективного отображения маркера 1000. Сначала поместите всю широту длину в ArrayList, а затем сразу добавьте список в ClusterManager с помощью mClusterManager.addItems(ArrayList‹..> );, mClusterManager.cluster();.

Это устранит проблему зависания пользовательского интерфейса и проблему нехватки памяти.

Чтобы реализовать ClusterManager, перейдите по этой ссылке: https://github.com/googlemaps/android-maps-utils/blob/master/demo/src/com/google/maps/android/utils/demo/CustomMarkerClusteringDemoActivity.java

person Idris Bohra    schedule 04.07.2017

Добавлять более 1000 маркеров одновременно не рекомендуется. Альтернативой является создание массива всех ваших маркеров и динамическое отслеживание/показ ближайших маркеров. Аналогичный вопрос/ответ можно найти здесь: API карт Google находит ближайшие маркеры

person Jenever    schedule 14.11.2016