11

I have big KML file to a native Android application, please check the following details and give an advice.

KML file details:

  • size: 1.7 MB
  • total number of kml file elements: 500 elements
  • total number of polygon: 1000 polygon

Android app details:

  • the above details will be viewed in Fragment
  • I used the following support library to implement this screen compile 'com.google.maps.android:android-maps-utils:0.4+'
  • some caluctations are done on loading the screens(like distance calculations)

Issue:

  • Take a lot of time to load the map and kml layer about 8 sec create KMLLayer instance

What is the best practice to implement the above details with good performance?

please advise.

Wael Abo-Aishah
  • 942
  • 2
  • 10
  • 27
  • 2
    You can load the visible items only, you don't need to load whole items at once. –  Sep 08 '17 at 20:52
  • @Ibrahim it's done exactly as you said, we change the process to have good performance by the following steps: 1- load markers when zooming level is too big (cover all area) 2- when user click on marker we load it's KML layer 3- on zoom out remove KML layer and show markers – Wael Abo-Aishah Sep 09 '17 at 09:06
  • 2
    Kindly post your code so that others can point you in right direction. – Ashish Pathak Sep 13 '17 at 05:34

4 Answers4

1

Best practice is doing long time operation in background (for example, on separate thread) and split complex tasks into small parts. So you can:

1) create and start load KML layer as soon as possible (e.g. on app create) and than just show it;

2) instead of one kml file with 500 elements and 1000 polygons, use 50 kml files with 10 elements and 100 polygons and load to layer only necessary files (for example you can split it by area location, or by semantic information, or by something else criteria);

3) combine 1 and 2 points;

4) precisely for google maps it's possible to create tiles with information from kml files and use TileProvider.

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
1

Since there's no actual answer, I'll post my own solution.

I've done mainly two things to optimize this.

  1. Instead of using Google maps utils built-in method addLayerToMap - I've used my own custom implementation. I've done so, because parsing kml is relatively fast(in my case - ~5-10 seconds) and it can be done in background thread. Adding all the points to the map, however, takes more than 10 seconds, and must be done on UI thread. Basically, I've used KmlLayer class as a base, and parsed kml file by myself into polygonOptions and all other things I need.

  2. Calculate which items are visible and which are not. Firstly, I filter which items are outside screen bounds. After that, I calculate each item's size(in pixels, no meters) - if item is smaller than threshold - item is also filtered out.

With these hacks applied, instead of freezing app for 15 seconds, user can freely navigate through map, and when he stops, after several seconds information will be displayed.

Marius
  • 810
  • 7
  • 20
0

I just make some updates on the screen behavior to get good performance and good user experience by the following steps:

  1. Divide the KML File to 65 files (the main areas on the map, for example, Zone A11 is located in one KML file and it contains all its details like Zone A11-1, Zone A11-2 and Zone A11-4 ...) and this division is done to be suitable the screen experience (for example user requirements)

  2. on the first load, I am loading only the markers for all KMLs centers and that is not affecting the performance

  3. When user click on the marker, I am loading the KML file for this area and zoom this area

  4. When user zoom out, I am removing this layer from the map and load marker

  5. When user moves the map I am calculating the nearest marker and load its KML layer

Note: preparing files on app launching will not provide better performance because the bad performance comes from adding the KML layer to the google map

Note2: using custom implementation for parsing and adding to Google map take a lot of time or need a lot of unit testing, and I think it's not recommended solution because it's better to leave this solution to be on Google Map utils build-in method (it's customized and always up to date)

Wael Abo-Aishah
  • 942
  • 2
  • 10
  • 27
  • I think sharing example or reference code would be too helpful to others. I came across this post while finding an optimised way to load large kml file. – Paresh Mayani Feb 26 '18 at 11:17
0

I'd suggest you to make sure that you are constructing the KmlLayer on a background thread and addLayerToMap() has to be done on the main thread though like this

GlobalScope.launch {
                    val stringUrl: String = "https://saltwx.com/bath/SW_bath6.kml"
                    val inputStream: InputStream = URL(stringUrl).openStream()
                  
                    val layer = KmlLayer(map,inputStream, applicationContext)
                    runOnUiThread {
                        try {

                             layer.addLayerToMap()
                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                   }}
Abhi
  • 1
  • 3