内容


用开源软件绘制建筑物内的位置、人员和关系地图

整合建筑物内部的公司名录和地图来创建人员、会议场所和其他资产的专用地图

Comments

地理定位领域中的巨头都拥有各自的地图绘制工具,这些工具几乎将全球范围内的大型建筑物都收录其中。Google、Yahoo! 和 Microsoft® 全都有地图绘制工具,使用这些工具可以灵活地提供土地、边界、高速公路和建筑物的测绘数据。本文讨论的重点是精确定位建筑物内的房间、人员和其他可跟踪数据。我们将使用 The Gimp 图像映射器插件定义可跟踪区域周围的坐标。并使用简单的文本匹配和 ImageMagick 注释工具创建建筑物内部的地图,从而显示关于建筑物内的所容之物及关系的有用信息。

需求

2000 年后制造的所有 PC 应当能够提供足够的能力编译和运行本文中的代码。如果建筑物设计图非常大或者需要映射非常大量的数据点,则有可能需要使用最新的多核处理器和几个 GB 的内存。一般情况下,阅读本文的开发人员所使用的计算机应该提供足够的 CPU 周期和内存,以便快速地映射典型的办公环境。

ImageMagick 工具套件、Perl 和 The Gimp 照片图像处理包全都是必备工具。前述工具均可用于 Windows®、Mac OS X 和包括 Linux® 在内的各种风格的 UNIX®(请参阅 参考资料)。您还需要一个简单快速的图像查看器,现在的桌面环境通常都附带这样的图像查看器。对于 Linux 用户,建议使用 Tom Gilbert 编写的 feh。不过,使用任何图像查看器都没有问题。

示例代码是针对 Linux 环境编写的。但是,经过微小的调整后,它将可以在 Mac OS X 和 Windows 上运行。这将留给读者作为练习。

建筑物地图图像采集和定义坐标

查找建筑物图像

创建建筑物内部结构地图的第一步是定义内部结构的坐标。完成此操作的方法很简单,那就是使用建筑物自身的设计图图像。如果找不到当地测绘工作组提供的建筑物 CAD 图像,那么可以拍摄一张建筑物入口附近贴出的建筑物平面示意图的数码图像。如果无法获得预渲染的建筑物地图,您也可以手工绘制示意图并且使用该示意图作为坐标系统的基础。本文中的示例代码 含有一个绘制好的建筑物地图,该地图为一个易于访问的 CAD 文件,因此我把它装载到一个免费的 CAD 查看器程序中,并使用捕捉屏幕功能获取了建筑物的设计图。

用 The Gimp 定义区域

定义二维图像中的点或有界图形的一种最简单方法是使用 The Gimp 的 ImageMap 插件。在 The Gimp 中打开设计图,并在菜单栏中选择 Filters > Web > ImageMap 选项。使用 ImageMap 工具,将标识符分配给图像中的各个像素相当简单,只需在相应的区域中指定矩形并在弹出的输入框中输入一个惟一的字符串。图 1 显示了正在运行的 ImageMap 插件工具。注意如何在 URL 字段中用您选择的名称创建正方形、多边形和圆形。使用 ImageMap 插件可以快速地输入像素或像素区域数据。要定义图形,只需在图像上双击鼠标左键,并输入标识文本,然后按下 Enter 键即可。使用这一技巧可以快速创建建筑物设计图的坐标地图。

图 1. 建筑物地图设计图
建筑物地图设计图
建筑物地图设计图

提取坐标和标识符

在 The Gimp 的 ImageMap 插件窗口中保存已创建的图像地图后,将会生成一个含有以下内容的文件:

清单 1. 图像地图文件
<img src="buildingMap1.png" width="570" height="666" border="0" usemap="#map" />

<map name="map">
<!-- #$-:Image Map file created by GIMP Imagemap Plugin -->
<!-- #$-:GIMP Imagemap Plugin by Maurits Rijk -->
<!-- #$-:Please do not edit lines starting with "#$" -->
<!-- #$VERSION:2.0 -->
<!-- #$AUTHOR:Unknown -->
<area shape="rect" coords="506,596,516,606" href="0a" />
<area shape="rect" coords="133,573,143,583" href="1a" />
<area shape="rect" coords="82,203,92,213" href="2a" />
<area shape="rect" coords="490,116,500,126" href="3a" />
<area shape="rect" coords="68,45,78,55" href="conference_room0" />
<area shape="rect" coords="188,131,198,141" href="conference_room1" />
<area shape="rect" coords="420,16,430,26" href="4b" />
...
</map>

为简单起见,我们将使用以下这条简单的语句只提取相关的坐标和标识符内容。

grep oo map |perl -lane 's/(coords|href|=|")//g;@F=split;print"@F[2,3]"'>coords

这条命令将会把默认图像地图文件更改为更易于使用的格式,并将输出重定向到坐标文件。清单 2 显示了示例坐标文件。

清单 2. 示例坐标文件
506,596,516,606 0a
133,573,143,583 1a
82,203,92,213 2a
490,116,500,126 3a
68,45,78,55 conference_room0
188,131,198,141 conference_room1
420,16,430,26 4b
...

建筑物中的位置已经定义完成,下一步需要构建一些数据用于指定各位置的内容。在我们的企业中,这意味着查看企业名录并查询特定建筑物中固定位置内的所有员工。其他区域的位置占用数据可以通过会议室预订系统以及场所规划和紧急情况规划数据库来采集。清单 3 中的示例数据文件含有各员工的姓名和他们在建筑物中指定的位置。

清单 3. 示例 nmLst 名称列表文件
Franco 1a
Cliff 0a
Larry conference_room0
Melanie 2a
Michael 4b
Paul 7c.1
Chris conference_room1
Jeffrey 5b
Lisa 3a
Dave 7c.2
...

注意,这是为了方便开发人员使用的简化示例。您可以在名称列表文件中指定任意数目的标识符。还可以在同一个办公区内定义多个人员,以及按职位、在公司供职的年份数等条件进行搜索。现在我们有了坐标/办公室文件和属性/办公室文件。让我们通过一些图形标识符把两个文件联合在一起,从而开始生成我们的图像。

对于本示例,姓名中有 “el” 的所有员工都将被绘制为正方形,姓名中有 “is” 的所有员工都将被绘制为圆形。使用如下所示的命令来根据姓名属性进行简单查找。

perl -ane 'if(/el/){print "rectangle " . `grep " $F[1]" coords`}' nmLst >  dots
perl -ane 'if(/is/){print "circle " . `grep " $F[1]" coords`}'    nmLst >> dots

dots 文件中存储的输出将类似于清单 4 中的内容。虽然我们将使用一条简单语句和文本文件通过属性文件生成坐标,但是其通用性适用于分配和存储坐标信息的任何方法。例如,您可以将姓名和资产序号存储于 DB2® 数据库中,并为独立表中的资产分配坐标。选择两张表组合在一起后的内容,然后可以生成如下所示的图形和坐标文件。

清单 4. 示例点图形和坐标文件
rectangle 82,203,92,213 2a
rectangle 490,116,500,126 4b
circle 188,131,198,141 conference_room1
circle 420,16,430,26 3a

创建建筑物内部地图图像

虽然 dots 文件将提供基本的图形和坐标信息,但是我们仍然需要使用 ImageMagick 在建筑物设计图图像上绘制标识符。在我们的第一个示例中,renderBasic.pl 将在位于指定坐标的图像上绘制阿尔法混合 (alpha-blended) 的红色矩形和绿色圆形。用 cat dots | perl renderBasic.pl buildingMap1.png output.png 命令运行程序。图 2 显示了 renderBasic.pl 程序的示例输出。

图 2. 拥有绘制位置的示例建筑物
拥有绘制位置的示例建筑物
拥有绘制位置的示例建筑物

在继续说明 renderBasic.pl 程序并进一步举例之前,必须要说明一下此实现所采用的渲染方法。对于 gd 包,C 和 Perl API 都有一些限制。无论选定哪些选项或指定哪些参数,绘制阿尔法混合的圆形都显得不太可能。消除此限制最简单的方法就是在命令行中使用 ImageMagick 的 convert 命令绘制所有地理图元。renderBasic.pl 程序只是构建需要执行的一长串 ImageMagick convert 命令,并批量运行命令以生成所需输出。

renderBasic.pl 程序

构成 renderBasic.pl 程序的 Perl 命令如下所示。第一项任务是检查用法是否正确,接着检查程序中所使用变量的定义。建立一个 while 循环从 stdin 中读取数据,这样可以将 dots 文件中的各项内容提取出来。对于本示例,只有 dots 文件中的第一组坐标对将用于构建各种绘制命令。例如,绘制圆形时,在中心点周围创建半径逐渐减少的阿尔法混合圆形可以获得优美的渐变效果。在创建了阿尔法混合绘制命令后,检查命令缓冲是否接近饱和,如果是则运行这一部分命令。此外,这种构建大型转换语法绘制命令的迭代方法是为了避开 GD C 和 Perl API 不能绘制阿尔法混合圆形的限制(至少在撰写本文时是如此)。

清单 5. renderBasic.pl 的第 1 部分
#!/usr/bin/perl -w
# renderBasic.pl - build ImageMagick draw commands for building interiors
use strict;
die "usage: cat dots_file | renderBasic.pl input output" unless @ARGV==2;
my $lineCount = 1;    # line count for ImageMagick cmd
my ($inFile, $outFile) = @ARGV; # input, output files
my $cmd = qq( convert );

while(<STDIN>)
{
  my($type, $loc, $key) = split;
  my( $x, $y ) = split ",", $loc;
  my $count = 1;

  # building the ImageMagick draw commands
  while( $count < 10 )
  {
    my $alpha = 255 - (20 * $count);  # decrease the alpha blending by 20 each pass
    if( $type =~ /circle/ )
    {
      my $stopX = $x + (10 - $count);
      my $stopY = $y + (10 - $count);
$cmd .= qq( -fill "rgba(100,200,70,$alpha)" -draw 'circle $x,$y, $stopX,$stopY'  \\\n);
    }else{
      my $tempX = ($x - 10) + $count;
      my $tempY = ($y - 10) + $count;
      my $stopX = ($x + 20) - $count;
      my $stopY = ($y + 20) - $count;
$cmd .= qq( -fill "rgba(200,100,50,$alpha)" 
-draw 'rectangle $tempX,$tempY, $stopX,$stopY' \\\n);
    }
    $count++;
  }#while each 10 area

  # run the command in pieces 
  if( $lineCount % 50 == 0 )
  {
    $cmd .= qq( $inFile $outFile );
    $cmd = `$cmd`;
    $inFile = "$outFile";
    $cmd = qq( convert );
  }#if command big enough to be executed

  $lineCount++;

}#while stdin

$cmd .= qq( $inFile $outFile );
$cmd = `$cmd`;

其他示例

来访者经常会询问会议室的位置,从而获知最近的停车位置。为了避免同事把车误停在建筑的较远一侧并走很远,可以考虑使用以下命令:cat dots | perl adjust_renderBasic.pl withParking_buildingMap1.png output.png。在本例中,我再次使用了 The Gimp 通过在设施的高空图上覆盖以前的示例设计图来创建图像。图 3 显示了这样做可能会看到的示例结果。由于建筑物内各个房间的位置已经定义好了,因此可以对 adjust_renderBasic.pl 程序进行简单的修改,使它用红色显示经理的位置并用蓝色显示程序员的位置。清单 6 显示了对 adjust_renderBasic.pl 中图形布局坐标的修改:

清单 6. adjust_renderBasic.pl 修改
  my($type, $loc, $key) = split;
  my( $x, $y ) = split ",", $loc;
  my $count = 1;
  $x += 85; #shift right 85
  $y += 90; #shift down 90
图 3. 拥有绘制位置和高空图的示例建筑物
拥有绘制位置和高空图的示例建筑物
拥有绘制位置和高空图的示例建筑物

结束语

使用这些技巧,您将能够利用 ImageMagick 的强大功能构建建筑物的内部地图。在我们的企业中,提早为商务旅行同事提供会议室的位置可以提高效率并减少争端。场所规划人员和资源经理必将从自定义内部绘制工具中获益,因为这些工具可以帮助他们形象化地了解建筑物的使用情况,而无需购买昂贵的第三方软件。


下载资源


相关主题

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文
  • 了解关于 The Gimp 图像处理软件的更多信息并下载该工具。适用于 Windows、Mac OS X 和多种风格的 UNIX 的 The Gimp 已提供 下载
  • ImageMagick 是用于创建、编辑和排列位图图像的软件套件。适用于 Windows、Mac OS X 和多种风格的 UNIX 的 ImageMagick 已提供 下载
  • 如果系统还未安装 Perl,请从 Perl.org 站点下载。此套件还包含关于 Perl 的丰富知识。适用于 Windows、Mac OS X 和多种类型的 UNIX 的 Perl 已提供 下载
  • feh 是一个适用于 Linux 的快速轻量级图像查看器。
  • 收听针对软件开发人员的有趣访谈和讨论,一定要访问 developerWorks podcast
  • 访问 developerWorks 开放源码专区,获得丰富的 how-to 信息、工具和项目更新,帮助您用开放源码技术进行开发,并与 IBM 产品结合使用。
  • 下载 IBM 产品评估版本,并开始使用 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
  • 使用 IBM 试用软件 改进您的下一个开发项目,这些软件可以通过下载或从 DVD 中获得。

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source
ArticleID=257737
ArticleTitle=用开源软件绘制建筑物内的位置、人员和关系地图
publish-date=09242007