Created
August 11, 2010 00:14
-
-
Save RandomEtc/518261 to your computer and use it in GitHub Desktop.
experimental Modest Maps provider for the Bing REST API
This file contains 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
package com.modestmaps.mapproviders.microsoft | |
{ | |
import com.modestmaps.core.Coordinate; | |
import com.modestmaps.mapproviders.AbstractMapProvider; | |
import com.modestmaps.mapproviders.IMapProvider; | |
import com.modestmaps.util.BinaryUtil; | |
import flash.events.Event; | |
import flash.events.EventDispatcher; | |
import flash.events.IEventDispatcher; | |
import flash.net.URLLoader; | |
import flash.net.URLRequest; | |
import flash.net.URLVariables; | |
public class BingMapsProvider extends AbstractMapProvider implements IMapProvider, IEventDispatcher | |
{ | |
public static const ROAD:String = 'Road'; | |
public static const AERIAL:String = 'Aerial'; | |
public static const HYBRID:String = 'AerialWithLabels'; | |
public static const AERIAL_WITH_LABELS:String = 'AerialWithLabels'; | |
private var dispatcher:EventDispatcher; | |
private var key:String; | |
private var type:String; | |
private var imageURL:String = null; | |
private var subDomains:Array = []; | |
private var serverSalt:int = 0; | |
public var copyright:String = null; | |
public var logo:String = null; | |
public function BingMapsProvider(key:String, type:String='Road', API:String='http://dev.virtualearth.net/REST/V1/Imagery/Metadata/') | |
{ | |
super(); | |
this.key = key; | |
this.type = type; | |
this.dispatcher = new EventDispatcher(this); | |
var data:URLVariables = new URLVariables(); | |
data.key = key; | |
data.output = 'xml'; | |
var request:URLRequest = new URLRequest(API + type); | |
request.data = data; | |
var loader:URLLoader = new URLLoader(); | |
loader.addEventListener(Event.COMPLETE, onLoadComplete); | |
loader.load(request); | |
} | |
private function onLoadComplete(event:Event):void | |
{ | |
var response:XML = XML(event.target.data); | |
default xml namespace = new Namespace('http://schemas.microsoft.com/search/local/ws/rest/v1'); | |
this.logo = response.BrandLogoUri[0].text().toString(); | |
this.copyright = response.Copyright[0].text().toString(); | |
var metadata:XML = response.ResourceSets[0].ResourceSet[0].Resources[0].ImageryMetadata[0]; | |
this.imageURL = metadata.ImageUrl[0].text().toString(); | |
for each (var string:XML in metadata.ImageUrlSubdomains[0].string) { | |
this.subDomains.push(string.text().toString()); | |
} | |
serverSalt = int(Math.random() * this.subDomains.length); | |
// TODO: deal with ImageWidth/ImageHeight? | |
var zoomMin:int = parseInt(metadata.ZoomMin[0].text(),10); | |
var zoomMax:int = parseInt(metadata.ZoomMax[0].text(),10); | |
__bottomRightInLimit = __bottomRightInLimit.zoomTo(zoomMax); | |
__topLeftOutLimit = __topLeftOutLimit.zoomTo(zoomMin); | |
dispatchEvent(new Event(Event.COMPLETE)); | |
} | |
////////// microsoft | |
protected function quadKey(coord:Coordinate):String | |
{ | |
var sourceCoord:Coordinate = sourceCoordinate(coord); | |
// convert row + col to zoom string | |
// padded with zeroes so we end up with zoom digits after slicing: | |
var rowBinaryString:String = BinaryUtil.convertToBinary(sourceCoord.row); | |
rowBinaryString = rowBinaryString.slice(-sourceCoord.zoom); | |
var colBinaryString:String = BinaryUtil.convertToBinary(sourceCoord.column); | |
colBinaryString = colBinaryString.slice(-sourceCoord.zoom); | |
// generate zoom string by combining strings | |
var zoomString:String = ""; | |
for(var i:Number = 0; i < sourceCoord.zoom; i += 1) { | |
zoomString += BinaryUtil.convertToDecimal(rowBinaryString.charAt( i ) + colBinaryString.charAt( i )); | |
} | |
return zoomString; | |
} | |
////////// map provider | |
public function getTileUrls(coord:Coordinate):Array | |
{ | |
var size:int = Math.pow(2,coord.zoom); | |
if (coord.row < 0 || coord.row >= size) { | |
return []; | |
} | |
var subdomain:String = subDomains[Math.abs(serverSalt + coord.row + coord.column + coord.zoom) % 4]; | |
var quadkey:String = quadKey(coord); | |
return [ imageURL.replace('{subdomain}',subdomain).replace('{quadkey}',quadkey) + '&stl=h' ]; | |
} | |
public function toString():String | |
{ | |
return 'BING_'+type.toUpperCase(); | |
} | |
////////// events | |
public function willTrigger(type:String):Boolean | |
{ | |
return dispatcher.willTrigger(type); | |
} | |
public function dispatchEvent(event:Event):Boolean | |
{ | |
return dispatcher.dispatchEvent(event); | |
} | |
public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void | |
{ | |
dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); | |
} | |
public function hasEventListener(type:String):Boolean | |
{ | |
return dispatcher.hasEventListener(type); | |
} | |
public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void | |
{ | |
dispatcher.removeEventListener(type, listener, useCapture); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment