Here Maps Api:指针输入上带有气泡图标的可拖动多段线

Here Maps Api: Draggable polyline with bubble icon on pointenter

我在使用指针输入器上的气泡图标实现折线时遇到问题。尝试在多段线上放置标记,但这似乎不起作用,所有多段线都覆盖着我并不真正需要的标记。思路是这样的-

https://wego.here.com/directions/mix/Popasnianskyi-raion,-Ukraine:48.80203,38.30358/Komarova-vulytsia,-54,-Sakhnovshchynskyi-raion,-64501,-Ukraine:via49.16267,35.86741/Solonianskyi-raion,-Ukraine:48.03645,34.26061?map=48.39529,36.2739,7,normal

在 Google 地图中它被称为 Draggable directions,但我找不到任何关于它的文档 Here maps.

开箱即用的 HERE JS API 中不存在“可拖动方向”。您需要自己实施。请参阅 https://tcs.ext.here.com/examples/v3.1/fleet 上的示例,直接在浏览器中打开 'Vew page source'。请在此处搜索已定义的事件:pointermove、pointerenter、dragstart、drag、dragend。请使用标记的属性 'volatile'将其设置为true以提高标记的移动性能。


上面示例中的部分代码:

/*
    author domschuette
    (C) HERE 2015
    */
    


    
    function createDragRoutes(alternatives){
        for(var i=0;i<alternatives;i++){
        dragRoute[i]=new Object();  
        dragRoute[i].routeHoverMarker = new H.map.Marker({lat: 50.126237073013314, lng: 8.627775069326162}, {
            icon: icon,
            visibility: false,
            zIndex: 1,
            volatility: true
        });
        dragRoute[i].routeHoverMarker.draggable = true;

        map.addObject(dragRoute[i].routeHoverMarker);

        dragRoute[i].pointermoveOnRouteHoverMarker = function(evt) {
        //  console.log(currentPolyline.routeNo);
            currentPolyline.dispatchEvent(evt);
            currentPolyline.setZIndex(zindex++);
        };

        dragRoute[i].dragstartOnRouteHoverMarker = function (evt) {
            //console.log(this);
            //console.log("routeHoverMarker dragstart:: ", evt, evt.target, currentPolyline);
            currentPolyline.dispatchEvent(evt);
        };

        dragRoute[i].dragOnRouteHoverMarker = function(evt) {
            
            //console.log(evt.target);
            
            var coord = map.screenToGeo((evt.pointers[0].viewportX), (evt.pointers[0].viewportY + 8));
            evt.target.setGeometry(coord);

            currentPolyline.dispatchEvent(evt);
        };

        dragRoute[i].dragendOnRouteHoverMarker = function (evt) {
            
            currentPolyline.dispatchEvent(evt);
        };

        dragRoute[i].routeHoverMarker.addEventListener("pointermove", dragRoute[i].pointermoveOnRouteHoverMarker, false);
        dragRoute[i].routeHoverMarker.addEventListener("dragstart", dragRoute[i].dragstartOnRouteHoverMarker, true);
        dragRoute[i].routeHoverMarker.addEventListener("drag", dragRoute[i].dragOnRouteHoverMarker, false);
        dragRoute[i].routeHoverMarker.addEventListener("dragend", dragRoute[i].dragendOnRouteHoverMarker, false);
        
        
        dragRoute[i].calculateRouteParams = {
                    
                    
        };
    
        }

}

    /*TODO*/
    var createIcon = function (line1, line2) {
        var div = document.createElement("div");

        var div = document.createElement("div");
        var svgMarker = "";

        if(line1 != "" && line2 != "")
        {
            svgMarker = svgMarkerImage_Line;
            svgMarker = svgMarker.replace(/__line1__/g, line1);
            svgMarker = svgMarker.replace(/__line2__/g, line2);
            svgMarker = svgMarker.replace(/__width__/g, line1.length  * 4 + 57);
            svgMarker = svgMarker.replace(/__widthAll__/g, line1.length  * 4 + 120);
        }
        else
        {
            svgMarker = svgMarkerBase64Image.replace(/__widthAll__/g, "60");
        }
        div.innerHTML = svgMarker;

        return new H.map.Icon(svgMarker, {
            anchor: new H.math.Point(24, 57)
        });
    };
    
    var MultiplePolyline = function (route) 
    {
        var routeInfo = {};
        var lineString = new H.geo.LineString();

        var shape = route.shape,
        waypoints = route.waypoint,
        i,
        l = shape.length,
        distance,
        hour,
        minute,
        second,
        timeleft = route.summary.baseTime;

        hour = Math.floor( timeleft / 3600 );
        minute = Math.floor( (timeleft % 3600) / 60 );
        second = Math.floor( timeleft % 60 );

        document.getElementById("time").innerHTML = "Time: " + hour + ":" + minute + ":" + second;

        if(metricSystem)
        document.getElementById("distance").innerHTML = "Distance: " + route.summary.distance / 1000 + " km";
        else
        document.getElementById("distance").innerHTML = "Distance: " + route.summary.distance *0.000621371192; + " miles";

        for(i = 0; i < l; i++)
        {
            var parts = shape[i].split(',');
            lineString.pushLatLngAlt(parts[0], parts[1]);
            for(var iW = 0,lW = waypoints.length; iW < lW; iW++){
                var wPos = waypoints[iW].mappedPosition;
                if(wPos.latitude == parts[0] && wPos.longitude == parts[1]) waypoints[iW].idxInStrip = i;
            }
        }

        var waypointMarkers = [];
        for(var iW = 0,lW = waypoints.length; iW < lW; iW++){
            var wPos = new H.geo.Point(waypoints[iW].mappedPosition.latitude, waypoints[iW].mappedPosition.longitude);
            if (!window.calcRouteTimeOutId){
                waypointMarkers.push( createWaypointMarker(wPos, wPos.lat.toFixed(5) + ", " + wPos.lng.toFixed(5), ""+(iW+1)) );
            }

        }
        routeInfo.waypointMarkers = waypointMarkers;

        //var color=  "rgba("+(Math.floor((Math.random() * 255) + 1)) + ","+ (Math.floor((Math.random() * 255) + 1)) +","+ (Math.floor((Math.random() * 255) + 1)) +","+ 1 + ")";
        var color=  "rgba(8,37,226,1)";
        dragRoute[currentRoute].polyline = new H.map.Polyline(lineString,
        {
            zIndex: 99,
            style:
            {
                lineWidth: 5,
                strokeColor: color, 
            }
        });

        dragRoute[currentRoute].polyline.routeNo=currentRoute;

        routeInfo.polyline = dragRoute[currentRoute].polyline;
        dragRoute[currentRoute].polyline.setData(routeInfo);

        for(var iW = 0,lW = waypointMarkers.length; iW < lW; iW++){
            var info = {
                idxW: iW,
                polyline: dragRoute[currentRoute].polyline,
                waypointMarkers: waypointMarkers
            };
            waypointMarkers[iW].setData(info);
        }

        dragRoute[currentRoute].polyline.draggable = true;

        dragRoute[currentRoute].polyline.setArrows({color:"#F00F",width:2,length:3,frequency: 4});

        dragRoute[currentRoute].pointerenterOnPolyline = function (evt) {
            currentPolyline = evt.target;
            currentRoute=currentPolyline.routeNo;
            var coord = map.screenToGeo((evt.pointers[0].viewportX), (evt.pointers[0].viewportY + 8));
            dragRoute[currentPolyline.routeNo].routeHoverMarker.setGeometry(coord);
            dragRoute[currentPolyline.routeNo].routeHoverMarker.setVisibility(true);
        };

        dragRoute[currentRoute].dragstartOnPolyline = function (evt) {
            
        //  console.log("dragRoute[currentRoute].dragstartOnPolyline:: ", evt);
            currentPolyline = evt.currentTarget;
            currentRoute=currentPolyline.routeNo;
            
        //  console.log(" currentRoute value : " + currentRoute);
            mapBehavior.disable();

            var viewportX = evt.pointers[0].viewportX,
            viewportY = evt.pointers[0].viewportY,
            pStrip = currentPolyline.getGeometry(),
            clipedPolyline = clipPolyline(currentPolyline, viewportX, viewportY, 8),
            foundIdxPolylineForWaypoint = false,
            partPolyline = false,

            eachStripPointFn = function(lat, lng, alt, idx) {
                if(foundIdxPolylineForWaypoint) return;
                if(partPolyline[0] == lat && partPolyline[1] == lng) {
                    for(var iP=2,lP=partPolyline.length; iP<lP; iP+=2){
                        var stripPoint = pStrip.extractPoint(idx+iP/2);
                        if( stripPoint && stripPoint.lat==partPolyline[iP] && stripPoint.lng==partPolyline[iP+1]){
                            foundIdxPolylineForWaypoint = idx;
                        }
                        else{
                            foundIdxPolylineForWaypoint = false;
                        }
                    }
                }

            };
            if(clipedPolyline[0]) {
                partPolyline = clipedPolyline[0];
                pStrip.eachLatLngAlt(eachStripPointFn);
            };
            dragRoute[currentPolyline.routeNo].foundIdxPolylineForWaypoint = foundIdxPolylineForWaypoint;
        };

        dragRoute[currentRoute].dragendOnPolyline = function (evt)
        {
            mapBehavior.enable();
            currentPolyline = evt.currentTarget;
            currentRoute=currentPolyline.routeNo;

            var coord = map.screenToGeo((evt.pointers[0].viewportX), (evt.pointers[0].viewportY + 8));
            
            if(!dragRoute[currentPolyline.routeNo].foundIdxPolylineForWaypoint) 
                return;

            for(var iW = 0,allWaypoits = dragRoute[currentPolyline.routeNo].allWaypoitsForNewRoute,lW = allWaypoits.length; iW < lW; iW++){
                dragRoute[currentPolyline.routeNo].calculateRouteParams["waypoint"+iW] = 'geo!' + allWaypoits[iW].lat + "," + allWaypoits[iW].lng;
            }

            router.calculateRoute(dragRoute[currentPolyline.routeNo].calculateRouteParams, onResult, onError);

            var routeInfo = currentPolyline.getData();
            removeAllRouteObjects(routeInfo);
        };

        dragRoute[currentRoute].polyline.addEventListener("pointerenter", dragRoute[currentRoute].pointerenterOnPolyline, false);
        dragRoute[currentRoute].polyline.addEventListener("pointermove", function(evt)
        {
            currentPolyline = evt.currentTarget;
            currentRoute=currentPolyline.routeNo;
            var viewportX = evt.pointers[0].viewportX,
            viewportY = evt.pointers[0].viewportY,
            clipedPolyline = clipPolyline(currentPolyline, viewportX, viewportY, 8),
            coord = map.screenToGeo(viewportX, (viewportY + 8));

            if(clipedPolyline.length == 0) {
                dragRoute[currentPolyline.routeNo].routeHoverMarker.setVisibility(false);
                return;
            }

            dragRoute[currentPolyline.routeNo].routeHoverMarker.setGeometry(coord);
        }, false);

        dragRoute[currentRoute].polyline.addEventListener("dragstart", dragRoute[currentRoute].dragstartOnPolyline, false);
        dragRoute[currentRoute].polyline.addEventListener("drag", function(evt)
        {
            // console.log("drag polyline:: ", evt, waypoints);
            currentPolyline = evt.currentTarget;    
            currentRoute=currentPolyline.routeNo;               
            var coord = map.screenToGeo((evt.pointers[0].viewportX), (evt.pointers[0].viewportY + 8)),
                newWpIdx = false;

            if(!dragRoute[currentPolyline.routeNo].foundIdxPolylineForWaypoint) return;

            dragRoute[currentPolyline.routeNo].allWaypoitsForNewRoute = [];

            for(var iW = 0,lW = waypoints.length; iW < lW; iW++){
                var wPos = waypoints[iW].mappedPosition;
                dragRoute[currentPolyline.routeNo].allWaypoitsForNewRoute.push(new H.geo.Point(wPos.latitude, wPos.longitude));
                if(dragRoute[currentPolyline.routeNo].foundIdxPolylineForWaypoint > waypoints[iW].idxInStrip && waypoints[iW+1] && dragRoute[currentPolyline.routeNo].foundIdxPolylineForWaypoint < waypoints[iW+1].idxInStrip){
                    dragRoute[currentPolyline.routeNo].allWaypoitsForNewRoute.push(coord);
                    newWpIdx = iW+1;
                }
            }
            calculateSampleRoute(dragRoute[currentPolyline.routeNo].allWaypoitsForNewRoute, newWpIdx);

        }, false);
        dragRoute[currentRoute].polyline.addEventListener("dragend", dragRoute[currentRoute].dragendOnPolyline, false);


        polylineLayer.addObject(dragRoute[currentRoute].polyline);

        if (window.tmpPolyline){
            try{
                polylineLayer.removeObject(window.tmpPolyline);
            }catch(e){}

            window.tmpPolyline = false;
        }
        if(window.calcRouteTimeOutId) window.tmpPolyline = dragRoute[currentRoute].polyline;


        var fence = new H.map.Polyline(lineString,
        {
            style:
            {
                lineColor: color,
                lineWidth: 80
            }
        });

        fenceLayer.addObject(fence);

        clearTimeout(window.calcRouteTimeOutId);
        window.calcRouteTimeOutId = false;
    }

    var calculateRoute = function(wPoints)
    {
        if(wPoints.length == 2 && (!wPoints[0] || !wPoints[1])) return;

        var e = document.getElementById("routeOption");
        var routeOption = e.options[e.selectedIndex].value;

        var mode = routeOption + ";";
        mode += document.getElementById('useCar').checked ? "car;" : "truck;"
        mode += 'traffic:';

        e = document.getElementById('traffic');
        var tr = e.options[e.selectedIndex].value;

        mode += tr + ";";
        mode += 'tollroad:' + document.getElementById("tollroads").value + ',';
        mode += 'motorway:' + document.getElementById("motorways").value + ',';
        mode += 'boatFerry:' + document.getElementById("boatFerries").value + ',';
        mode += 'railFerry:' + document.getElementById("railFerries").value + ',';
        mode += 'tunnel:' + document.getElementById("tunnels").value + ',';
        mode += 'dirtRoad:' + document.getElementById("dirtRoads").value;

        trailersCount = document.getElementById('trailersCount').value;

        var tunnelCategory = "";
        
        var hazard = new Array();

        if(document.getElementById('combustible').checked)
        {
            hazard.push("combustible");
            tunnelCategory = "D";
        }
        if(document.getElementById('organic').checked)
        {
            hazard.push("organic");
            tunnelCategory = "D"; 
        }
        if(document.getElementById('poison').checked)
        {
            hazard.push("poison");
            tunnelCategory = "D";
        }
        if(document.getElementById('radioActive').checked)
        {
            hazard.push("radioActive");
            tunnelCategory = "D";
        }
        if(document.getElementById('corrosive').checked)
        {
            hazard.push("corrosive");
            tunnelCategory = "D";
        }
        if(document.getElementById('poisonousInhalation').checked)
        {
            hazard.push("poisonousInhalation");
            tunnelCategory = "D";
        }
        if(document.getElementById('harmfulToWater').checked)
        {
            hazard.push("harmfulToWater");
            tunnelCategory = "D"; 
        }
        if(document.getElementById('other').checked)
        {
            hazard.push("other");
            tunnelCategory = "D";
        }
        
        if(document.getElementById('gas').checked)
        {
            hazard.push("gas");
            if(tunnelCategory != "D")
                tunnelCategory = "E";
        }
        if(document.getElementById('flammable').checked)
        {
            hazard.push("flammable");
            tunnelCategory = "C";
        }
        if(document.getElementById('explosive').checked)
        {
            hazard.push("explosive");
            tunnelCategory = "B";
        }
        
        hazard = hazard.join(",");

        var lWeight = parseFloat(document.getElementById("limitedWeight").value);
        var aWeight = parseFloat(document.getElementById("weightPerAxel").value);
        var h = parseFloat(document.getElementById("height").value);
        var w = parseFloat(document.getElementById("width").value);
        var l = parseFloat(document.getElementById("length").value);

        alternatives = parseFloat(document.getElementById("alt").value);
        if(oldAlternative != alternatives){
            createDragRoutes(alternatives);
            oldAlternative=alternatives;
        }

        if(isNaN(lWeight)) lWeight = 0;
        if(isNaN(aWeight)) aWeight = 0;
        if(isNaN(h)) h = 0;
        if(isNaN(w)) w = 0;
        if(isNaN(l)) l = 0;

        
        var e = document.getElementById("metric");
        var isMetric = e.options[e.selectedIndex].value;
        
        if (isMetric == 1) {
            metricSystem = true;
        }
        else{
            metricSystem = false;
        }
        
        if(!metricSystem)
        {
            h /= 3.2808;
            w /= 3.2808;
            l /= 3.2808;
        }

        if(wPoints.length>2){
            alternatives =1;
        }
        
        dragRoute[currentRoute].calculateRouteParams = {
                'app_code': app_code,
                'app_id': app_id,
                'mode': mode,
                'language': lang,
                'representation' : 'overview',
                'metricSystem' : metricSystem ? "metric" : "imperial",
                'routeattributes' : 'wp,sc,sm,sh,bb,lg,no,shape',
                'legattributes' : 'wp,mn,li,le,tt',
                'maneuverattributes' : 'po,sh,tt,le,ti,li,pt,pl,rn,nr,di',
                'linkattributes' : 'sh,le,sl,ds,tr',
                'instructionformat' : 'html',
                'shippedhazardousgoods' : hazard,
                'tunnelCategory' : tunnelCategory,
                'trailersCount' : trailersCount,
                'alternatives' : alternatives-1             
            };
        
        
        for(var iW=0,lW=wPoints.length; iW < lW; iW++){
            dragRoute[currentRoute].calculateRouteParams['waypoint'+iW] = 'geo!' + wPoints[iW].lat + "," + wPoints[iW].lng;
        }

        var calculateRouteParams = dragRoute[currentRoute].calculateRouteParams;
        

        if(lWeight > 0)
        calculateRouteParams.limitedWeight = lWeight;
        if(aWeight > 0)
        calculateRouteParams.weightPerAxle = aWeight;
        if(h > 0)
        calculateRouteParams.height = h;
        if(w > 0)
        calculateRouteParams.width = w;
        if(l > 0)
        calculateRouteParams.length = l;

        router.calculateRoute(calculateRouteParams, onResult, onError);
    };
    
    var onResult = function(result) {
        if(!result.response || !result.response.route || !result.response.route[0]) 
            return;
        
        if(releaseShown != true){
            releaseInfoTxt.innerHTML+="<br />HLP Routing: "+result.response.metaInfo.moduleVersion;
            releaseShown = true;
        }
            
        for(var i=0; i<result.response.route.length; i++){
            currentRoute=i;
            MultiplePolyline(result.response.route[i]);
        }
            
        currentRoute=0;
        
    };
    
    var onError = function(error)
    {
        console.log(error);
    };

    var createWaypointMarker = function(geocoord, info1, info2) {
        info1 = info1 ? info1 : "";
        info2 = info2 ? info2 : "";

        var marker = new H.map.Marker({lat: geocoord.lat, lng: geocoord.lng}, {
            icon: createIcon(info1, info2),
            volatility: true
        });
        marker.draggable = true;
        marker.addEventListener("dragstart", 
            function(evt){
                mapBehavior.disable();
            }, false);

        marker.addEventListener("drag", function(evt){

            var curMarker = evt.currentTarget,
            coord = map.screenToGeo((evt.pointers[0].viewportX), (evt.pointers[0].viewportY));

            curMarker.setGeometry(coord);
            var routeInfo = curMarker.getData(),
                waypointMarkers = routeInfo.waypointMarkers,
                waipoints = [];

            for(var iW=0,lW=waypointMarkers.length; iW<lW; iW++){
                waipoints.push(waypointMarkers[iW].getGeometry());
            }
            calculateSampleRoute(waipoints, routeInfo.idxW);
        }, false);

        marker.addEventListener("dragend", function(evt){
            mapBehavior.enable();

            var curMarker = evt.currentTarget;
            var coord = map.screenToGeo((evt.pointers[0].viewportX ), (evt.pointers[0].viewportY ));

            curMarker.setGeometry(coord);

            var routeInfo = curMarker.getData();
            var waypointMarkers = routeInfo.waypointMarkers;
            var wPoints = [];

            for(var iW=0,lW=waypointMarkers.length; iW<lW; iW++){
                var wPos = waypointMarkers[iW].getGeometry();
                wPoints.push(waypointMarkers[iW].getGeometry());
            }
            calculateRoute(wPoints);
            removeAllRouteObjects(routeInfo);

        }, false);

        // Add marker to the markerLayer, to make it visible on the map
        markerLayer.addObject(marker);

        map.getViewModel().setLookAtData({
            bounds: markerLayer.getBoundingBox()
        });

        return marker;
    };

    var removeAndStartRouting = function()
    {
        if (document.getElementById('showMultipleRoutes').checked) {
            clrcnt++;
            if(clrcnt >= 5)
            {
                markerLayer.removeObject(markerLayer.getObjects()[0]);
                markerLayer.removeObject(markerLayer.getObjects()[0]);
                polylineLayer.removeObject(polylineLayer.getObjects()[0]);
                fenceLayer.removeObject(fenceLayer.getObjects()[0]);
                clrcnt = 0;
            }
        } else {
            markerLayer.removeAll();
            polylineLayer.removeAll();
            fenceLayer.removeAll();

            clrcnt = 0;
        }

        var from = document.getElementById('input-from').value,
        to = document.getElementById('input-to').value,
        gFrom, gTo;

        if(from && to) {
            gFrom = null;
            gTo = null;

            geocoder.search({searchText: from}, function(result) {

                //add Geocoder Release information if not already done
                if (releaseGeocoderShown== false){
                    loadGeocoderVersionTxt();
                    releaseGeocoderShown = true;
                }
                if(result.Response.View[0].Result[0].Location != null)
                {
                    gFrom = result.Response.View[0].Result[0].Location.DisplayPosition;
                }
                else
                {
                    gFrom = result.Response.View[0].Result[0].Place.Locations[0].DisplayPosition;
                }
                gFrom.lat = gFrom.Latitude;
                gFrom.lng = gFrom.Longitude;

                //createWaypointMarker(gFrom);
                calculateRoute([gFrom, gTo]);
            }, function(){});

            geocoder.search({searchText: to}, function(result) {
                //add Geocoder Release information if not already done
                if (releaseGeocoderShown== false){
                    loadGeocoderVersionTxt();
                    releaseGeocoderShown = true;
                }
                if(result.Response.View[0].Result[0].Location != null)
                {
                    gTo = result.Response.View[0].Result[0].Location.DisplayPosition;
                }
                else
                {
                    gTo = result.Response.View[0].Result[0].Place.Locations[0].DisplayPosition;
                }
                gTo.lat = gTo.Latitude;
                gTo.lng = gTo.Longitude;

                //createWaypointMarker(gTo);
                calculateRoute([gFrom, gTo]);
            }, function(){});
        }
    };

    var removeAllRouteObjects = function(routeInfo){
        try{
            polylineLayer.removeObject(routeInfo.polyline);
        }catch(e){}


        for(var iW = 0,lW = routeInfo.waypointMarkers.length; iW<lW; iW++){
            try{
                markerLayer.removeObject(routeInfo.waypointMarkers[iW]);
            }catch(e){}
        }
    };

    var clipPolyline = function(polyline, viewportX, viewportY, bboxSize){
        var pleft = viewportX - bboxSize,
        pright = viewportX + bboxSize,
        ptop = viewportY - bboxSize,
        pbottom = viewportY + bboxSize,
        coordLeftTop = map.screenToGeo(pleft, ptop),
        coordRigthBottom = map.screenToGeo(pright, pbottom),
        rect = new H.geo.Rect(coordLeftTop.lat,coordLeftTop.lng,coordRigthBottom.lat,coordRigthBottom.lng),
        clipedPolyline = polyline.clip(rect);

        return clipedPolyline;
    };

    var calculateSampleRoute = function(waipoints, idxW){
        var prevW = idxW-1,
        nextW = idxW+1;

        window.tempwPoints = [];
        if(prevW >= 0) window.tempwPoints.push(waipoints[prevW]);
        window.tempwPoints.push(waipoints[idxW]); //current
        if(nextW < waipoints.length) window.tempwPoints.push(waipoints[nextW]);

        if(!window.calcRouteTimeOutId){
            window.calcRouteTimeOutId = setTimeout(
            function(){
                calculateRoute(window.tempwPoints);
            },
            200
            );
        }

        //console.log("waypoint drag :: ", evt  );

    };

    var truckOverlayProvider = new H.map.provider.ImageTileProvider({
        label: "Tile Info Overlay",
        descr: "",
        min: 8,
        max: 20,
        getURL: function( col, row, level )
        {
            server_rr++;
            if(server_rr > 4)
            server_rr = 1;
            return ["https://",
            server_rr,
            ".base.maps.api.here.com/maptile/2.1/truckonlytile/newest/normal.day/",
            level,
            "/",
            col,
            "/",
            row,
            "/256/png8",
            "?style=fleet",
            "&app_code=",
            app_code,
            "&app_id=",
            app_id
            ].join("");
        }
    });

    var truckOverlayLayer = new H.map.layer.TileLayer(truckOverlayProvider);

    var handleTransport = function(cb)
    {
        if(cb.checked)
        map.addLayer(truckOverlayLayer);
        else
        map.removeLayer(truckOverlayLayer);
    };

    var TrafficOverlay = new H.map.provider.ImageTileProvider({
        label: "TrafficOverlay",
        descr: "Here TrafficOverlay",
        min: 8,
        max: 20,
        getURL: function( col, row, level) {
            server_rr++;
            if(server_rr > 4)
            server_rr = 1;
            return ["https://",
            server_rr,
            ".traffic.maps.api.here.com/maptile/2.1/flowtile/newest/normal.day/",
            level,
            "/",
            col,
            "/",
            row,
            "/256/png8",
            "?app_code=",
            app_code,
            "&app_id=",
            app_id
            ].join("");
        }
    });

    var trafficOverlayLayer = new H.map.layer.TileLayer(TrafficOverlay);

    var handleTraffic = function(cb)
    {
        if(cb.checked)
        map.addLayer( trafficOverlayLayer );
        else
        map.removeLayer( trafficOverlayLayer );
    };

    var handleFence = function(cb)
    {
        //console.log(fenceLayer.getObjects()[0].isClosed());
        
        if(cb.checked)
        map.addObject( fenceLayer );
        else
        map.removeObject( fenceLayer );
    };

    var switchRegion = function(reg)
    {
        cfg = region[reg];
        map.setCenter(new H.geo.Point(cfg.center.lat, cfg.center.lng));
        document.getElementById("input-from").value = cfg.start;
        document.getElementById("input-to").value = cfg.dest;
        metricSystem = cfg.metric;
        language = cfg.lang;
        start = cfg.startCoordinate;
        destination = cfg.destCoordinate;
        markerLayer.removeAll();
        removeAndStartRouting();
    };

    switchRegion("EU");