2

I have a huge GeoJson file (about 12MB) to be added to a map fragment. I am using the android maps utility library to render it on the map. Its taking about 5-10 seconds to show the layer on the map, during which the app becomes unresponsive.Since the layer has to be added on the main UI thread, I can't move it to a background thread.Is there any way to keep the app responsive during this time? or Any alternatives to using the Geojosn file ?

I have moved the addLayer() method to the UI thread and its working. I have encountered a few problems. Here is the code.

ThreatMap.java

public class ThreatMap extends AppCompatActivity implements OnMapReadyCallback {

    private static final String TAG = "ThreatMap";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.threat_map);

        Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar_threat_map);
        TextView title = (TextView) findViewById(R.id.main_title);
        title.setText(R.string.actionbar_threat_map);
        setSupportActionBar(toolbar);

        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(false);


        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        ThreatMapRenderingTask task = new ThreatMapRenderingTask();
        task.execute(googleMap);
    }


    private class ThreatMapRenderingTask extends AsyncTask<GoogleMap, Void, GeoJsonLayer> {

        ProgressDialog progressDialog;

        public ThreatMapRenderingTask() {
            progressDialog = new ProgressDialog(ThreatMap.this);
        }

        @Override
        protected void onPreExecute() {

            progressDialog.setMessage("Loading Threat Map");
            progressDialog.show();
        }


        @Override
        protected GeoJsonLayer doInBackground(GoogleMap... googleMap) {

            GoogleMap gMap = googleMap[0];
            GeoJsonLayer layer = null ;

            PolygonOptions first = new PolygonOptions();
            try {
               layer =  new GeoJsonLayer(gMap, R.raw.threatmap, getApplicationContext());

            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return layer;
        }

        @Override
        protected void onPostExecute(GeoJsonLayer layer) {

            layer.addLayerToMap();

            for (GeoJsonFeature feature : layer.getFeatures()) {
                if (feature.hasProperty("EX_BOX_ID")) {
                    String state = feature.getProperty("STATE_PROV");
                    int ex_box_id = Integer.parseInt(feature.getProperty("EX_BOX_ID"));
                    String pb_box_id = feature.getProperty("PB_BOX_ID");


                    if (ex_box_id < 25) {
                        GeoJsonPolygonStyle polygonStyleRed = new GeoJsonPolygonStyle();
                        polygonStyleRed.setFillColor(Color.RED);
                        feature.setPolygonStyle(polygonStyleRed);
                    } else if (ex_box_id < 50 && ex_box_id > 25) {
                        GeoJsonPolygonStyle polygonStyleYellow = new GeoJsonPolygonStyle();
                        polygonStyleYellow.setFillColor(Color.YELLOW);
                        feature.setPolygonStyle(polygonStyleYellow);
                    } else {
                        GeoJsonPolygonStyle polygonStyleGreen = new GeoJsonPolygonStyle();
                        polygonStyleGreen.setFillColor(Color.GREEN);
                        feature.setPolygonStyle(polygonStyleGreen);
                    }
                }
            }

            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
            }

        }
    }
}

threat_map_fragment.xml

<fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ThreatMap"
    map:cameraTargetLat="78.00"
    map:cameraTargetLng="16.00"
    map:cameraZoom="3"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:map="http://schemas.android.com/apk/res-auto" />

threat_map.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/app_bar_threat_map"
        layout="@layout/appbar" />
    <include
       android:id="@+id/map"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       layout="@layout/threat_map_fragment"
       android:layout_below="@id/app_bar_threat_map"/>

</LinearLayout>

I am having a couple of problems.

  1. The map fragment is not zooming to the default location defined in the xml file.

  2. I have used GeoJsonPolygonStyle method, and added color to the polygons on the layer. The color is not visible at all zoom levels. I have to zoom in a lot, to see the color for some polygons. What is the reason for this and is there any work around ?

V-rund Puro-hit
  • 5,518
  • 9
  • 31
  • 50
rtk
  • 21
  • 1
  • 3
  • Any chance to split the file into smaller bits? Are you sure you gotta do the import on the main thred? Isn't there a method `addLayer()` that's gotte be called on the UI thread? – m02ph3u5 Jun 18 '16 at 10:37
  • thanks @m02ph3u5 , i have moved the addLayer() to UI thread and its working, I have encountered few more problems after this. I'm updating the question, please have a look. – rtk Jun 20 '16 at 04:17
  • try this sample code on githube https://github.com/hiepxuan2008/GoogleMapDirectionSimple/ – Muhammad Waleed Jun 20 '16 at 06:17
  • Might be worth a bug report @rtk – m02ph3u5 Jun 20 '16 at 10:06

1 Answers1

0

I am facing similar issue. Currently, my approach is dividing the larger geojson file into small chunks and loading them by calling multiple async tasks (parallel processing). This happened to improve the performance as compared to loading a single file. But still I am looking for optimizing techniques. You can check here (Show large geojson file in android google maps)

Community
  • 1
  • 1
Sujal
  • 1,447
  • 19
  • 34