none
Performance tuning: draw boundary via getBoundary() RRS feed

  • Question

  • Hi,

    How to improve performance of drawing a polygon of a US state, like below?

    One solution is to draw the polygon based on locations explicitly. What are other ways?

    https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk#sdsLoadSingleBoundary+JS

    	var geoDataRequestOptions = {
    					entityType: 'AdminDivision1'
    				};
    				Microsoft.Maps.loadModule('Microsoft.Maps.SpatialDataService', function () {
    					//Use the GeoData API manager to get the boundary
    					Microsoft.Maps.SpatialDataService.GeoDataAPIManager.getBoundary(new Array('WA, US'), geoDataRequestOptions, map, function (data) {
    						if (data.results && data.results.length > 0) {
    							map.entities.push(data.results[0].Polygons);
    						}
    					});
    				});


    • Edited by Pingpong689 Saturday, April 1, 2017 8:47 AM
    Friday, March 31, 2017 10:10 PM

Answers

  • There are a number of possible improvements.

    When using the GeoData API:

    • Geocode your data head of time and store the coordinates in your application. The Bing Maps terms of use allow you to store the geocode data for use in your application. This is one of the easiest ways to improve performance overall. The way the GeoData API works is that it retrieves which ever boundary intersects a coordinate. When you pass in a free form text value into the GeoData API it has to geocode your request on the fly before retrieving a boundary. This will always be slower than passing in a location object into the same function. As a bonus, this allows you to better manage and fine tune the coordinates to ensure that the expect boundaries are always retrieved.
    • Minor, but if you are only passing in a single value into the GeoData API, don't wrap it in an array. This adds a slight overhead.

    If you are only interested in US state boundaries you can also use the US Census data source that is in the Bing Spatial Data Services. This will be much faster than the GeoData API as the data set being queried only has 52 rows of data. This API also provides a lot more features in terms of searching. Here is a code sample using this data source to generate a Choropleth of US state populations: http://bingmapsv8samples.azurewebsites.net/#QueryAPI_ChoroplethMap

    If you only want to retrieve a single boundary from this data source you can do so easily in a number of ways. do a find by property search on the name. Do an intersection test on a coordinate (location).


    [Blog] [twitter] [LinkedIn]


    Saturday, April 1, 2017 7:20 PM
  • 1) If terms of GeoData API, storing the location will be faster than passing in free form text into it. In terms of GeoData API vs the Bing Spatial Data Services (SDS), SDS will be much faster as it has a lot less data to search through.

    2) The URL stays the same, you would simply create a filter and use the Query API of the Spatial Data Services module. Here is an example:

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script type='text/javascript'>
        var map;
    
        var sdsDataSourceUrl = 'https://spatial.virtualearth.net/REST/v1/data/755aa60032b24cb1bfb54e8a6d59c229/USCensus2010_States/States';
    
        function GetMap() {
            map = new Microsoft.Maps.Map('#myMap', {
                credentials: YourBingMapsKey,
                zoom: 2
            });
    
            //Load the Bing Spatial Data Services module.
            Microsoft.Maps.loadModule('Microsoft.Maps.SpatialDataService', function () {
                findByPropperty();
            });
        }
    
        function findByPropperty() {
            //Remove any existing data from the map.
            map.entities.clear();
    
            //Create a query to get nearby data.
            var queryOptions = {
                queryUrl: sdsDataSourceUrl,
                filter: new Microsoft.Maps.SpatialDataService.Filter('Name', 'eq', 'Ohio') //Filter to retrieve by state name. Note that this is case sensitive.
            };
    
            //Process the query.
            Microsoft.Maps.SpatialDataService.QueryAPIManager.search(queryOptions, map, function (data) {
                //Add results to the map.
                map.entities.push(data);
            });
        }
        </script>
        <script type='text/javascript' src='/BingMapsCredentials.js'></script>
        <script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>

    You can find details about the US Census data sources here: https://msdn.microsoft.com/en-us/library/mt805047.aspx


    [Blog] [twitter] [LinkedIn]

    Sunday, April 2, 2017 6:23 PM

All replies

  • There are a number of possible improvements.

    When using the GeoData API:

    • Geocode your data head of time and store the coordinates in your application. The Bing Maps terms of use allow you to store the geocode data for use in your application. This is one of the easiest ways to improve performance overall. The way the GeoData API works is that it retrieves which ever boundary intersects a coordinate. When you pass in a free form text value into the GeoData API it has to geocode your request on the fly before retrieving a boundary. This will always be slower than passing in a location object into the same function. As a bonus, this allows you to better manage and fine tune the coordinates to ensure that the expect boundaries are always retrieved.
    • Minor, but if you are only passing in a single value into the GeoData API, don't wrap it in an array. This adds a slight overhead.

    If you are only interested in US state boundaries you can also use the US Census data source that is in the Bing Spatial Data Services. This will be much faster than the GeoData API as the data set being queried only has 52 rows of data. This API also provides a lot more features in terms of searching. Here is a code sample using this data source to generate a Choropleth of US state populations: http://bingmapsv8samples.azurewebsites.net/#QueryAPI_ChoroplethMap

    If you only want to retrieve a single boundary from this data source you can do so easily in a number of ways. do a find by property search on the name. Do an intersection test on a coordinate (location).


    [Blog] [twitter] [LinkedIn]


    Saturday, April 1, 2017 7:20 PM
  • Hi Ricky_Brundritt,

    Thanks for the advice.

    1] Which way will provide the best performance? I guess it is the one that stored all locations and create polygon based on them explicitly?

    2] On US Census data source, what url or parameter will return one state, e.g. Ohio? The url below in the example returns all statues, which requires looping each to get the required one.

    'https://spatial.virtualearth.net/REST/v1/data/755aa60032b24cb1bfb54e8a6d59c229/USCensus2010_States/States'

    https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk#sdsChoroplethMap+JS

    Thanks in advance.


    • Edited by Pingpong689 Saturday, April 1, 2017 9:18 PM
    Saturday, April 1, 2017 9:17 PM
  • 1) If terms of GeoData API, storing the location will be faster than passing in free form text into it. In terms of GeoData API vs the Bing Spatial Data Services (SDS), SDS will be much faster as it has a lot less data to search through.

    2) The URL stays the same, you would simply create a filter and use the Query API of the Spatial Data Services module. Here is an example:

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script type='text/javascript'>
        var map;
    
        var sdsDataSourceUrl = 'https://spatial.virtualearth.net/REST/v1/data/755aa60032b24cb1bfb54e8a6d59c229/USCensus2010_States/States';
    
        function GetMap() {
            map = new Microsoft.Maps.Map('#myMap', {
                credentials: YourBingMapsKey,
                zoom: 2
            });
    
            //Load the Bing Spatial Data Services module.
            Microsoft.Maps.loadModule('Microsoft.Maps.SpatialDataService', function () {
                findByPropperty();
            });
        }
    
        function findByPropperty() {
            //Remove any existing data from the map.
            map.entities.clear();
    
            //Create a query to get nearby data.
            var queryOptions = {
                queryUrl: sdsDataSourceUrl,
                filter: new Microsoft.Maps.SpatialDataService.Filter('Name', 'eq', 'Ohio') //Filter to retrieve by state name. Note that this is case sensitive.
            };
    
            //Process the query.
            Microsoft.Maps.SpatialDataService.QueryAPIManager.search(queryOptions, map, function (data) {
                //Add results to the map.
                map.entities.push(data);
            });
        }
        </script>
        <script type='text/javascript' src='/BingMapsCredentials.js'></script>
        <script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>

    You can find details about the US Census data sources here: https://msdn.microsoft.com/en-us/library/mt805047.aspx


    [Blog] [twitter] [LinkedIn]

    Sunday, April 2, 2017 6:23 PM
  • Hi Ricky_Brundritt,

    Thank you for your reply. It works.

    I wonder if you can have a look at the related question below. I will mark your answer once you are aware of this.

    https://social.msdn.microsoft.com/Forums/en-US/9dae7cd4-0e9e-444d-b022-afd0e765ed59/performance-draw-counties-of-us-state-manual-vs-spatialdataservice-search-vs-spatialdataservice?forum=bingmaps

    Thanks in advance.


    Monday, April 3, 2017 6:28 PM