Show Line Data from GeoJSON File on the Map

GeoJsonOverlay

This example demonstrates how to load and parse bundled GeoJSON resource and display it on the map.

You will learn the following:

  • How to load GeoJSON from file (bundled as a local asset on the device) on a background thread.
  • How to draw lines on the map.

Include Raster to the project

In Android Studio, copy your GeoJSON file into assets folder (create assets folder if it does not exists). The path should be app/src/main/assets.

Initialize Map

We will add GeoJSON overlay to the map after the style has been loaded. So firstly we initialize the mapView in onViewCreated method.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val mapTilerKey = Helper.getMapTilerKey(context!!)
        Helper.validateKey(mapTilerKey)
        val styleUrl = "https://api.maptiler.com/maps/streets/style.json?key=${mapTilerKey}";

        // Create map view
        mapView = view.findViewById(R.id.geoJsonMapView)
        mapView?.onCreate(savedInstanceState)
        mapView?.getMapAsync { map ->

            // Navigate the map to the area with geojson data
            map.cameraPosition = CameraPosition.Builder()
                .target(LatLng(45.5076, -122.6736))
                .zoom(11.0)
                .build()

            // Load the style and load geoJson after the style has been loaded
            map.setStyle(styleUrl) {
                GeoJsonLoader(this, it).execute()
            }
        }
    }

In this method we initiate GeoJSON parsing on background thread

Load GeoJSON and create Feature Collection

The code for loading stream with GeoJSON data and parsing it into FeatureCollection is in GeoJsonLoader class. This class inherits from AsyncTask and it loads and parses GeoJSON in doInBackground method.

override fun doInBackground(vararg params: Void): FeatureCollection? {
        val fragment: GeoJsonOverlayFragment? = weakReference.get()
        if (fragment != null) {
            val context = fragment.activity?.applicationContext
            if (context != null) {
                val inputStream: InputStream = context.assets.open("example.geojson")
                return FeatureCollection.fromJson(convertStreamToString(inputStream))
            }
        }

        return null
    }

When the FeatureCollection is created, the class initiates drawing from onPostExecute method.

override fun onPostExecute(featureCollection: FeatureCollection?) {
        super.onPostExecute(featureCollection)
        val fragment: GeoJsonOverlayFragment? = weakReference.get()
        if (fragment != null && featureCollection != null) {
            drawLines(featureCollection)
        }
    }

Draw lines on the map

Finally, we retrieve the map style and add the new source using the feature collection created in previous step. Then we add line layer and configure its style.

private fun drawLines(featureCollection: FeatureCollection) {
        if (featureCollection.features() != null) {
            if (featureCollection.features()!!.size > 0) {
                style.addSource(GeoJsonSource("line-source", featureCollection))

                // The layer properties for our line. This is where we make the line dotted, set the
                // color, etc.
                style.addLayer(
                    LineLayer("linelayer", "line-source")
                        .withProperties(
                            PropertyFactory.lineCap(Property.LINE_CAP_SQUARE),
                            PropertyFactory.lineJoin(Property.LINE_JOIN_MITER),
                            PropertyFactory.lineOpacity(.7f),
                            PropertyFactory.lineWidth(7f),
                            PropertyFactory.lineColor(Color.parseColor("#3bb2d0"))
                        )
                )
            }
        }
    }