TapHandler

Live example

This tutorial will show you how you can handle taps on the map. The SDK will handle those clicks for you and return the corresponding geographic feature (geometry) at the tapped point via a callback. In addition, you can use the queryPoint if the SDK can not find a geographic feature at the tap point.

Step 1: Register a tap handler

  1. After creating a web map, as outlined in "A Map Application", you can register a tap handler in the map init success callback:

    ...
    map.setMapViewControllerDidStart(function() {
            map.addTapHandler(tapHandler);
    });
    ...
    
  2. This tap handler must to be previously defined, as shown here:

    var tapHandler = function (queryPointFromClick, zoom, geometries) {
        console.log(JSON.stringify(geometries), zoom, queryPointFromClick);
    }
    

That's it! You are now able to click on the map, look in the Console, and see the backend logs.

To have a little bit more fun, read further!

Step 2: Give this tap handler more power

  1. In order to do more with a given geometry, we can enhance the tap handler:

    var tapHandler = function (queryPoint, zoom, features) {
        console.log(JSON.stringify(features));
        cleanup();
        var currentFeature = getCurrentFeature(features, zoom);
        if (currentFeature) {
            if (overviewOrDetailZoomLevel(zoom)) {
                if (featureIsArea(currentFeature)) {
                    appendDemoMessage("Übersichtskarte und Klick in Halle - zoom to area");
                    map.zoomTo(currentFeature);
                }
            } else {
                appendDemoMessage("tap in einen stand");
                showFeatureDialog(currentFeature);
                appendDemoMessage("highlight feature");
                map.select(currentFeature);
            }
        } else {
            appendDemoMessage("ERROR: no detail feature");
        }
    };
    
  2. We now use some helper methods:
    1. Clean up all former activity.
    2. Get the "current" feature.
    3. Check if we are in an "Overview" zoom level. If yes, check if the feature is an area. If yes, zoom to it.
    4. If we are on a "Detail" zoom level, append a message with the feature properties to the log and highlight the feature
    5. If nothing was found, append an error message to the log
  3. In order to clean up all activity from previous taps, use the following method:

    function cleanup() {
            map.clearSelections();
    }
    
  4. Here are the methods used to get the "current" feature:

    function getCurrentFeature(features, zoomLevel) {
        if (overviewOrDetailZoomLevel(zoomLevel)) {
            return findHall(features);
        } else {
            return findBooth(features);
        }
    }
    
    function overviewOrDetailZoomLevel(zoomLevel) {
        return zoomLevel < map.firstDetailZoomLevel;
    }
    
    function findHall(features) {
        return findFeature(features, featureIsArea);
    }
    
    function findBooth(features) {
        return findFeature(features, featureIsBooth);
    }
    
    function findFeature(features, featureIsMethod) {
        for (var index = 0; index < features.length; index++) {
            if (featureIsMethod(features[index])) {
                return features[index];
            }
        }
        return undefined;
    }
    
    function featureIsArea(feature) {
        return feature.properties.entity_type === 'AREA';
    }
    
    function featureIsBooth(feature) {
        return feature.properties.entity_type === 'BOOTH';
    }
    
  5. The following methods show a feature dialog and extend the log:

    function showFeatureDialog(feature) {
        console.log("feature", feature);
        var popupFeature = {
            "name": feature.properties.name,
            "level": feature.properties.level,
            "entity_type": feature.properties.entity_type
        };
    
            document.getElementById("info").innerHTML = popupFeature.name + " - " + popupFeature.level + " - " + popupFeature.entity_type;
    }
    
    function appendDemoMessage(message) {
        var ulElement = document.getElementById("log").childNodes[1];
            var liElement = document.createElement("li");
            liElement.innerHTML = message;
            ulElement.insertBefore(liElement, ulElement.childNodes[0]);
    }
    
  6. Let us add some HTML and style to this example!

    <style type="text/css">
        body {
            width:600px;
        }
        #deepMap {
            width:598px;
            height:400px;
            border: 1px solid green;
        }
        #info {
            padding: 0 0 0 10px;
            height: 30px;
            line-height: 30px;
            border: 1px solid red;
        }
        #log {
            border: 1px solid blue;
            height: 100px;
            overflow-x: scroll;
        }
    </style>
     
    <body>
        <div id="map"></div>
        <div id="info">Stand-Info</div>
        <div id="log">
            <ul></ul>
        </div>
    </body>
    

That's all!

You have created a fully featured tap handler. If a user clicks on a building on your map, the map will zoom to this building. If the map is already zoomed to a zoom level lower than 2, a click on a room or booth will highlight this room/booth (see step 4 for details).