使用 Lotus Connections 和 Sametime 构建基于 GIS 的个人名片和即时消息应用

简介

Lotus® Connections 是一款面向业务的社会网络软件,Lotus Connections 2.5 提供了主页(HomePage)、个人档案(Profiles)、博客(Blogs)、维基(Wikis)等多种社区功能;

Lotus Sametime Standard 软件 IBM 公司提供的 UC² 平台,它提供了整合的企业即时消息传递、VoIP、视频聊天和 Web 会议功能。

这两个平台软件都为公司、社会的信息化发展中发挥重大作用,然而如何将他们以最简单、最直观的形式展现给最终用户,方便他们使用?

将他们集成到基于 GIS 的 Web 应用中会是一个很好的选择。通过使用这种 Web 应用,浏览者可以快速查找到 Connections 或 Sametime 中用户的地理位置,也可以定位到即将出行或感兴趣的某个地理区域后,浏览该区域的各个用户信息并与之交流。

本文章将从构建最基本的 GIS 应用开始,介绍在地图上增加自定义信息图层的方法,最后将 Louts Connections,Sametime 集成到电子地图中,构建基于 GIS 的个人名片和即时消息应用。

构建最简单的 GIS 应用

GIS (Geographic Information System),即地理信息系统,作为获取、存储、分析和管理地理空间数据的重要工具、技术和学科,在人们生产生活中发挥重大作用,市场上现在也有很多的 GIS 产品,比如谷歌的 Google Earth,各种在线数字地图等。

部分 GIS 厂商出于商业模式,提供了开放 API 供第三方开发人员使用,如谷歌地图 API,百度地图 API 等,开发人员可以使用这些 API 设计出满足自己需求的 GIS 应用。考虑到考虑到各厂商电子地图在国内的稳定性及是否提供开放 API,本文将选择使用百度地图 API 作为示例。

百度地图 API 是由百度公司提供的一套 JavaScript 应用程序接口,通过使用该 API,开发人员可以构建出丰富多彩的 GIS 应用。由百度地图 API 创建的最简单地图显示效果为:

图 1. 简单百度地图应用
图 1. 简单百度地图应用

下面介绍如何使用百度地图 API 创建最简单 GIS 应用:

  1. 注册百度地图 API 密钥
  2. 在网页中加载百度地图的 JavaScript
  3. 创建地图容器 HTML 节点 map_paint
  4. 创建地图设置对象,设置地图的中心经纬度坐标以及地图缩放级别
  5. 创建 map 对象,与 map_paint 进行绑定,并进行初始化
  6. 创建覆盖物对象
清单 1
 <html> 
  <head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
    <title>Baidu Map</title> 
 <script type="text/javascript" 
  src="http://api.map.baidu.com/api?key=mapkey&v=1.0"> 
 </script> 
 <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" 
  type="text/javascript"> 
 </script> 
 
 <script type="text/javascript"> 
  // 需要外部传入的参数,可在 initialize 函数中进行初始化
  // 地图中心的经纬度坐标
  var lat_center; 
  var lng_center; 
  
  // !!开发人员需要在此对全局变量进行初始化
  function initialize(){ 
  ……
  } 
  
  dojo.addOnLoad(function() { 
   initialize(); 
   // 设置地图中心坐标和缩放级别
   mapCenter = new BMap.Point(lng_center,lat_center); 
   var myOptions = { 
     zoomLevel: 16, 
     centerPoint: mapCenter, 
   }; 
   // 创建地图对象
   var map = new BMap.Map(document.getElementById("map_paint"), myOptions); 
   map.centerAndZoom(); 
   // 创建标注对象 marker 并添加到 map 
   var marker = new BMap.Marker(mapCenter); 
   map.addOverlay(marker); 
  }); 
  </script> 
 </head> 

 <body> 
  <div id="map_paint" style="width: 600px; height: 400px"></div> 
 </body> 
 </html>

mapkey为开发人员注册的百度地图 API 密钥。

需要说明的是:initialize 函数会对地图中心的经纬度坐标全局变量进行初始化,该初始化工作需要开发人员根据自身应用环境自己去实现,后面同样。

注册百度地图 API 密钥

在使用百度地图 API 之前,需要注册百度地图 API 密钥。该密钥申请网址为 http://openapi.baidu.com/map/signup.html。申请密钥需要填入开发人员网址,申请成功后,该网址将会和申请到的密钥绑定。在使用有百度地图的网页时,如果网页是通过文件方式运行或者以 http 形式同时主机域名为 localhost 的形式被访问,网页不会对密钥及开发人员申请的网址进行验证,其他情况下,网页加载地图前,网页会对密钥及网址进行验证,如果开发人员申请的域名与密钥不匹配,地图将会加载失败。

加载百度地图 Javascript

加载百度地图 API Javascript 时,需要使用申请的密钥:

清单 2
 <script type="text/javascript" 
 src="http://api.map.baidu.com/api?key=mapkey&v=1.0&services=true" > 
 </script>

其中 mapkey为开发人员申请的密钥。

创建地图容器节点

地图需要 HTML 元素作为容器,才能显示到页面上:

清单 3
 <div id="map_paint" style="width: 600px; height: 400px"></div>

地图设置

地图设置可以由一个 json 对象表示:

清单 4
 mapCenter = new Bmap.Point(lng,lat); 
在地图初始化之前,可以通过地图设置对象对地图进行设置:
 var myOptions = { 
 zoomLevel: 16, 
 centerPoint : mapCenter, 
 };

其中 zoomLevel 表示地图缩放级别, centerPoint 表示地理坐标点。

创建地图对象

清单 5
 var map = new BMap.Map(document.getElementById("map_paint"), myOptions);

第一个参数为需要绑定的地图容器节点,第二个参数为地图设置对象。

创建覆盖物对象

覆盖物指的是所有叠加或添加到地图上的内容,Bmap.Marker 是百度地图中最常用的覆盖物,该类对象可以标注地图上的点。地图对象通过 addOverlay 方法添加覆盖物对象:

清单 6
 var marker = new BMap.Marker(mapCenter); 
 map.addOverlay(marker);

增加用户图层

上节介绍了使用地图 API 创建地图区域,标注该区域内用户所在位置。然而要创建丰富多彩的 GIS 应用,单纯标注该域内各用户位置肯定是不够的,一般会需要在地图上增加用户图层。用户图层包含两个概念:根据用户信息中经纬度地理坐标定位到地图上某个点;显示该人员的相关信息或通过点击该层可以让浏览者与该人员进行聊天。

图 2. 增加用户图层
图 2. 增加用户图层

根据上述描述,用户信息应该包括用户地理经纬度坐标,显示的名称、CID(Lotus Connections 的用户标识),DN(Lotus Sametime 的用户标识)等信息。在本示例中,所有用户个人信息数据存放在用户信息数组全局变量中。

增加用户信息图层的基本步骤为:

  1. 遍历用户信息数组,获得各用户信息
  2. 根据各用户地理点坐标生成其标注类对象 marker
  3. 创建用户图层 layer
  4. 将 layer 加载到 marker 对象子节点下

需要说明的是,由于本节目的是介绍最终用户看到的效果和代码框架 ,对于第 3 个步骤,本节并没有真正根据 CID 或 DN 动态生成用户信息,真正的使用 Lotus Connections 和 Sametime 然后动态获得用户信息,动态创建用户图层的方法将会在下两节中进行介绍。

清单 7
  dojo.addOnLoad(function() { 
   initialize(); 
   // 创建 Map 
   mapCenter = new BMap.Point(lng,lat); 
   var myOptions = { 
     zoomLevel: 16, 
     centerPoint: mapCenter 
   }; 
   var map = new BMap.Map(document.getElementById("map_canvas"), myOptions); 
   map.centerAndZoom(); 
   // 遍历用户由用户信息创建标注对象 marker、用户信息图层 layer,并将 layer 加载到 marker 子节点下
   if (userInfoArray) { 
    for (i in userInfoArray) { 
     var lat = userInfoArray[i].lat; 
     var lng = userInfoArray[i].lng; 
     var display = userInfoArray[i].display; 
     var DN = userInfoArray[i].DN; 
     var CID = userInfoArray[i].CID; 
     // 创建标注对象 marker,并添加到 map 
     var marker = new BMap.Marker(new BMap.Point(lng,lat)); 
     map.addOverlay(marker); 
     // 根据 DN 和 CID 创建用户图层,该图层包括用户 Sametime 联系超链接和用户信息卡片
     var layer = createLayer(display,DN,CID); 
     // 查找 marker 节点,并将 container 加载到 Marker 的子节点下
     var markerArray = dojo.query(".BMap_Marker"); 
     markerArray[i].appendChild(layer); 
    } 
   } 
  }); 
  
  // 创建用户图层
  function createLayer(display,DN,CID){ 
   var layer = document.createElement("div"); 
   layer.id = "container_" + DN; 
   //container 在火狐浏览器下显示效果为红色半透明
   layer.setAttribute("style", 
    "position:relative;left:10px;top:10px;width:100px; height:20px;
    padding:1 1 1 1;background:red;border:solid orange;opacity:0.75;cursor:pointer;"); 
   // 为 container 添加 Sametime 联系功能
   layer.innerHTML = display; 
   // 创建自定义的 infoCard( 用户信息卡片 ) 
   var infoCard = createInfoCard(CID); 
   // 将 infoCard 加载到 layer 节点下,在鼠标在 layer 移入移出时,infoCard 自动隐藏或显示
   layer.appendChild(infoCard); 
   layer.onmouseover = function(){infoCard.setAttribute('style','display:block;')}; 
   layer.onmouseout = function(){infoCard.setAttribute('style','display:none')}; 

   return layer; 
  } 

  // 创建自定义的用户信息卡片
  function createInfoCard(CID){ 
   var infoCard = document.createElement("div"); 
   infoCard.id = "card_" + CID; 
   infoCard.setAttribute("style","display:none"); 
   renderCard(infoCard,CID); 
   return infoCard; 
  } 
  
  // 将用户 email,照片链接应用到用户信息卡片
  function renderCard(infoCard,CID){ 
   // 设置 infoCard 的 email,照片链接等
   htmlNode = 
   "<div style='border:solid blue;font-size:12px;BACKGROUND:green;opacity:0.99;'>" + 
    "<div style='border:solid blue;border-width:0px 0px 1px 0px'>" + 
     email+ 
    "</div>" + 
    "<img width=50px height=50px src='" + 
     photourl+ 
    "'>" + 
    "</div>"; 
   infoCard.innerHTML = htmlNode; 
  }

其中 email为用户邮箱,photourl为用户照片链接的 URL。

遍历用户信息数组

本示例的用户信息数组是 json 数组,每条 json 数据记录了一个用户信息,包括以下属性:lng,lat,display、CID,DN,分别对应用户的地理经度坐标,纬度坐标,图层上显示的名称,CID 和 DN 信息。该数组需要开发人员根据实际情况在 initialize 函数中初始化该数组。

创建用户图层

如图 2 所示,本文的信息图层显示效果为:地图会显示其地理区域内所有人员的名称,鼠标移动到人员名称上时,页面会显示该用户的 email 和照片信息。

上述功能实现思路为:首先使用 document.createElement("div") 创建用户图层节点 layer,设置 layer 的各个属性,然后将显示用户 email 和照片信息的 DOM 节点(infoCard)添加到该节点下;infoCard 默认为隐藏,当鼠标在用户图层的移入 / 移出时显示 / 隐藏。

加载用户图层

由于百度地图 API 并没有提供其标注对象 marker 向 DOM 节点转换的方式,因此无法直接获得标注对象对应的 DOM 节点。示例采取使用 Dojo 提供的查找 CSS 类的方式先找到所有标注对象对应的 DOM 节点数组,从该数组中找到所需的 DOM 节点 marker 的方法,最后将已创建的用户图层 DOM 节点节点加入到对应 marker 中。

加入 Lotus Connection

上节介绍的用户的 email,照片链接信息是由静态的 JavaScript 代码提供的,在现实的应用中,这类数据可以通过通过现有系统提供的 API 获得。针对 Louts Connections,本节将使用 Lotus Connections Profiles API,获得用户档案信息的 Atom 文档,使用 Dojo 解析该文档获得用户的 email 和照片链接数据,并将数据集成到上节 GIS 应用的信息图层中。

Lotus® Connections 是一款面向业务的社会网络软件,能够使得客户团队更加具有创造性,帮助客户利用动态的协作者、合作伙伴和用户网络具有更为高效的执行力。Lotus Connections 2.5 通过将主页(HomePage)、个人档案(Profiles)、社区(Communities)、活动(Activities)、文件(Files)、博客(Blogs)、维基(Wikis)和社会书签(Dogear)八个组件整合起来交付了此功能,并提供了增强社区体验的新特性。

Profiles 是 Louts Connections 中客户组织中人员目录的功能部件,提供了包括个人照片、报告结构、姓名、语言、所在时区和有关个人专业知识和兴趣领域的信息。Profiles 提供了两种类型 API:预订和发布,其中预订 API 实现了 Atom Syndication Format (Atom 1.0) 规范来提供 Atom 订阅源,客户的开发人员可以在自身应用程序中使用此订阅源来搜索和检索由客户组织内人员创建的任何个人档案中的信息。

Atom Syndication Format 是用于网站消息来源,基于 XML 的文档格式。它的使用,为 Web 开发提供了开放的,基于 Web 标准的轻量级编程接口。Dojo 是一个 JavaScript 实现的开源 DHTML 工具包,利用它提供的后端服务通信、统一数据访问接口、页面布局 Widget 库等组件,可以简化开发人员的开发流程,提升 Web 应用程序的可用性和交互能力。本节将使用 Dojo 提供的 Atom 模型对用户档案信息的 Atom 文档进行解析。

清单 8
  // 将用户 email,照片链接应用到用户信息卡片
  // 因为获得用户个人信息是异步的,因此不能以返回值形式返回
  function renderCard(infoCard,CID){ 
   var xhrArgs = { 
 url: "http://localhost/profiles/atom/search.do?userid=" + CID, 
    handleAs: "xml"
   }; 
   // 返回延迟对象
   var deferred = dojo.xhrGet(xhrArgs); 
   // 回调函数
   deferred.addCallback(function(xmlDoc, ioargs) { 
    var feedRoot = xmlDoc.getElementsByTagName("feed"); 
    var feed = new dojox.atom.io.model.Feed(); 
    feed.buildFromDom(xmlDoc.documentElement); 
    var entry = feed.getFirstEntry(); 
    // 获得用户的 email,照片链接等
    var name = entry.contributors[0].name; 
    var email = entry.contributors[0].email; 
    var photourl = entry.links[2].href; 
    // 设置 infoCard 的 email,照片链接等
    htmlNode = 
     "<div style='border:solid blue;font-size:12px;BACKGROUND:green;opacity:0.99;'>" + 
      "<div style='border:solid blue;border-width:0px 0px 1px 0px'>" + 
       email + 
       "</div>" + 
       "<img width=50px height=50px src='" + 
       photourl + 
       "'>" + 
     "</div>"; 
     infoCard.innerHTML = htmlNode; 
   }); 
   // 回调失败
   deferred.addErrback(function(error) { 
    console.debug("Something Wrong!"); 
    console.debug(e); 
   }); 
  }

通过 Profile API 获得个人信息文档 Atom feed

Profile 提供查询个人信息文档的一种 API 为“/atom/search.do”,通过使用该 API,服务器端将返回满足查询条件的 Atom 规范文档,浏览器端采用 Dojo 提供的 Atom 模型对该文档进行解析。Profile API 可以通过一个或多个参数限定搜寻条件或返回格式,如:email,format,key,output,userid,各个搜寻条件通过“&”组合到一起。其中,userid 是最常用的查询参数,它表示唯一的个人标志,通过 http://servername/connections/profiles/atom/search.do?userid=inputid URL, Connections 返回 userid 为 inputid的用户信息 Atom 文档。

如果想验证查询所用 profile API 的 URL 是否正确,可以使用浏览器打开该 URL,若该网页的源代码为 Atom 规范的文档,则表明该 URL 可以使用。

使用 Dojo 异步方式获得上述 feed

清单 9
   var xhrArgs = { 
 url: "http://localhost/profiles/atom/search.do?userid=" + CID, 
    handleAs: "xml"
   }; 
   // 返回延迟对象
   var deferred = dojo.xhrGet(xhrArgs); 
 deferred.addCallback(function(xmlDoc, ioargs) {...} 
 deferred.addErrback(function(xmlDoc, ioargs) {...}

dojo.xhrGet 提供了异步调用方式接受数据的统一接口。xhrGet 方法使用一个设置 xhrGet 工作方式的对象作为参数,该对象至少包含发送请求的 URL,同时可以定义何种方式处理返回数据,完成之后应该执行的操作等设置。xhrGet 方法返回延迟对象 deferred,该对象定义了成功和失败条件下的调用函数:addCallback 和 addErrback。由于上述代码中 xhrArgs 设置对象的 handleAs 参数为“xml”,deffered.addCallback() 会自动把 XML document 转化为为 DOM 对象。

对 xml 进行解析获得用户信息

清单 10
    var feedRoot = xmlDoc.getElementsByTagName("feed"); 
    var feed = new dojox.atom.io.model.Feed(); 
    feed.buildFromDom(xmlDoc.documentElement); 
    var entry = feed.getFirstEntry(); 
    // 获得用户的 email,照片链接等
    var name = entry.contributors[0].name; 
    var email = entry.contributors[0].email; 
    var photourl = entry.links[2].href;

dojox.atom.io.model 是 dojo 提供的 Atom XML 的 JavaScript 模型。这个模型可以将 Atom XML 转化为 JavaScript 结构对象,该对象可以很容易被修改并再序列化为 XML。dojox.atom.io.model 提供了专门解析 ATOM 文档的方法,比起单纯使用 DOM API 解析 Atom XML,它的处理步骤更加简单。dojox.atom.io.model 提供了表示 Atom 标签的一些类,比较常用的有:dojox.atom.io.model.Feed,dojox.atom.io.model.Entry,他们都继承自 dojox.atom.io.model.AtomItem。 dojox.atom.io.model.Feed 表示 Atom Feed 元素,包括 Feed 的 title,autor 等元素,也包含 entry 列表; dojox.atom.io.model.Entry 表示 Atom Entry 元素,包含了如 authors, contributors, title, content 等信息;而 dojox.atom.io.model.AtomItem 的 buildFromDom 可以将一个 DOM 对象转换为 AtomItem 对象。具体 API 请参见参考文献。

在 Atom 规范中,一个 feed 对象一般会包含一到多个 entry,因此一个 dojox.atom.io.model.Feed 会包含一到多个 dojox.atom.io.model.Entry 对象,但因为本次查询 dojo.xhrGet 方法使用的 url 以 userid 为查询目标,因此只会有一个结果,可以通过使用 feeed.getFirstEntry() 获得 userid 对应的用户信息 entry。用户的 email 信息可以通过 entry 的 contributor 数组中第一个人员的 email 属性获得,照片链接在 entry 中是 <linkrel="http://www.ibm.com/xmlns/prod/sn/image" .../> 格式的元素,可以通过通过 entry.links[2] 获得。

将用户信息应用到上节的个人信息图层

清单 11
    // 设置 infoCard 的 email,照片链接等
    htmlNode = 
     "<div style='border:solid blue;font-size:12px;BACKGROUND:green;opacity:0.99;'>" + 
      "<div style='border:solid blue;border-width:0px 0px 1px 0px'>" + 
       email + 
       "</div>" + 
       "<img width=50px height=50px src='" + 
       photourl + 
       "'>" + 
     "</div>"; 
     infoCard.innerHTML = htmlNode;

即将上节个人信息图层的 innerHTML 中静态数据替换为通过 Lotus Connection 获得的数据。

当然,你也可以通过 Lotus Connections 提供的其他 API 获得该用户的 Blog,Wiki 等信息,根据这些信息生成其他样式的个人信息名片。限于篇幅,文章对此不再进行描述,具体活的其他用户信息的方式可参阅参考文献中 Profile API 文档。

加入 Sametime

Lotus SametimeStandard 软件 IBM 公司提供的 UC² 平台,它提供了整合的企业即时消息传递、VoIP、视频聊天和 Web 会议功能,并且具备业务应用所需的安全特性,并且它还提供了一个可扩展的、开放的 Web 2.0 解决方案,允许开发人员使用 Ajax 工具将一整套 Sametime 功能嵌入到 Web 应用和门户中。用户由此可以获得全新、可定制、无需下载的、基于浏览器的聊天客户端,使您能够轻松地将 Sametime 聊天体验集成到 Web 站点中。

Sametime Links toolkit 是 Sametime 轻量级开发包,允许开发人员把 Sametime 提供的功能嵌入到网页或应用中。开发人员不需要改变当前网页的布局,只需要添加几行 HTML 代码,Sametime Links toolkit 就可以帮助开发人员将 Sametime 服务器中已有的已有的用户姓名超链接导入到网页中,用户点击该链接就可以与该用户联系。

将 Sametime Links 引用到网页中的步骤为:

  1. 引用 Sametime Javascript 和 CSS 导入到 HTML 页面
  2. 加载 Sametime Links Java™ applet
  3. 获得描述 Sametime Link 的超链接 HTML 代码
  4. 设置某个节点的 innerHTML 为上述代码

引用 Sametime Javascript 和 CSS

将下面的代码拷贝到网页 HTML 的 Head 节点中:

清单 12
 <LINK REL=STYLESHEET 
 HREF="http://serverHost/sametime/stlinks/stlinks.css" TYPE="text/css"> 
 <SCRIPT src="http://serverHost /sametime/stlinks/stlinks.js"></SCRIPT> 
 <SCRIPT>setSTLinksURL("http://serverHost/sametime/stlinks")</SCRIPT>

serverHost表示 Sametime Link 所在服务器域名。

加载 Sametime Links Java™ applet

向网页中添加下面的代码,这段代码可以放在 HTML 的任意位置:

清单 13
 <SCRIPT> 
 writeSTLinksApplet (loginName,key,isByToken); 
 </SCRIPT>

其中,loginName表示当前登录 Sametime 的用户名;key为用户的登录密码或令牌;Sametime Links 提供了三种登录 Sametime 社区的方式:使用密码,匿名和使用令牌,isByToken为 true 时表示使用令牌作为认证方式,false 表示使用密码为认证方式,默认为 false。

获得 Sametime link 的超链接

该超链接代码可以使用 Sametime Links 提供的 prepareSametimeLink 方法获得。

清单 14
 prepareSametimeLink(userName, displayName)

该方法将返回 Sametime link 的 HTML 代码,开发人员将某个 HTML 节点的 innerHTML 设置为这段代码后,HTML 节点上会显示 displayName,最终用户通过点击该节点,即可与 DN 为 userName 的用户进行交流。

而对于本文章,则是将用户图层节点的 innerHTML 设置为该超链接,即:

清单 15
  // 创建用户图层
  function createLayer(display,DN,CID){ 
   ……
   // 为 container 添加 Sametimes 联系功能
   var stLinkHTML = prepareSametimeLink(DN,display); 
   layer.innerHTML = stLinkHTML; 
   ……
  }
图 3. 增加 Sametime 超链接
图 3. 增加 Sametime 超链接
图 4. 与用户进行通信
图 4. 与用户进行通信

总结

将 Lotus Connections 和 Sametimes 集成到 GIS 应用,将会给最终用户一种直观使用它们的方法。本文从构建最基本的 GIS 应用入手,逐步加深,构建基于 GIS 的个人名片和即时消息应用。阅读本文后,读者将会了解 Dojo、百度地图 API、Lotus Connections 和 Sametimes 的使用技巧,能使用示例代码构建基于 GIS 的个人名片和即使信息应用,并能根据自己需求,修改少量代码,设计出适合自身使用的 GIS 应用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值