Fork us on GitHub

Geo-Viz and Codename One

Using Codename One's new graphics pipeline it is now possible...
Post Image

Geo-Viz and Codename One

I attended a tutorial at OSCON last year on HTML5 graphics where I was introduced to some cool data-visualization technologies. One thing that left an impression was the in GeoJSON format, which we used to generate some maps inside the browser using the D3 library and SVG. This was around the time that I was working on the new Codename One graphics pipeline, so at each step of the tutorial my inner commentator was whispering "we could do this in Codename One without too much difficulty".

Fast forward 6 months, and the new graphics pipeline is complete, so I thought, why not try implementing some of those cool GeoViz features in Codename One. We have all the pieces in place? So I present the Codename One GeoViz library.

What does the GeoViz Library do?

The GeoViz library allows you to load geographic data in GeoJSON format, and render it visually in your app. Below is a map of the USA that was rendered using this library.

GeoViz Demo Screenshot

What is GeoJSON?

GeoJSON is a standard format for storing geographic data in JSON format. A GeoJSON file may store a number of "features" which may include shape coordinates as well as information associated with the feature. For example, in the USA Map example, each state is a "feature" that includes shape coordinates for its contour, as well as property information such as the state name.

One of the nice things about GeoJSON is that it is already widely used and there are lots of existing free data sources (e.g. this GitHub Repo) where you can obtain state, country, city, etc…​ outlines that can now be easily included in your applications.

GeoVizComponent vs MapComponent vs Native Maps

Codename One already had two mechanisms for displaying maps: the MapComponent and the Native Maps library. Their purpose is different than the GeoVizComponent. Some key differences include:

  1. The MapComponent uses a "tile"-based approach where it downloads tile images from a map server (e.g. Open Streetmaps or Google Maps). The GeoVizComponent renders geographic "shapes" that are stored as vectors so they can be rendered at any size, and transformed in any way you like without pixelization.

  2. The MapComponent displays only maps as they are provided by the specified Map server. The GeoVizComponent will render any geographic information that can be expressed in a GeoJSON file. This might include a map of a building only, or a sparse map that only includes some key landmarks, or anything else you like.

Key Features

  • Pan and zoom. The component optionally supports pinch zoom and panning by dragging with your finger. You can also programmatically set the center point and zoom level, and animate the transition to the new viewport settings.

  • Custom painter support. You can implement your own painters to customize how features of the map are rendered. E.g. you can change the background color or different regions based on the data in associated data sets.

  • FeaturePressed/Released Events. You can detect touches to features of the map and respond to them accordingly.

Basic Usage

Step One: Load the GeoJSON file

GeoJSONLoader loader = new GeoJSONLoader();
FeatureCollection coll = loader.loadJSON(
        Display.getInstance().getResourceAsStream(null, "/us-states.json"),

This example loads the us-states JSON file from the app resources using the GeoJSONLoader class.

Step Two: Create the GeoVizComponent

GeoVizComponent comp = new GeoVizComponent(coll);

Implementing a Custom Painter

The default painter will just render the map with black outlines and white fills. If you want to customize this you can install your own custom FeaturePainter. The following is an example custom painter taken from the GeoViz demo:

// Add a custom feature painter so that we can paint states different
// colors depending on the data in our CSV file.
comp.setFeaturePainter(new FeaturePainter(){

     * Callback to fill a feature (State).  We implement this
     * so that we can fill selected states with red and other states
     * a color based on the currently selected year.
     * @param g The graphics context
     * @param feature The feature to paint
     * @param path The shape that is to be filled.
    protected void fill(Graphics g, Feature feature, GeneralPath path) {

        int oldColor = this.getFillColor();
        int oldAlpha = this.getFillAlpha();
        if (feature == selectedFeature){
        } else {
            RegionData[] regionData = popData.getRegionData(
            if (currentYear > 0){
                if (mode==MODE_POPULATION){
                    for (RegionData d : regionData){
                        if (d.year == currentYear){
                            if (d.pop != 0){
                                getColor(1.0, 0, 0, d.pop, minPopulation, maxPopulation));
                                this.setFillAlpha(getAlpha(d.pop, minPopulation, maxPopulation));
                } else if (mode==MODE_DENSITY){
                    for (RegionData d : regionData){
                        if (d.year == currentYear){
                            if (d.density != 0){
                                this.setFillColor(getColor(0, 1.0, 0, d.density, minDensity, maxDensity));
                                this.setFillAlpha(getAlpha(d.density, minDensity, maxDensity));
        super.fill(g, feature, path);


For the full example, check out the GeoViz Demo.

You can also check out the Javadocs for the the library here.

Share this Post:

Posted by Steve Hannah

Steve writes software for Codename One. He is an open source enthusiast who loves to tinker with new technologies.