Created
August 28, 2015 16:19
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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