none
Problem with Bing maps V8 in Dynamics CRM HTML web resource RRS feed

  • Question

  • Hi all,

    I have the
    below code that works fine with the Bing Maps V7 control but if I change it to
    use V8 it doesn't work.

    I'm
    basically changing: "http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0

    to: "http://www.bing.com/api/maps/mapcontrol?branch=release

    any advice
    much appreciated.

    ----------------------------------

    <html><head>

        <script src="../../ClientGlobalContext.js.aspx"></script>
        <script src="../Script/SDK.REST.js" type="text/javascript"></script>
        <title>Show Child Accounts</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

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

        <script type="text/javascript">

            var map = null;
            var messageBox = null;
            var lat = null;
            var lon = null;
            var City = null;
            var AccountName = null;
            var pushpin = null;

            var pushpinCollection = new Microsoft.Maps.EntityCollection();
            var messageBoxCollection = new Microsoft.Maps.EntityCollection();

            document.onreadystatechange = function() {
                if (document.readyState == "complete") {
                   //initialise map
                   getMap();

                  //Get child account records
                   getChildAccounts();
                }
            }


    function getChildAccounts() {
          

    //retrieve current entity id

               
    var parentaccountId = window.parent.Xrm.Page.data.entity.getId();

                var entitySchemaName = "Account";

                //get all child records based on parent customer id

              var odataQuery
    ="?$select=Name,Address1_City,Address1_Latitude,Address1_Longitude&$filter=BusinessTypeCode/Value
    eq 100000023";

                if (typeof(SDK) != "undefined") {

                   
               //The retrieveAccountsCallBack function is passed through as the successCallBack.

                   SDK.REST.retrieveMultipleRecords(entitySchemaName, odataQuery,
    getnotesImagesCallback, function(error) {
                       alert(error.message);
                   }, function() {});
                } else {
                   alert("Not able to load REST.SDK library");
                }
            }

           
    //callback method

            function getnotesImagesCallback(resultSet) {

                //initialise message box

                messageBox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), {
                   visible: false
                });

               messageBoxCollection.push(messageBox);

                //Show current account

                lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();
                City = window.parent.Xrm.Page.getAttribute("address1_city").getValue();
                AccountName = window.parent.Xrm.Page.getAttribute("name").getValue();

     
                pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(lat, lon));
               pushpin.Description = AccountName + ", " + City;

                //show message box on mouse move
              Microsoft.Maps.Events.addHandler(pushpin, 'mouseover', displaymessagebox);

                //remove message box on mouse lost
               Microsoft.Maps.Events.addHandler(pushpin, 'mouseout', hidemessagebox);
            
    pushpinCollection.push(pushpin);

                //add collection to map
               map.entities.push(pushpinCollection);
               map.entities.push(messageBoxCollection);

                if (resultSet.length > 0) {
                   TotalImages = resultSet.length;
                   for (i = 0; i < resultSet.length; i++) {
                       lat = resultSet[i].Address1_Latitude;
                       lon = resultSet[i].Address1_Longitude;
                       City = resultSet[i].Address1_City;
                       AccountName = resultSet[i].Name;

                     
    //pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(lat, lon));

                       
    pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(lat,
    lon),{icon: 'http://crm-srv2012:5555/NacroCRMLive/WebResources/new_green_pushpin',
    width: 50, height: 50, draggable: false});
                       
    pushpin.Description = AccountName + ", " + City;
                     
    //show message box on move move
                     Microsoft.Maps.Events.addHandler(pushpin, 'mouseover', displaymessagebox);
                      
    //remove message box on mouse lost
                      Microsoft.Maps.Events.addHandler(pushpin, 'mouseout', hidemessagebox);

                       pushpinCollection.push(pushpin);
                   }

                   
    //add collection to map
                   map.entities.push(pushpinCollection);
                   map.entities.push(messageBoxCollection);
               }

            }

     

            function displaymessagebox(e) {

               
    messageBox.setOptions({

                   description: e.target.Description,
                   visible: true,

                   offset: new Microsoft.Maps.Point(0, 25)
                });

               
    messageBox.setLocation(e.target.getLocation());

            }

            function hidemessagebox(e) {

               messageBox.setOptions({

                   visible: false
                });
            }



            function getMap() {

                c_lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                c_lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();

               map = new Microsoft.Maps.Map(document.getElementById('bingMaps'), {

                   credentials: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                   center: new Microsoft.Maps.Location(c_lat, c_lon),
                   mapTypeId: Microsoft.Maps.MapTypeId.road,

                   zoom: 9
                });
           }
       </script>

    </head>

    <body>

        <div id="bingMaps" style="width: 600px;
    height: 500px; "></div>

    </body></html>




    Tuesday, September 27, 2016 11:58 AM

Answers

  • A few issues. The first is that you add your entity collections to the map twice. This may cause an issue. The second is that how you add an infobox in v8 has changed. Rather than adding it to a layer you assign it to a map using infobox.setMap(map) this will ensure your infobox always render on top.

    If you are still having issues after making these changes, can you provide any errors you are seeing and describe what you do see i.e. Is the map loading but no pushpins...


    [Blog] [twitter] [LinkedIn]

    Tuesday, September 27, 2016 2:58 PM
  • Ah, see the issue, move the creation of the entity collections to the getMap function. The V8 control loads a bunch of resources asynchronously and it doesn't look like the EntityCollection class is fully downloaded before your create the variable.

    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Thursday, September 29, 2016 6:11 PM
    • Marked as answer by Terry Harrison Tuesday, October 11, 2016 9:03 AM
    Thursday, September 29, 2016 6:10 PM
  • Throw an alert into the getnotesImagesCallback to see if the code is making it there or not. If it doesn't make it there, take a look at the network traffic and see if the request failed. If it does work, then try and step through each line of code to figure out where an error is happening. If everything appears to be working but you are only seeing one pushpin, make sure to set the latitude/longitude values in the pushpin (currently you have them hardcoded).


    [Blog] [twitter] [LinkedIn]

    Friday, September 30, 2016 3:54 PM
  • The only data limits is based on what the browser can handle. Thousands of pushpins and polygons/polylines can easily be rendered on the map. Check the value of resultSet.length. If that is 111, then try adding a check to verify if the latitude/longitude values are valid. If invalid coordinates are passed in the pushpin likely won't render were you expect.

    [Blog] [twitter] [LinkedIn]

    Monday, October 3, 2016 7:27 PM

All replies

  • A few issues. The first is that you add your entity collections to the map twice. This may cause an issue. The second is that how you add an infobox in v8 has changed. Rather than adding it to a layer you assign it to a map using infobox.setMap(map) this will ensure your infobox always render on top.

    If you are still having issues after making these changes, can you provide any errors you are seeing and describe what you do see i.e. Is the map loading but no pushpins...


    [Blog] [twitter] [LinkedIn]

    Tuesday, September 27, 2016 2:58 PM
  • Hi Ricky,

    Thanks for the reply. I've tried removing the first 'add collection' and have also removed all references to message boxes just to try and get it working but still the same issue. What I am seeing is just a plain white box where the map would be, nothing else.

    I've also tried some code from the dev kit for V8 and this works fine (as below):

    <html><head>
            <title>loadMapWithOptionsHTML</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head>
        <body>
            <div id="printoutPanel"></div>
           
            <div id="myMap" style="width: 100vw; height: 100vh;"></div>
            <script type="text/javascript">


                function loadMapScenario() {

                c_lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                c_lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();

                    var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
                        credentials: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                        center: new Microsoft.Maps.Location(c_lat, c_lon),
                        mapTypeId: Microsoft.Maps.MapTypeId.aerial,
                        zoom: 10
                    });
                     var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), { color: 'orange' });
                    map.entities.push(pushpin); 
              
                   }
            </script>
            <script src="http://www.bing.com/api/maps/mapcontrol?branch=release&amp;callback=loadMapScenario" defer="" type="text/javascript" async=""></script>
       
    </body></html>

    So it seems what I need is something like the above code but with the added odata / REST call from the original. I'm unsure how to go about this though as the collection examples in the dev resources all use the bing test data. I cant find any real examples. Any help much appreciated.

    Thanks,

    Terry

    Wednesday, September 28, 2016 11:21 AM
  • Ah, see the issue, move the creation of the entity collections to the getMap function. The V8 control loads a bunch of resources asynchronously and it doesn't look like the EntityCollection class is fully downloaded before your create the variable.

    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Thursday, September 29, 2016 6:11 PM
    • Marked as answer by Terry Harrison Tuesday, October 11, 2016 9:03 AM
    Thursday, September 29, 2016 6:10 PM
  • Thanks Ricky,

    You were right, I've moved this to the getMap function and the map now displays. I've also simplified a lot further and changed to use a layer as per the SDK and although I can now get my current account pushpin displayed I still cant get the REST / odata collection to work.

    The current code is as below and this will show the current pushpin as well as a hardcoded pushpin on a separate layer. As soon as I move any of this into the 'getnotesImagesCallback' function to try to populate the layer collection I end up with nothing. The map just shows my current 'pushpin1' and nothing else.

    Thanks again,

    Terry

    <html><head>
        <script src="../../ClientGlobalContext.js.aspx"></script>
        <script src="../Script/SDK.REST.js" type="text/javascript"></script>
        <title>Show Child Accounts</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head><body>
        <script src="http://www.bing.com/api/maps/mapcontrol?branch=release" defer="" type="text/javascript" async=""></script>
        <script type="text/javascript">
            var map = null;
            var messageBox = null;
            var lat = null;
            var lon = null;
            var City = null;
            var AccountName = null;
            var pushpin = null;

            document.onreadystatechange = function() {
                if (document.readyState == "complete") {

                    //initialise map
                    getMap();

                    //Get child account records
                    getChildAccounts();
                }
            }
     
            function getChildAccounts() {

                //retrieve current entity id
                var entitySchemaName = "Account";
                var layer = new Microsoft.Maps.Layer();

                //get all child records based on parent customer id
                var odataQuery ="?$select=Name,Address1_City,Address1_Latitude,Address1_Longitude&$filter=BusinessTypeCode/Value eq 100000023";
     
                if (typeof(SDK) != "undefined") {

                    //The retrieveAccountsCallBack function is passed through as the successCallBack.
                    SDK.REST.retrieveMultipleRecords(entitySchemaName, odataQuery, getnotesImagesCallback, function(error) {
                        alert(error.message);
                    }, function() {});
                } else {
                    alert("Not able to load REST.SDK library");
                }

             pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(52.89213, -1.45416), { color: 'green' });
             layer.add(pushpin);
            map.layers.insert(layer);
            }

            //callback method
            function getnotesImagesCallback(resultSet) {
     
                //Show current account
                lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();
                City = window.parent.Xrm.Page.getAttribute("address1_city").getValue();
                AccountName = window.parent.Xrm.Page.getAttribute("name").getValue();

                if (resultSet.length > 0) {
                    TotalImages = resultSet.length;
                    for (i = 0; i < resultSet.length; i++) {
                        lat = resultSet[i].Address1_Latitude;
                        lon = resultSet[i].Address1_Longitude;
                        City = resultSet[i].Address1_City;
                        AccountName = resultSet[i].Name;
     
                         //pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(52.89213, -1.45416), { color: 'green' });
                        //layer.add(pushpin);
                    }
                }
            }

            function getMap() {

                var pushpinCollection = new Microsoft.Maps.EntityCollection();

                c_lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                c_lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();

                map = new Microsoft.Maps.Map(document.getElementById('bingMaps'), {
                    credentials: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                    center: new Microsoft.Maps.Location(c_lat, c_lon),
                    mapTypeId: Microsoft.Maps.MapTypeId.road,
                    zoom: 9
                });
                     var pushpin1 = new Microsoft.Maps.Pushpin(map.getCenter(), { color: 'orange' });
                    map.entities.push(pushpin1);
            }
        </script>
        <div id="bingMaps" style="width: 600px; height: 500px; ;"></div>
    </body></html>

    Friday, September 30, 2016 11:44 AM
  • Throw an alert into the getnotesImagesCallback to see if the code is making it there or not. If it doesn't make it there, take a look at the network traffic and see if the request failed. If it does work, then try and step through each line of code to figure out where an error is happening. If everything appears to be working but you are only seeing one pushpin, make sure to set the latitude/longitude values in the pushpin (currently you have them hardcoded).


    [Blog] [twitter] [LinkedIn]

    Friday, September 30, 2016 3:54 PM
  • Thanks Ricky, im finally getting there with this. I have it (mostly) working now using your advice. I found a few issues. Firstly it didn't like starting at 0 in the for loop and just dropped out for some reason. Changing to start at 1 resolved this. Also I removed the layer and just added pins each time using 'map.entities.push(pushpin);'.

    The only issue I have now is that there are 111 items in the resultset, however it gets to around 90 and then drops out and doesn't add anymore. Is there any limitation on the number of pushpins? Would clustering get around this?

    Thanks,

    Terry

    --------------------------------------------------------------

    <html><head>
        <script src="../../ClientGlobalContext.js.aspx"></script>
        <script src="../Script/SDK.REST.js" type="text/javascript"></script>
        <title>Show Child Accounts</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head><body>
        <script src="http://www.bing.com/api/maps/mapcontrol?branch=release" defer="" type="text/javascript" async=""></script>
        <script type="text/javascript">
            var map = null;
            var messageBox = null;
            var lat = null;
            var lon = null;
            var City = null;
            var AccountName = null;
            var pushpin = null;

            document.onreadystatechange = function() {
                if (document.readyState == "complete") {

                    //initialise map
                    getMap();

                    //Get child account records
                    getChildAccounts();
                }
            }
     
            function getChildAccounts() {

                //retrieve current entity id
                var entitySchemaName = "Account";
               
                //get all child records based on parent customer id
                var odataQuery ="?$select=Name,Address1_City,Address1_Latitude,Address1_Longitude&$filter=BusinessTypeCode/Value eq 100000023";
     
                if (typeof(SDK) != "undefined") {

                    //The retrieveAccountsCallBack function is passed through as the successCallBack.
                    SDK.REST.retrieveMultipleRecords(entitySchemaName, odataQuery, getnotesImagesCallback, function(error) {
                        alert(error.message);
                    }, function() {});
                } else {
                    alert("Not able to load REST.SDK library");
                }
            }

            //callback method
            function getnotesImagesCallback(resultSet) {
     
                //Show current account
                lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();
                City = window.parent.Xrm.Page.getAttribute("address1_city").getValue();
                AccountName = window.parent.Xrm.Page.getAttribute("name").getValue();

                if (resultSet.length > 0) {
                    TotalImages = resultSet.length;
                    for (i = 1; i < resultSet.length; i++) {
                        lat = resultSet[i].Address1_Latitude;
                        lon = resultSet[i].Address1_Longitude;
                        City = resultSet[i].Address1_City;
                        AccountName = resultSet[i].Name;
     
                         //if (i>0) {
                         pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(lat,lon), { color: 'green' });
                         map.entities.push(pushpin);
                        //}
                    }
                }
            }

            function getMap() {

                var pushpinCollection = new Microsoft.Maps.EntityCollection();

                c_lat = window.parent.Xrm.Page.getAttribute("address1_latitude").getValue();
                c_lon = window.parent.Xrm.Page.getAttribute("address1_longitude").getValue();

                map = new Microsoft.Maps.Map(document.getElementById('bingMaps'), {
                    credentials: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                    center: new Microsoft.Maps.Location(c_lat, c_lon),
                    mapTypeId: Microsoft.Maps.MapTypeId.road,
                    zoom: 9
                });
                     var pushpin1 = new Microsoft.Maps.Pushpin(map.getCenter(), { color: 'orange' });
                    map.entities.push(pushpin1);
            }
        </script>
        <div id="bingMaps" style="width: 600px; height: 500px; ;"></div>
    </body></html>


    Monday, October 3, 2016 10:43 AM
  • The only data limits is based on what the browser can handle. Thousands of pushpins and polygons/polylines can easily be rendered on the map. Check the value of resultSet.length. If that is 111, then try adding a check to verify if the latitude/longitude values are valid. If invalid coordinates are passed in the pushpin likely won't render were you expect.

    [Blog] [twitter] [LinkedIn]

    Monday, October 3, 2016 7:27 PM
  • Thanks Ricky,

    This is all working now.

    Regards,

    Terry

    Tuesday, October 11, 2016 9:02 AM