2009年4月21日星期二

迷官

說明
由於迷宮的設計,老鼠走迷宮的入口至出口路徑可能不只一條,如何求出所有的路徑呢?

解法
求所有路徑看起來複雜但其實更簡單,只要在老鼠走至出口時顯示經過的路徑,然後退回上一格重新選擇下一個位置繼續遞迴就可以了,比求出單一路徑還簡單,我們的程式只要作一點修改就可以了。
演算法

Procedure GO(maze[]) [
VISIT(maze, STARTI, STARTJ);
]

Procedure VISIT(maze[], i, j) [
maze[i][j] = 1;

IF(i == ENDI AND j == ENDJ) [
// FIND A ROUTE, PRINT THE ROUTE
]

IF(maze[i][j+1] == 0)
VISIT(maze, i, j+1);
IF(maze[i+1][j] == 0)
VISIT(maze, i+1, j);
IF(maze[i][j-1] == 0)
VISIT(maze, i, j-1);
if(maze[i-1][j] == 0)
VISIT(maze, i-1, j);

maze[i][j] = 0;
]


  • Java program
public class Mouse {
private int startI, startJ; // 入口
private int endI, endJ; // 出口

public static void main(String[] args) {
int maze[][] = {{2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 0, 0, 0, 0, 0, 0, 0, 2},
{2, 0, 2, 2, 0, 2, 2, 0, 2},
{2, 0, 2, 0, 0, 2, 0, 0, 2},
{2, 0, 2, 0, 2, 0, 2, 0, 2},
{2, 0, 0, 0, 0, 0, 2, 0, 2},
{2, 2, 0, 2, 2, 0, 2, 2, 2},
{2, 0, 0, 0, 0, 0, 0, 0, 2},
{2, 2, 2, 2, 2, 2, 2, 2, 2}};

System.out.println("顯示迷宮:");
for(int i = 0; i < maze.length; i++) {
for(int j = 0; j < maze[0].length; j++)
if(maze[i][j] == 2)
System.out.print("█");
else
System.out.print(" ");
System.out.println();
}

Mouse mouse = new Mouse();
mouse.setStart(1, 1);
mouse.setEnd(7, 7);

mouse.go(maze);
}

public void setStart(int i, int j) {
this.startI = i;
this.startJ = j;
}

public void setEnd(int i, int j) {
this.endI = i;
this.endJ = j;
}

public void go(int[][] maze) {
visit(maze, startI, startJ);
}

private void visit(int[][] maze, int i, int j) {
maze[i][j] = 1;

if(i == endI && j == endJ) {
System.out.println("\n找到出口!");
for(int m = 0; m < maze.length; m++) {
for(int n = 0; n < maze[0].length; n++) {
if(maze[m][n] == 2)
System.out.print("█");
else if(maze[m][n] == 1)
System.out.print("◇");
else
System.out.print(" ");
}
System.out.println();
}
}

if(maze[i][j+1] == 0)
visit(maze, i, j+1);
if(maze[i+1][j] == 0)
visit(maze, i+1, j);
if(maze[i][j-1] == 0)
visit(maze, i, j-1);
if(maze[i-1][j] == 0)
visit(maze, i-1, j);

maze[i][j] = 0;
}
}

2009年4月20日星期一

得分排行

說明

假設有一教師依學生座號輸入考試分數,現希望在輸入完畢後自動顯示學生分數的排行,當然學生的分數可能相同


解法

這個問題基本上要解不難,只要使用額外的一個排行陣列走訪分數陣列就可以了,直接使用下面的程式片段作說明:
for(i = 0; i <>
juni[i] = 1;
for(j = 0; j <>
if(score[j] > score[i])
juni[i]++;
}
}

printf("得分\t排行\n");
for(i = 0; i <>
printf("%d\t%d\n", score[i], juni[i]);


上面這個方法雖然簡單,但是反覆計算的次數是n^2,如果n值變大,那麼運算的時間就會拖長;改變juni陣列的長度為n+2,並將初始值設定為0,如下所示:

得分排行

接下來走訪分數陣列,並在分數所對應的排行陣列索引元素上加1,如下所示:
得分排行

將排行陣列最右邊的元素設定為1,然後依序將右邊的元素值加至左邊一個元素,最後排行陣列中的「分數+1」」就是得該分數的排行,如下所示:
得分排行
這樣的方式看起來複雜,其實不過在計算某分數之前排行的人數,假設89分之前的排行人數為x人,則89分自然就是x+1了,這也是為什麼排行陣列最右邊要設定為1的原因;如果89分有y人,則88分自然就是x+y+1,整個陣列右邊元素向左加的原因正是如此。

如果分數有負分的情況,由於C/C++或Java等程式語言無法處理負的索引,所以必須加上一個偏移值,將所有的分數先往右偏移一個範圍即可,最後顯示的時候記得減回偏移值就可以了。



import java.io.*;

public class ScoreRank {
public static void main(String[] args)
throws NumberFormatException, IOException {
final int MAX = 100;
final int MIN = 0;

int[] score = new int[MAX+1];
int[] juni = new int[MAX+2];

BufferedReader reader =
new BufferedReader(
new InputStreamReader(System.in));
int count = 0;

do {
System.out.print("輸入分數,-1結束:");
score[count++] =
Integer.parseInt(reader.readLine());
} while((score[count-1] != -1));

count--;

for(int i = 0; i < count; i++)
juni[score[i]]++;
juni[MAX+1] = 1;

for(int i = MAX; i >= MIN; i--)
juni[i] = juni[i] + juni[i+1];

System.out.println("得分\t排行");
for(int i = 0; i < count; i++) {
System.out.println(score[i] + "\t" +
juni[score[i]+1]);
}
}
}

2009年4月1日星期三

從Java應用程序存取Microsoft Excel檔案

感謝Apache,現在 利用POI有辦法提供Java應用程序存取Microsoft Excel文件(.xls ) POI 可以從apache.org 下載。 以下是小教程如何寫入Excel文件。 寫Excel文件步驟是:
  1. 創建輸出文件使用FileOutputStream
  2. 創建一個工作簿創建一個實例 HSSFWorkbook
  3. 創建一個新的資產負債表,建立的一個實例 HSSFSheet
  4. 創建字體對象援引法createFont ( )的 HSSFWorkbook
  5. 創建細胞風格對象援引法createCellStyle ( )的 HSSFWorkbook
  6. 創建數據格式對象援引法createDataFormat 階級 HSSFWorkbook
  7. 創建行致電方法createRow ( rowNumber )由實例HSSFSheet
  8. 收件簿到輸出文件。
這裡是一個簡單的程序來寫Excel文件包括2細胞:


import java.util.*;
import org.apache.poi.hssf.usermodel.*;
import java.io.*;
public class WriteSimpleXLS{

public WriteSimpleXLS() {
try{
FileOutputStream fos = new FileOutputStream("output.xls");
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet();
HSSFRow r = null;
HSSFCell c = null;
HSSFCellStyle cs = wb.createCellStyle();
HSSFDataFormat df = wb.createDataFormat();
HSSFFont f = wb.createFont();

//set font
f.setFontHeightInPoints((short) 12);
f.setColor( (short)HSSFFont.COLOR_RED );

//set cell style
cs.setFont(f);
//set data format
cs.setDataFormat(df.getFormat(”#,##0.0〃));
wb.setSheetName(0, “First Sheet”);

//create row
r = s.createRow(0);
//create cell
c = r.createCell((short)0);
c.setCellStyle(cs);
c.setCellValue("Nico");
//create another cell
c = r.createCell((short)1);
c.setCellStyle(cs);
c.setCellValue("Ganteng");

//now that we’re done creating workbook,it’s time to write it to output file
wb.write(fos);
fos.close();
}catch(IOException e){
System.err.println(e.getMessage());
e.printStackTrace();
}
}

public static void main(String[] arg){
WriteSimpleXLS wsx = new WriteSimpleXLS();
}
}

2009年3月30日星期一

利用Facebook Connect 開發與 Facebook 整合的應用程序

Facebook的連接將是未來發展的Facebook的平台-讓您的力量整合Facebook的平台進入自己的網站。 使您的用戶...
  • 您的網站 Facebook的帳戶和信息進行無縫“連接”
  • 連接並找到他們的朋友誰也可以使用您的網站
  • 在您的網站上與他們在Facebook朋友分享信息和行動

可信認證

用戶可以在Facebook帳戶與任何合作夥伴的網站使用我們的簡化和值得信賴的認證。 無論是在登錄,或任何其他地方的開發商想補充的社會背景下,用戶可以驗證和連接他們的帳戶中一個值得信賴的環境。 用戶將完全控制的權限授予。

真實身份

Facebook的用戶代表自己的真實姓名和真實身份。 與Facebook的連接,用戶可以將他們的真實身份資料,他們無論身在何處,在網絡上,其中包括:基本檔案信息,個人資料圖片,名稱,朋友,照片,活動,論壇等等。

好友鏈接

Facebook的人指望保持聯繫其朋友和家人。透過與Facebook的連接,他們無論身在何處或在網絡上,都可以找到他們的朋友,開發人員可以添加豐富的社會方面,他們的網站。開發商甚至可以動態顯示其中的Facebook的朋友已經有帳戶在其網站上。

動態隱私

作為一個移動的用戶開放的網絡,他們的隱私設置將跟隨他們,以確保用戶信息和隱私規則總是最新的。 例如,如果用戶更改其個人資料圖片,或刪除的朋友聯繫,這將是自動更新的外部網站。和用戶可以控制誰可以看到他們的資料片-同樣的規則,他們在Facebook一套可用於您的網站也使用我們的動態隱私控制。

社會分配

作為一個移動的用戶開放的網絡,他們發現有趣的內容,共享信息本身,並參與了很多經驗。 與Facebook的連接,用戶能夠輕鬆共享和發布這一信息,並採取行動,他們的朋友通過Facebook的飼料,要求,通知。


翻譯自: http://developers.facebook.com/connect.php


2009年3月6日星期五

Ajax SmartGWT!

Today, let me introduce a framework that builds on top of GWT Google Web Toolkit, it is called SmartGWT!



SmartGWT Release Notes 1.0 b2

  • GWT 1.6 M1 and M2 support. GWT 1.5.3 continues to be fully supported
  • New lightweight Enterprise Gray skin
  • Performance improvements
  • various API enhancements and bug fixes
  • complete support for WebServices (WSDL)
  • Additional Developer Tools (Inspect DOM and monitor RPC calls from hosted mode)
  • Portal support and samples
  • HTML based Print Preview support. No longer requires JSP
  • Support for auto-arranging and overlapping Calendar events
  • Support for checkbox selection for ListGrids
  • improved support for users to wire DataSource's with GWT-RPC calls
  • Improved javadocs
  • Separated additional skins into a smartgwt-skins.jar
  • Chrome, Firefox 3.1, and OSX hosted mode support


So what's so smart about SmartGWT?

SmartGWT is not just another Widget library. While most Ajax frameworks focus primarily on presentation and displaying mostly read-only data, either local or via XML / JSON, SmartClient was built with server side integration in mind. Most enterprise applications are not just about about data presentation, but about being able to propagate data changes made by the user to the backend. So while its tempting to use library X that has a cool tree widget, it's not until you actually try to use it your application that you encounter the real world hard problems. For example, how do you take data from your business objects on the server to not only display in a tree widget, but also be able to update your data model when, say, the user reorders the tree nodes or make edits / deletes in the UI.

Most Ajax frameworks stop short and leave it up to the user to manage state on the client side and propagating the changes to the server. This is no a trivial problem. Over the past few years UI widget libraries have improved significantly and there are now various options available to users. Simply put, having good looking widgets is not the hard problem today. In addition to having good looking widgets, having end-to-end integration of the UI components with the backend is the hard problem. It's this 20% of the functionality that takes 80% of the time in building most enterprise applications.



SmartGWT showcase: http://www.smartclient.com/smartgwt/showcase/




Reference:
  1. GWT http://code.google.com/webtoolkit/
  2. SmartGWT http://code.google.com/p/smartgwt/

2009年3月3日星期二

Ajax(DWR) + Struts 實例開發

Ajax是近年最火爆的網頁開發技術,以gmail為先驅的Ajax應用已經逐漸深入人心了。也許這就是所謂的輪回吧,電腦介面的設計從最初瘦到胖再 到瘦,如今又要開始胖了。不過,在web介面的胖與之前的胖還是有很多區別的,web介面的胖主要依賴於DHML和Javascript來實現。這也是本 文的來由了,相信很多OO的開發人員都不願與頁面層的效果打交道,尤其是Javascript的這樣的開發語言,我也是其中之一了,非常不喜歡 Javascript,語法鬆散,結構複雜。反正是不喜歡了,但是在web時代,既然流行胖子,想不用Javascript是不可能的了,那麼怎麼樣來簡 化Ajax的開發呢?DWR由此延生了,他封裝了XMLHttpRequest,直接調用服務端的方法,省了好多Javascript啊^_^

Struts雖然已經開始開下陡路,但底子厚,將DWR與Struts結合依然會是大多數開發者的選擇。
本文分兩部分:框架介紹和實例開發。先來:


第一部分 框架介紹


一、Ajax介紹

Ajax--Asynchronous JavaScript and XML,非同步JavaScript和XML。名字中已經包含Ajax的組成部分:非同步處理XMLHttpRequest,JavaScript,XML。
其中:


1、XMLHttpRequest是Ajax的關鍵部分,正是由於他的存在,才使得胖子越來越吃香了。


2、JavaScript是Ajax的必備部分,沒有他還玩個屁


3、XML是Ajax資料格式的推薦方式,但也可以不用
當然還少不了CSS,有了CSS使得在Ajax中更容易修改用戶的介面
Ajax的細節和樣例使用就不多說了,N多的資源,自己找吧。


 


二、DWR介紹
DWR-Direct Web Remote,翻譯過來應該是直接遠端網頁訪問。(這個Web一直找不到好的詞語來表達,這裏就用網頁吧)
如名字所述,DWR的主要特點就是可以在Ajax中直接調用伺服器上的方法,很奇妙吧。就是說,不需要通過URL來告訴服務來處理,而是直接在Javascript中調用類的方法,並返回資料。

DWR簡化了Ajax的開發:


1、封裝了Ajax中的使用,不再需要直接使用XMLHttpRequest了,這可是非常重要的,減少了好多Javascript呀


2、通過回調函數的方式,簡化了錯誤處理及返回資料的處理。


3、直接調用伺服器類的方法,不再需要通過URL方式,也省了不少的事。

DWR的主要部件有:dwr.xml/engine.js/util.js,前者是DWR的Servlet使用的配置檔,後兩者DWR替我們封裝的Ajax的代碼,當然也提供了其他有用的功能。


 


三、Struts介紹
Struts還用介紹嗎?沒聽說過?那就不用往下看,休息休息吧^_^
這裏就說一下在DWR如何調用Struts中Action的方法吧,說白了,是不可能的。這不是白說嗎? 實際上是這樣的,雖然DWR支持方法的調用,但ActionForward/ActionForm/ActionMap這些東西如何在DWR調用方法前生成 呢?我也不知道,所以DWR對Struts的支持實際上就是要重構Action中的方法,去掉上面的東西,然後就可以了(這是DWR說的,可不是我說的 ^_^)。


看了上面的一小通介紹,不知道大家有沒有什麼感覺,我也覺得寫得太少了,可能看了跟沒看差不多。不過這裏主要是想大家對這些概念有個瞭解。接下來的第二部分,將會以實例開發的方式來寫,這樣就更容易依樣畫葫蘆了(我也比較喜歡這樣的方式)。


摘要:先講一下應用的結構頁面端:
demo.jsp用來展示介面服務端: DemoAction是Struts中的Action子類負責控制轉換, DemoFacade是業務類負責業務處理。 Goods是一個業務實體類Struts部分的配置就
先講一下應用的結構
頁面端:
demo.jsp用來展示介面
服務端:
DemoAction是Struts中的Action子類負責控制轉換,
DemoFacade是業務類負責業務處理。
Goods是一個業務實體類

Struts部分的配置就忽略不說了,實際上這個應用並沒有包含Struts的配置
主要講一下dwr的配置,首先需要在web.xml增加下面的servelt映射:


 


<servlet>

   
<description>Direct Web Remoter Servlet</description>

   
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>

 
</servlet>

 
<servlet-mapping>

   
<servlet-name>dwr-invoker</servlet-name>

   
<url-pattern>/dwr/*</url-pattern>

 
</servlet-mapping>


如上uk.ltd.getahead.dwr.DWRServlet是dwr的核心,用來處理javascript的對遠端方法的調用,還有其他參數請參考相關文檔。
然後,需要在dwr.xml配置相應的遠端方法(與具體需要在用戶端調用的方法相關),如下為演示應用的配置:


<dwr>

   
<allow>

       
<convert converter="bean" match="dwr.demo.Goods"/>

       
<create creator="new" javascript="DemoAction" class="dwr.demo.DemoAction">

           
<include method="query4dwr"/>

           
<include method="copy4dwr"/>

           
<include method="paste4dwr"/>

       
</create>

       
<create creator="new" javascript="DemoFacade" class="dwr.demo.DemoFacade">

           
<include method="queryList"/>

           
<include method="restore"/>

           
<include method="del"/>

       
</create>

      
</allow>

</dwr>


 


















如 上有一個轉換器(converter)是用來映射dwr.demo.Goods為bean類型,其他轉換器類型請參考相關文檔;還有兩個創建器分別創建 javascript中的DemoAction類和DemoFacade類,分別對應dwr.demo.DemoAction類和 dwr.demo.DemoFacade,其中定義的方法就可以從javascript中直接調用了。


最後,我們需要在頁面中包含相應的javascript:





 


<script src='dwr/interface/DemoAction.js'></script>

 
<script src='dwr/interface/DemoFacade.js'></script>

 
<script src='dwr/engine.js'></script>

 
<script src='dwr/util.js'></script>


 


如上,dwr/interface/DemoAction.js和dwr/interface/DemoFacade.js是dwr自动生成的 javascript文件,包含相应的类及方法,dwr/engine.js是dwr的核心引擎脚本处理客户端调用的转换,dwr/util.js包含了 工具函数简化页面处理。



下面以查询为例,看一下dwr的具体使用:

DemoAction:

   
public List query4dwr(int type, boolean needClear, HttpServletRequest request) {

       
if (needClear) request.getSession().removeAttribute("dwr.demo.goodsId");

       
return demoFacade.queryList(type);

   
}

demo.jsp:

 
function updateResults() {

   
DWRUtil.removeAllRows("goodsbody");

   
var type = document.getElementById("type").value;

   
DemoAction.query4dwr(type, true, fillTable);

 
}

 
function fillTable(goods) {

   
document.forms[0].select.checked = false;

   
document.getElementById("totalRecords").innerHTML = goods.length;

   
DWRUtil.addRows("goodsbody", goods, [ addCheckbox, getName, getPrice, getCount]);

 
}

如 上,DemoAction.query4dwr(type, true, fillTable)就可以直接调用DemoAction的方法了,这里fillTable是函数,dwr通过回调函数的方式来进行后续处理。比较一下 javascript和action中的方法参数,HttpServletRequest是可以不传的,dwr会自动加上,另一个就是回调参数放在最后, 这是比较好的方式,其他方式请参考文档。



最后看一下,dwr如何与Struts集成,如下代码:

   
public ActionForward query(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

       
String type = request.getParameter("type");

       
//或者从form中取值

        


       
List goodsList = query4dwr(Integer.parseInt(type), true, request);

       
request.setAttribute("goodsList", goodsList);

        


       
return mapping.findForward("success");

   
}



   
public List query4dwr(int type, boolean needClear, HttpServletRequest request) {

       
if (needClear) request.getSession().removeAttribute("dwr.demo.goodsId");

       
return demoFacade.queryList(type);

   
}

前一个方法是Struts的方式,但dwr不支持,因此要重构一下在下面的方法才可以被dwr调用。

实际上,只有在方法中需要使用到HttpServletRequest是才需要重构方法,如果不使用HttpServletRequest,我们就可以直接调用业务层的类的方法,这样即简单又方便,如下:

demo.jsp:

 
function restore() {

   
DemoFacade.restore(updateResults);

 
}



DemoAction:

   
public synchronized void restore() {

       
goodsList.clear();    

       
initGoods();

   
}



小结



 
dwr封装了ajax中与服务端交互的模块,通过直接调用服务端类的方法简化了客户端与服务端的交互。虽然说还缺省类似tag这样的组件,但已经很大程度简化了ajax的开发。

DWR - Easy Ajax for Java

DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible.


DWR介紹
What is DWR?:
在伺服器上運行的Servlet來處理請求並把結果返回流覽器。

運行在流覽器上的Javascript,可以發送請求,並動態 改變頁面。DWR會根據你的Java類動態的生成Javascript代碼。這些代碼魔力是讓你感覺整個Ajax調用都是在流覽器上發生的,但事實上是伺服器執行了這些代碼,DWR負責資料的傳遞和轉換。

這種Java和Javascript之間的遠端調用會讓DWR用
戶感覺像是曾經習慣使用的RMI或SOAP的RPC機制。而且這一過程還不需要額外的流覽器插件。
Java是同步的,而Ajax是非同步的。所以當你調用一個遠端方法時,你要給DWR一個回調函數,當資料從網路上回來時,DWR會調用這個函數。

DWR的作用
:
有效地從應用程式碼中把 Ajax 的全部請求-回應迴圈消除掉。
用戶端代碼再也不需要直接處理XMLHttpRequest 物件或者伺服器的回應。
不再需要編寫物件的序列化代碼或者使用第三方工具才能把物件變成 XML。
不再需要編寫 servlet 代碼把 Ajax 請求調整成對 Java 域物件的調用


DWR原理

DWR是作為Web應用的一個Servlet進行部 署的,是一個黑盒子中的servlet。

對於公共有的每個類,DWR 動態地生成包含在 Web 頁面中的 JavaScript。生成的JavaScript 包含存根函數,代表 Java 類上的 對應方法並在幕後執行XMLHttpRequest。這些請求被發送給DWR。

把請求翻譯成伺服器端 Java 物件上的方法調用並把方法的返回值放在servlet 回應中發送回用戶端,編碼成 JavaScript。


編寫伺服器端Java類

不要出現Javascript保留關鍵字;和保留關鍵字同名的函數指定被排除。
多數Javascript的關鍵字和Java是相同的。所以你不可能有一個方法叫做”try()”。但是該死”delete()”對與Javascript有著特殊意義,而對Java則不是。

Javascript方法重載是不支援的,所以儘量不要再Java中使用。


1.
2. package test;
3.
4. public class HelloWorld {
5. public String sayHello(String name) {
6. return "Hi, " + name;
7. }
8. }



在dwr.xml檔註冊Java物件


在jsp頁面中添加DWR AJAX庫以及相應的js

注: 可以在啟動項目後,IE位址欄輸入 http://hostName:port/dwr/
查看動態javascript 路徑.以及所有可以運行的方法.




1、$(”username”) = document.getElementById(”username”);
2、setValue(id, value):這個函數能操作大多數HTML元素
3、getValue(id):getValue(id)是 setValue()對應的”讀版本”。
4、setValues():批量設置值
5、getValues():批量獲取值
6、getText(id):為select列表設計的。你可能需要取得顯示的文字,而不是當前選項的值。
7、selectRange:選擇一個輸入框中的一定範圍的文字。

2009年2月28日星期六

Portal (Portlet) or AJAX ?

I am going to develop a web application but not sure what development framework is better.
Nowadays, there are many frameworks for developing web application. For examples: JSF, JSP/Servlet, Java Portal (Portlet) framework, Springframework, Struts, Webworks, and also AJAX, etc. Too many taht I can't list or really know about them.

My first choice is Portal(portlet) + Ajax. For using Java as the development language, which portal is better? I prefer JBoss Portal, the framework is more structure and easy to use. The Liferay Portal has many well developped portlets for use.

Anyway, both of them I give up but customized the Apache Pluto-2.0. It is in the development statge. I want to get more suggestions on a Java Portal Server. Let's say, functions, arcvhitectures, etc.

2009年2月26日星期四

Facebook application

Recently, facebook games are very popular arround us. Almost all of my friends play and use facebbok. They like to share their friend and games.

I am also using facebbok and try to develop a simple application (game) in facebook.

The game is talking about how to be the most rich people in the town. If you have interest, just go to have a look.

AirCoon (娛樂大亨 - 金光大道傳奇)
http://apps.facebook.com/aircoon/

2009年2月25日星期三

What can we do with Google Maps in Macau?

  1. Find the nearest restaurant
  2. Locate the buildings (very useful in real estate agents)
  3. plan a trip
  4. etc.