Skip to content

Instantly share code, notes, and snippets.

@suvozy
Created August 28, 2015 16:19
Show Gist options
  • Save suvozy/5fb33150a32e4f4a3590 to your computer and use it in GitHub Desktop.
Save suvozy/5fb33150a32e4f4a3590 to your computer and use it in GitHub Desktop.
Bing maps: create url and determining best map view for an array of locations
<?php
// https://rbrundritt.wordpress.com/2009/07/21/determining-best-map-view-for-an-array-of-locations/
// Calculates the best map view for a list of locations for a map
//
// locations = List of location objects
// map_width = Map width in pixels
// map_height = Map height in pixels
// buffer = Width in pixels to use to create a buffer around the map. This is to keep pushpins from being cut off on the edge
//
// Returns a MapViewSpecification with the best map center point and zoom level for the given set of locations
public function get_map_view($locations, $map_width = 500, $map_height = 500, $buffer = 50)
{
$center = array('lat' => 0, 'lng' => 0);
$zoom_level = 1; // 1-19
$max_lat = -85;
$min_lat = 85;
$max_lng = -180;
$min_lng = 180;
// calculate bounding rectangle
for ($i = 0; $i < count($locations); $i++)
{
if ($locations[ $i ]['lat'] > $max_lat) $max_lat = $locations[ $i ]['lat'];
if ($locations[ $i ]['lat'] < $min_lat) $min_lat = $locations[ $i ]['lat'];
if ($locations[ $i ]['lng'] > $max_lng) $max_lng = $locations[ $i ]['lng'];
if ($locations[ $i ]['lng'] < $min_lng) $min_lng = $locations[ $i ]['lng'];
}
$center['lat'] = ($max_lat + $min_lat) / 2;
$center['lng'] = ($max_lng + $min_lng) / 2;
$zoom_w = 0; $zoom_h = 0;
// https://msdn.microsoft.com/en-us/library/bb259689.aspx
// map width = map height = 256 * 2 ^ level pixels
// Determine the best zoom level based on the map scale and bounding coordinate information
if ($max_lng != $min_lng && $max_lat != $min_lat)
{
// best zoom level based on map width
$zoom_w = log(360 / 256 * ($map_width - (2*$buffer) ) / ($max_lng - $min_lng)) / log(2);
// best zoom level based on map height
$zoom_h = log(180 / 256 * ($map_height - (2*$buffer) ) / ($max_lat - $min_lat)) / log(2);
}
// use the most zoomed out of the two zoom levels
$zoom_level = floor( min($zoom_w, $zoom_h) );
// An integer between 0 and 21.
$zoom_level = max($zoom_level, 1);
$zoom_level = min($zoom_level, 19);
$map_view['center'] = $center;
$map_view['zoom_level'] = $zoom_level;
return $map_view;
}
public function build_url($locations, $format)
{
$map_view = $this->get_map_view($locations);
$this->CI->load->config('api_key', TRUE);
$map_key = $this->CI->config->item('bing_public', 'api_key');
// https://msdn.microsoft.com/en-in/library/ff701724.aspx
$path = array(
'type' => 'REST',
'version' => 'v1',
'imagery' => 'Imagery',
'map' => 'Map',
'imagerySet' => 'Road',
'centerPoint' => $map_view['center']['lat'].','.$map_view['center']['lng'], // '0,0'
'zoomLevel' => $map_view['zoom_level'], // An integer between 0 and 21.
);
$query = array(
'mapSize' => '500,500',
'key' => $map_key,
// Pushpin Syntax and Icon Styles
// https://msdn.microsoft.com/en-in/library/ff701719.aspx
// pushpin=latitude,longitude;iconStyle;label
// 'pp' => '0,0;37;',
// declutterPins=0 [default]
'dcl' => '1',
'format' => $format,
);
$pp_query = '';
if (!empty($locations)) foreach ($locations as $loaction)
{
$pp_query .= '&'.'pp='.$loaction['lat'].','.$loaction['lng'].';37;';
}
$url = 'http://dev.virtualearth.net/'.implode('/', $path).'?'.http_build_query($query).$pp_query;
return $url;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment