2016 年 10 月

第 31 卷,第 10 期

此文章由机器翻译。

必应地图 - 使用必应地图 8 创建交互式地理位置应用程序

通过 James McCaffrey

企业正在生成数量庞大的数据,并且包含大量的数据包含纬度和经度位置信息。Bing 地图版本 8 库,6 月 2016 年发布具有许多新功能,使您可以创建交互式地域应用程序。在这篇文章中,我将介绍两个 Web 应用程序演示了一些最有趣的功能的 Bing Maps 8 库。第一个应用程序展示了一些功能,允许用户交互,包括新的绘图控件和完整的事件模型功能。第二个应用程序展示了一些功能,使用户能够处理大量数据,包括新的数据聚类分析模块和热度地图可视化对象。

本文假定您已基本熟悉开发 Web 应用程序,但并不假定您完全了解地理位置的应用程序或 Bing 地图 8 库。两个演示 Web 应用程序仅使用标准 HTML 和标准 JavaScript — 任何 ASP.NET 和任何 JavaScript 框架的-的月。每两个演示 Web 应用程序包含在一个 HTML 文件中。完整源代码和两个数据使用文件是在随附代码下载中可用。

看一看中的第一个 Web 应用程序 图 1。Web 页面加载时,立即时映射正在提取了以异步方式呈现在左侧的 HTML 控件。Map 对象居中附近 Portland,俄勒冈,并使用默认样式紫色图钉标记放置在地图中心。

图钉和多边形演示
图 1 图钉和多边形演示

然后,单击浏览按钮了 HTML5 文件控件上并指向名为 LatLonData.txt,存储在我 C:\Data 目录中的本地计算机上的文本文件。该文件具有四个数据点,每种具有一些关联的文本。然后单击标有地方图钉按钮控件上,该应用程序读取该文本文件、 创建四个自定义样式小橙色图钉并将其置于在映射的左侧。

接下来,我单击多边形项一样在代码图的右上角部分的绘图工具控件中并以交互方式吸引四个边绿色多边形了正上方市/县的温哥华,华盛顿我吸引了利用三边的第二个多边形的右侧和下方的地图中心。在绘图中,Web 应用程序侦听的绘图开始和绘图结束事件,并且这些事件激发时输出消息。

单击标记为绘制形状信息按钮控件上,Web 应用程序检索信息以交互方式创建的多边形,并显示三个三角形多边形的顶点。接下来,我移动鼠标光标通过,然后从最底部的橙色图钉。应用程序代码捕获鼠标悬停和 mouseout 并显示事件的位置。虽然并不显示在图中,我在图钉上移动鼠标光标时,会出现弹出 Infobox 对象,,我移动时鼠标光标消失,Infobox 中自动消失。

我通过将鼠标光标移动最顶层的橙色图钉完成我的演示会话,该应用程序的响应是创建将显示的数据与图钉 (文本"第一个数据位置") 和图钉 (45.46、-122.90) 的位置相关联的默认样式 Infobox 对象。

总之,第一个 Web 应用程序演示异步映射表加载、 动态自定义的图钉、 丰富的事件建模、 交互式形状创建和 Infobox 对象。

创建图钉和多边形演示应用程序

我开始编写第一个 Web 页之前,我创建了使用记事本的源数据文件︰

45.46,-122.90,first location data
45.38,-122.90,second location data
45.42,-122.94,third location data
45.42,-122.86,fourth location data

我没有按 < 输入 > 关键数据使我文件读取的代码不会尝试解释一个空的文本行的最后一行之后。我使用逗号作为字段分隔符,但我可以使用 tab 字符。我将数据文件保存为 LatLonData.txt C:\Data 目录中我本地计算机上。如您所见,Bing Maps 可以使用任何一种数据存储区中。

我使用记事本程序创建 Web 应用程序的演示。因为它会强制我需要小心,并且没有任何隐藏的神奇那些混乱的核心理念学习一种新技术时,我喜欢记事本。

因为我使用了只有传统的 HTML 和 JavaScript,所以我不需要执行任何特殊准备 IIS 或我的计算机。我创建了一个名为我的计算机上 C:\inetpub\wwwroot 目录中的 NodeAtlasLight 目录。该名称是任意参数并可以使用任何名称类似如果想要运行 Web 应用程序的演示。

我启动记事本使用"以管理员身份运行"选项使我能够保存我的代码在受保护的 C:\inetpub 根目录下。我将命名为应用程序 PushpinsAndPolygonsDemo.html,但 Bing Maps 8 库有没有所需的命名约定,因此如果您愿意,可以使用一个不同的文件名。

中所示的 Web 应用程序的整体结构 图 2。以下是该结构的高度缩写的版本︰

<html>
  <head>
    <script type=‘text/javascript’>
      // All JavaScript here
    </script>
  </head>
  <body>
    <!-- all HTML here -->
    <script type='text/javascript'
      src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap'
      async defer></script>
  </body>
</html>

关键代码是 < 正文 > 部分的底部 < t > 标记。您可以大概地将此选项以指的是,"加载基本的 Bing 地图 8 库以异步方式而呈现 HTML。当加载了库时,将控制权转到一个名为 GetMap 的 JavaScript 函数。" 可以加载 Bing Maps 8 库以同步方式,但在异步加载库加载缓慢的情况下提供更好的 UX。

图 2 图钉和多边形演示 Web 页结构

<!DOCTYPE html>
<!-- PushpinsAndPolygonsDemo.html -->
<html>
  <head>
    <title>Bing Maps 8 Pushpins with Infoboxes</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript">
    var map = null;
    var pushpins = [];
    var infobox = null;  // Shared infobox for all pushpins
    var ppLayer = null;  // Pushpin layer
    var drawingManager = null;
    var drawnShapes = null;  // an array
    function GetMap() { . . }
    function AddDrawControlEvents(manager) { . . }
    function WriteLn(txt) { . . }
    function LatLonStr(loc) { . . }
    function Button1_Click() { . . }
    function Button2_Click() { . . }
    function ShowInfobox(e) { . . }
    function HideInfobox(e) { . . }
    function CreateCvsDot(radius, clr) { . . }
    </script>
  </head>
  <body style="background-color:wheat">
    <div id='controlPanel' style="float:left; width:262px; height:580px;
      border:1px solid green; padding:10px; background-color: beige">
      <input type="file" id="file1" size="24"></input>
      <span style="display:block; height:10px"></span>
      <input id="button1" type='button' style="width:125px;"
        value='Place Pushpins' onclick="Button1_Click();"></input>
      <div style="width:2px; display:inline-block"></div>
      <input id="textbox1" type='text' size='15' value=' (not used)'></input><br/>
      <span style="display:block; height:10px"></span>
      <input id="button2" type='button' style="width:125px;"
        value='Drawn Shape Info' onclick="Button2_Click();"></input>
      <div style="width:2px; display:inline-block"></div>
      <input id="textbox2" type='text' size='15' value=' (not used)'></input><br/>
      <span style="display:block; height:10px"></span>
      <textarea id='msgArea' rows="34" cols="36"
        style="font-family:Consolas; font-size:12px"></textarea>
    </div>
    <div style="float:left; width:10px; height:600px">
    <div id='mapDiv' style="float:left; width:700px; height:600px;
      border:1px solid red;"></div>
    <br style="clear: left;" />  <!-- magic formatting -->
    <script type='text/javascript'
      src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap'
      async defer></script>
  </body>
</html>

Web 页面的整体布局由两个并行通过浮动 < div > 区域组成。左侧 < div > 包含的 HTML 控件。右边 < div > 包含的地图对象︰

<div id='mapDiv' style="float:left; width:700px; height:600px;
  border:1px solid red;">
</div>

很可能有专用方案的多个映射对象。而不是指定的地图宽度和高度使用像素为单位,还可以使用 CSS3 视区单位、 vw 和 vh。为简单起见,我将嵌入所有 HTML 直接样式,而不是使用单独的 CSS 文件,在位方面的麻烦的次要的费用。

总之,Bing 地图 8 map 对象使用程序定义的 JavaScript 函数,创建的并且将放置在 HTML < div > 区域,指定该映射的大小。您可以同步或异步加载地图。

初始化 Map 对象

Web 应用程序设置了六个全局脚本作用域对象︰

var map = null;
var pushpins = [];
var infobox = null;
var ppLayer = null;
var drawingManager = null;
var drawnShapes = null;

当我创建一个映射的应用程序时,我倾向于将类似于大型 C# 或 Java 类的体系结构,因此 JavaScript 对象的脚本作用域,通常是由两个或多个函数。但是,由于 JavaScript 语言 quirks 和大量使用回调函数和闭包,我将有时放置到脚本作用域区域只需要函数范围的对象。

名为 map 对象 Map 对象,该名称不是必需的虽然是多或少标准。图钉对象是一个数组,其中将保存所有图钉。我将对象初始化为一个空数组,而不是将其设置为 null,主要是以指示对象是一个数组。Infobox 对象是将由所有图钉共享 Infobox 类的单个实例。

Bing Maps 8 的新功能之一是层类。而不是将所有的可视化实体置于一个整体化集合,则现在可以将可视化对象组织到层。DrawingManager 对象是对 DrawingTools 控件的引用。DrawnShapes 对象是一个数组,其中将包含由用户绘制多边形对象形状。

该映射由函数 GetMap 初始化。定义以开始︰

function GetMap()
{
  var options = {
    credentials: "AmUck2_xxxx_jSCm",
    center: new Microsoft.Maps.Location(45.50, -122.50),
    mapTypeId: Microsoft.Maps.MapTypeId.road,
    zoom: 10, enableClickableLogo: false, showCopyright: false
  };
...

请注意,我喜欢利用我程序定义的函数,以区别于库函数或 JavaScript 的内置函数的名称。此处的代码定义了一些初始映射设置。所有这些都是可选的即使凭据项,即实质上是一个必应地图密钥。如果没有密钥,可以那里使用任何字符串并映射仍可加载和正常工作,但将精简 strip 您使用的消息的映射,在"指定的凭据无效。您可以注册免费的开发人员帐户在 http://www.bingmapsportal.com。" 创建一个帐户以获取密钥是相对简单,但如果您是急性子和我一样,您想要立即开始,您可以注册更高版本。

使用位置对象,它接受纬度、 经度,可选择随后与海拔高度相关的两个值后跟设置地图的中心属性。如果您是初次接触地域-应用程序,您必须加点小心。与标准几何点 (x,y) 的 x 值是"左-右"值,但是在地域-应用程序 latitude"上下"值。

接下来,该结构图显示并准备主 Infobox 对象︰

var mapDiv = document.getElementById("mapDiv");
map = new Microsoft.Maps.Map(mapDiv, options);
infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0),
  { visible: false, offset: new Microsoft.Maps.Point(0,0) });
infobox.setMap(map);

非常棒的 Bing 地图功能之一是 API 集使用变量和参数名称的是,大多数情况下,很容易理解。Infobox 置于 (0,0) 的位置,这是虚拟位置,因为 visible 属性设置为 false。偏移量的属性控制底部 Infobox 对象的小三角形的指针的位置。默认值为 (0,0),因此我可以省略了它。

接下来,图钉已做好准备︰

ppLayer = new Microsoft.Maps.Layer();
var cpp= new Microsoft.Maps.Pushpin(map.getCenter(), null);
ppLayer.add(cpp);
map.layers.insert(ppLayer);

PpLayer ("图钉层") 对象定义用于存储所有图钉可视化层。Cpp ("中心图钉") 添加到层中,然后在层添加到映射使图钉变得可见。图钉构造函数,此处为 null,第二个参数可以是一个 PushpinOptions 对象,稍后将介绍该对象。如果传递的值为 null,您默认图钉对象,也不能为紫色大约有 10 个像素为单位的半径。

Bing Maps 8 支持的所有可视化对象放置到一个全局集合的较旧的机制。该代码将如下所示︰

map.entities.push(cpp);

GetMap 函数可以通过创建 DrawingTools 控件并将其放到图来完成︰

...
    Microsoft.Maps.loadModule('Microsoft.Maps.DrawingTools', function() {
    var tools = new Microsoft.Maps.DrawingTools(map);
    tools.showDrawingManager(AddDrawControlEvents);
  });
}

Bing Maps 8 大体系结构更改为的库现在组织到 11 个模块。这样,您可以加载只有模块需要从而显著提高性能。代表其他模块包括搜索、 SpatialMath 和 HeatMap。

LoadModule 函数接受的模块,若要加载,再加上包含代码的模块加载后要执行的回调函数定义的名称。可能需要一段时间才能变得越来越熟悉回调函数,但像任何其他操作之后的几个示例, 可以获得该多好啊使用它们。

ShowDrawingManager 函数还接受一个回调函数,这次使用的名称 (AddDrawControlEvents) 而不一个匿名函数。函数 AddDrawControlEvents 的定义如下︰

function AddDrawControlEvents(manager)
{
  Microsoft.Maps.Events.addHandler(manager, 'drawingStarted',
    function(e) { WriteLn('Drawing has started'); });
  Microsoft.Maps.Events.addHandler(manager, 'drawingEnded',
    function(e) { WriteLn(‘Drawing has ended \n’); });
  drawingManager = manager;
}

此代码是短且相当细微。在单词,"后,在用户启动绘制形状使用 DrawingTools 控件 drawingStarted 事件自动触发,将使用一个名为 WriteLn 的程序定义函数的消息。" Events.addHandler 函数接受一个事件触发对象和一个回调函数。事件参数中,e,未在演示中使用,但它表示绘制的形状。

程序定义的函数 WriteLn 的定义如下︰

function WriteLn(txt)
{
  var existing = msgArea.value;
  msgArea.value = existing + txt + "\n";
}

MsgArea 对象是 HTML 文本区域标记在 Web 页的左侧。此处使用的方法获取现有内容和然后替换其与附加的文本相当不成熟,但可好,只要文本量没有得到巨大。

创建和显示自定义的图钉

当用户单击标有地方图钉按钮控件上时,会将控制传递给 Button1_Click 函数。该函数的结构为︰

function Button1_Click()
{
  var f = file1.files[0];
  var reader = new FileReader();
  reader.onload = function(e) {
    // Parse each line of result
    // Create pushpins
    // Add event handlers for pushpins
    // Display pushpins
  }
  reader.readAsText(f);
}

本地对象 f 包含关于 HTML file1 对象浏览控件所指向的物理文件的信息。由于 HTML 文件 API 允许选择多个文件,为文件 [0] 访问第一个文件。FileReader 对象将以异步方式加载的文件,以便网页上将保持响应状态。该文件读入内存时,将触发的 onload 事件。请注意,定义要执行的操作后读取的文件,然后调用 readAsText 函数来真的开始阅读该文件。

时,会执行的匿名函数 onload 事件触发开头︰

WriteLn("Source data = \n");
var lines = reader.result.split('\n');
for (var i = 0; i < lines.length; ++i) {
  var line = lines[i];
...

该文件的内容作为一个大型字符串含有嵌入 '\n' 字符存储在 reader.result 对象中。String.split 函数用于将每一行提取到一个数组。然后通过 length 属性中使用 for 循环中循环访问这些行。接下来:

var tokens = line.split(',');
WriteLn(tokens[0] + " " + tokens[1] + " " + tokens[2]);
var loc = new Microsoft.Maps.Location(tokens[0], tokens[1]);

回想一下,数据文件的行如下所示︰

45.46,-122.90,first location data

根据逗号分隔符拆分每个行和三个结果存储到名为令牌,因此纬度位于令牌 [0],经度位于标记为 [1] 的数组。读取文本文件时可能会出现大量错误,因为在生产系统中您将可能包装在 JavaScript try catch 块中创建位置对象的尝试。

接下来,为当前文本行的数据创建自定义的图钉︰

var ppOptions = { icon: CreateCvsDot(6, "orangered"),
  anchor: new Microsoft.Maps.Point(6,6), subTitle: tokens[2] };
var pp = new Microsoft.Maps.Pushpin(loc, ppOptions);
pushpins[i] = pp;

通过将信息传递给 PushpinOptions 对象的图标属性创建自定义的图钉。在这里,通过调用名为 CreateCvsDot 的程序定义的函数创建一个半径为 6 个像素的橙色红色的自定义颜色图标。我还设置当前图钉的副标题属性的文本遵循 lat lon 字段的数据文件。创建此标注后,则将它添加到全局图钉数组。

匿名函数代码完成︰

...
  Microsoft.Maps.Events.addHandler(pushpins[i], 'mouseover', ShowInfobox);
  Microsoft.Maps.Events.addHandler(pushpins[i], 'mouseout', HideInfobox);
}
ppLayer.add(pushpins);
map.layers.insert(ppLayer);
WriteLn("");

每个图钉具有使用程序定义的函数 ShowInfobox 和 HideInfobox 修改其鼠标悬停和 mouseout 事件。在创建所有图钉之后,保存这些数组将添加到图钉层,然后插入到映射,从而显示图钉。

函数 CreateCvsDot ("create HTML canvas 圆点") 的定义如下︰

function CreateCvsDot(radius, clr)  {
  var c = document.createElement('canvas');
  c.width = 2 * radius; c.height = 2 * radius;
  var ctx = c.getContext("2d");
  ctx.beginPath();
  ctx.arc(radius, radius, radius, 0, 2 * Math.PI);
  ctx.fillStyle = clr; ctx.fill();
  return(c.toDataURL());
}

该函数接受一个半径和一种颜色,并返回 HTML5 画布对象。有四种方法来创建自定义的图钉图标。您可以使用静态图像如.png 文件;可以使用静态图像使用 Base64 格式; 编码您可以创建动态的 HTML canvas 对象;或者,您可以创建动态可缩放的向量图形 (SVG) 对象。

若要动态创建图钉图标的能力赋予了很大的灵活性。例如,您可以创建不同的颜色和大小图标,具体取决于您的映射,区域中的图钉的密度或具体取决于地图的缩放级别。

事件处理程序函数 ShowInfobox 的定义如下︰

function ShowInfobox(e)
{
  var loc = e.target.getLocation();
  WriteLn('\n mouseover at ' + loc);
  infobox.setLocation(loc);
  infobox.setOptions( { visible: true, title: e.target.getSubTitle(),
    description: LatLonStr(loc) });
}

当用户将鼠标光标移到图钉时,图钉的鼠标悬停事件激发一次,控制将转移给 ShowInfobox该函数获取事件/图钉的位置,并使用它来放置图钉。请记住每个图钉的副标题属性包含文本,如"第一个数据位置"。 此文本将用作 Infobox 标题。

Infobox 的 description 属性设置为图钉,格式设置为使用程序定义的 helper 函数 LatLonStr 的两个小数位的位置︰

function LatLonStr(loc)
{
  var s = "(" + Number(loc.latitude).toFixed(2) + ", " +
    Number(loc.longitude).toFixed(2) + ")";
  return s;
}

HideInfobox 函数是︰

function HideInfobox(e)
{
  WriteLn(' mouseout at ' + e.target.getLocation());
  infobox.setOptions({ visible: false });
}

当用户移动鼠标光标离开图钉时,图钉的 mouseout 事件将激发并控制将转移给 HideInfobox。Visible 属性设置为 false,因此 Infobox 看不到但仍保留在该映射。

检索交互式形状

当用户单击标有绘制形状信息按钮控件上时,则将控制转移到其中 Button2_Click 函数。该函数的定义如下︰

function Button2_Click()
{
  drawnShapes = drawingManager.getPrimitives();
  var numShapes = drawnShapes.length;
  var mostRecent = drawnShapes[numShapes-1];  // Polygon
  var vertices = mostRecent.getLocations();
  WriteLn("There are " + numShapes + " drawn shapes");
  WriteLn("Vertices of most recent drawn shape: ");
  for (var i = 0; i < vertices.length; ++i) {
    WriteLn(LatLonStr(vertices[i]));
  }
}

DrawingTools 控件已放在地图上时创建全局 drawingManager 对象。它用于提取数组,其中包含所有绘图控件绘制的形状。所绘制的最后一个形状将数组中的最后一项。该代码假定绘制的形状类型的多边形,但 DrawingTool 控件可以创建不同类型的对象。您可以检查具有类似的代码的形状类型︰

var isPoly = mostRecent instanceof Microsoft.Maps.Polygon;

该函数可以通过提取使用 getLocations 函数的最后一个绘制形状的顶点来完成并循环访问的顶点来显示它们。

热度地图演示

当我使用地域-应用程序时,我想进行分类根据与其我正在处理的数据点数目。使用大量的位置非常具有挑战性。Bing 映射 8 库都有两种非常好的方法,可以使用大量的位置 — 群集图钉和热图。看一看在演示热图 图 3

热度地图演示
图 3 热度地图演示

有几种热图,但一种常见类型显示组合的数据点使用颜色渐变其中不同颜色表示不同的数据密度。演示 Web 应用程序初次加载地图的中心定位在 (37.50、-118.00),并将默认的大型紫色图钉放在中心。

首先,我单击了 HTML5 文件浏览按钮,并指向名为 NV_Cities.txt 包含城市数据的本地文件。接下来,我单击第一个按钮控件,也不能加载内华达状态中显示的市/县密度热度地图上。然后我清除了该热图使用第二个按钮控件。

接下来,我再次单击浏览按钮控件上,指向名为 CA_Cities.txt 的制表符分隔的文本文件。该数据文件包含在加利福尼亚州和其对应的纬度和经度信息 1,522 城市的列表。然后我单击显示热图按钮控件,它读取该文本文件,将解析出 lat lon 数据并且将该数据存储到一个数组。Lat lon 数据然后显示为热度地图,生成一个城市密度的可视化对象。

热度地图演示应用程序的结构就几乎完全像图钉和多边形演示的结构。对象的全局脚本作用域包括︰

var map = null;
var ppLayer = null;
var hmLayer = null;
var reader = null;   // FileReader object
var locs = [];
var cGrad = { '0.0': 'black', '0.2': 'purple', '0.4': 'blue', '0.6': 'green', 
  '0.8': 'yellow', '0.9': 'orange', '1.0': 'red' };
var hmOptions = { intensity: 0.65, radius: 7, colorGradient: cGrad };

HmLayer 对象是用于热图的图层。Locs 数组保存定义热图的位置对象。CGrad 对象定义热度地图选项的自定义颜色渐变。HmOptions 定义热图的选项。使用自定义的 HeatMapOptions 对象是可选的但在大多数情况下您将想要使用的选项来控制热图的外观。

下面是函数读取并分析源数据文件的 Button1_Click 中的代码︰

var lines = reader.result.split('\n');
for (var i = 0; i < lines.length; ++i) {  // Each line
  var line = lines[i];
  var tokens = line.split('\t');  // Split on tabs
  var loc = new Microsoft.Maps.Location(tokens[12], tokens[13]);
  locs[i] = loc;
}

源数据文件如下所示︰

CA  602000  2409704  Anaheim city    ( . . )  33.855497  -117.760071
CA  602028  2628706  Anchor Bay CDP  ( . . )  38.812653  -123.570267
...

每一行都具有 14 制表符分隔的值。第一个值是州的缩写。接下来两个字段是 Id。第四个字段是可以是一个城市、 镇或人口普查指定位置 (CDP) 的位置名称。然后就是八个字段包含如美国人口普查人口数和上关于领土区域的信息。最后两个字段是纬度和经度。我将数据从美国获取。美国人口普查网站,网址 bit.ly/29SETIU

创建并显示热图的代码是︰

Microsoft.Maps.loadModule('Microsoft.Maps.HeatMap', function() {
  hmLayer = new Microsoft.Maps.HeatMapLayer(locs, hmOptions);
  map.layers.insert(hmLayer);
});

HmLayer 创建层使用全局位置对象和包含自定义颜色渐变的 hmOptions 对象的数组。非常好!

Button2_Click 函数的代码将删除当前的热度地图内容︰

function Button2_Click()
{
  WriteLn('Clearing heat map' + "\n");
  hmLayer.clear();
  reader = null;
  locs = [];
}

此代码演示如何使用对对象进行分层的优点之一。而无需遍历 Map.entities 集合中的每个对象,您可以直接访问特定层中的对象。

聚类分析的图钉

在 Bing Maps 8 中我最喜爱的新功能之一是聚类分析的图钉。其思路很好地直观地解释。在 图 4, ,名为 ClusteredPushpinsDemo.html 在 Web 页面加载具有初始缩放比例为 10,居中 Portland,俄勒冈附近的映射当我单击标记为生成的 Pin 的按钮控件上时,该应用程序会使用在 Maps.TestDataGenerator getLocations 函数来创建 6000 的任意位置。然后应用程序代码会创建群集的图钉并显示它们。红色圆圈指示在关联的地图区域中,有 100 或更多的图钉和蓝色图钉表示 10 到 99 个图钉。

与聚类分析的图钉缩放级别 10
图 4 图钉群集与缩放级别 10

接下来,我放大三种级别。群集会自动在每个缩放更改时发生。在缩放级别 13 (请参阅 图 5) 各个图钉变为显示为红色的小圆点,并且绿色圆圈表示在该位置有两个到 9 个图钉。

与聚类分析的图钉缩放级别 13
图 5 图钉群集与缩放级别 13

热图以及图钉聚类分析,可以管理大量的位置项。但使用图钉群集允许用户访问各个项。

总结

此处介绍的演示 Web 应用程序应为您提供新的大型映射 8 库的是一个好主意。有许多其他新功能,我刚才没有讲,包括 Infobox 自定义、 图块层、 地域搜索和空间数学函数。如果您想要了解有关 Bing 地图 8 的详细信息,建议转到交互式 SDK 网站,网址 binged.it/29SFytX。它提供了大约 137 非常短,但阐释 Bing Maps 8 的许多主要功能的网页来完成。您还会发现,在正式文档 aka.ms/BingMapsV8Docs 非常编写得很好,并且非常有用。

我使用了两个主要替代项 Bing 地图 8 库、 Google 地图库中和开放源代码 Leaflet.js 库。所有三个库是太棒了,但我非常喜欢 Bing Maps 8。一些技术只是具有"右感觉"它们,以及对我来说,至少,Bing Maps 8 现在是我首选的地域应用程序库。


Dr.James McCaffrey 供职于华盛顿地区雷蒙德市沃什湾的 Microsoft Research。他参与过多个 Microsoft 产品的工作,包括 Internet Explorer 和 Bing。他的联系方式 jammc@microsoft.com。

衷心感谢以下 Microsoft 技术专家对本文的审阅: Ricky Brundritt (Bing Maps) 和 John Krumm (Microsoft research 开发)