[转载]android-charts 基于Java和Android开发的图形图表控件

mikel阅读(1214)

[转载]android-charts 基于Java和Android开发的图形图表控件 | CG的技术博客.

这里是Android-charts的说明页面

a collection of Android charts writen in java, can use in your Android apps when you need.
android-charts是一套基于Java和Android开发的图形图表控件,

including these charts blow:
目前该套图表主要包括以下组件:

  1. 网格图(gird chart)
  2. 线图(line charts),包含单线图和多线图
  3. 柱状图(stick charts),包含基本柱状图和特殊柱状图 支持显示均线
  4. K线或蜡烛线图(candle stick-chart) 支持显示均线
  5. 饼图(pie chart or pizza chart) 包括基本饼图和分割饼图
  6. 雷达图或蛛网图(radar chart or spider web chart) 包含面积雷达图

以上组件目前均以稳定版本发布,已有组件目前正在不断完善,新的组件在不断的添加中。

本地下载地址:
http://limc.co/code/androidcharts/AndroidCharts.zip

项目代码管理地址:
https://code.google.com/p/android-charts/

以下是画面截图(左上角为控件标题):
ScreenShot

[转载]推荐20款非常优秀的 jQuery 工具提示插件

mikel阅读(1196)

[转载]推荐20款非常优秀的 jQuery 工具提示插件 – 梦想天空(山边小溪) – 博客园.

工具提示(Tooltip)在网站中的一个小功能,但却有很重要的作用,常用于显示一些温馨的提示信息。如果网站中的工具提示功能做得非常有创意的话能够加深用户对网站印象。因此,今天这篇文章向大家推荐的20款优秀的 JQuery Tooltip 插件就是用于帮助你制作漂亮的工具提示效果。

1. Dynamic tooltip

flowplayer-dynamic-tooltip-jquery-tooltip-plugin-for-web-design

 

2. jGrowl

stanlemon-jgrowl-jquery-tooltip-plugin-for-web-design

3. jQuery Horizontal Tooltips Menu Tutorials

queness-horizontal-tooltips-menu-tutorials-jquery-tooltip-plugin-for-web-design

 

4. Coda Popup Bubble

jqueryfordesigners-coda-popup-bubble-jquery-tooltip-plugin-for-web-design

 

5. The Tooltip

banner js ajax freebies css

 

6. TipTip

code-drewwilson-tiptip-jquery-tooltip-plugin-for-web-design

 

7. (mb)Tooltip

pupunzi-mb-tooltip-jquery-tooltip-plugin-for-web-design

 

8. vTip

vertigo-project-vtip-jquery-tooltip-plugin-for-web-design

10. jQuery Ajax Tooltip

rndnext-blogspot-jquery-ajax-tooltip-jquery-tooltip-plugin-for-web-design

 

11. Digg-style post sharing tool with jQuery

queness-digg-style-post-sharing-tool-jquery-tooltip-plugin-for-web-design

 

12. Input Floating Hint Box

nicolae-namolovan-googlepages-input-hint-box-jquery-tooltip-plugin-for-web-design

 

13. Simpletip

simpletip-craigsworks-jquery-tooltip-plugin-for-web-design

 

14. qTip

craigsworks-qtip-jquery-tooltip-plugin-for-web-design

 

15. Orbital Tooltip

userfirst-orbital-jquery-tooltip-plugin-for-web-design

 

16. Tooltip

bassistance-tooltip-jquery-tooltip-plugin-for-web-design

 

17. tipsy

onehackoranother-tipsy-jquery-tooltip-plugin-for-web-design

 

18. Easiest jQuery Tooltip Ever

cssglobe-easiest-jquery-tooltip-ever-jquery-tooltip-plugin-for-web-design

 

19. Shiny Tooltips

 

20. BeautyTips

lullabot-beautytips-jquery-tooltip-plugin-for-web-design

[转载]"六度空间"的应用——找出两个陌生人之间的关系(二)

mikel阅读(923)

[转载]”六度空间”的应用——找出两个陌生人之间的关系(二) – Create Chen – 博客园.

终于”完工”

哎, 熬了好几个夜, 掉了好多根头发, 终于接近完工, 如果真的要拿给别人用还需要修补很多东西. 先发几张程序运行的图片吧:) 第一张是找出两人关系, 我试了很多人, 几乎都只需要通过一个人就能找到另一个人, 第二张是寻找XML文件中某个人有哪些好友.

存储内容的改进

在写上篇博客的时候程序一直在运行(在保存人和人之间的完整对应关系), 我估算还需要好几个小时才能停下来, 所存储的XML文件也会大的惊人, 估算达到1GB以上, 其实运算之前这个时候的XML中已经包含了所有的人, 只不过暂时是一种类似”有向图”(A是B的好友, B不是A的好友)的关系, 现在运算的也只是把有向图的关系完全拓展开, 变成无向图(A是B的好友, B也是A的好友而已). 在发现完整关系的情况下, 存储所需要的空间如此之大时, 我放弃了这种方法. 在下载完所有人的头像照片(4万多张)后, 我把XML中每个节点的school和faceUri删除掉了, 这样存储人与人的关系只用了15.8MB.

现在的存储结构如下:

<? xml version="1.0"?>
<Relations>
    <Person id="" name="">
        <Friend id="" name=""/>
        <Friend id="" name=""/>
        ........
    </Person>
    <Person id="" name="">
        <Friend id="" name=""/>
        <Friend id="" name=""/>
        ........
    </Person>
</Relations>

从这个XML中通过一些XML的操作方法可以就可以得到很多信息了.
RelationOperate类

1. 每次定义一个RelationOperate类, 需要传进一个XML文件地址, 以对它进行操作

private XmlDocument xmlDoc = new XmlDocument();
public RelationOperate(string xmlDocPath)
{
    xmlDoc.Load(xmlDocPath);
}

2. 通过一个id找到他的好友列表

/// <summary>
/// 获取一个id的好友
/// </summary>
/// <param name="id">要查找的id</param>
/// <returns>该id的好友id列表</returns>
public List<string> getFriend(string id)
{
List<string> friendList = new List<string>();
var PersonList = xmlDoc.SelectNodes("//Person"); //所有的Person节点
foreach (XmlNode xmlNode in PersonList)
    //若果Person节点已经包含了该id的用户
    if (xmlNode.Attributes["id"].InnerText == id)
    {
        //则增加这个Person节点的每一个子节点到friendList中
        //因为他的每一个子节点都是他的好友
        foreach (XmlNode node in xmlNode.ChildNodes)
            friendList.Add(node.Attributes["id"].InnerText);
        return friendList;
    }
//上面的条件不满足时, 就查找哪些Person的子节点(朋友)里边包含这个id
foreach (XmlNode xmlNode in PersonList)
    foreach (XmlNode node in xmlNode.ChildNodes)
    {
        if (node.Attributes["id"].InnerText == id)
        {
            friendList.Add(xmlNode.Attributes["id"].InnerText);
            break;
        }
    }
return friendList;
}

3. 获取一个id的姓名

public string getName(string id)
{
var PersonList = xmlDoc.SelectNodes("//Person"); //所有的Person节点
foreach (XmlNode xmlNode in PersonList)
    //若果Person节点已经包含了该id的用户
    if (xmlNode.Attributes["id"].InnerText == id)
    {
        return xmlNode.Attributes["name"].InnerText;
    }
//上面的条件不满足时, 就查找哪些Person的子节点(朋友)里边包含这个id
string name = "";
foreach (XmlNode xmlNode in PersonList)
    foreach (XmlNode node in xmlNode.ChildNodes)
    {
        if (node.Attributes["id"].InnerText == id)
        {
            name = node.Attributes["name"].InnerText;
            return name;
        }
    }
return name;
}

4. 获取一个姓名的id号码

public string getID(string name)
{
    var PersonList = xmlDoc.SelectNodes("//Person"); //所有的Person节点
    foreach (XmlNode xmlNode in PersonList)
        //若果Person节点已经包含了该id的用户
        if (xmlNode.Attributes["name"].InnerText.Contains(name))
        {
            return xmlNode.Attributes["id"].InnerText;
        }
    //上面的条件不满足时, 就查找哪些Person的子节点(朋友)里边包含这个id
    foreach (XmlNode xmlNode in PersonList)
        foreach (XmlNode node in xmlNode.ChildNodes)
        {
            if (node.Attributes["name"].InnerText.Contains(name))
            {
                string id = node.Attributes["id"].InnerText;
                return id;
            }
        }
    return null;
}

5. 获取两个id之间的关系(广度优先)

public List<string> getRelation(string A, string B)
{
    //A直接认识B 0层关系
    var Afriend = getFriend(A);
    List<string> relation = new List<string>();
    foreach (string id in Afriend)
        if (id == B)
        {
            relation.Add(A);
            relation.Add(B);
            return relation;
        }
    //A的好友是B的好友  1层关系
    var Bfriend = getFriend(B);
    foreach (string friendA in Afriend)
        foreach (string friendB in Bfriend)
        {
            //A的某个朋友也是B的某个朋友
            if (friendA == friendB)
            {
                relation.Add(A);
                relation.Add(friendA);
                relation.Add(B);
                return relation;
            }
        }
    //A的好友的好友是B的好友 2层关系
    List<FriendFriend> AFriendFriend = new List<FriendFriend>();
    foreach (string friend in Afriend)
    {
        if (friend != B)    //涉及两层关系时, A的Friend不直接是B
        {
            FriendFriend ff = new FriendFriend();
            ff.parent = friend;
            ff.friend = getFriend(friend);
            AFriendFriend.Add(ff);
        }
    }
    foreach (FriendFriend ff in AFriendFriend)
    {
        foreach (string friend in ff.friend)
            //涉及两层关系时,A的Friend的Friend不直接是B
            if (friend != A)
            {
                foreach (string friendB in Bfriend)
                {
                    //B的朋友也不直接是A, B的朋友也不直接是A的朋友
                    if ((friendB != A) && (friendB != ff.parent))
                    {
                        if (friend == friendB)
                        {
                            relation.Add(A);
                            relation.Add(ff.parent);
                            relation.Add(friend);
                            relation.Add(B);
                            break;
                        }
                        return relation;
                    }
                }
            }
    }
    //涉及3层关系  A的好友的好友C 是 B的好友的好友
    //C一定是那个种子节点
    //还没写3层关系
    return relation;
}

总结

结合上边的类操作已经保存好了的XML, 可以用WPF或者其它做出一些找关系的程序, 在自己的网站上加上这么一个功能, 很绚丽的哦. 另外我还发现应该用手机人人网的协议接口, 那个页面下载的内容精简, 没有很复杂的CSS, JavaScript等等, 以后真正要做出应用的话应该研究手机版的协议. 本文也只是提供一个思路, 可以做出一个这个东西. 另外真正了解”六度空间”的威力也是很好的, 如果一个产品被20个人看到, 每个人推荐给了另外的20个人…循环下去, 这个对产品的推广是十分有好处的. 当下很多东西正是基于”六度空间”的这个理论, 用户群变得超级庞大.

[转载]"六度空间"的应用——找出两个陌生人之间的关系(一)

mikel阅读(1063)

[转载]”六度空间”的应用——找出两个陌生人之间的关系(一) – Create Chen – 博客园.

      前几日在人人网上看到有位北京大学的做了一个”人人网六度空间”的Flash, 觉得很好玩, 遂向其请教一二, 自己也做了一个, 这篇就来做个梳理和总结吧, 哪些性能方面不好的希望大家能够指出并改进. 本篇没有完整的代码或程序可以下载, 更没有我获取到的数据可以下载, 数据也很大, 我用XML存储了我们学校整个人际关系用了几百兆! 切勿用文章内的思路做盗取他人隐私违法犯罪的商业应用!

“六度空间”可行性分析

六度空间”理论又称作六度分隔(Six Degrees of Separation)理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过六个人你就能够认识任何一 个陌生人。”该理论产生于20世纪60年代,由美国心理学家米尔格伦提出。

输入一个人A, 找到另一个人B, 通过在线联网的方式(本地不保存数据)找到A和B之间的关系那当然好, 但在人人网没有提供一个能快速找到任意一个人的好友的API情况下做到这点几乎是不可能的(时间方面). 我做了一个测试, 如果一个人有1000个好友, 在120kbps的网速下找到他的所有好友大概需要8s钟! 可想而知, 你想找出A和B之间的关系, 采用双向搜索自然来得快不少, 先找A所有的好友, 再找B的好友, 看看有没有交集…没有继续找A所有的好友的好友, 找B所有的好友的好友, 看看有没有交集…到这一步需要的时间地球大概已经转了半圈了, 我昨晚找了C的好友, 再找C的好友的所有好友, 从早上1:58找到早上6:01…所以我说这么多意思是没有快速API的情况下做成在线版几乎不可能, 除非你本地保存了数据, 说着A和B是直接好友关系.

那么就下载所有人人网用户的信息?人人网有近2亿账号, 如果每个只需要5秒的话,  对于我这个带宽120kbps, 硬盘250GB的电脑显然也不可能…那么就从小范围做起吧, 就找出我们学校所有人之间的关系吧.

得到学校里每个人, 以及每个人的好友

假设学校里的每个人都注册了人人网(对于那些没有注册人人网的俺也没法找到他们, 呵呵), 我偶然想到了一个特殊的人人网用户A, 这个用户是学校一个聊天论坛在人人网里的一个账号, 好友数量已经达到2000, 我有如下假设: 任何一个学校里的人B, 一定有一个他认识的人认识A, 按照人人网里的话说叫做”A和B有共同好友”, 这个假设根据我个人经验认为是正确的, 如果B不满足这个条件, 这个人一定孤陋寡闻, 不参加社交-_-!!

所以找到学校里每一个人, 可以以这个A为起点, 找到A的所有好友集合S1, 再找到S的所有好友, 那么整个学校的人的名单90%以上已经到手. 在昨天那个月黑风高的夜晚, 我整整用了4个小时把学校所有人都下载下来了(大概15W条记录).

存储人和人之间的关系

光下载到到人的名单还不行, 我并不想以A为中心建立大家之间的关系, 因为A毕竟是一个组织, 不是一个人, 以它为中心的关系几乎都是浮云, 现在已经有A的所有好友, 以及A的好友的好友集合S2{sa, sb, sc…}, 学校的所有人都包含在S2中了, 任何人之间的关系可以用图表示, 在人人网中且是无向图(没有A是B的好友, B不是A的好友这种情况), 所以还得再逆向的找出S2中的每个人的好友, 并存储这个关系!

图可以用矩阵法和邻接表表示, 因为这个关系图属于稀疏矩阵, 应该用邻接表表示更省空间(用矩阵表示也是几乎不可能的事情, 因为如果有学校有10000个人, 那么就得建立一个10000*10000的矩阵, 当然可以利用矩阵的一些运算比如找出矩阵特殊值等方法压缩这个矩阵, 但压缩之后的矩阵仍然不小…). 因此我建立了如下一个XML格式的文件存储人和人之间的关系.





........


........

这个把全校所有人都爬虫出来的代码是这样的, 先找出A的所有好友:

public void downLoadData()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"C:\Users\Chen Hua\Desktop\Relation.xml");

renrenoperation renren = new renrenoperation();
Console.WriteLine("Login Success");
//获得A的好友
var peopleList = renren.Get_FriendList("A的id号码");
foreach (Person person in peopleList)
{
var node = doc.CreateElement("Person");
node.SetAttribute("id", person.id);
node.SetAttribute("name", person.name);
node.SetAttribute("school", person.school);
node.SetAttribute("faceUri", person.faceUri);
doc.DocumentElement.AppendChild(node);
var list2 = renren.Get_FriendList(person.id);
Console.WriteLine(person.name + " Write Success.");
//获得A的每一个好友的好友
foreach (Person person2 in list2)
{
if (person2.school.Contains("某某学校") || person2.school.Contains("南京市"))
{
var friend = doc.CreateElement("Friend");
friend.SetAttribute("id", person2.id);
friend.SetAttribute("name", person2.name);
friend.SetAttribute("school", person2.school);
friend.SetAttribute("faceUri", person2.faceUri);
node.AppendChild(friend);
}
}
}
}

接下来就是把A的好友的好友提取出来, 找出A的好友的好友的好友…(逻辑有点那个…不知道大家有没有想通)

static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.Load(@"C:\Users\Chen Hua\Desktop\Relation.xml");
Console.WriteLine("XML加载完毕.");
var PersonList = doc.SelectNodes("//Person"); //所有的Person
foreach (XmlNode EveryPersonNode in PersonList) //Person中所有的节点
{
foreach (XmlNode EveryPersonChildNode in EveryPersonNode.ChildNodes) //每个Person的子节点, 朋友
{
if (ContainedThisPerson(EveryPersonChildNode, PersonList)) //如果发现这个朋友已经在Person集合中
{ }
else //如果不存在
{
var NewPersonNode = doc.CreateElement("Person");//新建一个节点
NewPersonNode.SetAttribute("id", EveryPersonChildNode.Attributes["id"].InnerText);//设置id, 名字, 学校, 头像等
NewPersonNode.SetAttribute("name", EveryPersonChildNode.Attributes["name"].InnerText);
NewPersonNode.SetAttribute("school", EveryPersonChildNode.Attributes["school"].InnerText);
NewPersonNode.SetAttribute("faceUri", EveryPersonChildNode.Attributes["faceUri"].InnerText);
{//开始加载这个节点有哪些朋友
foreach (XmlNode AnotherPersonList in PersonList)
foreach (XmlNode AnotherPersonListChildNode in AnotherPersonList.ChildNodes)
if (AnotherPersonListChildNode.Attributes["id"].InnerText == NewPersonNode.Attributes["id"].InnerText)
{
var newFriendNode = doc.CreateElement("Friend");
newFriendNode.SetAttribute("id", AnotherPersonListChildNode.ParentNode.Attributes["id"].InnerText);
newFriendNode.SetAttribute("name", AnotherPersonListChildNode.ParentNode.Attributes["name"].InnerText);
newFriendNode.SetAttribute("school", AnotherPersonListChildNode.ParentNode.Attributes["school"].InnerText);
newFriendNode.SetAttribute("faceUri", AnotherPersonListChildNode.ParentNode.Attributes["faceUri"].InnerText);
NewPersonNode.AppendChild(newFriendNode);
break;
}
}
doc.DocumentElement.AppendChild(NewPersonNode);
Console.WriteLine("Add New Node " + NewPersonNode.Attributes["name"].InnerText);
}
}
}
doc.Save(@"C:\Users\Chen Hua\Desktop\Relation.xml");
}

private static bool ContainedThisPerson(XmlNode node, XmlNodeList nodeList)
{
foreach (XmlNode nodeInList in nodeList)
{
if (node.Attributes["id"].InnerText == nodeInList.Attributes["id"].InnerText)
return true;
}
return false;
}

获得一个人的好友列表

上面说了那么多, 怎么获得好友列表呢?

1. 分析登陆协议, 看登陆时POST了哪些信息, 写一个登陆方法

2. 去http://friend.renren.com/GetFriendList.do?curpage=第几页好友(每一页显示20位)&id=你需要找的id

获得第2步每一页的字符串, 用正则表达式提取出好友的信息, 正则表达式我写好了:

@”<p class=””avatar””><a href=””[a-zA-z]+://www\.renren\.com/profile\.do\?id=([0-9]*)””><img src=””([a-zA-z]+://hdn.xnimg.cn/photos/[^\s]*)””[\s]?alt=””[a-zA-z]+://hdn.xnimg.cn/photos/[^\s]*jpg[\s]?.*””>[\s]?<dl>[\s]?<dt>.*</dt>[\s]?<dd><a href=””[^\s]*””>(.*)</a>[\s]+</dd>[\s]?.*[\s]?<dt>.*</dt>[\s]?<dd>(.*)</dd>”

下图是一个获取好友列表的测试图片:

先写这么多, 程序还在哗啦啦的运行中, 下篇继续…争取多一些程序优化方面的.

[转载]感知哈希算法——找出相似的图片

mikel阅读(1870)

[转载]感知哈希算法——找出相似的图片 – Create Chen – 博客园.

Google 图片搜索功能

在谷歌图片搜索中, 用户可以上传一张图片, 谷歌显示因特网中与此图片相同或者相似的图片.

        比如我上传一张照片试试效果:

原理讲解

参考Neal Krawetz博士的这篇文章, 实现这种功能的关键技术叫做”感知哈希算法”(Perceptual Hash Algorithm), 意思是为图片生成一个指纹(字符串格式), 两张图片的指纹越相似, 说明两张图片就越相似. 但关键是如何根据图片计算出”指纹”呢? 下面用最简单的步骤来说明一下原理:

第一步 缩小图片尺寸

将图片缩小到8×8的尺寸, 总共64个像素. 这一步的作用是去除各种图片尺寸和图片比例的差异, 只保留结构、明暗等基本信息.

第二步 转为灰度图片

将缩小后的图片, 转为64级灰度图片.

第三步 计算灰度平均值

计算图片中所有像素的灰度平均值

第四步 比较像素的灰度

将每个像素的灰度与平均值进行比较, 如果大于或等于平均值记为1, 小于平均值记为0.

第五步 计算哈希值

将上一步的比较结果, 组合在一起, 就构成了一个64位的二进制整数, 这就是这张图片的指纹.

第六步 对比图片指纹

得到图片的指纹后, 就可以对比不同的图片的指纹, 计算出64位中有多少位是不一样的. 如果不相同的数据位数不超过5, 就说明两张图片很相似, 如果大于10, 说明它们是两张不同的图片.

代码实现 (C#版本)

下面我用C#代码根据上一节所阐述的步骤实现一下.

using System;
using System.IO;
using System.Drawing;

namespace SimilarPhoto
{
class SimilarPhoto
{
Image SourceImg;

public SimilarPhoto(string filePath)
{
SourceImg = Image.FromFile(filePath);
}

public SimilarPhoto(Stream stream)
{
SourceImg = Image.FromStream(stream);
}

public String GetHash()
{
Image image = ReduceSize();
Byte[] grayValues = ReduceColor(image);
Byte average = CalcAverage(grayValues);
String reslut = ComputeBits(grayValues, average);
return reslut;
}

// Step 1 : Reduce size to 8*8
private Image ReduceSize(int width = 8, int height = 8)
{
Image image = SourceImg.GetThumbnailImage(width, height, () =&gt; { return false; }, IntPtr.Zero);
return image;
}

// Step 2 : Reduce Color
private Byte[] ReduceColor(Image image)
{
Bitmap bitMap = new Bitmap(image);
Byte[] grayValues = new Byte[image.Width * image.Height];

for(int x = 0; xfor (int y = 0; y &lt; image.Height; y++)
{
Color color = bitMap.GetPixel(x, y);
byte grayValue = (byte)((color.R * 30 + color.G * 59 + color.B * 11) / 100);
grayValues[x * image.Width + y] = grayValue;
}
return grayValues;
}

// Step 3 : Average the colors
private Byte CalcAverage(byte[] values)
{
int sum = 0;
for (int i = 0; i &lt; values.Length; i++)
sum += (int)values[i];
return Convert.ToByte(sum / values.Length);
}

// Step 4 : Compute the bits
private String ComputeBits(byte[] values, byte averageValue)
{
char[] result = new char[values.Length];
for (int i = 0; i &lt; values.Length; i++)
{
if (values[i] &lt; averageValue)
result[i] = '0';
else
result[i] = '1';
}
return new String(result);
}

// Compare hash
public static Int32 CalcSimilarDegree(string a, string b)
{
if (a.Length != b.Length)
throw new ArgumentException();
int count = 0;
for (int i = 0; i &lt; a.Length; i++)
{
if (a[i] != b[i])
count++;
}
return count;
}
}
}

谷歌服务器里的图片数量是百亿级别的, 我电脑里的图片数量当然没法比, 但以前做过爬虫程序, 电脑里有40,000多人的头像照片, 就拿它们作为对比结果吧! 我计算出这些图片的”指纹”, 放在一个txt文本中, 格式如下.

        用ASP.NET写一个简单的页面, 允许用户上传一张图片, 后台计算出该图片的指纹, 并与txt文本中各图片的指纹对比, 整理出结果显示在页面中, 效果如下:

本文地址: http://www.cnblogs.com/technology/archive/2012/07/12/Perceptual-Hash-Algorithm.html

[转载]百度地图离线API及地图数据下载工具

mikel阅读(1510)

[转载]百度地图离线API及地图数据下载工具-尝鲜篇 – liongis – 博客园.

上次做了一个谷歌地图离线API和地图数据下载工具,详见:http://www.cnblogs.com/liongis/archive/2012/04/27/2474194.html

有朋友问是否可以做一个百度地图的离线包,最近抽空弄了弄,花了半天的时间,终于搞出来了,不过目前还有点问题,在IE浏览器下运行有点问题,在谷歌浏览器下显示没有问题。

离线包中已经包含4-6级中国地区的数据,暂时没有影像和三维的。

代码如下:





百度离线版DEMO
<script type="text/javascript" src="js/apiv1.3.min.js"></script><!--script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script-->

<div id="container" style="width: 520px; height: 340px; border: 1px solid gray;"></div>

&nbsp;

<script type="text/javascript">// <![CDATA[
 var map = new BMap.Map("container",{mapType: BMAP_NORMAL_MAP});      //设置卫星图为底图
 var point = new BMap.Point(116.404, 39.915);    // 创建点坐标
 map.centerAndZoom(point,5);                     // 初始化地图,设置中心点坐标和地图级别。

 //map.addControl(new BMap.MapTypeControl());
 map.addControl(new BMap.NavigationControl());
 map.enableScrollWheelZoom();                  // 启用滚轮放大缩小。
 map.enableKeyboard();                         // 启用键盘操作。  
 //map.setCurrentCity("北京");          // 设置地图显示的城市 此项是必须设置的

// ]]></script>

js目录下的apijs1.3.min.js为百度地图的离线包

maptile目录为4-6级中国地区的地图数据,数据存储的方式为z/x/y

如果朋友觉得现在的地图数据太少的话,可以使用下面的百度地图数据下载工具进行下载:

下载界面:

把下载完的数据放到maptile目录下即可浏览到。

 

郑重申明:地图数据归地图提供商所有,本程序只为学习使用。

百度地图离线包下载地址:BaiduMapV1.3.zip

百度地图数据下载工具下载地址:MapCacheV0.1.zip

这个版本只是一个尝试,还存在一些问题:

1.IE下不能正常显示地图。

2.离线数据只支持地图,影像和三维还不支持。

3.其它功能没有测试。

感兴趣的朋友可以一起讨论,学习。

 

[转载]Asp.Net MVC 4.0 Web API

mikel阅读(1085)

[转载]Asp.Net MVC 4.0【Web API】 – 辉太 – 博客园.

随着技术的前沿,ASP.NET也很快就步入4.0的时代了,虽然现在还没正式应用,据说MVC4.0出来的新特性很是犀利,各种犀利。结果一下给没把持住,就涉足了一下。所以分享一下,大家愿意涉足的就了解一哈。

首先,我们需要给我们的VS装环境,目前MVC4.0还是(Beta)RC版,如果日后微软发布正式版,我们需要卸载掉今天装的RC版去装正式版用。(安装MVC4.0连接是:http://www.asp.net/vnext/overview/downloads).

MVC 4.0新出的特性可谓关注最强烈的就是Web API,那Web API 到底是什么东西呢?

ASP.NET的API也是一个框架,可以很容易地建立HTTP服务。既然了解到他也是一个框架,那么我们来搞一个简单的ASP.NET的Web API.

创建一个Web API项目

启动Visual Studio 2010,并选择新建项目从 开始页。或从文件菜单中,选择“ 新建“,然后项目。在模板 “窗格中,选择已安装的模板 和扩展的Visual C#节点。在Visual C#中,选择网络。在项目模板列表中,选择“ ASP.NET MVC Web应用程序。命名项目“HelloWebAPI”,然后单击“ 确定“。如下图1.

图1.在新的ASP.NET MVC 4项目 “对话框中,选择的Web API ,然后单击“ 确定“。如下图2.

图2.

添加模型

一个模型是一个对象,表示应用程序中的数据。ASP.NET的Web API可以自动序列化你的模型,JSON,XML或其他格式,然后写入到HTTP响应消息体序列化的数据。只要客户端可以读取序列化格式,它可以反序列化 的对象。大多数客户可以解析XML或JSON。此外,客户端可以显示的格式,希望通过设置HTTP请求消息中的Accept头。

开始创建一个简单的模型,代表了产品。
如果解决方案资源管理器中不可见,单 击“ 查看 “菜单,并选择“解决方案资源管理器”。在Solution Explorer中,右键单击Models文件夹。从上下文菜单中,选择添加 ,然后选择类。类命名为“Product”。接下来,添加以下属性的Product类别。具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace HelloWebAPI.Models
{
public class Product : Object
{
public int Id { get; set; }

public string Name { get; set; }

public string Category { get; set; }

public decimal Price { get; set; }
}
}

添加控制器

一个控制器是一个对象,处理HTTP请求。来看看VS自动创建的Controller(控制器),具体如下:

  • HomeController中是一个传统的ASP.NET MVC控制器。这是负责服务网站的HTML页面,而不是直接相关的Web API。
  • ValuesController是一个例子WebAPI控制器。

删除ValuesController 解决方案资源管理器中右键单击文件, 并选择“ 删除“。兵器添加一个新的控制器,如下图3.:(在解决方案资源管理器中,右键单击Controllers文件夹。选择“ 添加“ ,然后选择“ 控制器“。)

图3.在“ 添加控制器 “向导,将其命名控制器”的ProductsController“。在 模板下拉列表,选择空API控制器。然后单击添加。如下图4.

图4.(这里一定要看清楚模版),创建好ProductsController,具体修改代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net.Http;
using System.Net;
using System.Web.Http;

namespace HelloWebAPI.Controllers
{
using HelloWebAPI.Models;
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product{Id = 1 ,Name="Huitai", Category="People",Price=1.25M},
new Product{Id = 2,Name="Hello",Category="Hello",Price=4.5M},
new Product{Id = 3,Name="ViewSonic",Category="Computer",Price=1500M}
};

///

&nbsp;

<summary> /// 返回所有商品
/// </summary>

&nbsp;

&nbsp;

/// 返回一个枚举类型为Product
public IEnumerable GetAllProducts()
{
return this.products;
}

///

&nbsp;

<summary> /// 返回单一商品信息
/// </summary>

&nbsp;

&nbsp;

///商品的ID /// 商品
public Product GetProductById(int id)
{
var product = this.products.FirstOrDefault(p =&gt; p.Id == id);
if (product == null)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound);
throw new HttpResponseException(resp);
}
return product;
}
///

&nbsp;

<summary> /// 返回指定类别所有的商品
/// </summary>

&nbsp;

&nbsp;

public IEnumerableGetProductsByCategory(string category)
{
return this.products.Where(p =&gt; string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));
}
}
}

现在我们就有一个工作网络的API。每个控制器上的映射到一个URI的方法,具体如下:

控制器方法 URL
GetAllProducts /API/products
GetProductById /API/prdoucts/ID
GetProductsByCategory

 

客户端可以通过发送一个HTTP GET请求的URI调用的方法。我们来看看如何完成这种映射。结果如下图5.

图5.OK,我们需要看到的是我们想要的东西,而不是VS自动创建的Index.cshtml页面。

我们试着用JavaScriptJQuery调用的Web API,首先我们先修改一下Index.cshtml页面具体修改如下:




ASP.NET Web API
<script type="text/javascript" src="http://www.cnblogs.com/Scripts/jquery-1.6.2.min.js"></script>

<div>

<h1>All Products</h1>

&nbsp;
</div>
<div><label for="prodId">ID:</label> <input id="prodId" type="text" size="5" /> <input onclick="find();" type="button" value="Search" /> 

 
</div>

&nbsp;

为了获得一个产品列表,发送一个HTTP GET请求“/ API /Products”。你可以用JQuery做如下:

 $(document).ready(function () { //发送一个AJAX请求 $.getJSON("api/products/", function (data) { //OK,则展示所有商品列表 $.each(data, function (key, val) { //格式显示文本 var str = val.Name + ': $' + val.Price; //添加一个商品到列表 $('

<ul>
	<li></li>
</ul>

', { html: str }).appendTo($('#products')); }); }); }); 

getJSON函数发送Ajax请求。响应将是一个JSON对象的数组。getJSON的第二个参数是请求成功完成时调用的回调函数。 我们可以发送一个HTTP GET请求“/ API /Products/ ID “,其中ID是Product ID。具体如下:

 function find() { var id = $('#prodId').val(); $.getJSON("api/products/" + id, function (data) { var str = data.Name + ': $' + data.Price; $('#product').html(str); }) .fail( function (jqXHR, textStatus, err) { $('#product').html('Error: ' + err); }); } 

下面的代码显示完整Index.cshtml文件。具体代码如下:

 ASP.NET Web API
<script type="text/javascript" src="http://www.cnblogs.com/Scripts/jquery-1.6.2.min.js"></script>&nbsp;

<script type="text/javascript">// <![CDATA[
            $(document).ready(function () {
                //发送一个AJAX请求
                $.getJSON("api/products/", function (data) {
                    //OK,则展示所有商品列表
                    $.each(data, function (key, val) {
                        //格式显示文本
                        var str = val.Name + ': $' + val.Price;
                        //添加一个商品到列表
                        $('	<li/>', { html: str }).appendTo($('#products'));
                    });
                });
            });

             function find() {
                var id = $('#prodId').val();
                $.getJSON("api/products/" + id,
                function (data) {
                    var str = data.Name + ': $' + data.Price;
                    $('#product').html(str);
                })
            .fail(
                function (jqXHR, textStatus, err) {
                    $('#product').html('Error: ' + err);
                });
        }      

// ]]></script>
&nbsp;
<div>
<h1>All Products</h1>
</div>
<div><label for="prodId">ID:</label>
<input id="prodId" type="text" size="5" />
<input onclick="find();" type="button" value="Search" />
<p id="product"></p>

</div>

运行我们的程序,结果如下图6-9.

图6.图7.图8.图9.

虽然十分丑陋,但是终究还是出来了。OK,今天就先了解这么些,后续继续学习。文章那里要是有描述错误还是不对的地方,还请前辈们多多批评指教,大家共同学习,进步!

转载在项目中寻找代码的坏味道(命名)

mikel阅读(1088)

转载在项目中寻找代码的坏味道(命名) – 川山甲 – 博客园.

 

介绍
  这段时间一直做项目,所以相对忙碌些,今天终于有时间回过头来好好看一下自己写的代码,看哪里有问题,哪里有“坏味道”。
  慢慢过,慢慢回忆代码。开始捕捉坏味道。
常做的和常想的事情

晦涩的if条件
1)对于||的处理

上面的代码要比下面的代码理解起来花更多的时间

 

 尽管减少代码行数是一个好目标,但把理解代码所需的时间最小化是一个更好的目标。

 

返回值

上面的”$ret”是“我想不出名字“的托词。与其使用这样空洞的名字,不如挑一个能描述这个实体的值或者目的的名字。

$alias声明了这个变量是用来承载别名的——标明了这个变量的目的。并且可能帮我们找到缺陷

好的名字应当描述变量的目的或者它所承载的值。

 

临时变量

                                    这里的$i是“我的临时变量”,专门用来让统计数据自动增加,避免统计点的重复。但是对这个$i来讲最重要的并不是临时变量。用charset_index表示“我的统计数据的下标”,更具“描述性”。

循环迭代器
我在我的js代码中也发现了坏味道。

i变量名字很空泛,所以不要这么做。

 

像i,j,iter和it等名字常用做索引和循环迭代器。尽管名字很空泛,但是大家都知道它们的意思是“我是一个迭代器“。——实际上你用这些名字来表示其他含义,那会很混乱。所以不要这么做。

 

如果你非要用i,j,it这样空泛的名字,那么你要有个好的理由说服自己。

总结
  我们在编码的过程中,多花几秒钟想出一个好名字,你会发现我们的“命名能力“很快提升上去。
  我一般是先想中文名字,如果实在想不出对应的英文名字,我就会用翻译工具把想到的中文贴上去,然后进行裁剪命名变量或者函数名称。
赠送一张最近看到的不错的命名

[转载]构建canvas动画框架(二)

mikel阅读(981)

[转载]构建canvas动画框架(二) – shawn.xie – 博客园.

今天一直在弄css3的立体效果,发现如果结合canvas和css3的3d,可以做出很多不可思议的效果来,大家可以发挥想象力!

接着上节讲canvas动画框架:

1.通用类的提取:动画对象与帧对象

2.灵与肉的结合:便于拆卸的运动方程

3.进度条的实现:canvas的图片预加载

4.demo测试:通过一个demo测试框架

这一节我们先来说说运动方程的叠加

之前写过的一个动画框架,并没有把运动独立出来。这样造成的后果就是,每个动画对象没有自己的运动个性!如果我们批量创建一百个动画对象,并且想让它们每一个都拥有自己的运动属性,将非常麻烦。

所以,将运动与形式相分离,是最好的解决方案。

上节提到过,我们为Aniele动画对象创建了它自己的运动方程库motionFncs。那么怎么操作这个运动方程库呢?

//添加运动方法
     addMotionFnc:function (name,fnc) {
        this.motionFncs[name]=fnc;
    },
    //删除运动方法
    deleMotionFnc:function(name){
        this.motionFncs[name]=null;
    },
    //遍历运动方法库里的所有运动方法
    countMotionFncs:function () {
        for (var i=0; i            if(this.motionFncs[i]==null)
                continue;
            this.motionFncs[i].call(this);
        }
    },

上节已经介绍过,在Aniele动画对象中,我们添加了以上运动方法。

其中countMotionFncs是非常重要的一个方法,通过它的核心语句:this.motionFncs[i].call(this),我们把运动方程的this指针更改为动画对象,相当于把命令给了动画对象,动画对象就会乖乖地区执行一遍,比如我们定义了一个运动方程pass


function pass(){
    this.loca.x-=this.speed.x;
}

我们定义一个小人的动画对象:

man=new Aniele();

那么我可以用这个方法把运动方程添加到man的运动方法库里面:

man.addMotionFnc(0,run);

这样,这个小man就拥有了一个运动属性,只要我们在每一帧都执行一下这个运动方程,就可以实现man的运动了!

运动方程库中我们可以添加多个运动方程,运动方程会叠加而不互相影响,方便我们写出非常复杂的运动;并且在运动方程库中,我们不仅可以制定运动对象坐标的改变规则(运动),还可以随意改变运动对象的其他属性,包括透明度,翻转,缩放等等。

[转载]时间管理GTD

mikel阅读(1160)

[转载]时间管理GTD – 轩脉刃 – 博客园.

时间是程序员最大的资产,如何有效管理自己的时间必须成为程序员的必修课之一。在我过去 几年的工作生活中,深刻感受到开发人员在时间管理上的被动性。程序员是一个高智商的队伍,每个人在每天都会遇到各种挑战,接触到许多新的技术,产生各种行 为冲动。但是这些行为冲动往往由于时间和精力的原因无法成为实际,进而产生的挫败感是会限制程序员的创造力的。这里想推荐一种时间管理概念GTD。

GTD概念

GTD全称Getting Things Done,来自于David Allen的一本畅销书《Getting Things Done》。网上流传的中文版本为《尽管去做:无压工作的艺术》,有兴趣的读者可以去这里下载

http://ishare.iask.sina.com.cn/f/8657554.html

 

GTD的具体做法可以分成

收集,整理,组织,回顾,行动

五个步骤

收集:将所有想法都收集到一个收集栏中

 

整理:定期或者不定期地对inbox进行整理

整理步骤:

能立即短时间完成的:立即花2分钟完成

不能完成的或者不用完成的:直接放到垃圾箱中

要计划完成的:进行下一步组织工作

 

组织

 

对参考资料的组织:收集完成这个事情需要的文档资料

 

对下一步行动的组织:

将计划分为:

下一步行动清单:具体的下一步工作,如果需要很多详细的更多工作,就细化成具体的工作

等待清单:等待别人做的事情

未来/某天清单:记录可以延迟处理的事情

回顾

每周对所有清单进行回顾和更新

 

执行

对每份清单任务进行行动,行动时候切记不要思考是否应该执行。

 

按照所处环境,重要性等来完成清单上的事项

 

理论上的东西网上能搜索到很多,当然最详细的就在《Getting Things Done》一书中了。这里就推荐一款应用GTD概念进行时间管理的工具:

Doit.im

http://doit.im/cn/

这是一款很成熟的软件,有iphone,Android,web版本等。我相信如果你没有用过它你会很快喜欢上的

界面如下:

clip_image001

 

第一步将想法放入收集箱

收集箱是最经常使用的,无论你有什么想法,立即将你的想法放入到收集箱中。你会在买菜的时候,逛街的时候,工作的时候偶尔蹦跶出的想法,这些想法都是应该记录下来的。

 

第二步要做的是清理收集箱

这个操作会非常频繁

收集箱中的条目可能有几个去处:

1 这个事情根本不用去做,去垃圾箱

2 这个事情是很大的事情,(比如“建立一个网站”)去项目栏

3 这个事情是有步骤的,(比如“了解Go语言的底层实现”,可以分解为“收集Go语言的底层相关文章”“阅读文章”“参照代码,理解”“写一篇博客”),将这个事情从收集箱中删除,将下一步行动放到“下一步行动”栏,其他的几步放到“择日待办”栏中

 

第三步是每日工作前,巡视下一步行动,等待,择日待办栏

将今天要做的事情放到“今日待办”栏中,将计划明天要做的放入“明日待办”栏中

 

后续

我 已经使用这款工具两个星期了,对于它简便的事件管理功能非常喜爱。个人感觉,这种管理方式能最有效的就是杜绝了脑袋中不断记挂的“我还有哪些工作没做”的 恐惧。并且GTD比其他管理方法好的地方可能在于它的整理过程。以前对于某件事情即使是很有计划和方案,但是很容易造成事情计划不周全,导致很多事情实际 上是半途而废的,进而计划的任务和喜欢终止。GTD确实能有效杜绝这个现象。

程序员在思考自己的代码的同时也应该积极思考自己的思维方式和生活习惯。自勉~

GTD资料

百度百科:http://baike.baidu.com/view/406078.htm

时间管理行动家博客: http://www.gtdlife.com/

Doit.im官网:http://doit.im/cn/

使用方法http://note.sdo.com/u/jesse_luo/n/sCPcz~jFa1VMLX0jM00066

GTD中文电子书 http://ishare.iask.sina.com.cn/f/8657554.html

GTD案例分析 http://www.gtdlife.com/2009/1310/kaixinwang-to-time-management-is-a-disaster-1/