2012年9月14日星期五

利用canvas进行 最大邻域法 图像放大

利用html5中的canvas可以进行在线图片处理,下面以放大图片为例来介绍基本方法。

图片放大可以用很多插值方法,比如在html中指定img元素的width属性时,浏览器会自动对其进行插值放大。但一些时候我们需要自定义的插值放大方法,比如下面的链接演示了雷达回波图片的放大,采用了基本的最大邻域法来进行放大,这时需要我们自己来写算法。

先看演示:雷达回波图采用最大邻域法来进行放大

下面是主要的两个处理函数:


//获取图片像素信息
var getImagePixelData = function(img){
var canvas = $('')[0];
canvas.width = img.width;
canvas.height = img.height;

var context = canvas.getContext('2d');//获取2D绘制上下文context 原生API

context.drawImage(img, 0, 0);//在context中绘制图片 原生API

return context.getImageData(0,0,img.width, img.height);//获取context中的像素数据 原生API
}

//利用包含图片像素数据的对象imageData 获取 放大后的对象newImageData
var scaleImage = function(imageData, newImageData){

var ow = imageData.width, oh = imageData.height;

var scalew = newImageData.width/ow,
scaleh = newImageData.height/oh;

var se1, se2, se3;

var pos = 0, pos2 = 0;

for(var y = 0; y < oh; y++){
for(var x = 0; x < ow; x++){

if(imageData.data[pos+3]){
for(var ny = Math.floor(y*scaleh); ny < Math.floor((y+1)*scaleh); ny++){
for(var nx = Math.floor(x*scalew); nx < Math.floor((x+1)*scalew); nx++){
pos2 = (ny*newImageData.height + nx)*4;
newImageData.data[pos2] = imageData.data[pos];
newImageData.data[pos2+1] = imageData.data[pos+1];
newImageData.data[pos2+2] = imageData.data[pos+2];
newImageData.data[pos2+3] = imageData.data[pos+3];
}
}

}
pos += 4;
}
}

return newImageData;
}

2012年9月12日星期三

SVN命令详解


  1. 将文件checkout到本地目录

    svn checkout path(path是服务器上的目录)
    例如:svn checkout svn://192.168.1.1/pro/domain
    简写:svn co


  2. 往版本库中添加新的文件

    svn add file (此时尚未提交到服务器版本库中)
    例如:svn add test.php(添加test.php)
    svn add *.php(添加当前目录下所有的php文件)


  3. 将改动的文件提交到版本库

    svn commit -m "LogMessage" [-N] [--no-unlock] PATH
    (如果选择了保持锁,就使用–no-unlock开关)
    例如:svn commit -m "add test file for my test" test.php
    简写:svn ci


  4. 加锁/解锁

    svn lock -m "LockMessage" [--force] PATH
    例如:svn lock -m "lock test file" test.php
    svn unlock PATH


  5. 更新到某个版本

    svn update -r m path
    例如: svn update如果后面没有目录,默认将当前目录以
    及子目录下的所有文件都更新到最新版本。
    svn update -r 200 test.php(将版本库中的文件test.php还原到版本200)
    svn update test.php(更新,于版本库同步。如果在提交的时候提示过期的话,
    是因为冲突,需要先update,修改文件,然后清除svn resolved,最后再提交commit)
    简写:svn up


  6. 查看文件或者目录状态

    svn status path...(目录下的文件和子目录的状态,正常状态不显示)
    【?:不在svn的控制中;M:内容被修改;C:发生冲突;
    A:预定加入到版本库;K:被锁定】
    2)svn status -v path(显示文件和子目录状态)
    第一列保持相同,第二列显示工作版本号,第三和第四列显示
    最后一次修改的版本号和修改人。
    注:svn status、svn diff和 svn revert这三条命令在
    没有网络的情况下也可以执行的,
    原因是svn在本地的.svn中保留了本地版本的原始拷贝。
    简写:svn st


  7. 删除文件

    svn delete path -m "delete test fle"
    例如:svn delete svn://192.168.1.1/pro/test.php -m "delete file"
    或者直接svn delete test.php 然后再svn ci -m "delete test file"(推荐)
    简写:svn (del, remove, rm)


  8. 移动文件或者目录或文件更名

    svn move -m "move test fle"
    例如:svn move -m "move test file" a.php b.php
    svn move -m "move test file" address admin/address
    把当前目录下得address目录移动到当前目录下的admin/address下


  9. 查看日志

    svn log path
    例如:svn log test.php 显示这个文件的所有修改记录,及其版本号的变化


  10. 查看文件详细信息

    svn info path
    例如:svn info test.php


  11. 比较差异

    svn diff path(将修改的文件与基础版本比较)
    例如:svn diff test.php
    svn diff -r m:n path(对版本m和版本n比较差异)
    例如:svn diff -r 200:201 test.php
    简写:svn di


  12. 将两个版本之间的差异合并到当前文件

    svn merge -r m:n path
    例如:svn merge -r 200:205 test.php(将版本200与205之间的差异
    合并到当前文件,但是一般都会产生冲突,需要处理一下)


  13. SVN 帮助

    svn help
    svn help ci


  14. 恢复本地修改

    svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert:
    用法: revert PATH…
    注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复
    被删除的目录


  15. 解决冲突

    svn resolved: 移除工作副本的目录或文件的“冲突”状态。
    用法: resolved PATH…
    注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的
    相关文件,然后让 PATH 可以再次提交。


  16. 创建纳入版本控制下的新目录

    svn mkdir: 创建纳入版本控制下的新目录。
    用法: 1、mkdir PATH…
    2、mkdir URL…
    创建版本控制的目录。
    1、每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增
    调度,以待下一次的提交。
    2、每个以URL指定的目录,都会透过立即提交于仓库中创建。
    在这两个情况下,所有的中间目录都必须事先存在。


  17. 版本库下的文件和目录列表

    svn list path
    显示path目录下的所有属于版本库的文件和目录
    简写:svn ls


  18. 代码库URL变更

    svn switch (sw): 更新工作副本至不同的URL。
    用法: 1、switch URL [PATH]
    2、switch –relocate FROM TO [PATH...]
    1、更新你的工作副本,映射到一个新的URL,其行为跟“svn update”很像,也会将
    服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的
    方法。
    2、改写工作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动
    (比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同一目录时使用
    这个命令更新工作副本与仓库的对应关系。


  19. 输出指定文件或URL的内容。

    svn cat 目标[@版本]…如果指定了版本,将从指定的版本开始查找。
    svn cat -r PREV filename > filename
    (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)




[原文链接]:Linux学习篇-SVN命令详解

2012年9月11日星期二

使用 HTML5 WebSocket 构建实时 Web 应用


作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas、本地存储、多媒体编程接口、WebSocket 等等。这其中有“Web 的 TCP ”之称的 WebSocket 格外吸引开发人员的注意。WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。Web 开发人员可以非常方便地使用 WebSocket 构建实时 web 应用,开发人员的手中从此又多了一柄神兵利器。本文首先介绍 HTML5 WebSocket 的基本概念以及这个规范试图解决的问题,然后介绍 WebSocket 的基本原理和编程接口。接下来会通过一个简单案例来示范怎样实现一个 WebSocket 应用,并且展示 WebSocket 如何在功能强大和编程简单易用上达到的完美统一。最后介绍了目前主流浏览器对 WebSocket 支持的状况、局限性以及未来的展望。

实时 Web 应用的窘境



Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。所以保持客户端和服务器端的信息同步是实时 Web 应用的关键要素,对 Web 开发人员来说也是一个难题。在 WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术。下面我们简单介绍一下这几种技术:

轮询:



这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。这种同步方案的最大问题是,当客户端以固定频率向服务器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案。

长轮询:



长轮询是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高。

流:



流技术方案通常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。

综合这几种方案,您会发现这些目前我们所使用的所谓的实时技术并不是真正的实时技术,它们只是在用 Ajax 方式来模拟实时的效果,在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量,而且这些方案中客户端和服务器端的编程实现都比较复杂,在实际的应用中,为了模拟比较真实的实时效果,开发人员往往需要构造两个 HTTP 连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数据传输,这不可避免地增加了编程实现的复杂度,也增加了服务器端的负载,制约了应用系统的扩展性。

WebSocket 的拯救



HTML5 WebSocket 设计出来的目的就是要取代轮询和 Comet 技术,使客户端浏览器具备像 C/S 架构下桌面系统的实时通讯能力。 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。因为 WebSocket 连接本质上就是一个 TCP 连接,所以在数据传输的稳定性和数据传输量的大小方面,和轮询以及 Comet 技术比较,具有很大的性能优势。Websocket.org 网站对传统的轮询方式和 WebSocket 调用方式作了一个详细的测试和比较,将一个简单的 Web 应用分别用轮询方式和 WebSocket 方式来实现,在这里引用一下他们的测试结果图:

[caption id="" align="alignnone" width="504"]图 1. 轮询和 WebSocket 实现方式的网络负载对比图图 1. 轮询和 WebSocket 实现方式的网络负载对比图[/caption]

通过这张图可以清楚的看出,在流量和负载增大的情况下,WebSocket 方案相比传统的 Ajax 轮询方案有极大的性能优势。这也是为什么我们认为 WebSocket 是未来实时 Web 应用的首选方案的原因。


WebSocket 规范



WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

下面我们来详细介绍一下 WebSocket 规范,由于这个规范目前还是处于草案阶段,版本的变化比较快,我们选择 draft-hixie-thewebsocketprotocol-76版本来描述 WebSocket 协议。因为这个版本目前在一些主流的浏览器上比如 Chrome,、FireFox、Opera 上都得到比较好的支持,您如果参照的是新一些的版本话,内容可能会略有差别。

一个典型的 WebSocket 发起请求和得到响应的例子看起来如下:

清单 1. WebSocket 握手协议

客户端到服务端:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Upgrade: WebSocket
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
Origin: http://example.com
[8-byte security key]

服务端到客户端:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: http://example.com
WebSocket-Location: ws://example.com/demo
[16-byte hash response]


这些请求和通常的 HTTP 请求很相似,但是其中有些内容是和 WebSocket 协议密切相关的。我们需要简单介绍一下这些请求和应答信息,”Upgrade:WebSocket”表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。从客户端到服务器端请求的信息里包含有”Sec-WebSocket-Key1”、“Sec-WebSocket-Key2”和”[8-byte securitykey]”这样的头信息。这是客户端浏览器需要向服务器端提供的握手信息,服务器端解析这些头信息,并在握手的过程中依据这些信息生成一个 16 位的安全密钥并返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接。一旦连接建立,客户端和服务器端就可以通过这个通道双向传输数据了。

在实际的开发过程中,为了使用 WebSocket 接口构建 Web 应用,我们首先需要构建一个实现了 WebSocket 规范的服务器,服务器端的实现不受平台和开发语言的限制,只需要遵从 WebSocket 规范即可,目前已经出现了一些比较成熟的 WebSocket 服务器端实现,比如:


  • Kaazing WebSocket Gateway — 一个 Java 实现的 WebSocket Server

  • mod_pywebsocket — 一个 Python 实现的 WebSocket Server

  • Netty —一个 Java 实现的网络框架其中包括了对 WebSocket 的支持

  • node.js —一个 Server 端的 JavaScript 框架提供了对 WebSocket 的支持




如果以上的 WebSocket 服务端实现还不能满足您的业务需求的话,开发人员完全可以根据 WebSocket 规范自己实现一个服务器。在“WebSocket 实战”这一节,我们将使用 Microsoft .NET 平台上的 C# 语言来打造一个简单的 WebSocket 服务器,继而构建一个简单的实时聊天系统。

WebSocket JavaScript 接口



上一节介绍了 WebSocket 规范,其中主要介绍了 WebSocket 的握手协议。握手协议通常是我们在构建 WebSocket 服务器端的实现和提供浏览器的 WebSocket 支持时需要考虑的问题,而针对 Web 开发人员的 WebSocket JavaScript 客户端接口是非常简单的,以下是 WebSocket JavaScript 接口的定义:

清单 2. WebSocket JavaScript 定义

[Constructor(in DOMString url, in optional DOMString protocol)]
interface WebSocket {
readonly attribute DOMString URL;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
//networking
attribute Function onopen;
attribute Function onmessage;
attribute Function onclose;
boolean send(in DOMString data);
void close();
};
WebSocket implements EventTarget;


其中 URL 属性代表 WebSocket 服务器的网络地址,协议通常是”ws”,send 方法就是发送数据到服务器端,close 方法就是关闭连接。除了这些方法,还有一些很重要的事件:onopen,onmessage,onerror 以及 onclose。我们借用 Nettuts 网站上的一张图来形象的展示一下 WebSocket 接口:
[caption id="" align="alignnone" width="443"]图 2. WebSocket JavaScript 接口图 2. WebSocket JavaScript 接口[/caption]

下面是一段简单的 JavaScript 代码展示了怎样建立 WebSocket 连接和获取数据:

清单 3. 建立 WebSocket 连接的实例 JavaScript 代码
 var  wsServer = 'ws://localhost:8888/Demo'; 
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
console.log("Connected to WebSocket server.");
}
function onClose(evt) {
console.log("Disconnected");
}
function onMessage(evt) {
console.log('Retrieved data from server: ' + evt.data);
}
function onError(evt) {
console.log('Error occured: ' + evt.data);
}


浏览器支持



下面是主流浏览器对 HTML5 WebSocket 的支持情况:
浏览器支持情况
ChromeSupported in version 4+
FirefoxSupported in version 4+
Internet ExplorerSupported in version 10+
OperaSupported in version 10+
SafariSupported in version 5+


WebSocket 实战



这一节里我们用一个案例来演示怎么使用 WebSocket 构建一个实时的 Web 应用。这是一个简单的实时多人聊天系统,包括客户端和服务端的实现。客户端通过浏览器向聊天服务器发起请求,服务器端解析客户端发出的握手请求并产生应答信息返回给客户端,从而在客户端和服务器之间建立连接通道。服务器支持广播功能,每个聊天用户发送的信息会实时的发送给所有的用户,当用户退出聊天室时,服务器端需要清理相应用户的连接信息,避免资源的泄漏。以下我们分别从服务器端和客户端来演示这个 Web 聊天系统的实现,在实现方式上我们采用了 C# 语言来实现 WebSocket 服务器,而客户端是一个运行在浏览器里的 HTML 文件。

WebSocket 服务器端实现



这个聊天服务器的实现和基于套接字的网络应用程序非常类似,首先是服务器端要启动一个套接字监听来自客户端的连接请求,关键的区别在于 WebSocket 服务器需要解析客户端的 WebSocket 握手信息,并根据 WebSocket 规范的要求产生相应的应答信息。一旦 WebSocket 连接通道建立以后,客户端和服务器端的交互就和普通的套接字网络应用程序是一样的了。所以在下面的关于 WebSocket 服务器端实现的描述中,我们主要阐述 WebSocket 服务器怎样处理 WebSocket 握手信息,至于 WebSocket 监听端口的建立,套接字信息流的读取和写入,都是一些常用的套接字编程的方式,我们就不多做解释了,您可以自行参阅本文的附件源代码文件。

在描述 WebSocket 规范时提到,一个典型的 WebSocket Upgrade 信息如下所示:
GET /demo HTTP/1.1 
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Upgrade: WebSocket
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
Origin: http://example.com
[8-byte security key]

其中 Sec-WebSocket-Key1,Sec-WebSocket-Key2 和 [8-byte security key] 这几个头信息是 WebSocket 服务器用来生成应答信息的来源,依据 draft-hixie-thewebsocketprotocol-76 草案的定义,WebSocket 服务器基于以下的算法来产生正确的应答信息:


  1. 逐个字符读取 Sec-WebSocket-Key1 头信息中的值,将数值型字符连接到一起放到一个临时字符串里,同时统计所有空格的数量;

  2. 将在第 1 步里生成的数字字符串转换成一个整型数字,然后除以第 1 步里统计出来的空格数量,将得到的浮点数转换成整数型;

  3. 将第 2 步里生成的整型值转换为符合网络传输的网络字节数组;

  4. 对 Sec-WebSocket-Key2 头信息同样进行第 1 到第 3 步的操作,得到另外一个网络字节数组;

  5. 将 [8-byte security key] 和在第 3,第 4 步里生成的网络字节数组合并成一个 16 字节的数组;

  6. 对第 5 步生成的字节数组使用 MD5 算法生成一个哈希值,这个哈希值就作为安全密钥返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接




至此,客户端和服务器的 WebSocket 握手就完成了,WebSocket 通道也建立起来了。下面首先介绍一下服务器端实现是如何根据用户传递的握手信息来生成网络字节数组的。.NET 平台提供了很方便的对字符串,数值以及数组操作的函数,所以生成字节数组的方法还是非常简单明了的,代码如下:

清单 4. 生成网络字节数组的代码

private byte[]   BuildServerPartialKey(string clientKey)
{
string partialServerKey = "";
byte[] currentKey;
int spacesNum = 0;
char[] keyChars = clientKey.ToCharArray();
foreach (char currentChar in keyChars)
{
if (char.IsDigit(currentChar)) partialServerKey += currentChar;
if (char.IsWhiteSpace(currentChar)) spacesNum++;
}
try
{
currentKey = BitConverter.GetBytes((int)(Int64.Parse(partialServerKey)
/ spacesNum));
if (BitConverter.IsLittleEndian) Array.Reverse(currentKey);
}
catch
{
if (currentKey!= null) Array.Clear(currentKey, 0, currentKey.Length);
}
return currentKey;
}

得到网络字节数组以后,服务器端生成 16 位安全密钥的方法如下所示:

清单 5. 生成 16 位安全密钥的代码

private byte[] BuildCompleteServerKey(byte[] serverKey1, byte[] serverKey2,
byte[] last8Bytes)
{
byte[] concatenatedKeys = new byte[16];
Array.Copy(serverKey1, 0, concatenatedKeys, 0, 4);
Array.Copy(serverKey2, 0, concatenatedKeys, 4, 4);
Array.Copy(last8Bytes, 0, concatenatedKeys, 8, 8);
System.Security.Cryptography.MD5 MD5Service =
System.Security.Cryptography.MD5.Create();
return MD5Service.ComputeHash(concatenatedKeys);
}

整个实现是非常简单明了的,就是将生成的网络字节数组和客户端提交的头信息里的 [8-byte security key] 合并成一个 16 位字节数组并用 MD5 算法加密,然后将生成的安全密钥作为应答信息返回给客户端,双方的 WebSocekt 连接通道就建立起来了。实现了 WebSocket 握手信息的处理逻辑,一个具有基本功能的 WebSocket 服务器就完成了。整个 WebSocket 服务器由两个核心类构成,一个是 WebSocketServer,另外一个是 SocketConnection,出于篇幅的考虑,我们不介绍每个类的属性和方法了,文章的附件会给出详细的源代码,有兴趣的读者可以参考。

服务器刚启动时的画面如下:

[caption id="" align="alignnone" width="437"]图 3. WebSocket 服务器刚启动的画面图 3. WebSocket 服务器刚启动的画面[/caption]

客户端可以依据这个信息填写聊天服务器的连接地址,当有客户端连接到聊天服务器上时,服务器会打印出客户端和服务器的握手信息,每个客户的聊天信息也会显示在服务器的界面上,运行中的聊天服务器的界面如下:
[caption id="" align="alignnone" width="408"]图 4. 有客户端连接到 WebSocket 服务器的图 4. 有客户端连接到 WebSocket 服务器的[/caption]

以上我们简单描述了实现一个 WebSocket 服务器的最基本的要素,下一节我们会描述客户端的实现。

客户端实现



客户端的实现相对于服务器端的实现来说要简单得多了,我们只需要发挥想象去设计 HTML 用户界面,然后呼叫 WebSocket JavaScript 接口来和 WebSocket 服务器端来交互就可以了。当然别忘了使用一个支持 HTML5 和 WebSocket 的浏览器,在笔者写这篇文章的时候使用的浏览器是 Firefox。客户端的页面结构是非常简洁的,初始运行界面如下:
[caption id="" align="alignnone" width="353"]图 5. 聊天室客户端初始页面图 5. 聊天室客户端初始页面[/caption]

当页面初次加载的时候,首先会检测当前的浏览器是否支持 WebSocket 并给出相应的提示信息。用户按下连接按钮时,页面会初始化一个到聊天服务器的 WebSocekt 连接,初始化成功以后,页面会加载对应的 WebSocket 事件处理函数,客户端 JavaScript 代码如下所示:

清单 6. 初始化客户端 WebSocket 对象的代码
 function ToggleConnectionClicked() {
if (SocketCreated && (ws.readyState == 0 || ws.readyState == 1)) {
ws.close();
} else {
Log("准备连接到聊天服务器 ...");
try {
ws =
new WebSocket("ws://" + document.getElementById("Connection").value);
SocketCreated = true;
} catch (ex) {
Log(ex, "ERROR");
return;
}
document.getElementById("ToggleConnection").innerHTML = "断开";
ws.onopen = WSonOpen;
ws.onmessage = WSonMessage;
ws.onclose = WSonClose;
ws.onerror = WSonError;
}
};

function WSonOpen() {
Log("连接已经建立。", "OK");
$("#SendDataContainer").show("slow");
};

function WSonMessage(event) {
Log(event.data);
};

function WSonClose() {
Log("连接关闭。", "ERROR");
document.getElementById("ToggleConnection").innerHTML = "连接";
$("#SendDataContainer").hide("slow");
};


function WSonError() {
Log("WebSocket错误。", "ERROR");
};


当用户按下发送按钮,客户端会调用WebSocket对象向服务器发送信息,并且这个消息会广播给所有的用户,实现代码如下所示:

function SendDataClicked()
{
if (document.getElementById("DataToSend").value != "") {
ws.send(document.getElementById("txtName").value + "说 :\"" +
document.getElementById("DataToSend").value + "\"");
document.getElementById("DataToSend").value = "";
}
};


如果有多个用户登录到聊天服务器,客户端页面的运行效果如下所示:[caption id="" align="alignnone" width="415"]图 6. 聊天客户端运行页面图 6. 聊天客户端运行页面[/caption]


至此我们已经完成了一个完整的 WebSocket 客户端实现,用户可以体验一下这个聊天室的简单和快捷,完全不用考虑页面的刷新和繁琐的 Ajax 调用,享受桌面程序的用户体验。WebSocket 的强大和易用可见一斑,您完全可以在这个基础上加入更多的功能,设计更加漂亮的用户界面,切身体验 WebSocket 的震撼力。完整的客户端代码请参阅附件提供的源代码。

WebSocket 的局限性



WebSocket 的优点已经列举得很多了,但是作为一个正在演变中的 Web 规范,我们也要看到目前用 Websocket 构建应用程序的一些风险。首先,WebSocket 规范目前还处于草案阶段,也就是它的规范和 API 还是有变动的可能,另外的一个风险就是微软的 IE 作为占市场份额最大的浏览器,和其他的主流浏览器相比,对 HTML5 的支持是比较差的,这是我们在构建企业级的 Web 应用的时候必须要考虑的一个问题。

总结



本文介绍了 HTML5 WebSocket 的横空出世以及它尝试解决的的问题,然后介绍了 WebSocket 规范和 WebSocket 接口,以及和传统的实时技术相比在性能上的优势,并且演示了怎样使用 WebSocket 构建一个实时的 Web 应用,最后我们介绍了当前的主流浏览器对 HTML5 的支持情况和 WebSocket 的局限性。不过,我们应该看到,尽管 HTML5 WebSocket 目前还有一些局限性,但是已经是大势所趋,微软也明确表达了未来对 HTML5 的支持,而且这些支持我们可以在 Windows 8 和 IE10 里看到,我们也在各种移动设备,平板电脑上看到了 HTML5 和 WebSocket 的身影。WebSocket 将会成为未来开发实时 Web 应用的生力军应该是毫无悬念的了,作为 Web 开发人员,关注 HTML5,关注 WebSocket 也应该提上日程了,否则我们在新一轮的软件革新的浪潮中只能做壁上观了。

示例代码下载: source.zip

参考资料

学习


讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。




[原文链接]: 使用 HTML5 WebSocket 构建实时 Web 应用

2012年4月9日星期一

Javascript 中类的实现方式之一

世上本没有路,走的人多了……
Javascript中本没有类,但可以用函数来实现类。

先来看简单的矩形类Rect的实现:

function Rect(w,h){
this.width = w;
this.height = h;
}

var rect1 = new Rect(10,20);
window.alert('rect1.width = '+rect1.width);

上面实现了Rect类,这个类有两个公开数据成员width和height。定义一个对象(或者叫类的一个实例)的方法是在函数前加上new关键字。
下面来看怎么定义私有数据成员:

function Rect(w,h){
var width = w, height = h;

this.getWidth = function(){
return width;
}
this.getHeight = function(){
return height;
}
}

var rect1 = new Rect(10,20);
window.alert('rect1.width = '+rect1.getWidth());

上面将width和height定义为私有数据成员,并定义了两个公开成员函数getWidth和getHeight。
可见,定义私有数据成员或者私有成员函数的方法实际上是将他们定义为函数内部变量。

另外需要特别说明的是:一般情况下,在函数Rect内部,私有成员函数只可以访问私有成员(私有数据成员或者私有成员函数),而公开成员函数可以访问所有成员,这一点和我们熟悉的面向对象方法不太一样。

2012年4月1日星期日

理解和应用canvas变换

默认的canvas画布以左上角为原点,向右为x轴增长方向,向下为y轴增长方向。默认以像素为单位。

很多情况下使用默认绘图环境极为不便,默认坐标系与我们上学时经常用到的直角坐标系不太一致。

幸运的是我们可以利用为canvas提供的变换函数来进行坐标转换,比如将原点移动到画布中心,转换Y轴方向等。
当调用一个变换函数时,接下来的绘图将自动变换。所以变换前应该先将当前环境保存下来,执行完绘图时恢复之前的环境。
save()和restore()两个函数用来保存和恢复环境。

下面说一下常用的变换函数:

1. 平移函数 translate(dx, dy)
调用此函数后接下来的绘图x值自动增加dx,y值自动增加dy。效果就是平移一个绘图,也就是所有点都进行了平移。这也是改变原点的办法。

2. 旋转函数 rotate(angle)
调用此函数后接下来的绘图将沿原点顺时针方向旋转angle弧度

3. 缩放函数 scale(a, b)
调用此函数后x坐标值将缩放a倍,y坐标将缩放b倍。效果是整个绘图放大或缩小了。
a和b的值可以为负值,比如 scale(1, -1)的效果是转换y轴的方向(向下变为向上)。

还有两个矩阵变换函数transform / setTransform。它们稍微复杂些,先不介绍。

上面那些变换函数可以一起使用,但你心中要明白每一步操作有什么影响。

回到开头的问题,比如我们想将原点移动到(300,400)这个点,然后使y轴方向向上,可以这么做:

dc.translate(300, 400);
dc.scale(1,-1);

接下来的绘图就是你熟悉的在直角坐标系下的绘图了。

当绘制正弦函数sin(x)时,由于y值最大为1,x的范围一般为2*π ,这时可以利用缩放函数scale对x轴和y轴进行放大。
又比如我们的数据值是在(1000,3000)附近,这时可以在设置好坐标后对坐标进行平移,使(1000,3000)这个点在画布中央。

dc.translate(300, 400);
dc.scale(1,-1);
dc.translate(-1000, -3000);



相关链接:1.canvas基础教程

2012年3月26日星期一

windows中的多线程处理

(一)建立新线程的函数


1.Win32 API函数 CreateThread
HANDLE WINAPI CreateThread(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);


2.也可以用C运行库的函数 _beginthread 来创建新线程
uintptr_t _beginthread( 
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);


(二)线程间通讯方法:


1.消息通讯
可以在线程中用SendMessage发送自定义消息到指定窗口
LRESULT WINAPI SendMessage(
__in HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam
);


2.创建线程时可以传递一个结构体的指针
3.利用全局变量来通讯

对Window程序消息循环的理解



  • 1.每个(创建窗口的)线程有一个消息队列,程序用下面的循环接收、转换消息,并将消息分发到合适的窗口处理程序:



    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }



  • 2.windows系统负责把消息放入每个线程的消息队列或者直接调用合适的窗口处理程序




  • 3.Post消息和Send消息的区别



    a. Post一个消息(可以调用API函数PostMessage)表示消息将经过消息队列,通过消息循环来分发消息
    b. Send一个消息(可以调用API函数SendMessage)表示消息会跳过消息队列,操作系统直接调用窗口处理程序



  • 4.可以在任意线程中发送自定义的消息(消息值>= WM_USER)到指定的窗口




  • 5.消息队列


    操作系统维护一个系统消息队列并为每一个GUI线程维护一个线程消息队列。为了避免为非GUI线程创建消息队列的开销,所有的线程在最初创建时没有消息队列。仅当线程第一次调用特定的用户函数时系统才创建一个线程消息队列;没有任何GUI函数的调用会导致消息队列的创建。


  • 6.队列消息和非队列消息


    a. 队列消息

    移动或点击鼠标、敲击键盘等大部分消息为队列消息。
    仅当消息队列中没有其它消息时,WM_PAINTWM_TIMERWM_QUIT消息才被发送到窗口处理程序。
    其它的消息按先进先出的原则被发送到窗口处理程序
    用户可以用PostMessage等函数来发送一个队列消息

    b. 非队列消息

    比如当窗口转为active状态时,或者用户调用某些系统函数(如SetWindowPos)时,消息将跳过消息队列,直接发往窗口处理程序。
    用户可以调用SendMessage等函数来发送一个非队列消息


2012年3月24日星期六

C++ 字符串字面值的使用

以下语句将输出helloworld

//code1
char *a = "helloworld";

std::cout<

上面的a实际上是指向字符串字面值常量的起始地址,如果对a指向的字符进行赋值将会出现错误(比如 *(a+1) = 'E' 将出错)。
实际上应该像下面这样定义指针a(上面那样定义也能编译通过,但不推荐):

//code2
const char *a = "helloworld";


也可以用字符串字面值初始化字符数组,这样可以将字符数组当成字符串来使用:

//code3
char b[] = "helloworld";

std::cout<

注意上面是用字符串字面值来初始化字符数组b,数组b的长度为11,最后一位b[10] = '\0'. 可以直接在cout语句中输出b所存储的字符串的值,和code1类似。
但是请注意b为字符数组,数组b中的字符是可以改变的

//code4
char b[] = "helloworld";

b[0] = 'H';
std::cout<

上面代码将输出Helloworld,第一个字符由小写h修改为大写H。

稍微深入一点来说:
每个程序在内存中都有一块区域来存放常量、字符串字面值常量等。当用字符指针的方式来定义一个字符串时,实际上是将指针指向了字符串字面值常量的起始地址。
当用字符数组的方式来定义字符串时,程序首先开辟一段新的内存,然后将字符串字面值常量复制到这个位置。

可以用下面的程序来验证这点

#include

int main()
{
const char* p1 = "helloworld";
char array1[] = "helloworld";
const char* p2 = "helloworld";

std::cout<<" p1's address: "< <<"\n array1's address:"< <<"\n p2's address: "<
}


上面程序输出为:

p1's address: 13072640
array1's address:1899864
p2's address: 13072640


可以看到p1和p2指向相同的地址,而array1则为新的地址

2012年3月13日星期二

Boost中的Regex类库将部分中文识别为空白字符的问题原因及解决办法

问题描述:
使用字符类\s匹配一个字符串中的空白字符时,部分中文字符也将被识别为空白。

原因:
查看Boost的Regex源代码可以发现,Regex使用cpp_regex_traits类(在文件 boost/regex/v4/cpp_regex_traits.hpp 中定义)来处理字符类


// class cpp_regex_traits_base:
// acts as a container for locale and the facets we are using.
//
template
struct cpp_regex_traits_base
{
cpp_regex_traits_base(const std::locale& l)
{ imbue(l); }
std::locale imbue(const std::locale& l);

std::locale m_locale;
std::ctype const* m_pctype; //这个类用来识别空白符
//……
}


可以看到Regex使用std::ctype类来识别空白符等
ctype类有一个is成员函数用来判断某个字符是否属于空白字符或数字字符等,regex正是使用了这个成员函数。
查看这个成员函数的介绍可知字符类是在cctype头文件中定义的
cctype头文件定义了一系列函数来分类和转换单个字符,函数isspace来判断一个字符是否为空白字符
再来看函数isspace的说明,可知在C++中,指定了locale的此函数的模板版本存在于头文件中.
也就是说指定不同的locale,此函数的行为将不同。而默认的locale为"C" locale集。这就是问题的根源。

解决办法:1.使用[ \t\r\n]等特定的字符来代替\s
2.设置合适的locale并使用宽字符集和Regex的宽字符版本wregex

2012年3月7日星期三

Windows下编译和安装Boost库的指定模块

当然你可以使用www.boostpro.com提供的安装工具来安装,免去以下的步骤。但是那会安装许多不必要的文件,占用大量磁盘空间,有可能使你更迷惑。可参见这篇文章

如果你想了解如何一步步编译安装Boost库,请接着往下读。

一、到官网(www.boost.org)下载最新版Boost并解压到任意目录
先来看一下解压后的目录结构,以$BOOST_ROOT代表你Boost所在的目录

$BOOST_ROOT\ .................boost 根目录
index.htm .........A copy of www.boost.org starts here
boost\ .........................所有的Boost头文件
libs\ ............各种库的测试用例,文档说明。可以在这个文件夹中查看各种库怎么使用
index.html ........库文档从这里开始
algorithm\
any\
array\
…更多的库…
status\ .........................Boost范围测试套件
tools\ ...........一些有用工具, 比如 Boost.Build, quickbook, bcp
more\ ..........................政策等其它文档.
doc\ ...............所有Boost库文档的子集


二、编译需要的库
首先要说明的是大多数Boost库现在已经可以使用了,直接包含boost目录下相应的头文件即可,并不需要编译安装。

以下是必须编译安装的Boost库:


以下库拥有可选的编译组件(也就是说如果你要使用它们中的某些功能,则需要单独编译安装)

  • Boost.DateTime 当你使用它的 to_string/from_string 或者序列化特性, 或者目标平台为 Visual C++ 6.x 或 Borland.

  • Boost.Graph 仅仅当你想 处理 GraphViz 文件.

  • Boost.Math 含有TR1 和 C99 cmath 函数二进制组件.

  • Boost.Random 当你使用 random_device.

  • Boost.Test 可以 “header-only” 或 “separately compiled”
    模式使用, 尽管 对于郑重使用时推荐单独编译.



如果要编译上面的库,首先打开命令行,转到$BOOST_ROOT目录并运行目录下的bootstrap.bat脚本,这个脚本为Boost.Build系统的运行准备环境。

bootstrap.bat

可以看到现在$BOOST_ROOT目录下有b2.exe和bjam.exe两个可执行文件。这两个文件是一样的,只是名字不同,它们可以调用Boost.Build系统来创建上面那些需要编译安装的库。

比如我们想单独编译安装regex库,运行下面的命令即可

bjam stage --with-regex link=static threading=multi runtime-link=static

下面介绍相关参数的含义:
stage 仅创建和安装库文件(不创建头文件),可以用 --stagedir= 选项指定库的安装位置,默认安装在当前目录下的stage文件夹内。
--with- 创建和安装指定的库,如果使用了这个选项,则仅仅指定的库被创建,其它库不被创建。如果不指定这个选项,默认创建所有需要编译安装的库。
link=static指定生成静态regex库
threading=multi指定生成多线程库
runtime-link=static指定链接静态C和C++ 运行库

其他选项可参见这篇文章

三、配置开发环境
打开Visual Studio,在 工具->选项->项目和解决方案->VC++目录 条目下配置Boost包含文件和库文件目录,这样以后就不用每次都要配置Boost目录。

C++程序配置类库

一、INI文件读取库


除了使用Windows提供的API函数(见之前文章介绍)和BoostQTwxWidgets等类库提供的配置函数外,还可以使用下面的类库:

1.SimpleIni(code.jellycan.com/simpleini/)


一个跨平台的类库,提供简单的API读写INI文件,支持ASCII, MBCS and Unicode文件格式。开源,使用MIT协议。
使用方法:

CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile("myfile.ini");
const char * pVal = ini.GetValue("section", "key", "default");
ini.SetValue("section", "key", "newvalue");


2.RudeConfig(rudeserver.com/config/index.html)



// Create config object
//
Config config;


// load a configuration/.ini file
//
config.load("myfile.ini");


// read information
//
config.setSection("General Info");
double cost = config.getDoubleValue("Cost");
const char *company = config.getStringValue("Company Name");


// create information
//
config.setSection("new section");
config.setStringValue("animal type", "giraffe");
config.setBoolValue("mammal", true);

// save changes
//
config.save();


3.minIni(code.google.com/p/minini/)


minIni是一个在嵌入式系统中使用的读取INI文件库。minIni占用极少资源,可以为各种文件IO库配置。

二、XML文件读取库


1.TinyXML-2(grinninglizard.com/tinyxml2docs)


如名字所示,是简单的XML文件读取库,并且是第二版。仅包含一个.h文件和一个.cpp文件,直接和自己的源代码一起编译即可使用。


三、序列化文件(类似JSON格式)读取库


1.libconfig(hyperrealm.com/libconfig/)


Libconfig是一个简单的用来处理结构化配置文件的库,像这样的文件:test.cfg。这种文件格式比XML更紧凑易读。不像XML,它是可识别类型的,所以在程序代码中不必做字符串解析。

int var1;
double var2;
const char *var3;

if(config.lookupValue("values.var1", var1)
&& config.lookupValue("values.var2", var2)
&& config.lookupValue("values.var3", var3))
{
// use var1, var2, var3
}
else
{
// error handling here
}

2012年2月21日星期二

科学家部署激光器、GPS技术来改善降雪测量

通过配备专门的激光和GPS技术,国家大气研究中心(NCAR)的科学家们正在与同事一道解决一个关键的冬季天气奥秘:如何准确地测量地面上的降雪量。

运输船员,水资源管理者和其他那些重大安全决策者需要对于积雪深度如何在大范围内分布的精确测量。 但是当积雪量在单一区域或街道变化时,传统的测量设备,如雪压表或尺度杆往往不能够捕获 降雪总量。

[caption id="attachment_1136" align="alignleft" width="375" caption="Ethan Gutmann examines a laser instrument for measuring snow. "]Ethan Gutmann examines a laser instrument for measuring snow. [/caption]
现在,科学家们发现,使用光脉冲、卫星信号和其他技术的原型装置提供了几乎实时测量大面积降雪量的可能性。 随着时间的推移,这种装置甚至可能提供全球积雪深度的图像。

“我们已经准确测量降雨几个世纪了,但降雪量更难测量,因为它受风吹日晒和其他因素的影响”,NCAR的科学家伊桑•葛特曼(Ethan Gutmann),“看起来新技术将最终使我们能够精确地说出多少雪降在地面上。”

NCAR正与几个合作组织,包括美国国家海洋和大气管理局(NOAA)和科罗拉多大学博尔德大学(University of Colorado Boulder)进行这项研究。 这项工作得到NCAR的赞助商--国家科学基金会的支持。

不确定的深度


在大风暴期间应急管理人员依靠降雪观测来调集雪犁,或决定是否关闭高速和机场。 他们还使用雪总量来决定一个地区是否达到灾难援助的资格。 在山区,官员需要准确的积雪深度报告来评估雪崩或洪水的威胁,并预估从春季和夏季径流可用的水总量。

更精确的测量,还可以帮助气象学家和水文学家更好地了解雪物理和水文过程。

但传统的测雪方法可能极大低估或高估雪总量​​,特别是在恶劣的条件下。 在大风暴中雪仪表可能会缺测几乎三分之一的雪,即使当他们被专门设计的围栏保护起来以减少风的影响。 雪探头或雪尺可以在有限的区域内揭示积雪深度。 但是,这些工具需要不同地点的很多人工测量,这种方法在大雪期间可能无法得到雪总量。

[caption id="attachment_1137" align="alignleft" width="450" caption="Snow dunes. The three-dimensional features of a snow field above treeline is revealed by laser measurements. The laser, installed by NCAR at a test site in the Rocky Mountains, measures snow at more than 1,000 points across an area almost the size of a football field. "]Snow dunes[/caption]
气象专家有时也会监测收集在平坦、白色的被称为雪板的木板上的降雪量,但是这是一个时间密集型的方法,需要人每隔几个小时来检查雪板并清除他们。 两个全国最大的志愿者努力--全国天气服务合作观察员计划和社会协作雨、冰雹和雪网(CoCoRaHS)--每一个涉及全国数千名使用雪板的参与者,但他们的报告通常是仅仅一天提出一次。

最近,超声波装置已部署在一些世界上最寒冷的地区。 就像雷达,这些设备测量携带能量的超声波脉冲抵达雪面并返回到发射器所需的时间长度。 然而,信号可能受不断变化的大气条件(包括温度、湿度和风)的影响。

测试新方法


NCAR正在发展的专门的激光仪器可以纠正这些问题。 一旦设置在一个位置,它们就可以自动测量大面积的积雪深度。不同于超声仪器,激光依靠不受大气条件影响的光脉冲。

[caption id="attachment_1138" align="alignleft" width="350" caption="Ethan Gutmann walks past a snow gauge at a research site in Colorado."]snow gauge[/caption]
古特曼新的测试表明,安装在博尔德以西的落基山脉高于树线以上的激光仪器,可以测量10英尺以上的积雪,和测量半英寸的精度相当或更好。 这种仪器,在一个多小时里,在几乎是一个足球场大小的区域内测量超过1000个点的积雪,产生一个积雪深度及其变化的三维图像。

古特曼的下一步--如果他能获得急需的资金--将是建立和测试可以测量几平方英里的雪的激光仪器。 测量如此大的区域需要一个能够以每秒获取超过12,000个测量的新工具。

“如果我们成功了,一下子这些类型的工具将能够显示横跨整个流域的降雪的图像”他说。

然而,激光器的一个限制是光脉冲不能穿透物体,如树木和建筑物。这可能需要低成本的激光装置网络的发展,它们将记录每一个封闭区域内的积雪深度。另外,未来配备了这种激光器的卫星可能拥有从上面观测整个世界降雪的能力。

古特曼和Kristine拉尔森--在美国科罗拉多州大学的同事--也正在探索如何使用GPS传感器来进行降雪测量。 GPS传感器记录了两个卫星的信号,直接达到雪表面和地面反射的信号。 当地面上有雪,GPS信号用(相比地面是裸露的土壤)不同的频率反射雪,使科学家能够确定在地面之上是多高的雪面。

这些传感单元可能是一个经济有效的测量雪总量的方法,因为气象学家可以利用现有的地面GPS接收机的全球网络。 然而,研究人员正在充分了解雪的密度和其表面粗糙度如何改变GPS信号。

“我们希望建立一个高科技工具,使官员不断监测积雪深度,即使在强烈的风暴期间,”拉森说。 “虽然我们仍然需要做很多工作,该技术非常有前途。”

“我认为这项技术具有很大的可能让应急管理人员和其他决策者受益,就想我们的天气预报”,古特曼说。

原文链接:scientists-deploy-lasers-gps-technology-improve-snow-measurements

2012年2月13日星期一

PHP代码获取当前系统的CPU和内存的空闲百分比

设想我们有一个php页面A比较耗资源,因此在每次执行页面A中的代码前需要检测一下系统目前CPU和内存的空闲百分比。
我们可以利用下面几个函数来解决这个问题


//获取cpu的空闲百分比
function get_cpufree(){
$cmd = "top -n 1 -b -d 0.1 | grep 'Cpu'";//调用top命令和grep命令
$lastline = exec($cmd,$output);

preg_match('/(\S+)%id/',$lastline, $matches);//正则表达式获取cpu空闲百分比
$cpufree = $matches[1];
return $cpufree;
}
//获取内存空闲百分比
function get_memfree(){
$cmd = 'free -m';//调用free命令
$lastline = exec($cmd,$output);

preg_match('/Mem:\s+(\d+)/',$output[1], $matches);
$memtotal = $matches[1];
preg_match('/(\d+)$/',$output[2], $matches);
$memfree = $matches[1]*100.0/$memtotal;

return $memfree;
}

//获取某个程序当前的进程数
function get_proc_count($name){
$cmd = "ps -e";//调用ps命令
$output = shell_exec($cmd);

$result = substr_count($output, ' '.$name);
return $result;
}


比如当CPU空闲率小于30%时我们延迟页面A执行:

$cpufree = get_cpufree();

while( $cpufree<30 ){
// wait for 0.1 seconds
usleep(0.1*1000000);
$cpufree = get_cpufree();
};

2012年2月9日星期四

在线绘制近10年全球天气形势图(chatianqi.org)

天气预报等气象行业经常要与天气图打交道,查看并分析500hPa、700hPa等不同层次的高度场、温度场、湿度场和风场等要素,了解对流层的结构,从而制作天气预报。而每次遇到暴雨强对流等灾害性天气,更要认真分析实时的天气图,之后还要总结各种灾害性天气出现时对应的典型天气形势。只有对大量灾害性天气的形势图进行总结分析,才能得出规律,以便更好进行下一次预报。

而每次写技术总结,学术交流文章,写论文都要再次回顾一些天气个例,利用绘图工具对典型的天气形势进行绘图。很多人会对那些复杂的绘图命令望而生畏,即使对一些绘图工具有一些了解,绘制专业并且漂亮的天气形势图也需要花费大量的时间。而且你需要重新整理各种历史资料,提取需要的数据等,而这种资料的整理也需要花费大量时间。

现在给大家推荐一个网站,可以在线绘制近10年全球天气形势图,让大家省却以上烦恼并将为大家节省大量宝贵的时间。
网址为:chatianqi.org 十分好记,就是"查天气"的拼音

无论你在何地,使用任何设备(单位电脑、平板电脑等),只要能连接互联网,就可以打开这个网站查看任一日期的天气图,并可以对比多个层次、多个时次的天气图。
快来体验一下吧!

2012年1月2日星期一

推荐一些适用于安卓(Android)平板的应用




  • 1.百度输入法Pad版 (官方网站)


    个人觉得很好用

  • 2.安卓市场平板客户端 (官方网站)


    这里可以搜索并下载各种应用与游戏,资源比较丰富

  • 3.MoboPlayer (官方网站)


    比较好用的视频播放器软件,支持各种视频格式

  • 4.Evernote (官方网站)


    强大的笔记本软件,可在各种平台间同步笔记。
    国内类似的应用为有道云笔记,但功能差远了,在wifi代理情况下不能同步。

  • 5.鲜果联播Android HD版 (官方网站)


    杂志般的阅读体验,可订阅各种内容。这个可以取代RSS阅读器了。

  • 6.Google Maps (官方网站)


    google 官方的地图应用,强大易用不必多说。另外Google Sky Map还可以查看星空。

  • 7.Google Music (官方网站)


    Google的另一个应用,这个一定要安装,超炫的音乐播放器。有人说你装了这个软件就再也不想装其他的音乐播放器了

  • 8.豆瓣FM (官方网站)


    豆瓣电台,自动推荐歌曲

  • 9.云中书城 (官方网站)


    盛大出品的阅读应用,可以下载各种电子书

  • 10.Twitter (官方网站)


    这个不解释

  • 11.豌豆荚 (官方网站)


    在Windows下安装豌豆荚程序,可以向android平板里面安装应用,并且可以截取平板上面的屏幕图像

  • 12.豆果美食 Android Pad版 (官方网站)


    发现的唯一针对Android平板进行优化设计的食谱应用,内容很丰富,拿着平板可以做菜了

  • 13.Adobe Reader (官方网站)


    官方的PDF阅读器,很流畅,支持文本重排,阅读体验非常好

  • 14.开卷有益 (官方网站)


    支持TXT EPUB UMD CHM HTML JPG PNG GIF CBZ格式电子书 漫画和图片。

2011年12月29日星期四

中国省、市、县的Javascript对象表示(JSON字符串)


{"北京市":{"市辖区":["东城区","西城区","崇文区","宣武区","朝阳区","丰台区","石景山区","海淀区","门头沟区","房山区","通州区","顺义区","昌平区","大兴区","怀柔区","平谷区"],"-":["密云县","延庆县"]},"天津市":{"市辖区":["和平区","河东区","河西区","南开区","河北区","红桥区","塘沽区","汉沽区","大港区","东丽区","西青区","津南区","北辰区","武清区","宝坻区"],"-":["宁河县","静海县","蓟县"]},"山西省":{"太原市":["市辖区","小店区","迎泽区","杏花岭区","尖草坪区","万柏林区","晋源区","清徐县","阳曲县","娄烦县","古交市"],"大同市":["市辖区","城区","矿区","南郊区","新荣区","阳高县","天镇县","广灵县","灵丘县","浑源县","左云县","大同县"],"阳泉市":["市辖区","城区","矿区","郊区","平定县","盂县"],"长治市":["市辖区","城区","郊区","长治县","襄垣县","屯留县","平顺县","黎城县","壶关县","长子县","武乡县","沁县","沁源县","潞城市"],"晋城市":["市辖区","城区","沁水县","阳城县","陵川县","泽州县","高平市"],"朔州市":["市辖区","朔城区","平鲁区","山阴县","应县","右玉县","怀仁县"],"晋中市":["市辖区","榆次区","榆社县","左权县","和顺县","昔阳县","寿阳县","太谷县","祁县","平遥县","灵石县","介休市"],"运城市":["市辖区","盐湖区","临猗县","万荣县","闻喜县","稷山县","新绛县","绛县","垣曲县","夏县","平陆县","芮城县","永济市","河津市"],"忻州市":["市辖区","忻府区","定襄县","五台县","代县","繁峙县","宁武县","静乐县","神池县","五寨县","岢岚县","河曲县","保德县","偏关县","原平市"],"临汾市":["市辖区","尧都区","曲沃县","翼城县","襄汾县","洪洞县","古县","安泽县","浮山县","吉","乡宁县","大宁县","隰县","永和县","蒲县","汾西县","侯马市","霍州市"],"吕梁市":["市辖区","离石区","文水县","交城县","兴县","临县","柳林县","石楼县","岚县","方山县","中阳县","交口县","孝义市","汾阳市"]},"吉林省":{"长春市":["市辖区","南关区","宽城区","朝阳区","二道区","绿园区","双阳区","农安县","九台市","榆树市","德惠市"],"吉林市":["市辖区","昌邑区","龙潭区","船营区","丰满区","永吉县","蛟河市","桦甸市","舒兰市","磐石市"],"四平市":["市辖区","铁西区","铁东区","梨树县","伊通满族自治县","公主岭市","双辽市"],"辽源市":["市辖区","龙山区","西安区","东丰县","东辽县"],"通化市":["市辖区","东昌区","二道江区","通化县","辉南县","柳河县","梅河口市","集安市"],"白山市":["市辖区","八道江区","抚松县","靖宇县","长白朝鲜族自治县","江源县","临江市"],"松原市":["市辖区","宁江区","前郭尔罗斯蒙古族自治县","长岭县","乾安县","扶余县"],"白城市":["市辖区","洮北区","镇赉县","通榆县","洮南市","大安市"],"延边朝鲜族自治州":["延吉市","图们市","敦化市","珲春市","龙井市","和龙市","汪清县","安图县"]},"黑龙江省":{"哈尔滨市":["市辖区","道里区","南岗区","道外区","香坊区","动力区","平房区","松北区","呼兰区","依兰县","方正县","宾县","巴彦县","木兰县","通河县","延寿县","阿城市","双城市","尚志市","五常市"],"齐齐哈尔市":["市辖区","龙沙区","建华区","铁锋区","昂昂溪区","富拉尔基区","碾子山区","梅里斯达斡尔族区","龙江县","依安县","泰来县","甘南县","富裕县","克山县","克东县","拜泉县","讷河市"],"鸡西市":["市辖区","鸡冠区","恒山区","滴道区","梨树区","城子河区","麻山区","鸡东县","虎林市","密山市"],"鹤岗市":["市辖区","向阳区","工农区","南山区","兴安区","东山区","兴山区","萝北县","绥滨县"],"双鸭山市":["市辖区","尖山区","岭东区","四方台区","宝山区","集贤县","友谊县","宝清县","饶河县"],"大庆市":["市辖区","萨尔图区","龙凤区","让胡路区","红岗区","大同区","肇州县","肇源县","林甸县","杜尔伯特蒙古族自治县"],"伊春市":["市辖区","伊春区","南岔区","友好区","西林区","翠峦区","新青区","美溪区","金山屯区","五营区","乌马河区","汤旺河区","带岭区","乌伊岭区","红星区","上甘岭区","嘉荫县","铁力市"],"佳木斯市":["市辖区","永红区","向阳区","前进区","东风区","郊区","桦南县","桦川县","汤原县","抚远县","同江市","富锦市"],"七台河市":["市辖区","新兴区","桃山区","茄子河区","勃利县"],"牡丹江市":["市辖区","东安区","阳明区","爱民区","西安区","东宁县","林口县","绥芬河市","海林市","宁安市","穆棱市"],"黑河市":["市辖区","爱辉区","嫩江县","逊克县","孙吴县","北安市","五大连池市"],"绥化市":["市辖区","北林区","望奎县","兰西县","青冈县","庆安县","明水县","绥棱县","安达市","肇东市","海伦市"],"大兴安岭地区":["呼玛县","塔河县","漠河县"]},"上海市":{"市辖区":["黄浦区","卢湾区","徐汇区","长宁区","静安区","普陀区","闸北区","虹口区","杨浦区","闵行区","宝山区","嘉定区","浦东新区","金山区","松江区","青浦区","南汇区","奉贤区"],"-":["崇明县"]},"江苏省":{"南京市":["市辖区","玄武区","白下区","秦淮区","建邺区","鼓楼区","下关区","浦口区","栖霞区","雨花台区","江宁区","六合区","溧水县","高淳县"],"无锡市":["市辖区","崇安区","南长区","北塘区","锡山区","惠山区","滨湖区","江阴市","宜兴市"],"徐州市":["市辖区","鼓楼区","云龙区","九里区","贾汪区","泉山区","丰县","沛县","铜山县","睢宁县","新沂市","邳州市"],"常州市":["市辖区","天宁区","钟楼区","戚墅堰区","新北区","武进区","溧阳市","金坛市"],"苏州市":["市辖区","沧浪区","平江区","金阊区","虎丘区","吴中区","相城区","常熟市","张家港市","昆山市","吴江市","太仓市"],"南通市":["市辖区","崇川区","港闸区","海安县","如东县","启东市","如皋市","通州市","海门市"],"连云港市":["市辖区","连云区","新浦区","海州区","赣榆县","东海县","灌云县","灌南县"],"淮安市":["市辖区","清河区","楚州区","淮阴区","清浦区","涟水县","洪泽县","盱眙县","金湖县"],"盐城市":["市辖区","亭湖区","盐都区","响水县","滨海县","阜宁县","射阳县","建湖县","东台市","大丰市"],"扬州市":["市辖区","广陵区","邗江区","郊区","宝应县","仪征市","高邮市","江都市"],"镇江市":["市辖区","京口区","润州区","丹徒区","丹阳市","扬中市","句容市"],"泰州市":["市辖区","海陵区","高港区","兴化市","靖江市","泰兴市","姜堰市"],"宿迁市":["市辖区","宿城区","宿豫区","沭阳县","泗阳县","泗洪县"]},"浙江省":{"杭州市":["市辖区","上城区","下城区","江干区","拱墅区","西湖区","滨江区","萧山区","余杭区","桐庐县","淳安县","建德市","富阳市","临安市"],"宁波市":["市辖区","海曙区","江东区","江北区","北仑区","镇海区","鄞州区","象山县","宁海县","余姚市","慈溪市","奉化市"],"温州市":["市辖区","鹿城区","龙湾区","瓯海区","洞头县","永嘉县","平阳县","苍南县","文成县","泰顺县","瑞安市","乐清市"],"嘉兴市":["市辖区","秀城区","秀洲区","嘉善县","海盐县","海宁市","平湖市","桐乡市"],"湖州市":["市辖区","吴兴区","南浔区","德清县","长兴县","安吉县"],"绍兴市":["市辖区","越城区","绍兴县","新昌县","诸暨市","上虞市","嵊州市"],"金华市":["市辖区","婺城区","金东区","武义县","浦江县","磐安县","兰溪市","义乌市","东阳市","永康市"],"衢州市":["市辖区","柯城区","衢江区","常山县","开化县","龙游县","江山市"],"舟山市":["市辖区","定海区","普陀区","岱山县","嵊泗县"],"台州市":["市辖区","椒江区","黄岩区","路桥区","玉环县","三门县","天台县","仙居县","温岭市","临海市"],"丽水市":["市辖区","莲都区","青田县","缙云县","遂昌县","松阳县","云和县","庆元县","景宁畲族自治县","龙泉市"]},"安徽省":{"合肥市":["市辖区","瑶海区","庐阳区","蜀山区","包河区","长丰县","肥东县","肥西县"],"芜湖市":["市辖区","镜湖区","马塘区","新芜区","鸠江区","芜湖县","繁昌县","南陵县"],"蚌埠市":["市辖区","龙子湖区","蚌山区","禹会区","淮上区","怀远县","五河县","固镇县"],"淮南市":["市辖区","大通区","田家庵区","谢家集区","八公山区","潘集区","凤台县"],"马鞍山市":["市辖区","金家庄区","花山区","雨山区","当涂县"],"淮北市":["市辖区","杜集区","相山区","烈山区","濉溪县"],"铜陵市":["市辖区","铜官山区","狮子山区","郊区","铜陵县"],"安庆市":["市辖区","迎江区","大观区","郊区","怀宁县","枞阳县","潜山县","太湖县","宿松县","望江县","岳西县","桐城市"],"黄山市":["市辖区","屯溪区","黄山区","徽州区","歙县","休宁县","黟县","祁门县"],"滁州市":["市辖区","琅琊区","南谯区","来安县","全椒县","定远县","凤阳县","天长市","明光市"],"阜阳市":["市辖区","颍州区","颍东区","颍泉区","临泉县","太和县","阜南县","颍上县","界首市"],"宿州市":["市辖区","墉桥区","砀山县","萧县","灵璧县","泗县"],"巢湖市":["市辖区","居巢区","庐江县","无为县","含山县","和县"],"六安市":["市辖区","金安区","裕安区","寿县","霍邱县","舒城县","金寨县","霍山县"],"亳州市":["市辖区","谯城区","涡阳县","蒙城县","利辛县"],"池州市":["市辖区","贵池区","东至县","石台县","青阳县"],"宣城市":["市辖区","宣州区","郎溪县","广德县","泾县","绩溪县","旌德县","宁国市"]},"福建省":{"福州市":["市辖区","鼓楼区","台江区","仓山区","马尾区","晋安区","闽侯县","连江县","罗源县","闽清县","永泰县","平潭县","福清市","长乐市"],"厦门市":["市辖区","思明区","海沧区","湖里区","集美区","同安区","翔安区"],"莆田市":["市辖区","城厢区","涵江区","荔城区","秀屿区","仙游县"],"三明市":["市辖区","梅列区","三元区","明溪县","清流县","宁化县","大田县","尤溪县","沙县","将乐县","泰宁县","建宁县","永安市"],"泉州市":["市辖区","鲤城区","丰泽区","洛江区","泉港区","惠安县","安溪县","永春县","德化县","金门县","石狮市","晋江市","南安市"],"漳州市":["市辖区","芗城区","龙文区","云霄县","漳浦县","诏安县","长泰县","东山县","南靖县","平和县","华安县","龙海市"],"南平市":["市辖区","延平区","顺昌县","浦城县","光泽县","松溪县","政和县","邵武市","武夷山市","建瓯市","建阳市"],"龙岩市":["市辖区","新罗区","长汀县","永定县","上杭县","武平县","连城县","漳平市"],"宁德市":["市辖区","蕉城区","霞浦县","古田县","屏南县","寿宁县","周宁县","柘荣县","福安市","福鼎市"]},"江西省":{"南昌市":["市辖区","东湖区","西湖区","青云谱区","湾里区","青山湖区","南昌县","新建县","安义县","进贤县"],"景德镇市":["市辖区","昌江区","珠山区","浮梁县","乐平市"],"萍乡市":["市辖区","安源区","湘东区","莲花县","上栗县","芦溪县"],"九江市":["市辖区","庐山区","浔阳区","九江县","武宁县","修水县","永修县","德安县","星子县","都昌县","湖口县","彭泽县","瑞昌市"],"新余市":["市辖区","渝水区","分宜县"],"鹰潭市":["市辖区","月湖区","余江县","贵溪市"],"赣州市":["市辖区","章贡区","赣县","信丰县","大余县","上犹县","崇义县","安远县","龙南县","定南县","全南县","宁都县","于都县","兴国县","会昌县","寻乌县","石城县","瑞金市","南康市"],"吉安市":["市辖区","吉州区","青原区","吉安县","吉水县","峡江县","新干县","永丰县","泰和县","遂川县","万安县","安福县","永新县","井冈山市"],"宜春市":["市辖区","袁州区","奉新县","万载县","上高县","宜丰县","靖安县","铜鼓县","丰城市","樟树市","高安市"],"抚州市":["市辖区","临川区","南城县","黎川县","南丰县","崇仁县","乐安县","宜黄县","金溪县","资溪县","东乡县","广昌县"],"上饶市":["市辖区","信州区","上饶县","广丰县","玉山县","铅山县","横峰县","弋阳县","余干县","鄱阳县","万年县","婺源县","德兴市"]},"青海省":{"西宁市":["市辖区","城东区","城中区","城西区","城北区","大通回族土族自治县","湟中县","湟源县"],"海东地区":["平安县","民和回族土族自治县","乐都县","互助土族自治县","化隆回族自治县","循化撒拉族自治县"],"海北藏族自治州":["门源回族自治县","祁连县","海晏县","刚察县"],"黄南藏族自治州":["同仁县","尖扎县","泽库县","河南蒙古族自治县"],"海南藏族自治州":["共和县","同德县","贵德县","兴海县","贵南县"],"果洛藏族自治州":["玛沁县","班玛县","甘德县","达日县","久治县","玛多县"],"玉树藏族自治州":["玉树县","杂多县","称多县","治多县","囊谦县","曲麻莱县"],"海西蒙古族藏族自治州":["格尔木市","德令哈市","乌兰县","都兰县","天峻县"]},"湖南省":{"长沙市":["市辖区","芙蓉区","天心区","岳麓区","开福区","雨花区","长沙县","望城县","宁乡县","浏阳市"],"株洲市":["市辖区","荷塘区","芦淞区","石峰区","天元区","株洲县","攸县","茶陵县","炎陵县","醴陵市"],"湘潭市":["市辖区","雨湖区","岳塘区","湘潭县","湘乡市","韶山市"],"衡阳市":["市辖区","珠晖区","雁峰区","石鼓区","蒸湘区","南岳区","衡阳县","衡南县","衡山县","衡东县","祁东县","耒阳市","常宁市"],"邵阳市":["市辖区","双清区","大祥区","北塔区","邵东县","新邵县","邵阳县","隆回县","洞口县","绥宁县","新宁县","城步苗族自治县","武冈市"],"岳阳市":["市辖区","岳阳楼区","云溪区","君山区","岳阳县","华容县","湘阴县","平江县","汨罗市","临湘市"],"常德市":["市辖区","武陵区","鼎城区","安乡县","汉寿县","澧县","临澧县","桃源县","石门县","津市市"],"张家界市":["市辖区","永定区","武陵源区","慈利县","桑植县"],"益阳市":["市辖区","资阳区","赫山区","南县","桃江县","安化县","沅江市"],"郴州市":["市辖区","北湖区","苏仙区","桂阳县","宜章县","永兴县","嘉禾县","临武县","汝城县","桂东县","安仁县","资兴市"],"永州市":["市辖区","芝山区","冷水滩区","祁阳县","东安县","双牌县","道县","江永县","宁远县","蓝山县","新田县","江华瑶族自治县"],"怀化市":["市辖区","鹤城区","中方县","沅陵县","辰溪县","溆浦县","会同县","麻阳苗族自治县","新晃侗族自治县","芷江侗族自治县","靖州苗族侗族自治县","通道侗族自治县","洪江市"],"娄底市":["市辖区","娄星区","双峰县","新化县","冷水江市","涟源市"],"湘西土家族苗族自治州":["吉首市","泸溪县","凤凰县","花垣县","保靖县","古丈县","永顺县","龙山县"]},"海南省":{"海口市":["市辖区","秀英区","龙华区","琼山区","美兰区"],"三亚市":["市辖区"],"省直辖县级行政单位":["五指山市","琼海市","儋州市","文昌市","万宁市","东方市","定安县","屯昌县","澄迈县","临高县","白沙黎族自治县","昌江黎族自治县","乐东黎族自治县","陵水黎族自治县","保亭黎族苗族自治县","琼中黎族苗族自治县","西沙群岛","南沙群岛","中沙群岛的岛礁及其海域"]},"广东省":{"广州市":["市辖区","东山区","荔湾区","越秀区","海珠区","天河区","芳村区","白云区","黄埔区","番禺区","花都区","增城市","从化市"],"韶关市":["市辖区","武江区","浈江区","曲江区","始兴县","仁化县","翁源县","乳源瑶族自治县","新丰县","乐昌市","南雄市"],"深圳市":["市辖区","罗湖区","福田区","南山区","宝安区","龙岗区","盐田区"],"珠海市":["市辖区","香洲区","斗门区","金湾区"],"汕头市":["市辖区","龙湖区","金平区","濠江区","潮阳区","潮南区","澄海区","南澳县"],"佛山市":["市辖区","禅城区","南海区","顺德区","三水区","高明区"],"江门市":["市辖区","蓬江区","江海区","新会区","台山市","开平市","鹤山市","恩平市"],"湛江市":["市辖区","赤坎区","霞山区","坡头区","麻章区","遂溪县","徐闻县","廉江市","雷州市","吴川市"],"茂名市":["市辖区","茂南区","茂港区","电白县","高州市","化州市","信宜市"],"肇庆市":["市辖区","端州区","鼎湖区","广宁县","怀集县","封开县","德庆县","高要市","四会市"],"惠州市":["市辖区","惠城区","惠阳区","博罗县","惠东县","龙门县"],"梅州市":["市辖区","梅江区","梅县","大埔县","丰顺县","五华县","平远县","蕉岭县","兴宁市"],"汕尾市":["市辖区","城区","海丰县","陆河县","陆丰市"],"河源市":["市辖区","源城区","紫金县","龙川县","连平县","和平县","东源县"],"阳江市":["市辖区","江城区","阳西县","阳东县","阳春市"],"清远市":["市辖区","清城区","佛冈县","阳山县","连山壮族瑶族自治县","连南瑶族自治县","清新县","英德市","连州市"],"东莞市":[],"中山市":[],"潮州市":["市辖区","湘桥区","潮安县","饶平县"],"揭阳市":["市辖区","榕城区","揭东县","揭西县","惠来县","普宁市"],"云浮市":["市辖区","云城区","新兴县","郁南县","云安县","罗定市"]},"内蒙古自治区":{"呼和浩特市":["市辖区","新城区","回民区","玉泉区","赛罕区","土默特左旗","托克托县","和林格尔县","清水河县","武川县"],"包头市":["市辖区","东河区","昆都仑区","青山区","石拐区","白云矿区","九原区","土默特右旗","固阳县","达尔罕茂明安联合旗"],"乌海市":["市辖区","海勃湾区","海南区","乌达区"],"赤峰市":["市辖区","红山区","元宝山区","松山区","阿鲁科尔沁旗","巴林左旗","巴林右旗","林西县","克什克腾旗","翁牛特旗","喀喇沁旗","宁城县","敖汉旗"],"通辽市":["市辖区","科尔沁区","科尔沁左翼中旗","科尔沁左翼后旗","开鲁县","库伦旗","奈曼旗","扎鲁特旗","霍林郭勒市"],"鄂尔多斯市":["东胜区","达拉特旗","准格尔旗","鄂托克前旗","鄂托克旗","杭锦旗","乌审旗","伊金霍洛旗"],"呼伦贝尔市":["市辖区","海拉尔区","阿荣旗","莫力达瓦达斡尔族自治旗","鄂伦春自治旗","鄂温克族自治旗","陈巴尔虎旗","新巴尔虎左旗","新巴尔虎右旗","满洲里市","牙克石市","扎兰屯市","额尔古纳市","根河市"],"巴彦淖尔市":["市辖区","临河区","五原县","磴口县","乌拉特前旗","乌拉特中旗","乌拉特后旗","杭锦后旗"],"乌兰察布市":["市辖区","集宁区","卓资县","化德县","商都县","兴和县","凉城县","察哈尔右翼前旗","察哈尔右翼中旗","察哈尔右翼后旗","四子王旗","丰镇市"],"兴安盟":["乌兰浩特市","阿尔山市","科尔沁右翼前旗","科尔沁右翼中旗","扎赉特旗","突泉县"],"锡林郭勒盟":["二连浩特市","锡林浩特市","阿巴嘎旗","苏尼特左旗","苏尼特右旗","东乌珠穆沁旗","西乌珠穆沁旗","太仆寺旗","镶黄旗","正镶白旗","正蓝旗","多伦县"],"阿拉善盟":["阿拉善左旗","阿拉善右旗","额济纳旗"]},"辽宁省":{"沈阳市":["市辖区","和平区","沈河区","大东区","皇姑区","铁西区","苏家屯区","东陵区","新城子区","于洪区","辽中县","康平县","法库县","新民市"],"大连市":["市辖区","中山区","西岗区","沙河口区","甘井子区","旅顺口区","金州区","长海县","瓦房店市","普兰店市","庄河市"],"鞍山市":["市辖区","铁东区","铁西区","立山区","千山区","台安县","岫岩满族自治县","海城市"],"抚顺市":["市辖区","新抚区","东洲区","望花区","顺城区","抚顺县","新宾满族自治县","清原满族自治县"],"本溪市":["市辖区","平山区","溪湖区","明山区","南芬区","本溪满族自治县","桓仁满族自治县"],"丹东市":["市辖区","元宝区","振兴区","振安区","宽甸满族自治县","东港市","凤城市"],"锦州市":["市辖区","古塔区","凌河区","太和区","黑山县","义县","凌海市","北宁市"],"营口市":["市辖区","站前区","西市区","鲅鱼圈区","老边区","盖州市","大石桥市"],"阜新市":["市辖区","海州区","新邱区","太平区","清河门区","细河区","阜新蒙古族自治县","彰武县"],"辽阳市":["市辖区","白塔区","文圣区","宏伟区","弓长岭区","太子河区","辽阳县","灯塔市"],"盘锦市":["市辖区","双台子区","兴隆台区","大洼县","盘山县"],"铁岭市":["市辖区","银州区","清河区","铁岭县","西丰县","昌图县","调兵山市","开原市"],"朝阳市":["市辖区","双塔区","龙城区","朝阳县","建平县","喀喇沁左翼蒙古族自治县","北票市","凌源市"],"葫芦岛市":["市辖区","连山区","龙港区","南票区","绥中县","建昌县","兴城市"]},"河南省":{"郑州市":["市辖区","中原区","二七区","管城回族区","金水区","上街区","邙山区","中牟县","巩义市","荥阳市","新密市","新郑市","登封市"],"开封市":["市辖区","龙亭区","顺河回族区","鼓楼区","南关区","郊区","杞县","通许县","尉氏县","开封县","兰考县"],"洛阳市":["市辖区","老城区","西工区","廛河回族区","涧西区","吉利区","洛龙区","孟津县","新安县","栾川县","嵩县","汝阳县","宜阳县","洛宁县","伊川县","偃师市"],"平顶山市":["市辖区","新华区","卫东区","石龙区","湛河区","宝丰县","叶县","鲁山县","郏县","舞钢市","汝州市"],"安阳市":["市辖区","文峰区","北关区","殷都区","龙安区","安阳县","汤阴县","滑县","内黄县","林州市"],"鹤壁市":["市辖区","鹤山区","山城区","淇滨区","浚县","淇县"],"新乡市":["市辖区","红旗区","卫滨区","凤泉区","牧野区","新乡县","获嘉县","原阳县","延津县","封丘县","长垣县","卫辉市","辉县市"],"焦作市":["市辖区","解放区","中站区","马村区","山阳区","修武县","博爱县","武陟县","温县","济源市","沁阳市","孟州市"],"濮阳市":["市辖区","华龙区","清丰县","南乐县","范县","台前县","濮阳县"],"许昌市":["市辖区","魏都区","许昌县","鄢陵县","襄城县","禹州市","长葛市"],"漯河市":["市辖区","源汇区","郾城区","召陵区","舞阳县","临颍县"],"三门峡市":["市辖区","湖滨区","渑池县","陕县","卢氏县","义马市","灵宝市"],"南阳市":["市辖区","宛城区","卧龙区","南召县","方城县","西峡县","镇平县","内乡县","淅川县","社旗县","唐河县","新野县","桐柏县","邓州市"],"商丘市":["市辖区","梁园区","睢阳区","民权县","?∠?","宁陵县","柘城县","虞城县","夏邑县","永城市"],"信阳市":["市辖区","师河区","平桥区","罗山县","光山县","新县","商城县","固始县","潢川县","淮滨县","息县"],"周口市":["市辖区","川汇区","扶沟县","西华县","商水县","沈丘县","郸城县","淮阳县","太康县","鹿邑县","项城市"],"驻马店市":["市辖区","驿城区","西平县","上蔡县","平舆县","正阳县","确山县","泌阳县","汝南县","遂平县","新蔡县"]},"西藏自治区":{"拉萨市":["市辖区","城关区","林周县","当雄县","尼木县","曲水县","堆龙德庆县","达孜县","墨竹工卡县"],"昌都地区":["昌都县","江达县","贡觉县","类乌齐县","丁青县","察雅县","八宿县","左贡县","芒康县","洛隆县","边坝县"],"山南地区":["乃东县","扎囊县","贡嘎县","桑日县","琼结县","曲松县","措美县","洛扎县","加查县","隆子县","错那县","浪卡子县"],"日喀则地区":["日喀则市","南木林县","江孜县","定日县","萨迦县","拉孜县","昂仁县","谢通门县","白朗县","仁布县","康马县","定结县","仲巴县","亚东县","吉隆县","聂拉木县","萨嘎县","岗巴县"],"那曲地区":["那曲县","嘉黎县","比如县","聂荣县","安多县","申扎县","索县","班戈县","巴青县","尼玛县"],"阿里地区":["普兰县","札达县","噶尔县","日土县","革吉县","改则县","措勤县"],"林芝地区":["林芝县","工布江达县","米林县","墨脱县","波密县","察隅县","朗县"]},"陕西省":{"西安市":["市辖区","新城区","碑林区","莲湖区","灞桥区","未央区","雁塔区","阎良区","临潼区","长安区","蓝田县","周至县","户县","高陵县"],"铜川市":["市辖区","王益区","印台区","耀州区","宜君县"],"宝鸡市":["市辖区","渭滨区","金台区","陈仓区","凤翔县","岐山县","扶风县","眉县","陇县","千阳县","麟游县","凤县","太白县"],"咸阳市":["市辖区","秦都区","杨凌区","渭城区","三原县","泾阳县","乾县","礼泉县","永寿县","彬县","长武县","旬邑县","淳化县","武功县","兴平市"],"渭南市":["市辖区","临渭区","华县","潼关县","大荔县","合阳县","澄城县","蒲城县","白水县","富平县","韩城市","华阴市"],"延安市":["市辖区","宝塔区","延长县","延川县","子长县","安塞县","志丹县","吴旗县","甘泉县","富县","洛川县","宜川县","黄龙县","黄陵县"],"汉中市":["市辖区","汉台区","南郑县","城固县","洋县","西乡县","勉县","宁强县","略阳县","镇巴县","留坝县","佛坪县"],"榆林市":["市辖区","榆阳区","神木县","府谷县","横山县","靖边县","定边县","绥德县","米脂县","佳县","吴堡县","清涧县","子洲县"],"安康市":["市辖区","汉滨区","汉阴县","石泉县","宁陕县","紫阳县","岚皋县","平利县","镇坪县","旬阳县","白河县"],"商洛市":["市辖区","商州区","洛南县","丹凤县","商南县","山阳县","镇安县","柞水县"]},"四川省":{"成都市":["市辖区","锦江区","青羊区","金牛区","武侯区","成华区","龙泉驿区","青白江区","新都区","温江区","金堂县","双流县","郫县","大邑县","蒲江县","新津县","都江堰市","彭州市","邛崃市","崇州市"],"自贡市":["市辖区","自流井区","贡井区","大安区","沿滩区","荣县","富顺县"],"攀枝花市":["市辖区","东区","西区","仁和区","米易县","盐边县"],"泸州市":["市辖区","江阳区","纳溪区","龙马潭区","泸县","合江县","叙永县","古蔺县"],"德阳市":["市辖区","旌阳区","中江县","罗江县","广汉市","什邡市","绵竹市"],"绵阳市":["市辖区","涪城区","游仙区","三台县","盐亭县","安县","梓潼县","北川羌族自治县","平武县","江油市"],"广元市":["市辖区","市中区","元坝区","朝天区","旺苍县","青川县","剑阁县","苍溪县"],"遂宁市":["市辖区","船山区","安居区","蓬溪县","射洪县","大英县"],"内江市":["市辖区","市中区","东兴区","威远县","资中县","隆昌县"],"乐山市":["市辖区","市中区","沙湾区","五通桥区","金口河区","犍为县","井研县","夹江县","沐川县","峨边彝族自治县","马边彝族自治县","峨眉山市"],"南充市":["市辖区","顺庆区","高坪区","嘉陵区","南部县","营山县","蓬安县","仪陇县","西充县","阆中市"],"眉山市":["市辖区","东坡区","仁寿县","彭山县","洪雅县","丹棱县","青神县"],"宜宾市":["市辖区","翠屏区","宜宾县","南溪县","江安县","长宁县","高县","珙县","筠连县","兴文县","屏山县"],"广安市":["市辖区","广安区","岳池县","武胜县","邻水县","华莹市"],"达州市":["市辖区","通川区","达县","宣汉县","开江县","大竹县","渠县","万源市"],"雅安市":["市辖区","雨城区","名山县","荥经县","汉源县","石棉县","天全县","芦山县","宝兴县"],"巴中市":["市辖区","巴州区","通江县","南江县","平昌县"],"资阳市":["市辖区","雁江区","安岳县","乐至县","简阳市"],"阿坝藏族羌族自治州":["汶川县","理县","茂县","松潘县","九寨沟县","金川县","小金县","黑水县","马尔康县","壤塘县","阿坝县","若尔盖县","红原县"],"甘孜藏族自治州":["康定县","泸定县","丹巴县","九龙县","雅江县","道孚县","炉霍县","甘孜县","新龙县","德格县","白玉县","石渠县","色达县","理塘县","巴塘县","乡城县","稻城县","得荣县"],"凉山彝族自治州":["西昌市","木里藏族自治县","盐源县","德昌县","会理县","会东县","宁南县","普格县","布拖县","金阳县","昭觉县","喜德县","冕宁县","越西县","甘洛县","美姑县","雷波县"]},"云南省":{"昆明市":["市辖区","五华区","盘龙区","官渡区","西山区","东川区","呈贡县","晋宁县","富民县","宜良县","石林彝族自治县","嵩明县","禄劝彝族苗族自治县","寻甸回族彝族自治县","安宁市"],"曲靖市":["市辖区","麒麟区","马龙县","陆良县","师宗县","罗平县","富源县","会泽县","沾益县","宣威市"],"玉溪市":["市辖区","红塔区","江川县","澄江县","通海县","华宁县","易门县","峨山彝族自治县","新平彝族傣族自治县","元江哈尼族彝族傣族自治县"],"保山市":["市辖区","隆阳区","施甸县","腾冲县","龙陵县","昌宁县"],"昭通市":["市辖区","昭阳区","鲁甸县","巧家县","盐津县","大关县","永善县","绥江县","镇雄县","彝良县","威信县","水富县"],"丽江市":["市辖区","古城区","玉龙纳西族自治县","永胜县","华坪县","宁蒗彝族自治县"],"思茅市":["市辖区","翠云区","普洱哈尼族彝族自治县","墨江哈尼族自治县","景东彝族自治县","景谷傣族彝族自治县","镇沅彝族哈尼族拉祜族自治县","江城哈尼族彝族自治县","孟连傣族拉祜族佤族自治县","澜沧拉祜族自治县","西盟佤族自治县"],"临沧市":["市辖区","临翔区","凤庆县","云县","永德县","镇康县","双江拉祜族佤族布朗族傣族自治县","耿马傣族佤族自治县","沧源佤族自治县"],"楚雄彝族自治州":["楚雄市","双柏县","牟定县","南华县","姚安县","大姚县","永仁县","元谋县","武定县","禄丰县"],"红河哈尼族彝族自治州":["个旧市","开远市","蒙自县","屏边苗族自治县","建水县","石屏县","弥勒县","泸西县","元阳县","红河县","金平苗族瑶族傣族自治县","绿春县","河口瑶族自治县"],"文山壮族苗族自治州":["文山县","砚山县","西畴县","麻栗坡县","马关县","丘北县","广南县","富宁县"],"西双版纳傣族自治州":["景洪市","勐海县","勐腊县"],"大理白族自治州":["大理市","漾濞彝族自治县","祥云县","宾川县","弥渡县","南涧彝族自治县","巍山彝族回族自治县","永平县","云龙县","洱源县","剑川县","鹤庆县"],"德宏傣族景颇族自治州":["瑞丽市","潞西市","梁河县","盈江县","陇川县"],"怒江傈僳族自治州":["泸水县","福贡县","贡山独龙族怒族自治县","兰坪白族普米族自治县"],"迪庆藏族自治州":["香格里拉县","德钦县","维西傈僳族自治县"]},"山东省":{"济南市":["市辖区","历下区","市中区","槐荫区","天桥区","历城区","长清区","平阴县","济阳县","商河县","章丘市"],"青岛市":["市辖区","市南区","市北区","四方区","黄岛区","崂山区","李沧区","城阳区","胶州市","即墨市","平度市","胶南市","莱西市"],"淄博市":["市辖区","淄川区","张店区","博山区","临淄区","周村区","桓台县","高青县","沂源县"],"枣庄市":["市辖区","市中区","薛城区","峄城区","台儿庄区","山亭区","滕州市"],"东营市":["市辖区","东营区","河口区","垦利县","利津县","广饶县"],"烟台市":["市辖区","芝罘区","福山区","牟平区","莱山区","长岛县","龙口市","莱阳市","莱州市","蓬莱市","招远市","栖霞市","海阳市"],"潍坊市":["市辖区","潍城区","寒亭区","坊子区","奎文区","临朐县","昌乐县","青州市","诸城市","寿光市","安丘市","高密市","昌邑市"],"济宁市":["市辖区","市中区","任城区","微山县","鱼台县","金乡县","嘉祥县","汶上县","泗水县","梁山县","曲阜市","兖州市","邹城市"],"泰安市":["市辖区","泰山区","岱岳区","宁阳县","东平县","新泰市","肥城市"],"威海市":["市辖区","环翠区","文登市","荣成市","乳山市"],"日照市":["市辖区","东港区","岚山区","五莲县","莒县"],"莱芜市":["市辖区","莱城区","钢城区"],"临沂市":["市辖区","兰山区","罗庄区","河东区","沂南县","郯城县","沂水县","苍山县","费县","平邑县","莒南县","蒙阴县","临沭县"],"德州市":["市辖区","德城区","陵县","宁津县","庆云县","临邑县","齐河县","平原县","夏津县","武城县","乐陵市","禹城市"],"聊城市":["市辖区","东昌府区","阳谷县","莘县","茌平县","东阿县","冠县","高唐县","临清市"],"滨州市":["市辖区","滨城区","惠民县","阳信县","无棣县","沾化县","博兴县","邹平县"],"荷泽市":["市辖区","牡丹区","曹县","单县","成武县","巨野县","郓城县","鄄城县","定陶县","东明县"]},"甘肃省":{"兰州市":["市辖区","城关区","七里河区","西固区","安宁区","红古区","永登县","皋兰县","榆中县"],"嘉峪关市":["市辖区"],"金昌市":["市辖区","金川区","永昌县"],"白银市":["市辖区","白银区","平川区","靖远县","会宁县","景泰县"],"天水市":["市辖区","秦城区","北道区","清水县","秦安县","甘谷县","武山县","张家川回族自治县"],"武威市":["市辖区","凉州区","民勤县","古浪县","天祝藏族自治县"],"张掖市":["市辖区","甘州区","肃南裕固族自治县","民乐县","临泽县","高台县","山丹县"],"平凉市":["市辖区","崆峒区","泾川县","灵台县","崇信县","华亭县","庄浪县","静宁县"],"酒泉市":["市辖区","肃州区","金塔县","安西县","肃北蒙古族自治县","阿克塞哈萨克族自治县","玉门市","敦煌市"],"庆阳市":["市辖区","西峰区","庆城县","环县","华池县","合水县","正宁县","宁县","镇原县"],"定西市":["市辖区","安定区","通渭县","陇西县","渭源县","临洮县","漳县","岷县"],"陇南市":["市辖区","武都区","成县","文县","宕昌县","康县","西和县","礼县","徽县","两当县"],"临夏回族自治州":["临夏市","临夏县","康乐县","永靖县","广河县","和政县","东乡族自治县","积石山保安族东乡族撒拉族自治县"],"甘南藏族自治州":["合作市","临潭县","卓尼县","舟曲县","迭部县","玛曲县","碌曲县","夏河县"]},"贵州省":{"贵阳市":["市辖区","南明区","云岩区","花溪区","乌当区","白云区","小河区","开阳县","息烽县","修文县","清镇市"],"六盘水市":["钟山区","六枝特区","水城县","盘县"],"遵义市":["市辖区","红花岗区","汇川区","遵义县","桐梓县","绥阳县","正安县","道真仡佬族苗族自治县","务川仡佬族苗族自治县","凤冈县","湄潭县","余庆县","习水县","赤水市","仁怀市"],"安顺市":["市辖区","西秀区","平坝县","普定县","镇宁布依族苗族自治县","关岭布依族苗族自治县","紫云苗族布依族自治县"],"铜仁地区":["铜仁市","江口县","玉屏侗族自治县","石阡县","思南县","印江土家族苗族自治县","德江县","沿河土家族自治县","松桃苗族自治县","万山特区"],"黔西南布依族苗族自治州":["兴义市","兴仁县","普安县","晴隆县","贞丰县","望谟县","册亨县","安龙县"],"毕节地区":["毕节市","大方县","黔西县","金沙县","织金县","纳雍县","威宁彝族回族苗族自治县","赫章县"],"黔东南苗族侗族自治州":["凯里市","黄平县","施秉县","三穗县","镇远县","岑巩县","天柱县","锦屏县","剑河县","台江县","黎平县","榕江县","从江县","雷山县","麻江县","丹寨县"],"黔南布依族苗族自治州":["都匀市","福泉市","荔波县","贵定县","瓮安县","独山县","平塘县","罗甸县","长顺县","龙里县","惠水县","三都水族自治县"]},"宁夏回族自治区":{"银川市":["市辖区","兴庆区","西夏区","金凤区","永宁县","贺兰县","灵武市"],"石嘴山市":["市辖区","大武口区","惠农区","平罗县"],"吴忠市":["市辖区","利通区","盐池县","同心县","青铜峡市"],"固原市":["市辖区","原州区","西吉县","隆德县","泾源县","彭阳县"],"中卫市":["市辖区","沙坡头区","中宁县","海原县"]},"湖北省":{"武汉市":["市辖区","江岸区","江汉区","乔口区","汉阳区","武昌区","青山区","洪山区","东西湖区","汉南区","蔡甸区","江夏区","黄陂区","新洲区"],"黄石市":["市辖区","黄石港区","西塞山区","下陆区","铁山区","阳新县","大冶市"],"十堰市":["市辖区","茅箭区","张湾区","郧县","郧西县","竹山县","竹溪县","房县","丹江口市"],"宜昌市":["市辖区","西陵区","伍家岗区","点军区","猇亭区","夷陵区","远安县","兴山县","秭归县","长阳土家族自治县","五峰土家族自治县","宜都市","当阳市","枝江市"],"襄樊市":["市辖区","襄城区","樊城区","襄阳区","南漳县","谷城县","保康县","老河口市","枣阳市","宜城市"],"鄂州市":["市辖区","梁子湖区","华容区","鄂城区"],"荆门市":["市辖区","东宝区","掇刀区","京山县","沙洋县","钟祥市"],"孝感市":["市辖区","孝南区","孝昌县","大悟县","云梦县","应城市","安陆市","汉川市"],"荆州市":["市辖区","沙市区","荆州区","公安县","监利县","江陵县","石首市","洪湖市","松滋市"],"黄冈市":["市辖区","黄州区","团风县","红安县","罗田县","英山县","浠水县","蕲春县","黄梅县","麻城市","武穴市"],"咸宁市":["市辖区","咸安区","嘉鱼县","通城县","崇阳县","通山县","赤壁市"],"随州市":["市辖区","曾都区","广水市"],"恩施土家族苗族自治州":["恩施市","利川市","建始县","巴东县","宣恩县","咸丰县","来凤县","鹤峰县"],"省直辖行政单位":["仙桃市","潜江市","天门市","神农架林区"]},"河北省":{"石家庄市":["市辖区","长安区","桥东区","桥西区","新华区","井陉矿区","裕华区","井陉县","正定县","栾城县","行唐县","灵寿县","高邑县","深泽县","赞皇县","无极县","平山县","元氏县","赵县","辛集市","藁城市","晋州市","新乐市","鹿泉市"],"唐山市":["市辖区","路南区","路北区","古冶区","开平区","丰南区","丰润区","滦县","滦南县","乐亭县","迁西县","玉田县","唐海县","遵化市","迁安市"],"秦皇岛市":["市辖区","海港区","山海关区","北戴河区","青龙满族自治县","昌黎县","抚宁县","卢龙县"],"邯郸市":["市辖区","邯山区","丛台区","复兴区","峰峰矿区","邯郸县","临漳县","成安县","大名县","涉县","磁县","肥乡县","永年县","邱县","鸡泽县","广平县","馆陶县","魏县","曲周县","武安市"],"邢台市":["市辖区","桥东区","桥西区","邢台县","临城县","内丘县","柏乡县","隆尧县","任县","南和县","宁晋县","巨鹿县","新河县","广宗县","平乡县","威县","清河县","临西县","南宫市","沙河市"],"保定市":["市辖区","新市区","北市区","南市区","满城县","清苑县","涞水县","阜平县","徐水县","定兴县","唐县","高阳县","容城县","涞源县","望都县","安新县","易县","曲阳县","蠡县","顺平县","博野县","雄县","涿州市","定州市","安国市","高碑店市"],"张家口市":["市辖区","桥东区","桥西区","宣化区","下花园区","宣化县","张北县","康保县","沽源县","尚义县","蔚县","阳原县","怀安县","万全县","怀来县","涿鹿县","赤城县","崇礼县"],"承德市":["市辖区","双桥区","双滦区","鹰手营子矿区","承德县","兴隆县","平泉县","滦平县","隆化县","丰宁满族自治县","宽城满族自治县","围场满族蒙古族自治县"],"沧州市":["市辖区","新华区","运河区","沧县","青县","东光县","海兴县","盐山县","肃宁县","南皮县","吴桥县","献县","孟村回族自治县","泊头市","任丘市","黄骅市","河间市"],"廊坊市":["市辖区","安次区","广阳区","固安县","永清县","香河县","大城县","文安县","大厂回族自治县","霸州市","三河市"],"衡水市":["市辖区","桃城区","枣强县","武邑县","武强县","饶阳县","安平县","故城县","景县","阜城县","冀州市","深州市"]},"广西壮族自治区":{"南宁市":["市辖区","兴宁区","青秀区","江南区","西乡塘区","良庆区","邕宁区","武鸣县","隆安县","马山县","上林县","宾阳县","横县"],"柳州市":["市辖区","城中区","鱼峰区","柳南区","柳北区","柳江县","柳城县","鹿寨县","融安县","融水苗族自治县","三江侗族自治县"],"桂林市":["市辖区","秀峰区","叠彩区","象山区","七星区","雁山区","阳朔县","临桂县","灵川县","全州县","兴安县","永福县","灌阳县","龙胜各族自治县","资源县","平乐县","荔蒲县","恭城瑶族自治县"],"梧州市":["市辖区","万秀区","蝶山区","长洲区","苍梧县","藤县","蒙山县","岑溪市"],"北海市":["市辖区","海城区","银海区","铁山港区","合浦县"],"防城港市":["市辖区","港口区","防城区","上思县","东兴市"],"钦州市":["市辖区","钦南区","钦北区","灵山县","浦北县"],"贵港市":["市辖区","港北区","港南区","覃塘区","平南县","桂平市"],"玉林市":["市辖区","玉州区","容县","陆川县","博白县","兴业县","北流市"],"百色市":["市辖区","右江区","田阳县","田东县","平果县","德保县","靖西县","那坡县","凌云县","乐业县","田林县","西林县","隆林各族自治县"],"贺州市":["市辖区","八步区","昭平县","钟山县","富川瑶族自治县"],"河池市":["市辖区","金城江区","南丹县","天峨县","凤山县","东兰县","罗城仫佬族自治县","环江毛南族自治县","巴马瑶族自治县","都安瑶族自治县","大化瑶族自治县","宜州市"],"来宾市":["市辖区","兴宾区","忻城县","象州县","武宣县","金秀瑶族自治县","合山市"],"崇左市":["市辖区","江洲区","扶绥县","宁明县","龙州县","大新县","天等县","凭祥市"]},"重庆市":{"市辖区":["万州区","涪陵区","渝中区","大渡口区","江北区","沙坪坝区","九龙坡区","南岸区","北碚区","万盛区","双桥区","渝北区","巴南区","黔江区","长寿区"],"-":["綦江县","潼南县","铜梁县","大足县","荣昌县","璧山县","梁平县","城口县","丰都县","垫江县","武隆县","忠县","开县","云阳县","奉节县","巫山县","巫溪县","石柱土家族自治县","秀山土家族苗族自治县","酉阳土家族苗族自治县","彭水苗族土家族自治县"],"市":["江津市","合川市","永川市","南川市"]},"新疆维吾尔自治区":{"乌鲁木齐市":["市辖区","天山区","沙依巴克区","新市区","水磨沟区","头屯河区","达坂城区","东山区","乌鲁木齐县"],"克拉玛依市":["市辖区","独山子区","克拉玛依区","白碱滩区","乌尔禾区"],"吐鲁番地区":["吐鲁番市","鄯善县","托克逊县"],"哈密地区":["哈密市","巴里坤哈萨克自治县","伊吾县"],"昌吉回族自治州":["昌吉市","阜康市","米泉市","呼图壁县","玛纳斯县","奇台县","吉木萨尔县","木垒哈萨克自治县"],"博尔塔拉蒙古自治州":["博乐市","精河县","温泉县"],"巴音郭楞蒙古自治州":["库尔勒市","轮台县","尉犁县","若羌县","且末县","焉耆回族自治县","和静县","和硕县","博湖县"],"阿克苏地区":["阿克苏市","温宿县","库车县","沙雅县","新和县","拜城县","乌什县","阿瓦提县","柯坪县"],"克孜勒苏柯尔克孜自治州":["阿图什市","阿克陶县","阿合奇县","乌恰县"],"喀什地区":["喀什市","疏附县","疏勒县","英吉沙县","泽普县","莎车县","叶城县","麦盖提县","岳普湖县","伽师县","巴楚县","塔什库尔干塔吉克自治县"],"和田地区":["和田市","和田县","墨玉县","皮山县","洛浦县","策勒县","于田县","民丰县"],"伊犁哈萨克自治州":["伊宁市","奎屯市","伊宁县","察布查尔锡伯自治县","霍城县","巩留县","新源县","昭苏县","特克斯县","尼勒克县"],"塔城地区":["塔城市","乌苏市","额敏县","沙湾县","托里县","裕民县","和布克赛尔蒙古自治县"],"阿勒泰地区":["阿勒泰市","布尔津县","富蕴县","福海县","哈巴河县","青河县","吉木乃县"],"省直辖行政单位":["石河子市","阿拉尔市","图木舒克市","五家渠市"]}}

Android平板应用

http://news.newhua.com/news/2011/0801/128694.shtml

2011年12月26日星期一

戴尔 Streak 10 Pro 平板 3.2 root 方法

3.2和3.1的ROOT方法
=============================================================
1、首先开机,打开“设置-应用程序-开发-USB调试”。如果电脑没有自行安装好驱动,那就在开机状态下利用豌豆荚或者91手机助手安装驱动。
2、关机,然后按“重启也+电源键”,使机器进入APX模式。此时屏幕处于黑屏状态,电脑会提示安装APX驱动,驱动在上边提供的强刷包中。
3、执行最上面提供的对应版本的强刷包中的ROOT.BAT,然后就是一个等啊。等着S10自动重启,ROOT.BAT的命令行窗口自行关闭。
4、恭喜您成功了。验证您ROOT成功与否成功方法是看应用程序列表中有没有superuser这个软件的图标。

参考文章:1. http://bbs.gfan.com/android-3033020-1-1.html
2. how-to-root-dell-streak-10-pro-zh.html

2011年12月24日星期六

Dell streak 10 pro 系统升级

1.此平板电脑的官方介绍见此 product_feature_Streak

2.全新的Dell streak 10 pro预装的是Google Android Honeycomb3.1系统,但是现在可以升级到3.2系统
官方升级方法见此: streak_10_pro_upgrade

3.如果你使用的是代理上网,将无法按照上面的方法升级系统。此时可以在平板电脑的浏览器中打开下面链接来下载pkg升级文件:
http://mobileupdate.dell.com/?version=GALLO1A154615

2011年12月13日星期二

动态加载jQuery然后处理www.ncl.ucar.edu网页内容


//----- 动态加载jQuery
var j = document.createElement('script');
j.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js';

var h = document.getElementsByTagName('head')[0];

h.appendChild(j);

//------ 添加一个div用来保存结果
clear();
$('#wrap').prepend('
');

//------- 处理resource名称
clear();
var dts = $('#general_main > dl >dt');
var titles='';
dts.each(function(){
var title = $(this).children('strong').text();
console.log(title);
titles += title + ',';
})

$('#result').text(titles);

//----- 处理默认值
clear();
var dts = $('#general_main > dl >dd');
var titles='';
dts.each(function(){
if($.trim($(this).text() )=='' ) return;

var title = $(this).find('p').last().text();
console.log(title);
if(title){
titles += title + '##';
}else{
titles += 'novalue##';
}

})

$('#result').text(titles);