Displaying Buildings

Our next step is to draw the outline of the building that we can see on the map. The Google Maps API provides a set of functions for drawing images and outlines on the map, but we need to keep track of the data we are drawing so we can remove it when it changes. Each building has a unique identifier (UUID) that we can use to check if we’ve previously drawn it. We need to keep track of the NeonBuilding object, the floor we have selected, and the current set of outlines we’ve drawn on the map, so we’ll make a class to store this data by building ID:

private ConcurrentHashMap<UUID, BuildingOverlays> buildingHashMap = new ConcurrentHashMap<>();

/**
    * An object that keeps track of what is drawn to the map for each building
    */
    private class BuildingOverlays {
    public NeonBuilding building;   //current building being displayed
    public int floor;               //current floor being displayed
    ArrayList<Polygon> outlines;    //outlines drawn to the map

    public BuildingOverlays(NeonBuilding b, int floor, ArrayList<Polygon> outlines) {
        this.building = b;
        this.floor = floor;
        this.outlines = new ArrayList<>(outlines);
    }
}

On the successful download of buildings, we should iterate through them and check if our buildingHashMap contains the building ID. If it does, we can ignore it. If it doesn’t, then we should draw the building outline to the screen:

@Override
public void onComplete(List<NeonBuilding> list, DownloadResult downloadResult) {
    if(downloadResult == DownloadResult.SUCCESS)
    {
        for (final NeonBuilding building : list) {
            //check if the building has already been drawn to the screen
            if (buildingHashMap.containsKey(building.getID()))
                continue;

            //since we are drawing for the first time, get the ground floor for display
            final NeonBuildingFloor buildingFloor = building.getFloor(0);

            //draw the outline of this floor to the screen
            //since this is in a background thread, we draw on the UI thread
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    drawOutline(building, buildingFloor);
                }
            });
        }
    }
    else
        Log.i("NEONSampleApp","result failed with: "+list.toString());
}

/**
    * Draws a NeonFloorOutline to the map.  Converts to
    * a set of Google Polygons
    */
private void drawOutline(NeonBuilding building, NeonBuildingFloor floor) {
    Log.i("NEONSampleApp", "Drawing outline for building: " + building.getID() + ", floor: " + floor.getLabel());

    ArrayList<Polygon> outlines = new ArrayList<>();
    for (LatLongOutline outline : floor.getOutline().Outlines) {
        //construct the outer hull
        ArrayList<LatLng> ol = new ArrayList<>();
        for (LatLong ll : outline.Hull)
            ol.add(new LatLng(ll.Latitude, ll.Longitude));

        //construct the inner holes
        ArrayList<ArrayList<LatLng>> polygonHoles = new ArrayList<>();
        for (ArrayList<LatLong> llo : outline.Holes) {
            ArrayList<LatLng> hol = new ArrayList<>();
            for (LatLong ll : llo)
                hol.add(new LatLng(ll.Latitude, ll.Longitude));
            polygonHoles.add(hol);
        }

        //add to map
        Polygon p = mMap.addPolygon(new PolygonOptions().addAll(ol).clickable(true));

        //set holes in the polygon
        p.setHoles(polygonHoles);

        //tag it with the building ID
        p.setTag(building.getID());

        //add to list
        outlines.add(p);
    }

    //put the BuildingOverlay object in the hashmap
    buildingHashMap.put(building.getID(), new BuildingOverlays(building, floor.getFloorNumber(), outlines));
}

On shutdown, the buildingHashMap should be cleared:

private void shutdown()
{
    disconnectFromNeonAPI();

    if (dataLooper != null) {
        dataLooper.quit();
        dataLooper = null;
    }

    mainHandler.removeCallbacks(loadBuildingsRunnable);

    buildingHashMap.clear();
}

Building Outline