Map APIs for windows PHONE 8.1 in HTML, CSS, JS

2020-05-08 07:28发布

问题:

I am aware there is a similar question (Map APIs not working for windows phone in HTML), but I don't have enough reputation to comment so I am having to ask my own question.

I have successfully added bing maps to my windows 8.1 store app (HTML, JS, CSS), but when trying to add the reference in visual studio (the maps SDK) to windows phone 8.1 the option isnt available to me. I went through the answer to the question asked previously and in the examples there is a windows store app (fine!), a mobile web app and a C# example. So I tried the mobile web version but just adding this link

<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&mkt=en-gb"></script> 

obviously gives the error that you cant add a remote script as a local one (something along those lines)

So I tried just copying the code from the url above and saving locally but that gave me the error about script trying to inject dynamic content. Now I am at a bit of a loose end as to what to try next...any suggestions/links to helpful content will be greatly appreciated!

I should mention, I have seen a lot of documentation on adding the maps and that they are included within the windows phone 8.1 sdk so you dont need the bing maps sdk BUT these were mostly xaml, is there a way to access the sdk via js?

回答1:

Actually you can add the bing APi for Win8.1 to WP8.1, just hack the bing map APi dll and set the file to Visual Studio and add th bing reference like this

 <!-- Bing Maps references -->
<script type="text/javascript" src="/Bing.Maps.JavaScript/js/veapicore.js"></script>
<script type="text/javascript" src="/Bing.Maps.JavaScript/js/veapiModules.js"></script>

then work normally as you work with Win8.1, see my project. by the way add a code to verify connection status, cause this map work only if the connection exits (if you will add some pushpin manually it can work with no connection)

Fair Of Sfax WP



回答2:

Because the Bing Maps Extension in only available for Windows 8.1 Apps (hoping they will update it...) and because you can't include external JS lib references in your WinJS Page Controls, this is how you could get Bing Maps working on a WP8.1 HTML/JS app:

Insert a webview inside your Page Control html like:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>mapcontrol</title>

</head>
<body>
    <div class="mapcontrol fragment">
        <section id="mapcanvas" class="" aria-label="Main content" role="main">
            <x-ms-webview id="Map" style="width:100%; height:100%"></x-ms-webview>
        </section>
    </div>
</body>
</html>

Create one HTML page and one JS file and put all the code you need for creating the map:

HTML Page (copy of one WP8 source sample):

<!DOCTYPE html>
<html>
<head>
<title>Bing Map</title>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx? v=7.0&mkt=en-gb"></script>
<script type="text/javascript" src="/pages/bingmap/bingmap.js"></script>
</head>
<body>
<div id="mapContainer">
    <div id='myMap'></div>
    <div class="appBar">
        <div class="appBarContainer">
            <img id="searchBtn" src="images/search.png" alt="searchBtn" />
            <img id="gpsBtn" src="images/gps.png" alt="gpsBtn" />
            <img id="trafficBtn" src="images/traffic.png" alt="trafficBtn" />
            <img id="mapModeBtn" src="images/layers.png" alt="mapModeBtn" />
        </div>
    </div>
    <div id="navBar">
        <img id="upBtn" src="images/up.png" alt="upBtn" />
        <img id="leftBtn" src="images/left.png" alt="leftBtn" />
        <img id="rightBtn" src="images/right.png" alt="rightBtn" />
        <img id="downBtn" src="images/down.png" alt="downBtn" />
    </div>
    <div id="zoomRotateBar">
        <img id="zoomInBtn" src="images/zoomIn.png" alt="zoomInBtn" />
        <img id="zoomOutBtn" src="images/zoomOut.png" alt="zoomOutBtn" />
        <div id="rotationBtns">
            <img id="rotateCWBtn" src="images/cwRotation.png" alt="rotateCWBtn" />
            <img id="rotateCCWBtn" src="images/ccwRotation.png" alt="rotateCCWBtn" />
        </div>
    </div>
</div>

<div id="searchPanel" style="display:none;">
    <h2>Search</h2>
    <input type="text" id="searchTbx" />
</div>

<div id="mapModePanel" style="display:none;">
    <h2>Map Mode</h2>

    <ul>
        <li>
            <input type="radio" name="mapMode" id="autoMode" value="auto" checked="checked" />
            <label for="autoMode">Auto</label>
        </li>
        <li>
            <input type="radio" name="mapMode" id="aerialMode" value="aerial" />
            <label for="aerialMode">Aerial</label>
        </li>
        <li>
            <input type="radio" name="mapMode" id="birdseyeMode" value="birdseye" />
            <label for="birdseyeMode">Birdseye</label>
        </li>
        <li>
            <input type="radio" name="mapMode" id="osMode" value="os" />
            <label for="osMode">Ordnance Survey</label>
        </li>
        <li>
            <input type="radio" name="mapMode" id="roadMode" value="road" />
            <label for="roadMode">Road</label>
        </li>
    </ul>
</div>
</body>
</html>

JS code for this page (copy of the sample source):

(function () {
    var map,
    searchManager,
    geoLocationProvider,
    gpsLayer,
    gpsEnabled = false,
    trafficLayer,
    trafficEnabled = false;

// INIZIO INIT
function init() {

    getMap();

    //Test for multi-touch support
    if (navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) {
        //Hide zoom and rotate controls
        document.getElementById('zoomRotateBar').style.display = 'none';
    } else {
        //Only display rotation buttons when the map style is birdseye
        Microsoft.Maps.Events.addHandler(map, 'maptypechanged', updateNavBar);
        Microsoft.Maps.Events.addHandler(map, 'viewchangeend', updateNavBar);

        //Add zooming and rotating functionality
        addListener(document.getElementById('zoomInBtn'), 'click', function () {
            map.setView({ zoom: map.getZoom() + 1 });
        });

        addListener(document.getElementById('zoomOutBtn'), 'click', function () {
            map.setView({ zoom: map.getZoom() - 1 });
        });

        addListener(document.getElementById('rotateCWBtn'), 'click', function () {
            map.setView({ heading: map.getHeading() + 90 });
        });

        addListener(document.getElementById('rotateCCWBtn'), 'click', function () {
            map.setView({ heading: map.getHeading() - 90 });
        });
    }

    //Test for single-touch support
    if (navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 0) {
        //Hide navigation controls
        document.getElementById('navBar').style.display = 'none';
    } else {
        //Add panning functionality
        addListener(document.getElementById('upBtn'), 'click', function () {
            map.setView({ center: map.getCenter(), centerOffset: new Microsoft.Maps.Point(0, 100) });
        });

        addListener(document.getElementById('leftBtn'), 'click', function () {
            map.setView({ center: map.getCenter(), centerOffset: new Microsoft.Maps.Point(100, 0) });
        });

        addListener(document.getElementById('rightBtn'), 'click', function () {
            map.setView({ center: map.getCenter(), centerOffset: new Microsoft.Maps.Point(-100, 0) });
        });

        addListener(document.getElementById('downBtn'), 'click', function () {
            map.setView({ center: map.getCenter(), centerOffset: new Microsoft.Maps.Point(0, -100) });
        });
    }

    addListener(document.getElementById('searchBtn'), 'click', function () {
        document.getElementById('searchPanel').style.display = '';
        document.getElementById('searchTbx').focus();
    });

    addListener(document.getElementById('searchTbx'), 'keydown', function (e) {
        if (!e) {
            e = window.event;
        }

        //process search when enter key pressed
        if (e.keyCode == 13) {
            search(this.value);
        }
    });

    addListener(document.getElementById('gpsBtn'), 'click', toggleGPS);

    addListener(document.getElementById('trafficBtn'), 'click', toggleTraffic);

    addListener(document.getElementById('mapModeBtn'), 'click', function () {
        document.getElementById('mapModePanel').style.display = '';
    });

    var mapModeBtns = document.getElementsByName('mapMode');

    for (var i = 0; i < mapModeBtns.length; i++) {
        addListener(mapModeBtns[i], 'click', function () {
            setMapMode(this.value);

            document.getElementById('mapModePanel').style.display = 'none';
        });
    }
}
// FINE INIT



function getMap() {
    var mapOptions = {
        credentials: "YOUR BING MAPS KEY",
        showDashboard: false,
        showCopyright: false,
        showScalebar: false,
        enableSearchLogo: false,
        enableClickableLogo: false,
        backgroundColor: new Microsoft.Maps.Color(255, 0, 0, 0)
    };

    // Initialize the map
    map = new Microsoft.Maps.Map(document.getElementById("myMap"), mapOptions);

    gpsLayer = new Microsoft.Maps.EntityCollection();
    map.entities.push(gpsLayer);
}

function updateNavBar() {
    if (map.isRotationEnabled()) {
        document.getElementById('rotationBtns').style.display = '';
    } else {
        document.getElementById('rotationBtns').style.display = 'none';
    }
}

function search(query) {
    if (searchManager) {
        var request = {
            where: query,
            count: 1,
            callback: geocodeCallback,
            errorCallback: geocodeError
        };

        searchManager.geocode(request);
    } else {
        //Load the Search module and create a search manager.
        Microsoft.Maps.loadModule('Microsoft.Maps.Search', {
            callback: function () {
                //Create the search manager
                searchManager = new Microsoft.Maps.Search.SearchManager(map);

                //Perfrom search logic
                search(query);
            }
        });
    }
}

function geocodeCallback(response, userData) {
    if (response &&
        response.results &&
        response.results.length > 0) {
        var r = response.results[0];
        var l = new Microsoft.Maps.Location(r.location.latitude, r.location.longitude);

        //Display result on map        
        var p = new Microsoft.Maps.Pushpin(l);
        map.entities.push(p);

        //Zoom to result
        map.setView({ center: l, zoom: 15 });
    } else {
        showMessage("Not results found.");
    }

    document.getElementById('searchPanel').style.display = 'none';
}

function geocodeError(request) {
    showMessage("Unable to Geocode request.");

    document.getElementById('searchPanel').style.display = 'none';
}

function toggleGPS() {
    gpsEnabled = !gpsEnabled;

    // Initialize the location provider
    if (!geoLocationProvider) {
        geoLocationProvider = new Microsoft.Maps.GeoLocationProvider(map);
    }

    //Clear the GPS layer 
    gpsLayer.clear();

    if (gpsEnabled) {
        // Get the user's current location
        geoLocationProvider.getCurrentPosition({
            successCallback: function (e) {
                gpsLayer.push(new Microsoft.Maps.Pushpin(e.center));
            },
            errorCallback: function (e) {
                showMessage(e.internalError);
            }
        });
    } else {
        //Remove the accuracy circle and cancel any request that might be processing
        geoLocationProvider.removeAccuracyCircle();
        geoLocationProvider.cancelCurrentRequest();
    }
}

function toggleTraffic() {
    trafficEnabled = !trafficEnabled;

    //Check to see if the traffic layer exists
    if (trafficLayer) {
        if (trafficEnabled) {
            trafficLayer.show();
        } else {
            trafficLayer.hide();
        }
    } else {
        //Load the traffic module and create the traffic layer.
        Microsoft.Maps.loadModule('Microsoft.Maps.Traffic', {
            callback: function () {
                //Create the traffic layer
                trafficLayer = new Microsoft.Maps.Traffic.TrafficLayer(map);

                //Get the base tile layer and set the opacity
                var layer = trafficLayer.getTileLayer();
                layer.setOptions({ opacity: 0.5 });

                trafficLayer.show();
            }
        });
    }
}

function setMapMode(mode) {
    var m;

    switch (mode) {
        case 'auto':
            m = Microsoft.Maps.MapTypeId.auto;
            break;
        case 'aerial':
            m = Microsoft.Maps.MapTypeId.aerial;
            break;
        case 'birdseye':
            m = Microsoft.Maps.MapTypeId.birdseye;
            break;
        case 'os':
            m = Microsoft.Maps.MapTypeId.ordnanceSurvey;
            break;
        case 'road':
        default:
            m = Microsoft.Maps.MapTypeId.road;
            break;
    }

    map.setView({ mapTypeId: m });
}

function showMessage(msg) {
    try {
        alert(msg);
    }
    catch (e) {
        if (Windows != null &&
            Windows.UI != null &&
            Windows.UI.Popups != null) {
            var popup = Windows.UI.Popups.MessageDialog(msg);
            popup.showAsync();
        }
    }
}

//Cross browser support for adding events. Mainly for IE7/8
function addListener(element, eventName, eventHandler) {
    if (element.addEventListener) {
        element.addEventListener(eventName, eventHandler, false);
    } else if (element.attachEvent) {
        if (eventName == 'DOMContentLoaded') {
            eventName = 'readystatechange';
        }
        element.attachEvent('on' + eventName, eventHandler);
    }
}

addListener(document, 'DOMContentLoaded', init);
})();

(Change "YOUR BING MAPS KEY" with your Bing Maps Developer Key) Then in your Page Control JS code navigate to the page hosted in the webview:

// For an introduction to the Page Control template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232511
(function () {
    "use strict";

var ControlConstructor = WinJS.UI.Pages.define("/pages/mapcontrol/mapcontrol.html", {
    // This function is called whenever a user navigates to this page. It
    // populates the page elements with the app's data.
    ready: function (element, options) {
        //// TODO: Initialize the page here.


        var webview = document.getElementById("Map");
        webview.navigate("ms-appx-web:///pages/bingmap/bingmap.html");


    },


});

})();


回答3:

Using the Bing Maps JavaScript control that you reference does work in WP8 and 8.1. I put together a cross platform code sample that works on WP, Win8 and Web a while back and made it available here: http://code.msdn.microsoft.com/Cross-Platform-Bing-Maps-e96600d5