2010年8月31日 星期二

201008宜蘭行_交通_租機車

身為無車一族,去宜蘭要怎麼去勒?自從雪隧開通以後就增加了很多選擇,你可以搭火車、從台北火車站搭葛瑪蘭客運、從台北市政府轉乘站搭首都客運、從北宜公路或濱海公路開車、騎車、騎腳踏車或步行,都可以很輕易的到達宜蘭?

總之,你可以問google找到很多辦法到達宜蘭,當然這不是本篇的重點。

身為無車一族,當然也不可能到宜蘭租汽車啪啪造,這會使得淳樸宜蘭的道路安全堪慮;所以,我們當然要秉持著學生青春無敵,熱死不怕的精神騎機車來迷路!

理論上根據民宿的位置我們會選擇三個地方下車1.礁溪2.宜蘭3.羅東,這次ola所選的民宿在羅東,就讓我們來看看羅東哪邊可以租車。以前在宜蘭唸書的時候早就聽聞租車是一件很黑的事情,所以詢問民宿老闆、比對google、然後把機車店老闆的聲音錄下來用電腦做過斷層分析以後,我覺得這家租車行很有可能"還不錯"!

店名:達伯租車
網站:http://www.wretch.cc/blog/double550513
電話:0932-264-222(應該對吧?)
住址:宜蘭縣羅東鎮公正路30號

給了店名、網址、電話、住址,他到底在哪裡?
1.首先出羅東火車站,如果是坐客運來就是下車後抬頭,穿過羅東火車站,就會看到一個圓環。

2.到達圓環後,將頭微微向右前方轉動25.36度,你就可以看到一個紅色招牌。如果你是正常時間到達羅東,還會看到店門口有一堆人!

3.到達以後,不管你是先預約還是現場才詢問,雙方同意租車後就是登記,登記需要填寫一份製式表格文件,整份文件最下面是本票(雖然以前聽說租車一定不要簽本票,但是我好像沒租過不用簽的),然後壓一張証件(推薦是壓汽車駕照,因為身分證跟健保卡好像不太適合)。

4.我租的是一天350,遲到一小時50元的新奔馳。(表情痴呆是因為我在想林場肉羹在哪裡....)

到達伯的時候已經11點30分了,整間租車行剩下三台車,還是不斷的有人詢問是否還有125,所以如果已經預定要去玩的人,一定要先預約!當走過去發現剩下那台是留給你的感覺就是不一樣。XDDD

最後,這台車騎起來車況很好,也還蠻有力的,安全帽肉眼看起來很乾淨,老闆與老闆娘也算是熱情!如果是從羅東出發的租機車族,可以考慮優先預定這家的車喔。 ^.< ..

2010年8月30日 星期一

201008宜蘭行_行程規劃(三天兩夜)

雖然在宜蘭住了七年多一點點,但真的要規劃該去哪裡玩似乎還是一件難事!上網看了PTT、小惡魔跟google亂蒐,決定以下非常觀光客的行程,完全就是"沒有私房景點"、"沒有在地人優勢"的....一般般行程。

為了不要有負我的肚子,行程都是用食物來分隔。 XD

星期六:
早...餐─台北古早味三明治(台北某家麵包店)
早餐至中餐─金車威士忌酒廠(員山)
中...餐─卜肉與蔥油餅(三星)
中餐至晚餐─宜蘭大學(母校當然算景點!?)及宜蘭亂吃(黑店冰、雞肉串、檸檬愛玉、奕順軒、正常小籠包)
晚...餐─紅槽魷魚(宜蘭市)
晚.餐.後─淡江大學夜景(礁溪)

星期天:
早...餐─好吃蛋餅(冬山)
早餐至中餐─梅花湖風景區(冬山)
中...餐─永豐海鮮(蘇澳)
中餐至晚餐─百米木屐村、蘇澳冷泉及某個國小後面的海灘!(南方澳)
晚...餐─羅東夜市(羅東)及PTT強力推薦嘉澎炭烤(員山吧?)
晚.餐.後─羅東運動公園

星期一:
早...餐─無(沒想過要起床)
早餐到中餐─睡....
中...餐─廣興糕、鵝肉宗(冬山還是羅東?)
中.餐.後─買博士鴨及宜蘭餅,回家。

依照工程師死性不改的個性!我們要來看一下達成率。就在我經過詳細的計算,利用27台電腦平行驗算以後,得出本次出遊行成規劃與實際玩樂達成率為:77%!!!!!!!!!

最後,一定要加上一個地圖作為首篇的結尾。


紅線是實際走的路途,如此順路的行程(咦?)我只能說:我真是規劃大師!!!!趕快來請我!!!!

2010年8月20日 星期五

MapGuide+Flex = ? Part4

最近專案"好像"很忙,一直在想還要繼續玩這個自製Viewer嗎?早上趕了一些專案的東西,然後開了一個不知何謂的會,下午又趕了一些東西,耳朵束起來聽了一些事情以後,傍晚又覺得算了,還是做些有趣的事情好了。

其實列了好多要實做出來的功能,經過10秒鐘的長思,我決定要先把基本的功能先補一補,既然上次做了屬性查詢,也就是所謂的圖查文,那當然就必須要有文查圖;應用上最常用的圖查文功能就是"定位查詢"!

講了一堆,所以今天實作的就是"定位查詢",雖然非常的普通,但畢竟是很多變化功能的基礎。好~~~說了很多不知道是說給誰看的廢話,先來想想我們要做出怎麼樣的定位功能?

功能需求:由介面輸入要定位的圖層、查詢的條件,系統會列出符合的項目,再利用點選的方式來選擇真正要進行定位的圖元。

如果要達成以上的功能,必須先實作幾個部分:
前端:
1. 可以輸入圖層名稱、查詢條件的使用者介面。
2. 可以列出篩選後的屬性列表。
3. 點選列表項目後進行定位動作。
後端:
1. 依照圖層名稱、查詢條件篩選MgFeatureReader,並且回傳必要資料的函式。
2. 依照點選的項目回傳定位的相關資訊

來看一下實做出來的效果:
1. 首先,在工具列上面增加一個查詢定位的按鈕。

2. 實作一個彈跳的查詢介面,沒有花很多時間在介面的設定上面,所以先跳過利用程式組查詢語法的介面,直接利用一個文字輸入框來承接查詢語法。

3. 按下查詢後,會呼叫服務取回符合查詢條件的資料列表,利用Repeater來做出點取列表。

4. 點取其中一個項目後,會透過事件傳遞,呼叫寫在Viewer裡面的ZoomToView,地圖讀取回來以後,會有一個簡單的定位位置動畫。


回家測試的時候,發現當時為了方便測試動畫寫在框選放大點擊上,忘記拿掉了。XDDDD

最後還是,若是你不幸逛到這裡,又加上我沒有在改程式,也沒有換網址了話,請批評指教。多蝦!

2010年8月19日 星期四

2010情人節大餐

依據我多年吃晚餐的經驗,決定在2010年8月16日情人節獻出我的第一桌!我只能說:曾經看過小當家肯定有幫助?

第一道:鹹蛋苦瓜,遙想第一次覺得苦瓜好吃,是跟嘉嘉在公館的台大麵店,自此之後苦瓜突然變成常吃常點食物之一,或許瓜農應該要跟他們簽約一下。

第二道:焗白菜,一直都很喜歡吃焗烤白菜,老媽突然在去年蹦出這道菜,被我偷學了。^.<

第三道:沙茶洋蔥雞丁,俗話說的好:管他炒什麼,加沙茶就對了....

第四道:沙茶羊肉,俗話說的好:羊肉加空心菜還不加沙茶嗎?(咦?)

第五道:麻婆豆腐,從小時後吃過某一家現在買不到的麻婆豆腐罐頭後,我就一直覺得吃麻婆豆腐很幸福。XD

第六道:蝦仁炒蛋,天呀!這蝦也太彈牙了吧!誰炒的!

第七道,豆鼓鱈魚,鱈魚沒什麼好講的!全世界最好吃的魚?

合體!共計不知道多少時間!滿滿的誠意喔!

主角,我是說藏在後面那位!

情人節快樂!!

餓了~~~~

快記-想法-關於我的Flex Viewer

今天晚上的短暫討論,有幾個想法趕快記下來。

有關丟掉MapServer
1. 直接讀取Spatial,但是考慮效能,或許成圖這件事情必須要在Flex前端完成,所以要寫解析wkt跟很多很多美化圖面的程式。
2. 直接利用程式透過MapGuide產生預存圖,後續的地圖成圖都以預存圖處理,不再動態生成,或許就不需要買MapGuide了?

有關地圖分塊讀取
1. 前台的Viewer必須要多個Image物件,來接多個後台成圖圖片。
2. 若是後台使用ByteArray就變的一定要整串回傳了?

2010年8月18日 星期三

喜歡寫程式嗎?

學生時代覺得寫程式很有趣,遇到有些老師會希望同學加強程式能力,會出一些加分題!如果我有空總是會去研究一下,說來也很有趣,這樣的加分題總是沒有幾個人要做,做的人往往都不太需要加分。

後來到了研究所,也理所當然的繼續寫程式,論文也程式、計畫也程式、修課也程式,真不知道寫這麼多程式要做什麼?

現在工作了,也在寫程式,但是"寫程式"這件事情就慢慢不有趣了。雖然我不喜歡喝酒,但是這就跟很多人講的一樣,喝酒就是到微薰,睡覺也好、對身體也好、心情也好,什麼都好勒?現在我覺得寫程式就像是喝酒,一直喝、天天喝、當水喝,喝到麻痺的時候好像就傷身又無趣,就連旁人看了都覺得煩。

但是,8月初的一個靈感讓我覺得寫程式好像又有趣了起來,也就是以下這三篇:
MapGuide+Flex=? Part1
MapGuide+Flex=? Part2
MapGuide+Flex=? Part3
結果變成,做專案的時候也在想該怎麼寫,騎車的時候也在想,有幾天連睡覺的時候都在想,有時候上班就只想趕快把東西做點進度,繼續來完成前天或昨天的構想,還記得框選放大寫出來的時候,真是超興奮的哩!又突然有種"其實很有趣嘛"的感覺,雖然也沒什麼人會對這個東西有興趣,做出來也只是自High而已,還是有很多很多項目想做。

所以?喜歡嗎?討厭嗎?我也不知道.....

2010年8月13日 星期五

MapGuide+Flex = ? Part3

這兩天用了好久排版的東西,總算讓現正執行的案子在各個瀏覽器上看起來"好像"一樣,也加了一些之前覺得很麻煩的功能,突然想起來我的OlaMapGuideForFlex還是醜醜的,而且沒什麼比較有用的功能,所以就決定來對他加工一下,順便整理一下之前寫的不夠漂亮的程式碼。 lol

所以這次改版(自以為改版)有幾個改變:
1. 版面假裝成超級楊春版的Esri ArcGIS Server版面。

2. 因為是假裝成ArcGIS Server的版面,地圖變成墊在功能列底下,所以增加了隨視窗縮放地圖一起連動調整的事件。
全螢幕(1916*909):

小視窗(900*458):

3. 增加判斷依功能改變滑鼠指標的事件

4. 增加屬性查詢功能。這個功能寫了一個IdentifyView的物件,專門用來接後端查詢出來的結果,目前是先寫死只能查詢人行道(圖面上橘黃色區域)的屬性,但是後端所查詢的資料欄位為動態產生,所以"理論上"只要再花一點時間就可以做出隨意點選的屬性查詢了。XD

在寫屬性查詢功能的時候才發現原本成圖的部分有些許問題,造成從MapGuide取得的圖會有錯位的狀況,結果因為寫這個功能抓到BUG,太妙了。 XD

5. 將原先寫在程式內的主頁連結改到XML檔中。這樣在裝機的時候(還想到裝機勒XD,根本沒人會想用吧)就可以很方便的像ASP.NET的web.config檔一樣,改一改連接就好。

還有好多功能想加上去,不知道有多少時間可以玩這個。專案走開啦 淚奔~~~ T.T

若是你不幸逛到這裡,又加上我沒有在改程式,也沒有換網址了話,請批評指教。多蝦!

MapGuide_回到完整框架

在使用MapGuide Viewer時,常常會遇到一個問題,希望在某個位置按下鈕或是觸發什麼事件以後,就可以導到其他頁面,但因為MapGudieViewer本身也是使用切框架的方式製做,所以當我們簡單的用Response.Redirect("a.aspx")想把網頁導到a頁面,就會發現只有那一個框架內的網頁產生變化,其他框架的內容還是好端端的在那邊。

解決方法就是使用有top屬性的方式來轉換頁面:
1. 使用可設定Target的物件來進行頁面轉換,EX:Menu
2. 在按鈕上面增加屬性

button.Attributes.Add("onclick","top.location.href='a.aspx';")

3. 使用JavaScript

Response.Write("<script>(top.location.href='a.aspx');</script>");


我想應該大部分的人都會使用第三種方式,這樣可以在程式的最後面加上,而不會在按了某個鈕以後立刻轉過去。

MapGuide_內建框架與MasterPage

在使用MapGuide的基本框架時,我們都會使用以下的方式來叫出所謂的MapGuide Viewer:

<frameset rows="*">
<frame src="/mapguide2010/mapviewernet/ajaxviewer.aspx?SESSION=<%= sessionId %>&WEBLAYOUT=<%= webLayout %>" name="ViewerFrame" />
</frameset>

但有時候我們會想要將整個框架放在某個頁面裡面,希望他是頁面的一體,如果恰巧又希望這個"一體"是整個網站,我們通常都會想到ASP.NET2.0以後出現的master page,想著只需要將MapGuide框架放在某一個子頁就可以輕鬆的把網頁包進去了,正常來說的確是這樣,但執行後會發現MapGuide不管怎麼樣都不會顯示出來。/.\

原因是當frame標籤在body標籤內時,會造成frame沒有作用,但我們都使用frame來呈現MapGuide框架,而master page裡面也一定會有body個標籤,這時候該怎麼辦?這時我們就可以設計另一個子頁,裡面使用iframe來包住含有MapGuide框架的頁面,就可以達到我們預期的效果。

注意:當使用iframe標籤時,結束必須也使用標籤結束,而不可以只使用/結束,將會造成錯誤。

<iframe id="f1" width="100%" height="600" src="SupplyMap2.aspx"></iframe>

2010年8月11日 星期三

TWD97轉經緯度WGS84 經緯度WGS84轉TWD97

在台灣做地理資訊系統相關工作常常會遇到坐標轉換的問題,而有一件很有趣的事情,在網路上面有很多坐標轉換公式、很多的轉換方法、很多已經寫好的轉換程式,但是就是很難查到如果要寫成程式到底該怎麼做?如果現在必須要在TWD97的坐標系統下進行經緯度定位,我到底該如何在自己的程式中做這件事情?

總之,我們可以查到一堆公式、一堆論文、一堆已經寫好的程式、什麼三參數六參數,這個老師那個老師,然後切換一下VS的視窗,發現查了一個早上也沒看到程式多一行。

今天我也遇到一樣的問題,必須要轉換經緯度成TWD97。

有幸,在網路上查到[Victor的程式設計遇上小提琴]這篇文章,而他所參考的原始公式為一個Steve Dutch學者的文章,在Victor的部落格中已經提供了TWD97與WGS84兩者互轉的Python與JAVA程式,但我所執行的專案大部分為VB或C#語法,所以在這邊貼出改寫他程式碼後的C#語法,希望可以幫到找不到轉換程式寫法的人。

為了方便看到這篇的人複製貼上,以下的程式碼可以直接在VS中於App_Code裡面新增一個CoordinateTransform.cs的class,然後直接全部貼上。

共有兩個Public的函式
1. lonlat_To_twd97輸入XY度分秒或是XY的弧度值返回TWD97 "X,Y"字串。
2. TWD97_To_lonlat輸入TWD97 XY值與type(1表示傳回度分秒字串、2表示傳回弧度字串)。
當然還有兩個重點就是計算轉換的程式碼。
1. Cal_lonlat_To_twd97
2. Cal_TWD97_To_lonlat

所以要使用的時候很簡單,在你的程式裡面先把這個Class new起來,然後傳入你要轉換的值,他會回你一個字串,再自行用字串拆解拆開。
例:

CoordinateTransform CoordinateTransform = new CoordinateTransform();
this.Label1.Text = CoordinateTransform.TWD97_To_lonlat(248170.826, 2652129.977, 2);

Class程式碼:

public class CoordinateTransform
{
double a = 6378137.0;
double b = 6356752.314245;
double lon0 = 121 * Math.PI / 180;
double k0 = 0.9999;
int dx = 250000;

public CoordinateTransform()
{
//
// TODO: 在此加入建構函式的程式碼
//
}

//給WGS84經緯度度分秒轉成TWD97坐標
public string lonlat_To_twd97(int lonD,int lonM,int lonS,int latD,int latM,int latS)
{
double RadianLon = (double)(lonD) + (double)lonM / 60 + (double)lonS / 3600;
double RadianLat = (double)(latD) + (double)latM / 60 + (double)latS / 3600;
return Cal_lonlat_To_twd97(RadianLon, RadianLat);
}
//給WGS84經緯度弧度轉成TWD97坐標
public string lonlat_To_twd97(double RadianLon, double RadianLat)
{
return Cal_lonlat_To_twd97(RadianLon, RadianLat);
}

//給TWD97坐標 轉成 WGS84 度分秒字串 (type1傳度分秒 2傳弧度)
public string TWD97_To_lonlat(double XValue, double YValue, int Type)
{

string lonlat = "";

if (Type == 1)
{
string[] Answer = Cal_TWD97_To_lonlat(XValue, YValue).Split(',');
int LonDValue = (int)double.Parse(Answer[0]);
int LonMValue = (int)((double.Parse(Answer[0]) - LonDValue) * 60);
int LonSValue = (int)((((double.Parse(Answer[0]) - LonDValue) * 60) - LonMValue) * 60);

int LatDValue = (int)double.Parse(Answer[1]);
int LatMValue = (int)((double.Parse(Answer[1]) - LatDValue) * 60);
int LatSValue = (int)((((double.Parse(Answer[1]) - LatDValue) * 60) - LatMValue) * 60);

lonlat = LonDValue + "度" + LonMValue + "分" + LonSValue + "秒," + LatDValue + "度" + LatMValue + "分" + LatSValue + "秒,";
}
else if (Type == 2)
{
lonlat = Cal_TWD97_To_lonlat(XValue, YValue);
}

return lonlat;
}



private string Cal_lonlat_To_twd97(double lon ,double lat)
{
string TWD97 = "";

lon = (lon/180) * Math.PI;
lat = (lat/180) * Math.PI;

//---------------------------------------------------------
double e = Math.Pow((1 - Math.Pow(b,2) / Math.Pow(a,2)), 0.5);
double e2 = Math.Pow(e,2)/(1-Math.Pow(e,2));
double n = ( a - b ) / ( a + b );
double nu = a / Math.Pow((1-(Math.Pow(e,2)) * (Math.Pow(Math.Sin(lat), 2) ) ) , 0.5);
double p = lon - lon0;
double A = a * (1 - n + (5/4) * (Math.Pow(n,2) - Math.Pow(n,3)) + (81/64) * (Math.Pow(n, 4) - Math.Pow(n, 5)));
double B = (3 * a * n/2.0) * (1 - n + (7/8.0)*(Math.Pow(n,2) - Math.Pow(n,3)) + (55/64.0)*(Math.Pow(n,4) - Math.Pow(n,5)));
double C = (15 * a * (Math.Pow(n,2))/16.0)*(1 - n + (3/4.0)*(Math.Pow(n,2) - Math.Pow(n,3)));
double D = (35 * a * (Math.Pow(n,3))/48.0)*(1 - n + (11/16.0)*(Math.Pow(n,2) - Math.Pow(n,3)));
double E = (315 * a * (Math.Pow(n,4))/51.0)*(1 - n);

double S = A * lat - B * Math.Sin(2 * lat) +C * Math.Sin(4 * lat) - D * Math.Sin(6 * lat) + E * Math.Sin(8 * lat);

//計算Y值
double K1 = S*k0;
double K2 = k0*nu*Math.Sin(2*lat)/4.0;
double K3 = (k0*nu*Math.Sin(lat)*(Math.Pow(Math.Cos(lat),3))/24.0) * (5 - Math.Pow(Math.Tan(lat),2) + 9*e2*Math.Pow((Math.Cos(lat)),2) + 4*(Math.Pow(e2,2))*(Math.Pow(Math.Cos(lat),4)));
double y = K1 + K2*(Math.Pow(p,2)) + K3*(Math.Pow(p,4));

//計算X值
double K4 = k0*nu*Math.Cos(lat);
double K5 = (k0*nu*(Math.Pow(Math.Cos(lat),3))/6.0) * (1 - Math.Pow(Math.Tan(lat),2) + e2*(Math.Pow(Math.Cos(lat),2)));
double x = K4 * p + K5 * (Math.Pow(p, 3)) + dx;

TWD97 = x.ToString()+ "," + y.ToString();
return TWD97;
}


private string Cal_TWD97_To_lonlat(double x, double y)
{

double dy = 0;
double e = Math.Pow((1- Math.Pow(b,2)/Math.Pow(a,2)), 0.5);

x -= dx;
y -= dy;

// Calculate the Meridional Arc
double M = y/k0;

// Calculate Footprint Latitude
double mu = M/(a*(1.0 - Math.Pow(e, 2)/4.0 - 3*Math.Pow(e, 4)/64.0 - 5*Math.Pow(e, 6)/256.0));
double e1 = (1.0 - Math.Pow((1.0 - Math.Pow(e, 2)), 0.5)) / (1.0 + Math.Pow((1.0 - Math.Pow(e, 2)), 0.5));

double J1 = (3*e1/2 - 27*Math.Pow(e1, 3)/32.0);
double J2 = (21*Math.Pow(e1, 2)/16 - 55*Math.Pow(e1, 4)/32.0);
double J3 = (151*Math.Pow(e1, 3)/96.0);
double J4 = (1097*Math.Pow(e1, 4)/512.0);

double fp = mu + J1*Math.Sin(2*mu) + J2*Math.Sin(4*mu) + J3*Math.Sin(6*mu) + J4*Math.Sin(8*mu);

// Calculate Latitude and Longitude

double e2 = Math.Pow((e*a/b), 2);
double C1 = Math.Pow(e2*Math.Cos(fp), 2);
double T1 = Math.Pow(Math.Tan(fp), 2);
double R1 = a*(1-Math.Pow(e, 2))/Math.Pow((1-Math.Pow(e, 2)*Math.Pow(Math.Sin(fp), 2)), (3.0/2.0));
double N1 = a/Math.Pow((1-Math.Pow(e, 2)*Math.Pow(Math.Sin(fp), 2)), 0.5);

double D = x/(N1*k0);

// 計算緯度
double Q1 = N1*Math.Tan(fp)/R1;
double Q2 = (Math.Pow(D, 2)/2.0);
double Q3 = (5 + 3*T1 + 10*C1 - 4*Math.Pow(C1, 2) - 9*e2)*Math.Pow(D, 4)/24.0;
double Q4 = (61 + 90*T1 + 298*C1 + 45*Math.Pow(T1, 2) - 3*Math.Pow(C1, 2) - 252*e2)*Math.Pow(D, 6)/720.0;
double lat = fp - Q1*(Q2 - Q3 + Q4);

// 計算經度
double Q5 = D;
double Q6 = (1 + 2*T1 + C1)*Math.Pow(D, 3)/6;
double Q7 = (5 - 2*C1 + 28*T1 - 3*Math.Pow(C1, 2) + 8*e2 + 24*Math.Pow(T1, 2))*Math.Pow(D, 5)/120.0;
double lon = lon0 + (Q5 - Q6 + Q7)/Math.Cos(fp);

lat = (lat * 180) / Math.PI; //緯
lon = (lon * 180) / Math.PI; //經


string lonlat = lon + "," + lat;
return lonlat;
}


}

最後,我用控制點去進行轉換也覺得誤差很小,如果要進行一般性的應用,我想是相當足夠。

題外話:剛剛又去Victor的部落格看了一看,我猜測他是資工的,沒想到這樣平凡、常用、實用的內容,竟然不是在所謂的測量或地理資訊相關網站找到,我真的不知道該說什麼。

Oracle_匯出錯誤 ORA-20446 ORA-06512

解決上一篇的問題,我們就可以很開心的進行匯出工作,當進行到最後一步,等著要把匯出檔帶出去更新的時候,又跳出下一個錯誤訊息。

問題:ORA-20446: The owner of the job is not registered ORA-06512: 在 "SYSMAN.MGMT_JOBS", line 168 ORA-06512: 在 "SYSMAN.MGMT_JOBS", line 86 ORA-06512: 在 line 1

這...完全看不懂是什麼東西,由於對於Oracle的權限並不是非常暸解,但就我理解Google是說:因為我們所登入的這個帳號並沒有某個權限,導致沒辦法將資料匯出,所以我們必須把這個帳號加進去"某個權限裡面"。

[以下解法來自於一大堆大陸網站]
解法:
1. 開啟SQL Plus。
2. 以sysman進行登入。
3. 輸入以下指令:execute MGMT_USER.MAKE_EM_USER('要匯出資料的使用者名稱');


完成以後,就可以正確匯出資料囉!

Oracle_主機證明資料_帳密錯誤解法

昨天處理Oracle的資料匯入匯出時,出現了兩個問題,趕快紀錄一下。

問題:如果你在操作Oracle的時候採用Enterprise Manager的介面來進行資料匯出、匯入的工作時,會發現他並不是要你輸入綱要的密碼,而是問你"主機證明資料"。主機證明資料?這是什麼?Google說:Oracle主機的帳號及密碼。好!立刻輸入系統管理者的帳號密碼,叭叭!錯!應該是輸入錯誤,叭叭!錯!輸入一百次跟他拼了!叭叭!叭叭!叭叭!叭叭!叭叭!叭叭!就會開始懷疑到底是不是自己記錯了,登出伺服器再進來一次,好!反正怎麼測都沒輸入錯誤,但是怎麼樣他都回應錯了。

[以下解法來自紫糯米]
解法:必須將系統帳號加到"以批次工作登入"這個原則當中。
1. 控制台→系統管理工具→本機安全性原則

2. 在根目錄安全性設定下→本機原則→使用者權力指派,再雙擊右方"以批次工作登入"。

3. 新增使用者或群組→將本機的系統管理者帳號加進去。

4. 最後一個步驟不是很確定,因為我完成設定後,重新開啟Oracle Enterprise Manager進行資料匯入,還是一樣會卡在帳號密碼錯誤,因為不確定要重開哪一個服務,所以我重新開機後就成功了。XD

理論上,如果你遇到這一個問題,表示你馬上會遇到下一個,請看下一篇。

2010年8月9日 星期一

MapGuide+Flex = ? Part2

上星期五嘗試把MapGuide的圖接回來在Flex上面呈現,這個假日就一直在想要怎麼樣才能夠增加互動,表現出一點Flex的特點。(前篇)有提到框選放大或平移這類要對物件操作進而表現動畫是我認為比較困難的地方,昨晚打一打電動突然想到一個流程,感覺可以做出來類似的效果,所以今天就偷偷地繼續玩一下Flex+MapGuide。

所以今天做了三件事情:
1. 重新整理星期五的程式碼,將與圖操作有關的部分寫成一個Viewer物件,與主程式溝通就用自訂事件來傳遞ValueObject。
2. 模仿MapGuide製作ZoomToView(CenterX,CenterY,Scale)的定位函式。
3. 利用Flex繪圖功能,製作框選放大的動畫,並與第2項結合完成框選放大功能。
4. 計算滑鼠平移量並配合ZoomToView函式完成平移功能。

成果:
1. 將Viewer改成物件,除了獨立出來操作性更便利外,動畫可以對整個物件下,就變成:

2. 框選放大(框選中的圖)

3. 平移(平移中的圖)


個人覺得框選放大的效果還不錯,如果連線正常可以試試看。 XD

2010年8月6日 星期五

MapGuide+Flex = ?

自從今年初開始自學Flex以後,就一值希望可以有機會做用Flex開發的專案,而在地理資訊系統當中,若是說到Flex大家應該都會想到ArcGISServer,因為在他的官網上面有免費的FlexAPI可以下載,而且還有很多範例跟公版可以參考學習;之前也花了一段時間去暸解其架構,但因為手上專案並不是屬於ArcGISServer+Flex的開發環境,所以也只能偷偷用在其他專案的小地方。

而在接觸Flex的時間裏面,其實一值幻想MapGuide應該也會出以Flex為開發語言的Viewer,來跟ESRI一較高下;現在MapGuide2011出來了,但似乎沒有聽到MapGuide與RIA整合的任何消息,失望之餘還是覺得這件事情Autodesk沒有去做是非常沒有道理的,也曾經在看書、寫程式、騎車的時候想過這件事情,總覺得應該做到。

一個月前,突然想到,即使不要把Viewer整合進去,把整個MapGuide框架都放進去總可以了吧?事實證明,雖然把框架放到Flex上面呈現,但是對於地圖的操作上則受限於Flex本身解讀較困難html時的弱點,沒辦法很順暢的操作。

最近為了解決一個專案的問題,嘗試不透過MapGuide所提供的框架,而是直接以程式去操作MapGuide的各項動作(也就是前篇),突然想到若是利用這種方式,直接在後端服務建立一個虛擬的地圖,或許可以做出一個簡單的Viewer,甚至空間查詢、空間統計等等都可以在Flex上面呈現。

所以我的構想是,必須在後端服務於MapGuide幫我成圖以後,將該圖傳回Flex上面呈現,而FDO的各項資料處理,比例尺設定等等當然就還是利用MapGuide進行設定,架構就像下圖:

把圖成功取回來之後,我們就可以利用一些比例尺計算的技巧,做出一個簡單的Viewer:

目前的功能有:
1. 依照比例尺與XY坐標讀取地圖。
2. 前滾放大地圖、後滾縮小地圖。
3. 滑鼠於圖面上移動時會有動態坐標。
4. 點擊地圖會取得點擊點坐標。

其實如果有寫過相關程式的應該會知道,如果我能夠取得點擊點坐標,我就可以在後端利用空間查詢的方式取得任何一個圖層MgFeatureReader,而做到屬性查詢的功能;如果我可以依照比例尺與XY坐標讀到地圖,表示我可以做到各項定位功能;並且透過單純的資料庫服務,於後端製作一個臨時層達到各項資料與圖面的互動;所以真的的困難點其實不是這些所謂的"功能",最困難的地方在於要怎麼樣去包裝好這個呈圖的物件,比如說要如何框選放大,如何做出平移的動畫,諸如此類的內容或許更令人頭大。

總之,不管怎麼樣MapGuide進到Flex裡面,而且我們可以對他進行操作,看來是一件非常有趣的事情!!既然放進來了一定要對他做一件我之前一值想做的事情:

旋轉了!真感動。 T.T

MapGuide_Map.Open VS Map.Create(不開MapGuide框架操作地圖)

在開發MapGuide程式時,通常都會依照我們所設計的網頁框架,將其中一個frame指定給/mapguide2010/mapviewernet/ajaxviewer.aspx,並且後面帶有SESSION跟WEBLAYOUT的參數,這樣就可以很容易的顯示出一個簡單的MapGuide公版。(不清楚該如何設定的可以參考)開出頁面以後,若是需要對地圖進行操作,我們就可以new出一個MgMap,然後使用Map.Open("地圖名稱")來取得地圖,並且進行任何一個介紹過的功能。

但是有時候我們並不想把整個MapGuide的框架打開來操作地圖,可能只希望去連接MapGuide Server的資料,利用程式的處理來獲取一些資訊,比如說:我想要去查詢信義區有多少間7-11,看到這個需求,通常的回應是:利用台北市行政區圖與7-11的點位資料進行空間查詢(空間查詢可參考),那麼我們可能會在MapGuide框架下,撰寫一個便利商店空間查詢功能,讓使用者選擇行政區跟需要統計的子項目來獲得答案,但可能實際需求只是需要一個統計列表;又可能想要去擷取於MapGuide Server上某個比例尺下的圖面資料貼在另一個系統上,那我們可能會製做一個匯出圖檔的功能,讓使用者操作,但實際需求是只要取得該區域的影像放到imageBox就好;所以不管怎樣,我們的思維往往被侷限在"我必須先產生MapGuide的框架"才能進而進行地圖的操作。

那我們有沒有辦法不要開啟MapGuide的框架,直接對MapGuide Server取得資料?去觀察整個開啟框架然後打開地圖進而對MapGuide Server進行操作的過程中有一個重點,就是Map.Open("地圖名稱")這個指令,既然使用Open這個字,就代表他是將已經存在的地圖打開來,那"已經存在"的地圖是誰?其實就是我們所用的MapGuide框架,所以!使用框架時它幫我們做了一個很重要的事情:new一個地圖!

所以整件事情的重點是,我要如何可以不要開框架的情況下創造出地圖,後來發現其實很有趣,整個答案就是前一句話,我要創造一個地圖,所以函式是:Map.Create(resourceService,MgResourceIdentifier,mapName),我們可以嘗試把程式碼略為修改,就可以發現我們不需要經過框架而產生出地圖,才對MapGuide Server進行操作。所以整個程式流程就像下圖:

寫這篇的時候讓我想到另一個有趣的事情,請見下篇。

2010年8月2日 星期一

Flex_ArrayCollection的操作_排序

上一篇文章有用到排序的功能,但有時候我們想要排序的欄位並不只一個,這時候該怎麼做?

在AdvancedDataGrid的元件上有一個已經寫好的多欄位排序功能,可以提供使用者利用點選的方式來決定欄位先後順序,也可以依照某一個欄位進行屬性判斷後變色,效果相當不錯。

但是如果我們希望利用程式碼來控制排序要怎麼做?
我們可以利用Sort這個controls,透過增加SortField的方式來做出多欄位排序的效果:
1. 建立排序欄位資料,(SortField第一個變數:欄位名稱、第二個變數:是否辨別大小寫、第三個變數:是否用降冪(T降 F升))

var SF1:SortField=new SortField("ID",true,false);
var SF2:SortField=new SortField("Type",true,false);
var SF3:SortField=new SortField("Level",true,false);
var SF4:SortField=new SortField("Online",true,true);

2. 將要排序的先後存入Array,下面程式碼代表排列順序為2→3→4→1。

var SortArray:Array = new Array();
SortArray.push(SF2);
SortArray.push(SF3);
SortArray.push(SF4);
SortArray.push(SF1);

3. 將Array指定給sort物件。

var sort:Sort=new Sort();
sort.fields=SortArray;

所以我們就可以製作一個介面,利用上面的程式碼,指定要排序的方式,來達到以程式碼操作的目的。(下圖為先排列上線與否,再將等級由高到低排列)

Flex_ArrayCollection的操作_存入ValueObject

今天有同事提到一個問題:想把從txt檔讀出的XY字串轉到DataGrid上面呈現,並且自動依照X欄位排序,所以做了以下的測試。

課程上了一半,在資料處理上感覺還是ArratCollection的操作最為重要,單就為了快速的Binding就幾乎絕大部分的資料最後都要選擇存入當中;但要存進什麼?怎麼樣存?就看各種不同的需求而定了。而在上課的時候,老師極力推薦使用ValueObject的概念。所以這篇將會利用ValueObject的概念來處理資料(相關資料:Flex_ArrayCollectionFlex_Array與ArrayCollection的差異Flex_混亂的arrayCollection與[Bindable])
假設我們已經取得文字檔當中的字串為(3,70;4,90;2,40;1,60),(該結構為(X1,Y1;X2,Y2),也就是XY用逗號相隔,每組資料用分號相隔)。所以我想要做的流程是:
1. 利用字串的split函式將XY資料拆出來。
2. 建立一個XYObject的ValueObject儲存XY值。
3. 將XYObject存入ArrayCollection當中。
4. 建立一個設定使用X排序的Sort,指定給ArrayCollection。
5. 將ArrayCollection動態Binding到DataGrid上。

所以程式裡面會需要三個東西:
1. 處理XY值的ValueObject。
2. 給文字檔字串返回存有ValueObject的ArrayCollection函式。
3. 設定排序欄位返回sort的函式。

直接看程式碼:
1. ValueObject:只有存取XY值,並未對XY值做任何判斷及處理。

2. 主程式碼:

3.執行結果:

最後,貼上可以複製的程式碼:
1. ValueObject

package
{
public class XYObject
{
public var X:int;
public var Y:int;

public function XYObject(X:int,Y:int)
{
this.X=X;
this.Y=Y;
}
}
}

2. 主程式碼

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
<![CDATA[
import mx.collections.SortField;
import mx.collections.Sort;
import mx.collections.ArrayCollection;

[Bindable]
public var XYArrayCollection:ArrayCollection = new ArrayCollection();
public var XY:String="3,70;4,90;2,40;1,60";

private function clickHandler():void
{
//清除之前紀錄
XYArrayCollection.removeAll();
//給XY字串,返回資料存入XYObject的ArrayCollection
XYArrayCollection=PutXYObjectToAC(XY);
//給排序欄位,返回以設定好之Sort
XYArrayCollection.sort = CreateSort("X");
//為了排序,重新整理ArrayCollection
XYArrayCollection.refresh();
}
private function PutXYObjectToAC(XYString:String):ArrayCollection
{
var XYarray:Array = new Array();
var XYAC:ArrayCollection = new ArrayCollection();
XYarray = XY.split(";");
for (var i:int=0; i<XYarray.length;i++)
{
var XYValue:Array = new Array();
XYValue = XYarray[i].toString().split(",");
XYAC.addItem(new XYObject(XYValue[0],XYValue[1]));
}
return XYAC
}

private function CreateSort(SortFieldName:String):Sort
{
var sort:Sort=new Sort();
var f1:SortField=new SortField(SortFieldName,true,false);
sort.fields=new Array(f1);
return sort;
}
]]>
</mx:Script>

<mx:DataGrid width="300" dataProvider="{this.XYArrayCollection}">
<mx:columns>
<mx:DataGridColumn headerText="里程" dataField="X"/>
<mx:DataGridColumn headerText="高程" dataField="Y"/>
</mx:columns>
</mx:DataGrid>
<mx:Button id="btn_Go" label="執行" click="clickHandler()"/>

</mx:Application>

利用這樣的概念去處理資料,真的是相當漂亮。