วิธีจัดการเครื่องหมายที่กำหนดเองมากกว่า 1,000 รายการใน Google Map ด้วยข้อ จำกัด ของกรอบขอบเขตเพื่อหลีกเลี่ยงข้อยกเว้นหน่วยความจำไม่เพียงพอ

ฉันใช้ Google Map พร้อมมาร์กเกอร์ที่กำหนดเองในโครงการของฉัน โดยที่มาร์กเกอร์แต่ละตัวจำเป็นต้องตั้งค่าด้วยมุมมองที่กำหนดเอง เพื่อวัตถุประสงค์ที่แตกต่างกัน เช่น เวย์พอยท์ที่มีเส้นหลายเส้นและมาร์กเกอร์เพื่อระบุพวกมัน รูปหลายเหลี่ยมพร้อมมาร์กเกอร์ ฯลฯ ตอนนี้เมื่อมาร์กเกอร์เหล่านี้มีมากกว่า 1,000 ตัว บิตแมปล้มเหลวในการโหลดลงในแผนที่และ OOM ถูกส่งออกไป

ฉันใช้ vector Drawables เป็นตัวระบุตัวของเครื่องหมายและมุมมองข้อความปกติเพื่อปรับระดับ การสร้างบิตแมปใช้รูปภาพขนาด 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 MB สำหรับบิตแมปของคุณเท่านั้น ...   -  person Selvin    schedule 14.11.2016
comment
หากฉันใช้ Canvas เพื่อวาดมาร์กเกอร์แทนการสร้างบิตแมปจากแคช XML จะช่วยลดขนาดบิตแมปได้หรือไม่   -  person bodhidipta    schedule 16.11.2016


คำตอบ (2)


ฉันรู้ว่ามันสายเกินไปที่จะตอบคำถามนี้ แต่คุณสามารถใช้ ClusterManager เพื่อแสดงเครื่องหมาย 1,000 ตัวได้อย่างมีประสิทธิภาพ ขั้นแรกให้ใส่ lat long ทั้งหมดลงใน ArrayList แล้วเพิ่มรายการลงใน ClusterManager พร้อมกันโดยใช้ mClusterManager.addItems(ArrayList‹..> );, mClusterManager.cluster();.

การทำเช่นนี้จะช่วยขจัดปัญหาการค้างของ UI และปัญหาหน่วยความจำไม่เพียงพอ

เพื่อที่จะใช้ ClusterManager โปรดอ้างอิงลิงค์นี้: https://github.com/googlemaps/android-maps-utils/blob/master/demo/src/com/google/maps/android/utils/การสาธิต/CustomMarkerClusteringDemoActivity.java

person Idris Bohra    schedule 04.07.2017

การเพิ่มเครื่องหมายมากกว่า 1,000 ตัวในคราวเดียวไม่ใช่แนวทางปฏิบัติที่ดี อีกทางเลือกหนึ่งคือการสร้างอาร์เรย์ของเครื่องหมายทั้งหมดของคุณและติดตาม/แสดงเครื่องหมายที่ใกล้ที่สุดแบบไดนามิก สามารถดูคำถาม/คำตอบที่คล้ายกันได้ที่นี่: google maps api ค้นหาเครื่องหมายที่ใกล้ที่สุด

person Jenever    schedule 14.11.2016