Find more Examples here

Advanced Nearby Search (Map-API)

Version reduced to minimal set of HTML Read Example Description

Description

Please click on the map to trigger a near by search.

This example uses the oax.api.nearby API to find tours within a certain distance around a location, fetches tour data by invoking oax.api.oois and renders a list of the found tours:

oax.api.maps( initOA );

function initOA( oamaps, gm ) {

    // search radius
    var radius = 5000;

    // map configuration object
    var config = {
        center : new gm.LatLng( 47.54687, 10.2928 ),
        zoom : 12,
        mapTypeId : 'oa_map',
        mapTypeControlOptions : { mapTypeIds: ['oa_map', 'oa_topo', 'oa_map_winter'] }
    };
    
    // initialize Outdooractive map
    map = oamaps.map( document.getElementById("map_canvas"), config );

    // initialize clusterLayer
    layer = new oamaps.ClusterLayer( { initDataPointList:[] } );

    // listen on marker click event to highlight tour
    layer.listen('markerClick', function( obj ) { highlight( obj.id ); } );

    // listen on info window click event to open detail page
    layer.listen('iwSelect', openDetailPage );

    // add clusterLayer to map
    layer.setMap( map );

    // add click event handler to start nearby search as soon as user clicks on map
    gm.event.addListener(map, 'click', mapClick);

    // keep references to center and marker object
    var searchCenter, centerMarker;

    // remember the last request, to prevent async race conditions
    var last_request;

    // search around map center on page load
    mapClick( { latLng: config.center } );

    // event handler called when user clicks on map
    // note: clicking on circle or marker doesn't raise map click
    function mapClick(event) {

        // remove the current result set from the map
        resetLayerAndList();

        // draw search center and circle
        drawMarkerAndCircle( event.latLng );

        // nearby search request object
        var request = {

            // request type
            searchNearby : {

                // the search center
                location: event.latLng,

                // the search radius
                radius: radius,

                // the result list will be sorted by distance
                sortby: "distance"
            }

        };

        // remember the last request, to prevent async race conditions
        last_request = request;

        // start nearby search
        // parameter: request object, callback function
        oa.api.requestIds( request, searchResult );
        
    }

    // callback for nearby search result
    function searchResult( answer ) {

        // was the search successfull and run without errors ?
        if (last_request === answer.request  && answer.success) {

            // add result to cluster layer with help of id list
            layer.setDataPointList( answer.data.ids );

            var request = { idlist: answer.data.ids, lightweightApp: 'tour' };

            // load result data to display list with tour titles
            // note: callback function needs ordered id list as data API call doesn't ensure initial order
            new oa.api.OOIs( request ).load( dataResult );

        }

    }

    function dataResult( dataObj, dataArr ) {

        // create root element of unorderd list used to list result (html)
        var ul = document.createElement('ul');

        var id, title, position;

        // loop through result set like sorted by nearby API
        for( var i=0; i<dataArr.length; i++) {

            id = dataArr[i].id;
            title = dataArr[i].title;

            ul.appendChild( createListItem( id, title ) );

        }

        // add result list to dom
        document.getElementById("map_panel").appendChild(ul);
    }

    function createListItem( id, title, distance ) {

        // create list entry element for each tour
        li = document.createElement('li');

        // create href link element, like:
        // <a id="t_1384978" href="javascript:highlight('1384978');">
        hr = document.createElement( 'a' );
        hr.setAttribute( "href", "#" + id );
        hr.setAttribute( "id", "t_" + id );
        hr.appendChild( document.createTextNode( title.substr(0,25) + '...' ) );
        hr.addEventListener( "click", function() { highlight(id); } )

        // append dom elements
        li.appendChild(hr);

        return li;
    }


    // remove result set of last search from the map
    function resetLayerAndList() {

        // var map_panel = document.getElementById("map_panel");
        
        // remove result list from last search
        if (map_panel.childNodes.length>0) {

            map_panel.removeChild( map_panel.firstChild );

        }

        // remove clusters from last search
        layer.setDataPointList([]);

        oamaps.iwCloseAll( map );
        
    }

    // visualize search center and radius on the map
    function drawMarkerAndCircle( center ) {

        // marker options
        var markerOpts = {
            map: map,
            icon: {
                anchor: { x:5, y:5 },
                url: '/icons/circle.png'
            }
        };

        // circle options
        var searchCircleOpts = {
            map: map,
            clickable: false,
            strokeColor: '#FF9900',
            strokeOpacity: 1.0,
            strokeWeight: 4,
            fillColor: '#FF0000',
            fillOpacity: 0.25,
            radius: radius
        };

        // initial search ?
        if (!centerMarker) {

            // initial search: create marker to visualize nearby search center
            markerOpts["position"] = center;

            // place a marker at the search center
            centerMarker = new gm.Marker( markerOpts );

            // add map and circle center to circle options
            searchCircleOpts["center"] = center;

            // instantiate circle
            searchCircle = new gm.Circle(searchCircleOpts);

        } else {

            // repeated search: move nearby search center to new position
            centerMarker.setPosition( center );

            // repeated search: move nearby search cirle to new position
            searchCircle.setCenter( center );

        }

    }

    var highlightedTour;

    function highlight( id ) {

        var listElement = document.getElementById( "t_" + id );
        var mapPanel    = document.getElementById( "map_panel" );

        // show tour geometry
        layer.showTour( id );

        // open tour info window
        layer.iwOpenOOI( id );

        listElement.className = "devoa_highlight";

        if (highlightedTour) {
            document.getElementById( "t_" + highlightedTour ).className = "";
        }

        highlightedTour = id;

        // calculate if tour is inside list viewport (scroll)
        var topScroll    = listElement.offsetTop - 5;
        var bottomScroll = listElement.offsetTop - mapPanel.clientHeight + listElement.offsetHeight;

        // tour outside viewport (top)
        if (mapPanel.scrollTop > topScroll) {

            // scroll list to highlighted tour
            mapPanel.scrollTop = topScroll;
            
        } else

            // tour outsice viewport (bottom)
            if (mapPanel.scrollTop < bottomScroll) {

                // scroll list to highlighted tour
                mapPanel.scrollTop = bottomScroll;
            }

    }

}

// open a detail page
function openDetailPage( obj ) {
    return window.location = "../../FlexView-API/FlexView.DetailPage.html?id=" + obj.id;
}