65.9K
CodeProject 正在变化。 阅读更多。
Home

D & B 绿色企业查找器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2013年7月10日

CPOL

13分钟阅读

viewsIcon

26486

downloadIcon

325

面向商务用户、消费者和销售/营销专业人士的移动、地理中心应用

 

介绍  

绿色技术是一个很棒的想法,但除非有很多人或企业在使用它,否则它不会产生多大影响。它也倾向于非常以地点为中心,因为许多绿色技术依赖于当地地理和气候的特征。

这个项目,也称为*绿色商务查找器*,将允许用户搜索针对绿色企业、资源、材料和地理信息的数据库,以支持他们的绿色倡议。它将为用户提供一种方式来使用邓白氏(Dun and Bradstreet)开发者沙箱数据集提供的过滤器和类别 - 例如人口统计、少数族裔拥有、女性拥有、退伍军人拥有等,并支持用户定义的过滤器和搜索条件,如回收和剩余材料。

拥有这种数据可以对销售人员以及希望寻找志同道合的企业进行交流、合作和 B2B(企业对企业)活动的商家都有价值。理想情况下,它将对移动和计算机平台都完全可用。

背景  

 

此应用的主要数据源将来自邓白氏(Dun & Bradstreet)开发者沙箱(可在Windows Azure Marketplace上免费预览)。完整数据集包含数百万条记录,但在此次竞赛中,他们提供了 10,000 条记录供我们构建应用。

对于这个原型,该应用程序将从头开始设计,以针对移动平台,尽管它也将适用于桌面 Web 客户端。技术/工具将包括 Microsoft Visual Studio Preview 2013、LightSwitch HTML5 Client、Jquery、JQuery Mobile、Promise、oData 和 PhoneGap(以提供对 GPS、摄像头、联系人等原生移动功能的访问)。

背景 

此应用的主要数据源将来自邓白氏(Dun & Bradstreet)的开发者沙箱(可在 Windows Azure Marketplace 上免费预览)。完整数据集包含数百万条记录,但在此次竞赛中,他们提供了 10000 条记录供开发者使用。

本文档记录了一个原型设计。从头开始,此应用程序将设计用于移动设备。技术围绕 Microsoft 技术栈,尽管设计将足够模块化,以便可以使用其他平台。

要在此项目中取得成功,开发者应精通(或愿意学习)LINQ、JQuery、Javascript、OData 协议、Excel、PhoneGap、Azure 和 LightSwitch(Visual Studio 2011 中的一种新项目类型)。 

ODATA 协议支持 Atom Feed 和 JSON,但我所处理的数据源是 Atom 格式的。

 

要求和项目信息 

大部分的规格和项目信息都使用思维导图进行记录。

在我最近的几个项目(包括个人和工作项目)中,我一直在尝试使用思维导图,并且取得了相当不错的效果。简而言之,思维导图提供了一种可视化的概念、设计和信息的方式,并将所有内容集中在一处——有点像增强版的书签。

在这个项目中,我花了几个小时进行在线研究,以查找答案、下载和产品信息。我的所有笔记都作为嵌入式资源包含在这个思维导图中,并且不会显示在截图上。

要创建此地图,我使用了 XMind 的免费版本,但市面上有很多选择。我喜欢 XMind,因为它开源且拥有相当活跃的终端用户社区。他们提供免费版本和几个付费升级版本。到目前为止,我一直对其非常满意。您在此处看到的是一张截图,但在竞赛结束后,我将把最终版本的源地图作为下载。此外,此思维导图已与 XMind 用户社区共享,并可在此处下载>> http://www.xmind.net/m/s9tE/ (我的用户名是 infomaven77)。

此原型的大部分功能面向企业主和销售/营销用户,但暴露的信息对希望光顾绿色认证企业的消费者也有价值。未来的增强功能还将面向消费者市场、众包,并与基于位置的社交应用集成。

技术栈   

Technology Stack 

 

 

 功能要求 

Functional Requirements 

 

非功能性要求 

 

 

 

代码、功能与挑战

现在是大家一直期待的部分……毕竟这是一个为“编码者”准备的网站。

此项目的完整源代码将从 github.com 提供下载,链接如下>>

https://github.com/infomaven/DNBGreenMash.git   

通过下载代码,您将获得以下功能

配置为使用三个不同数据源的 LightSwitch HTML5 Client - D&B OData、EDR Hazardous Waste OData Service(均来自 Windows Azure Marketplace)以及 Northwind OData Service。还有一个内部数据库用于存储本地使用的数据(应用程序数据)。这是 Visual Studio 自动创建的数据库

  1. 显示绿色认证企业的屏幕:已排序数据 
    • 显示当前选定联系人信息和绿色认证信息的屏幕 
  2. 在美国搜索绿色企业的屏幕:功能齐全 
  3. 径向搜索屏幕:未过滤数据。搜索尚未连接。 
  4. 显示少数族裔拥有的企业和退伍军人拥有的企业的屏幕:已排序数据
  5. 使用 Bing Custom Map 控件显示 Northwind 客户数据的屏幕:功能齐全
显示地图中选定项目的详细信息屏幕
6. 使用 Bing Custom Map 控件显示 D & B 绿色商务数据的屏幕:部分功能齐全       
  
 

解压到本地目录后,项目在 Visual Studio 中看起来是这样的>>

 

客户端屏幕之间的关系是分层的。在此项目中,名为 *BrowseGreenBiz* 的屏幕被编程为充当主页。它包含运行应用程序中所有其他屏幕的导航命令。


下面是托管应用程序中所有创建的屏幕的底层 html 客户端页面。但是,LightSwitch 项目还支持在(.SERVER 文件夹中)添加额外的服务器端页面和对象。 

  <!DOCTYPE HTML> 
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=10" />
    <meta name="HandheldFriendly" content="true" />
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <title>DNB_GreenBusinessFinder.HTMLClient</title>
    <script type="text/javascript">
        // Work around viewport sizing issue in IE 10 on Windows Phone 8
        if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
            document.writeln("<style>@-ms-viewport { width: auto!important; }</style>");
        }
    </script>
    <!-- Change light-theme-2.0.0.css and msls-light-2.0.0.css to dark-theme-2.0.0.css and msls-dark-2.0.0.css respectively to use the 
         dark theme.  Alternatively, you may replace light-theme-2.0.0.css with a custom jQuery Mobile theme. -->
    <link rel="stylesheet" type="text/css" href="Content/light-theme-2.0.0.css" />
    <link rel="stylesheet" type="text/css" href="Content/msls-light-2.0.0.css" />
    <link rel="stylesheet" type="text/css" href="Content/jquery.mobile.structure-1.3.1.min.css" />
    <link rel="stylesheet" type="text/css" href="Content/msls-2.0.0.min.css" />
    <!-- Default font, header, and icon styles can be overriden in user-customization.css -->
    <link rel="stylesheet" type="text/css" href="Content/user-customization.css"/>
</head>
<body>
    <div id="msls-id-app-loading" class="ui-body-a msls-layout-ignore">
        <div class="msls-app-loading-img"></div>
        <span class="ui-icon ui-icon-loading"></span>
        <div class="ui-bottom-load">
            <div>DNB_GreenBusinessFinder.HTMLClient</div>
        </div>
    </div>
    <script type="text/javascript" charset="utf8"
            src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
    <script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/globalize/0.1.1/globalize.min.js"></script>
    <script type="text/javascript" src="Scripts/winjs-1.0.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery.mobile-1.3.1.min.js"></script>
    <script type="text/javascript" src="Scripts/datajs-1.1.0.min.js"></script>
    <script type="text/javascript" src="Scripts/Generated/resources.js"></script>
    <script type="text/javascript" src="Scripts/msls-2.0.0.min.js"></script>
    <script type="text/javascript" src="Scripts/Generated/generatedAssets.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            msls._run()
            .then(null, function failure(error) {
                alert(error);
            });
        });
    </script>
    <script type="text/javascript" charset="utf-8" src="Scripts/lightswitch.bing-maps.js"></script></body>
</html> 


LightSwitch 的“陷阱”:以下是使用 LightSwitch HTML5 Client 时需要注意的一些事项。尽管 LightSwitch 是 Visual Studio 中的一个项目,但它有一些特性使其行为与典型项目不同。我没有使用过 Silverlight 客户端,因此无法评论这些情况是否适用于该场景。

1) 项目会在您的会话期间“自动保存”所有更改。如果您在处理项目时出错,您必须使用 CNTRL-Z 撤销每项更改。如果您添加了一个对象(屏幕、数据源等),则必须将其从项目中物理删除。

    • 注意:系统应该清理所有代码,但我发现它有时会忽略 webconfig 文件,尤其是在通过向导添加数据源时。在添加和删除 DnB OData Feed 2-3 次后,我发现 webconfig.xml 包含 3 个不同的条目,它们都指向同一个根 URL。这不好!如果您删除任何数据源,请务必在此处进行检查。 
<connectionStrings>
    <add name="_IntrinsicData" connectionString="Data Source=|SqlExpressInstanceName|;AttachDbFilename=|ApplicationDatabasePath|;Integrated Security=True;Connect Timeout=30;MultipleActiveResultSets=True" />
    <add name="0ef66677-8cb8-4b3a-8bf4-0bd4f76da97e" connectionString="Service Url=https://api.datamarket.azure.com/DNB/DeveloperSandbox/v1;Is Windows Authentication=False;User Name=USER_NAME;Password=PASSWORD;Allow Invalid Certificate=False" />
    <add name="dc8b80fd-13f9-4aed-a101-8a2bc0dc9238" connectionString="Service Url=https://api.datamarket.azure.com/EDR/EnvironmentalHazardRank/v1;Is Windows Authentication=False;User Name=USER_NAME;Password=PASSWORD;Allow Invalid Certificate=False" />
    <add name="8c8a7d53-8378-4979-ba1a-a409eea30067" connectionString="Service Url=http://services.odata.org/Northwind/Northwind.svc;Is Windows Authentication=False;Allow Invalid Certificate=False" />
  </connectionStrings> 
2) 当您使用 Visual Studio NuGet 插件向导更新包时,它有时会遗漏更新解决方案中已有的版本号。进行此类更新后,我发现 Scripts 文件夹中的一个 JS 文件仍然包含旧版本号。您可能需要手动更新这些。还要检查 default.htm 文件以确保版本号正确。同步不一致的一个迹象是,如果您收到如下所示的运行时错误消息>>

             
              

3) 与其 Silverlight 同类产品不同,LightSwitch 的 HTML5 Client 没有提供开箱即用的搜索屏幕。但是,如果数据源的元数据规则允许某个字段“可查询”,您可以修改客户端的浏览屏幕以使用数据绑定的文本框作为搜索参数,并在服务器上执行搜索。 

4) 我从中吸取了教训,LightSwitch 创建的数据实体与常规关系数据库表并不完全相同。我还没有弄清楚如何对此数据执行等同于“sql inner join”或“outer join”的操作。这限制了我在此示例项目中实现的一些功能,但该项目将为该领域的进一步研究提供一个良好的起点。 

             

5) LightSwitch “设计器”不是基于 GUI 的。这与“Visual”Studio 的概念背道而驰,但一旦您习惯了这个概念,它就能很好地工作。屏幕上的所有控件都以层次结构表示,有助于说明它们在用户界面中的外观。

其他挑战 

 
DnB 位置的映射: 此项目使用了 Bing Maps API,并由 LightSwitch 团队提供 JavaScript 包装器以及一个用 JQuery 编写的自定义控件。包装器在以地图格式基本显示位置列表方面效果很好,但在映射单个位置时我遇到了问题。在原型中,我实现了两个使用映射功能的屏幕。一个连接到 Northwind OData 服务,另一个连接到 DNB OData 集。对于 D & B 数据,我能够渲染地图但无法渲染位置点。

            自定义控件的示例包装函数>>

            (function ($) {
                var _credentialsKey = "Ao75sYhQSfLgssT0QkO9n22xt0lgxzntrZ1xpCwLOC-kGhI584OYED3viFXLIWgC";
                // load the directions module only once per session
                Microsoft.Maps.loadModule('Microsoft.Maps.Directions');
                $.widget("msls.lightswitchBingMapsControl", {
                    options: {
                        mapType: Microsoft.Maps.MapTypeId.road,
                        zoom: 3,
                        showDashboard: false
                    },
                    _create: function () {
                    },
                    _init: function () {
                        this.createMap();
                    },
                    destroy: function () {
                        this._destroyBingMapsControl();
                    },
                    createMap: function () {
                        this.htmlMapElement = this.element[0];
                        // create empty map
                        this.map = new Microsoft.Maps.Map(this.htmlMapElement,
                                            {
                                                credentials: _credentialsKey,
                                                mapTypeId: this.options.mapType,
                                                zoom: this.options.zoom,
                                                showDashboard: this.options.showDashboard
                                            });
                    },

            应用程序启动后,使用 JavaScript 回调异步将位置加载到 UI 中>> 

            myapp.Browse_nwCustomers.Customer_render = function (element, contentItem) {
                mapDiv = $('<div />').appendTo($(element));
                $(mapDiv).lightswitchBingMapsControl();
                var visualCollection = contentItem.value;
                if (visualCollection.isLoaded) {
                    showItems(current, step, contentItem.screen);
                } else {
                    visualCollection.addChangeListener("isLoaded", function () {
                        showItems(current, step, contentItem.screen);
                    });
                    visualCollection.load();
                }
            };
            function showItems(start, end, screen) {
                $(mapDiv).lightswitchBingMapsControl("resetMap");
                $.each(screen.Customers.data, function (i, customer) {
                    if (i >= start && i <= end) {
                        $(mapDiv).lightswitchBingMapsControl("addPinAsync", customer.Address,
                            customer.City, customer.Country, i + 1, function () {
                                screen.Customers.selectedItem = customer;
                                screen.showPopup("Customers_selectedItem");
                            });
                    }
                });
            };  

检测用户位置: 地理数据对于此应用程序的正常运行至关重要。由于 HTML5 无法访问移动设备的 GPS 功能,因此建议使用 Cordova/PhoneGap 和 Red Gate 的 Nomad 等工具来封装此功能。Windows 8 和 Windows Phone 8 用户在实现此功能时会更容易,因为 GPS 支持似乎已包含在操作系统中。Michael Washington 在他的网站上有一篇关于此主题的出色入门文章
http://lightswitchhelpwebsite.com

             

径向搜索:在给定半径内搜索绿色企业的实际数据问题比我预期的要容易。这可以使用经典的 CS 算法“范围搜索”来实现,并进行修改以适应圆形边界区域。我在 http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#GeoLocationDemo 找到了一篇有详细文档的 Java 解决方案。这篇文章特别好,因为作者解释了执行此计算的正确方法和错误方法。阅读完之后,我在 github 上找到了 Anthony Zigenbine 编写的 C# 移植版本,我将将其改编用于此应用程序。


            这个项目没有时间实现此功能,但我认为可以很容易地将其作为云服务整合。

              public GeoLocation[] BoundingCoordinates(double distance)
                    {
                        if (distance < 0d)
                            throw new Exception("Distance cannot be less than 0");
                        // angular distance in radians on a great circle
                        double radDist = distance / earthRadius;
                        double minLat = radLat - radDist;
                        double maxLat = radLat + radDist;
                        double minLon, maxLon;
                        if (minLat > MIN_LAT && maxLat < MAX_LAT)
                        {
                            double deltaLon = Math.Asin(Math.Sin(radDist) /
                                Math.Cos(radLat));
                            minLon = radLon - deltaLon;
                            if (minLon < MIN_LON) minLon += 2d * Math.PI;
                            maxLon = radLon + deltaLon;
                            if (maxLon > MAX_LON) maxLon -= 2d * Math.PI;
                        }
                        else
                        {
                            // a pole is within the distance
                            minLat = Math.Max(minLat, MIN_LAT);
                            maxLat = Math.Min(maxLat, MAX_LAT);
                            minLon = MIN_LON;
                            maxLon = MAX_LON;
                        }
                        return new GeoLocation[]
                        {
                            FromRadians(minLat, minLon),
                            FromRadians(maxLat, maxLon)
                        };
                    } 
 社交集成: 
我对在此应用程序中添加社交 API 非常感兴趣,但从未找到完全合适的。我考虑过的一些潜在候选者是 http://foursquare.com、http://www.openstreetmap.org/,或者 ESRI 在 github 上提供的一些 API - http://esri.github.io/。我相信这将是包含面向企业、政府和消费者的应用程序中的一个非常重要的元素。美国俄亥俄州哥伦布市通过创建一个“绿色地图”来描绘其都会区,并建立一个网站,让人们参与推广绿色技术和实践,从而朝着这个方向迈出了重要一步。网址>> http://www.columbusgreenspot.org/join/

不熟悉的技术在此项目中构成了一个持续的挑战。除了我的开发技能总体上有些过时外,为此项目选择的所有关键工具 - OData、Visual Studio Ultimate Preview、WCF Data Services 和 LightSwitch - 在过去 3-4 个月里都经历了一些破坏性更改,而且一切都还在不断变化。虽然能再次体验“尖端”技术令人兴奋,但要让一切正常工作却很困难,当我遇到困难时,我总是不确定是由于用户错误还是软件本身的真正问题。下面简要概述了我在使用这些工具时遇到的一些问题。我欢迎有过类似经历的读者的任何评论。

一般“陷阱”:  

            1) DnB 数据集 – 我们所有人都遇到了使用 Substring 查询的问题。在浏览器中使用时,此类查询会返回 http 错误 400,但相同的语法在 Northwind OData Service(可通过 odata.org 免费获得)上效果很好。例如,以下查询>> 

            http://services.odata.org/Northwind/Northwind.svc/Customers?$filter=substring(CompanyName, 1) eq 'lfreds Futterkiste'  

            工作正常,而这个>> 

            https://api.datamarket.azure.com/DNB/DeveloperSandbox/v1/LocationLatLong?$filter=substring(Company, 1) eq 'solu'   

             则不行。在 LightSwitch 中,当我尝试对 DnB 数据源实现搜索功能时,也出现了这个问题。似乎该数据的元数据定义不支持 Substring 搜索。我设置了一个 TODO 任务,以找到一种使用数据操作来完成此任务的替代方法。

            2) 在 Visual Studio 2013 Preview 中,“添加服务引用”的上下文菜单选项失败了。

             

            为了尝试解决此问题,我使用了命令行工具,并以管理员权限从命令行运行了以下工具来生成代理类,但从未将其作为简单的控制台应用程序成功运行。

            c:\windows\....\framework...\4.0xxxx\DataSvcutil.exe /uri:https://api.datamarket.azure.com/DNB/DeveloperSandbox/v1/ /out:<name>.cs 

 GitHub:这是我第一次使用 GitHub。我以前使用过 Visual Source Safe、SVN 和 Tortoise 源代码控制,但发现 github 有点令人困惑。我总觉得我遗漏了什么非常明显的东西。然而,它似乎是一个强大的工具,我希望在不久的将来更深入地研究它。如果有人有关于如何在 Windows 上使用 github 的好的入门教程的建议,我洗耳恭听。


时间管理一直是一个巨大的挑战。我处理任务的一种方式是尝试使用看板(Kanban)原理来管理我的工作。在下面的思维导图中,“任务”区域标记了项目中不同任务的应用的颜色代码。基本上,我对看板的理解是,您将每个任务分类为以下之一 { 准备就绪、进行中、已阻止、已完成 },并且您试图限制“进行中”组中的项目数量。还有更多内容,但这是我目前的收获。
如果您有关于使用看板的见解或成功案例,我非常想听听。

            使用看板进行任务管理 

             

             

脚注 

              

下面是我开始使用 LightSwitch 并且也启发我构建此应用程序的在线资源的链接列表。
结语   

在我开发这个项目的时候,我意识到这个应用程序的概念有潜力独立发展,变得比参赛作品大得多。我总觉得将来还会有其他迭代……这更多的是一个起点,而不是一个完整的应用程序。
  我希望“绿色商务查找器”能启发您思考如何利用新技术来改善我们世界的生活质量,并帮助人们建立联系。我也希望您觉得这篇文章有用。欢迎评论和反馈——我一直在努力改进。   
请收藏并在 2013 年 7 月底回来查看最终版本和代码示例。

  
历史 

            版本 0.1 - 2013/7/10 – 创建初始草稿以解释概念 

            版本 1.0 – 2013/7/25 – 添加项目信息

            版本 1.1 – 2013/7/28 – 添加资源和挑战以及初始代码示例

            版本 1.2 – 2013/7/31 – 添加最终代码示例 和图片集 



© . All rights reserved.