c#兩種方式調用google地球,調用COM API以及調用GEPLUGIN 與js交互,加載kml文件,dae文件。將二維高德地圖覆蓋到到三維谷歌地球表面。

網絡上資源不少不全面,本身在開發的時候走了很多彎路,在這裏整理了最全面的google全套開發,COM交互,web端交互。封裝好了各類模塊功能。 直接就能夠調用。javascript

第一種方式:調用COMAPI實現調用google地球css

一、安裝googleearth客戶端。傳送門:https://pan.baidu.com/s/1xi3fwCIy3Jt6t5XbypqpCg 提取碼:0l7uhtml

二、添加引用using EARTHLib;若是找不到此dll,到googleearth的安裝目錄下尋找後添加到引用便可。java

三、添加預約義的方法到項目中,後續獲取窗口句柄,以及設置窗口的時候會調用其中的一些方法。node

    class NativeMethods
    {
         [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
         public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, UInt32 uflags);
  
         [DllImport("user32.dll", CharSet = CharSet.Auto)]
         public static extern IntPtr PostMessage(int hWnd, int msg, int wParam, int lParam);
  
         #region 預約義
  
         public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
         public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
         public static readonly IntPtr HWND_TOP = new IntPtr(0);
         public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);

         public static readonly UInt32 SWP_NOSIZE = 1;
         public static readonly UInt32 SWP_NOMOVE = 2;
         public static readonly UInt32 SWP_NOZORDER = 4;
         public static readonly UInt32 SWP_NOREDRAW = 8;
         public static readonly UInt32 SWP_NOACTIVATE = 16;
         public static readonly UInt32 SWP_FRAMECHANGED = 32;
         public static readonly UInt32 SWP_SHOWWINDOW = 64;
         public static readonly UInt32 SWP_HIDEWINDOW = 128;
         public static readonly UInt32 SWP_NOCOPYBITS = 256;
         public static readonly UInt32 SWP_NOOWNERZORDER = 512;
         public static readonly UInt32 SWP_NOSENDCHANGING = 1024;
  
         #endregion
  
         public delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
  
         [DllImport("user32", CharSet = CharSet.Auto)]
         public extern static IntPtr GetParent(IntPtr hWnd);
  
         [DllImport("user32", CharSet = CharSet.Auto)]
         public extern static bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
  
         [DllImport("user32", CharSet = CharSet.Auto)]
         public extern static IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
  
         [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
         public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
  
         public static int GW_CHILD = 5;
         public static int GW_HWNDNEXT = 2;
     }

四、定義變量jquery

        private bool isGEStart = false;//GE是否開啓
        private ApplicationGEClass geApp;
        /// <summary>
        /// 用來關閉GoogleEarth的消息定義
        /// </summary>
        static readonly Int32 WM_QUIT = 0x0012;

        private IntPtr GEHWnd = (IntPtr)5;
        private IntPtr GEHrender = (IntPtr)5;
        private IntPtr GEParentHrender = (IntPtr)5;

五、作完上面的工做後,開始初始化谷歌地球。將下列代碼放入本身定義的方法中便可。linux

try
            {
                if (!this.DesignMode)
                {
                    geApp = new ApplicationGEClass();

                    GEHWnd = (IntPtr)geApp.GetMainHwnd();
                    //隱藏GoogleEarth主窗口
                    NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE + NativeMethods.SWP_HIDEWINDOW);

                    GEHrender = (IntPtr)geApp.GetRenderHwnd();
                    GEParentHrender = (IntPtr)NativeMethods.GetParent(GEHrender);
                    //將渲染窗口嵌入到主窗體
                    NativeMethods.MoveWindow(GEHrender, 0, 0, this.panelEx_google.Size.Width, this.panelEx_google.Size.Height, true);
                    NativeMethods.SetParent(GEHrender, this.panelEx_google.Handle);
                    isGEStart = true;
                   
                }
            }
            catch (Exception ex)
            {
                
                isGEStart = false;
                Thread.Sleep(1000);
            }

六、以上代碼可加載谷歌地球,而且釋放資源,程序運行如圖:c++

第一種方式實質上是啓動GoogleEarth客戶端,並獲取窗口句柄,再將窗口顯示的本身定義的控件下面,此種方法也能夠實現需求,可是通過測試,此方法存在兩大弊端。第一,在啓動谷歌地球的時候將佔用大量的CPU資源。第2、在釋放谷歌地球的時候時候,可能會釋放失敗,沒法關閉googleearth此時也將佔用大量的CPU。基於以上弊端因此採用第二種方式。webroswer調用js。git

 

二、重點:乾貨。web

c#使用GEPlugin插件,webroswer與js交互,實現web端的googleearth體驗。而且加載kml,加載三維模型dae,加載路徑,電子圍欄。各類功能已封裝。調用便可使用。

一、下載GEPlugin 傳送門:

連接:https://pan.baidu.com/s/1e_elo_x0KlhfFgNzbboa6w
提取碼:687b 

二、使用GEPlugin相對於COMAPI要較爲複雜。可是性能最優。下載封裝好的文件,單獨的exe,放在程序項目文件中,啓動這個文件,在程序中調用一個方法便可加載google地球到webroswer。由於這個文件有公司logo。因此不便發佈於此,有想要的能夠私信我。單獨發送。謹記:此文件只供學習使用,交流心得,不得用於任何商業行爲。

三、下面開始正式的編碼。若是下載了exe的文件,而且打開後,執行此段代碼,谷歌地球將被加載完成。獲取的硬盤id以及cpu序列號,將此數據傳遞到封裝好的服務中。防止別的瀏覽器直接輸入網址瀏覽。安全校驗使用。

而且將你的form設置成對COM可見

[ComVisible(true)]
    public partial class AnalysisForm : Form

 

private CassiniDev.Server _server1;
private bool IsWebServerStarted = false;
public string WEBSERVER_PATH;


private void NavigateAnaForm_Shown() { string PLUGIN_URL_LOCAL; string PLUGIN_URL_RELOAD; //GoogleEarth延時加載的線程 //在程序啓動時使用單獨的線程來加載WebBroswer控件中的GE地圖,以避免出現主界面加載時卡頓的現象 Thread geLazyLoadingThread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate () { //Thread.Sleep(50); //記錄系統中現有的GEPlugIn線程 Process[] listExistedGePlugInProcess = Process.GetProcessesByName("geplugin"); this.BeginInvoke( new Action(() => { PLUGIN_URL_LOCAL = "http://127.0.0.1:9809/map.asp?px1=" + GetCpuID() + "&PX2=" + GetDiskID(); PLUGIN_URL_RELOAD = "http://127.0.0.1:9808/reload.html"; this.webBrowserGE.ObjectForScripting = this; this.webBrowserGE.ScriptErrorsSuppressed = false ; //_server = new CassiniDev.Server(9630, "/", WEBSERVER_PATH, //"G:\\Desktop\\1111\\bin\\Debug\\NavFiles", // System.Net.IPAddress.Parse("127.0.0.1"), "", false, true); //http://127.0.0.1:9809/map.asp?px1=178BFBFF00810F10&PX2=GLOWAY STK720GS3-S7 //http://192.168.0.196:9808/map.asp?px1=BFEBFBFF000906E9&PX2=SanDisk Cruzer Glide 3.0 USB Device this.webBrowserGE.Navigate(PLUGIN_URL_LOCAL); this.webBrowserGE.Visible = true; } )); })); //啓動GoogleEarth裝載的線程 geLazyLoadingThread.SetApartmentState(ApartmentState.STA); geLazyLoadingThread.Start(); }

private string GetDiskID()
{
try
{
//獲取硬盤ID
String HDid = " ";
ManagementClass mc = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
HDid = (string)mo.Properties["Model"].Value;
}
moc = null;
mc = null;
return HDid;
}
catch
{
return "unknown";
}
finally
{
}
}
private string GetCpuID()
{
try
{
//獲取CPU序列號代碼
string cpuInfo = " ";//cpu序列號
ManagementClass mc = new ManagementClass("Win32_Processor");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
}
moc = null;
mc = null;
return cpuInfo;
}
catch
{
return "unknown";
}
finally
{
}

 
 

}

 

四、此時地圖便可加載完成,萬水千山,踏出第一步。可是此時沒法向谷歌地球添加kml或者三維模型。和一些其餘的操做。若是要加載kml文件。繼續往下看。

五、此時啓動web容器 ,先添加引用 CassiniDev4-lib;找不到又不想下載? 傳送門來了:

連接:https://pan.baidu.com/s/1LOzD7plVaGG3NstMEEUb0g
提取碼:oymj  

        /// <summary>
        /// 啓動Web容器服務
        /// </summary>
        public void Start_WebServer()
        {
            WEBSERVER_PATH = string.Concat(new object[] { Directory.GetCurrentDirectory(), Path.DirectorySeparatorChar, "3DView" });

            _server1 = new CassiniDev.Server(9630, "/", WEBSERVER_PATH,
                     System.Net.IPAddress.Parse("127.0.0.1"), "", false, true);

            if (!IsWebServerStarted)
            {
                try
                {
                    _server1.Start();
                    IsWebServerStarted = true;
                    MessageBox.Show("web 服務已經打開!");
                }
                catch (Exception ex)
                {
                    MessageBox.Show( "服務打開失敗!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _server1.Dispose();
                    return;
                }
                /*
                try
                {
                    _server2.Start();
                    IsWebServerStarted = true;
                }
                catch (Exception ex)
                {
                    XtraMessageBox.Show(Program.devExpressDarkSkin, "GBQ服務2打開失敗!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _server2.Dispose();
                    return;
                }
                */
            }
            else
            {
                try
                {
                    _server1.ShutDown();
                    IsWebServerStarted = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show( "服務關閉失敗!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _server1.Dispose();
                    //return;
                }

                try
                {
                    _server1.Start();
                    IsWebServerStarted = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show( "服務打開失敗!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _server1.Dispose();
                    return;
                }
            }
        }

 

六、此時小夥伴要問,爲何要啓動一個web服務,不要着急,往下看。加載kml文件。

 

webBrowserGE.Document.InvokeScript("importLidarKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/zouhang1.kml",true });

 

是否是很神奇,只須要一行代碼,你的kml文件,或者kml文件中帶有有三維模型的文件,便可被加載成功,由於程序已經徹底封裝了你所須要的功能。

解析上一個疑惑,爲何要啓動一個web服務,由於invokescprit加載文件的時候須要以網址的形式加載,因此啓動一個web服務器,並設置好root目錄,將你的kml文件放置到root目錄下便可。

 

七、你覺得此時kml文件就能夠加載成功了?成功的道路老是充滿坎坷的。此時的你加載kml的時候,應該是看不到任何反應的。由於我當初在這個地方踩了不少的坑。大家很幸運,不須要在這裏掙扎。記錄一下。分享給大家。

 

 

///重要重要重要        

public string getMapServerandLag_callback() { return "7,1,18"; }

多麼簡單的一個方法,可是沒有他你什麼也作不了。這個是地圖加載後的回調方法。務必加上。用於給層級賦值。

下面還有幾個方法,分享給你門,無關緊要。

//加載失敗後的回調函數       
public void JSInitFailureCallback_(string error){
}   
//加載成功後的回調函數

public void geSuccessLoadedCallback_()
{

 
 

}

 

 八、通過以上的努力你已經達成了目標的80%了。你所想要的功能已經基本實現。

另一些其餘的加載方法在這裏附上

                webBrowserGE.Document.InvokeScript("importGoogleMapKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/ditu.kml" });
                webBrowserGE.Document.InvokeScript("importLidarKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/zouhang1.kml",true });
                webBrowserGE.Document.InvokeScript("importRemarkKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/1111.kml" });
                webBrowserGE.Document.InvokeScript("importDrawKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/1111.kml" });
                webBrowserGE.Document.InvokeScript("importLidarKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/1111.kml", true });
                webBrowserGE.Document.InvokeScript("importDrawKmlFilebyUrl", new object[] { "http://192.168.1.196:9630/3DPaint/KmlDrawings/1111.kml", true });
                webBrowserGE.Document.InvokeScript("searchLocation_e", new object[] { 38, 117 });
                webBrowserGE.Document.InvokeScript("importLidarKmlFilebyUrl", new object[] { "http://127.0.0.1:9630/3DMap/111.kml" });

                webBrowserGE.Document.InvokeScript("getGEKml_e");
                webBrowserGE.Document.InvokeScript("setMapLayersStatus", new object[] { false, false, false, false, false, false, false, false, false, false, false, false });

很是簡單,可本身摸索。

九、上圖

 

 

到這裏就結束了?不存在的。技術用於之境。下面分享給你們,如何將二維高德地圖蒙皮到三維谷歌球體上。拭目以待。

十、加載高德地圖到谷歌地球上。實現谷歌地球與高德地圖之間的切換。

首先。須要下載兩個座標轉換文件。傳送門:

連接:https://pan.baidu.com/s/18QCXtXdx98NJ-gkG5wU6_w
提取碼:b9c9 


//此文件是實現座標以及經緯度的轉換

<%@ Import Namespace="System.Web.HttpResponse" %> <%@ language="javascript" Debug="true"%> <% function downloadfile() { var xValue=Request.QueryString("x") var yValue=Request.QueryString("y") var zValue=Request.QueryString("z") var FileName="landun_"+ zValue*1+"_"+xValue*1+"_"+yValue*1+".kml" var kmlstring=GetKmlSrtring() Response.AddHeader("content-disposition", "attachment;filename="+FileName+";") Response.ContentType = "text/xml" Response.Write(kmlstring) Response.Flush Response.Clear } //生成kml文件的內容 function GetKmlSrtring() { var xValue=Request.QueryString("x") var yValue=Request.QueryString("y") var zValue=Request.QueryString("z") var kmlstr="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">" ///GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"y"); ///GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1+1,"y") ///GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1,"x") ///GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"x") if(zValue*1>=21) { kmlstr=kmlstr+"<Document>\r\n<Region>\r\n<Lod>\r\n<minLodPixels>256</minLodPixels>\r\n<maxLodPixels>-1</maxLodPixels>\r\n</Lod>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1+1,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"x")+"</west>\r\n</LatLonAltBox>\r\n</Region>\r\n<GroundOverlay>\r\n" kmlstr=kmlstr+"<drawOrder>1</drawOrder>\r\n<Icon>\r\n<href>http://wprd04.is.autonavi.com/appmaptile</href><httpQuery>&amp;lang=zh_cn&amp;size=1&amp;scl=1&amp;style=7&amp;x="+(xValue*1)+"&amp;y="+(yValue*1)+"&amp;z="+(zValue*1)+"&amp;</httpQuery></Icon>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1,xValue*1,yValue*1+1,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"x")+"</west>\r\n</LatLonAltBox>\r\n<altitudeMode>clampToGround</altitudeMode>\r\n<altitude>0</altitude>\r\n" kmlstr=kmlstr+"</GroundOverlay>\r\n</Document>\r\n</kml>" }else{ kmlstr=kmlstr+"<Document>\r\n<Region>\r\n<Lod>\r\n<minLodPixels>256</minLodPixels>\r\n<maxLodPixels>-1</maxLodPixels>\r\n</Lod>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1+1,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"x")+"</west>\r\n</LatLonAltBox>\r\n</Region>\r\n<NetworkLink>\r\n" kmlstr=kmlstr+"<name>"+(xValue*2)+"_"+(yValue*2)+"_"+(zValue*1+1)+"</name>\r\n<Region>\r\n<Lod>\r\n<minLodPixels>256</minLodPixels>\r\n<maxLodPixels>-1</maxLodPixels>\r\n</Lod>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1+1,xValue*2,yValue*2,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1+1,xValue*2,yValue*2+1,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1+1,xValue*2,yValue*2,"x")+"</west>\r\n</LatLonAltBox>\r\n</Region>\r\n<Link>\r\n" kmlstr=kmlstr+"<href>http://127.0.0.1:9630/3DMap/ditu.aspx</href><httpQuery>mt=ditu&amp;x="+(xValue*2)+"&amp;y="+(yValue*2)+"&amp;z="+(zValue*1+1)+"&amp;v=1.7&amp;dx=0&amp;dy=0&amp;trans=0</httpQuery>\r\n</Link>\r\n</NetworkLink>\r\n" kmlstr=kmlstr+"<NetworkLink>\r\n<name>"+(xValue*2+1)+"_"+(yValue*2)+"_"+(zValue*1+1)+"</name>\r\n<Region>\r\n<Lod>\r\n<minLodPixels>256</minLodPixels>\r\n<maxLodPixels>-1</maxLodPixels>\r\n</Lod>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2+1,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1+1,xValue*2+2,yValue*2,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2,"x")+"</west>\r\n</LatLonAltBox>\r\n</Region>\r\n<Link>\r\n" kmlstr=kmlstr+"<href>http://127.0.0.1:9630/3DMap/ditu.aspx</href><httpQuery>mt=ditu&amp;x="+(xValue*2+1)+"&amp;y="+(yValue*2)+"&amp;z="+(zValue*1+1)+"&amp;v=1.7&amp;dx=0&amp;dy=0&amp;trans=0</httpQuery>\r\n</Link>\r\n</NetworkLink>\r\n" kmlstr=kmlstr+"<NetworkLink>\r\n<name>"+(xValue*2)+"_"+(yValue*2+1)+"_"+(zValue*1+1)+"</name>\r\n<Region>\r\n<Lod>\r\n<minLodPixels>256</minLodPixels>\r\n<maxLodPixels>-1</maxLodPixels>\r\n</Lod>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1+1,xValue*2,yValue*2+1,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1+1,xValue*2,yValue*2+2,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2+1,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1+1,xValue*2,yValue*2+1,"x")+"</west>\r\n</LatLonAltBox>\r\n</Region>\r\n<Link>\r\n" kmlstr=kmlstr+"<href>http://127.0.0.1:9630/3DMap/ditu.aspx</href><httpQuery>mt=ditu&amp;x="+(xValue*2)+"&amp;y="+(yValue*2+1)+"&amp;z="+(zValue*1+1)+"&amp;v=1.7&amp;dx=0&amp;dy=0&amp;trans=0</httpQuery>\r\n</Link>\r\n</NetworkLink>\r\n" kmlstr=kmlstr+"<NetworkLink>\r\n<name>"+(xValue*2+1)+"_"+(yValue*2+1)+"_"+(zValue*1+1)+"</name>\r\n<Region>\r\n<Lod>\r\n<minLodPixels>256</minLodPixels>\r\n<maxLodPixels>-1</maxLodPixels>\r\n</Lod>\r\n<LatLonAltBox>\r\n" kmlstr=kmlstr+"<north>"+(GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2+1,"y"))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2+2,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1+1,xValue*2+2,yValue*2+1,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1+1,xValue*2+1,yValue*2+1,"x")+"</west>\r\n</LatLonAltBox>\r\n</Region>\r\n<Link>\r\n" kmlstr=kmlstr+"<href>http://127.0.0.1:9630/3DMap/ditu.aspx</href><httpQuery>mt=ditu&amp;x="+(xValue*2+1)+"&amp;y="+(yValue*2+1)+"&amp;z="+(zValue*1+1)+"&amp;v=1.7&amp;dx=0&amp;dy=0&amp;trans=0</httpQuery>\r\n</Link>\r\n</NetworkLink>\r\n" kmlstr=kmlstr+"<GroundOverlay>\r\n<drawOrder>1</drawOrder>\r\n<Icon>\r\n" kmlstr=kmlstr+"<href>http://wprd04.is.autonavi.com/appmaptile</href><httpQuery>&amp;lang=zh_cn&amp;size=1&amp;scl=1&amp;style=7&amp;x="+(xValue*1)+"&amp;y="+(yValue*1)+"&amp;z="+(zValue*1)+"&amp;</httpQuery>\r\n</Icon>" kmlstr=kmlstr+"<LatLonAltBox>\r\n<north>"+((GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"y")))+"</north>\r\n<south>"+(GetMercatorCoordinates(zValue*1,xValue,yValue*1+1,"y"))+"</south>\r\n<east>"+GetMercatorCoordinates(zValue*1,xValue*1+1,yValue*1,"x")+"</east>\r\n<west>"+GetMercatorCoordinates(zValue*1,xValue*1,yValue*1,"x")+"</west>\r\n</LatLonAltBox>\r\n" kmlstr=kmlstr+"<altitudeMode>clampToGround</altitudeMode>\r\n<altitude>0</altitude>\r\n</GroundOverlay>\r\n</Document>\r\n</kml>" } return kmlstr; } //獲得墨卡託座標(雙軸) function GetMercatorCoordinates(zValue,xoryValue,yoryValue, xory) { var xyMercator={} //獲得墨卡託座標 xyMercator.x=(-180+(360/(Math.pow(2,zValue)))*xoryValue) xyMercator.y=20037508.3427892 +(-40075016.6855784/(Math.pow(2,zValue)))*yoryValue ///Response.Write("<script>alert('xyMercator.x "+xyMercator.x+" xyMercator.y "+xyMercator.y +"');</script>"); //根據墨卡託座標轉換爲GPS經緯度,再轉換爲火星座標系經度或緯度 var LatLon = GetMarLatitudeAndLongitude(xyMercator, xory) ///Response.Write("<script>alert('xory "+xory+ " LatLon "+LatLon+"');</script>"); return LatLon } //返回修正後的經度或緯度 function GetMarLatitudeAndLongitude(xyMercator, xory) { var y var longitudeandlatitude={} //此處需注意longitudeandlatitude.lng不須要再進行計算轉換,直接賦值便可 longitudeandlatitude.lng = xyMercator.x y=xyMercator.y / 20037508.3427892 * 180 longitudeandlatitude.lat=(180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2))//.toFixed(12) ///Response.Write("<script>alert('longitudeandlatitude.lat"+longitudeandlatitude.lat+ " longitudeandlatitude.lng"+longitudeandlatitude.lng+"');</script>"); //轉換GPS經緯度爲火星經緯度 var mar = transform(longitudeandlatitude.lat, longitudeandlatitude.lng) if(xory=="y") { return mar.mgLat; } else { return mar.mgLon } } //此方法已啓用 //獲取經緯度,墨卡託座標轉換爲經緯度 function GetLatitudeAndLongitude(mercatorY) { var y,longitudeandlatitude y=mercatorY / 20037508.3427892 * 180 longitudeandlatitude=(180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2))//.toFixed(12) return longitudeandlatitude } //GPS經緯度轉化爲火星經緯度 function transform(wgLat, wgLon) { var lnglat={} if (outOfChina(wgLat, wgLon)) { lnglat.mgLat = wgLat; lnglat.mgLon = wgLon; return lnglat; } var dLat = transformLat(wgLon - 105.0, wgLat - 35.0); var dLon = transformLon(wgLon - 105.0, wgLat - 35.0); var radLat = wgLat / 180.0 * Math.PI; var magic = Math.sin(radLat); magic = 1 - 0.00669342162296594323 * magic * magic; var sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / ((6378245.0 * (1 - 0.00669342162296594323)) / (magic * sqrtMagic) * Math.PI); dLon = (dLon * 180.0) / (6378245.0 / sqrtMagic * Math.cos(radLat) * Math.PI); lnglat.mgLat = wgLat - dLat; ///Response.Write("<script>alert('wgLat"+wgLat+ " dLat"+dLat+"lnglat.mgLat "+lnglat.mgLat+"');</script>"); lnglat.mgLon = wgLon - dLon; return lnglat; } //是否不在中國 function outOfChina(lat, lon) { if (lon < 72.004 || lon > 137.8347) return true; if (lat < 0.8293 || lat > 55.8271) return true; return false; } //轉換緯度 function transformLat(x, y) { var ret ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0; ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0; return ret; } //轉換經度 function transformLon(x, y) { var ret ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0; ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0; return ret; } %> <%downloadfile()%>

 

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<NetworkLink>
  <name>Google Ditu (China Maps)</name>
  <Region>
    <LatLonAltBox>
      <north>85.051128779807</north>
      <south>-85.051128779807</south>
      <east>180</east>
      <west>-180</west>
    </LatLonAltBox>
    <Lod>
      <minLodPixels>256</minLodPixels>
      <maxLodPixels>-1</maxLodPixels>
    </Lod>
  </Region>
  <Link>
    <href>http://127.0.0.1:9630/3DMap/ditu.aspx</href><httpQuery>mt=ditu&amp;x=0&amp;y=0&amp;z=0&amp;v=1.7&amp;dx=0&amp;dy=0&amp;trans=0</httpQuery>    <viewRefreshMode>onRegion</viewRefreshMode>
  </Link>
</NetworkLink>
</kml>

只需向普通地圖同樣,直接加載下載好的,ditu.kml文件同樣,便可實現從谷歌地球切換到高德地圖。

有圖有真相

 

附上一些附加的文件js文件。供參考研究。再次申明,只可用於技術學習,不可用於商業行爲,謹記!!!

if (!window['googleLT_']) {
    window['googleLT_'] = (new Date()).getTime();
}

if (!window['google']) {
    window['google'] = {};
}

if (!window['google']['loader']) {
    window['google']['loader'] = {};

    google.loader.ServiceBase = 'http://www.google.com/uds';
    google.loader.GoogleApisBase = 'http://ajax.googleapis.com/ajax'; 
	google.loader.ApiKey = 'ABQIAAAA7WGF96hesauuOvt92hVLGRSCo55h5L89YfkfbOZYeht3olu9OBQ-iPLPnY04cIbcfiDwRhN8JorTRg';
	google.loader.KeyVerified = true;
	google.loader.LoadFailure = false;
	google.loader.Secure = false;
	google.loader.GoogleLocale = 'www.google.com';
	google.loader.ClientLocation = {"latitude":31.8175,"longitude":117.22775,"address":{"city":"Hefei","region":"Anhui","country":"China","country_code":"CN"}};
	google.loader.AdditionalParams = '';
    
	//JS匿名函數,JS加載時當即執行
	(function () {
        var d = void 0,
            g = !0,
            h = null,
            j = !1,
            k = encodeURIComponent,
            l = window,
            m = document;

        function n(a, b) {
            return a.load = b
        }

        var p = "push",
            q = "replace",
            r = "charAt",
            t = "indexOf",
            u = "ServiceBase",
            v = "name",
            w = "getTime",
            x = "length",
            y = "prototype",
            z = "setTimeout",
            A = "loader",
            B = "substring",
            C = "join",
            D = "toLowerCase";

        function E(a) {
            return a in F ? F[a] : F[a] = -1 != navigator.userAgent[D]()[t](a)
        }
        var F = {};

        function G(a, b) {
            var c = function () {};
            c.prototype = b[y];
            a.T = b[y];
            a.prototype = new c
        }

        function H(a, b, c) {
            var e = Array[y].slice.call(arguments, 2) || [];
            return function () {
                var c = e.concat(Array[y].slice.call(arguments));
                return a.apply(b, c)
            }
        }

        function I(a) {
            a = Error(a);
            a.toString = function () {
                return this.message
            };
            return a
        }

        function J(a, b) {
            for (var c = a.split(/\./), e = l, f = 0; f < c[x] - 1; f++) e[c[f]] || (e[c[f]] = {}), e = e[c[f]];
            e[c[c[x] - 1]] = b
        }

        function K(a, b, c) {
            a[b] = c
        }

        if (!L) var L = J;
        if (!M) var M = K;
        google[A].v = {};
        L("google.loader.callbacks", google[A].v);
        var N = {},
            O = {};
        google[A].eval = {};
        L("google.loader.eval", google[A].eval);

        n(google, function (a, b, c) {
            function e(a) {
                var b = a.split(".");
                if (2 < b[x]) throw I("Module: '" + a + "' not found!");
                "undefined" != typeof b[1] && (f = b[0], c.packages = c.packages || [], c.packages[p](b[1]))
            }
            var f = a,
                c = c || {};
            if (a instanceof Array || a && "object" == typeof a && "function" == typeof a[C] && "function" == typeof a.reverse)
                for (var i = 0; i < a[x]; i++) e(a[i]);
            else e(a); if (a = N[":" + f]) {
                c && (!c.language && c.locale) && (c.language = c.locale);
                c && "string" == typeof c.callback && (i = c.callback, i.match(/^[[\]A-Za-z0-9._]+$/) && (i = l.eval(i), c.callback =
                    i));
                if ((i = c && c.callback != h) && !a.s(b)) throw I("Module: '" + f + "' must be loaded before DOM onLoad!");
                i ? a.m(b, c) ? l[z](c.callback, 0) : a.load(b, c) : a.m(b, c) || a.load(b, c)
            } else throw I("Module: '" + f + "' not found!");
        });

        L("google.load", google.load);
        google.S = function (a, b) {
            b ? (0 == P[x] && (Q(l, "load", R), !E("msie") && !E("safari") && !E("konqueror") && E("mozilla") || l.opera ? l.addEventListener("DOMContentLoaded", R, j) : E("msie") ? m.write("<script defer onreadystatechange='google.loader.domReady()' src=//:><\/script>") : (E("safari") || E("konqueror")) && l[z](T, 10)), P[p](a)) : Q(l, "load", a)
        };
        L("google.setOnLoadCallback", google.S);

        function Q(a, b, c) {
            if (a.addEventListener) a.addEventListener(b, c, j);
            else if (a.attachEvent) a.attachEvent("on" + b, c);
            else {
                var e = a["on" + b];
                a["on" + b] = e != h ? aa([c, e]) : c
            }
        }

        function aa(a) {
            return function () {
                for (var b = 0; b < a[x]; b++) a[b]()
            }
        }
        var P = [];
        google[A].O = function () {
            var a = l.event.srcElement;
            "complete" == a.readyState && (a.onreadystatechange = h, a.parentNode.removeChild(a), R())
        };
        L("google.loader.domReady", google[A].O);
        var ba = {
            loaded: g,
            complete: g
        };

        function T() {
            ba[m.readyState] ? R() : 0 < P[x] && l[z](T, 10)
        }

        function R() {
            for (var a = 0; a < P[x]; a++) P[a]();
            P.length = 0
        }
        google[A].d = function (a, b, c) {
            if (c) {
                var e;
                "script" == a ? (e = m.createElement("script"), e.type = "text/javascript", e.src = b) : "css" == a && (e = m.createElement("link"), e.type = "text/css", e.href = b, e.rel = "stylesheet");
                (a = m.getElementsByTagName("head")[0]) || (a = m.body.parentNode.appendChild(m.createElement("head")));
                a.appendChild(e)
            } else "script" == a ? m.write('<script src="' + b + '" type="text/javascript"><\/script>') : "css" == a && m.write('<link href="' + b + '" type="text/css" rel="stylesheet"></link>')
        };
        L("google.loader.writeLoadTag", google[A].d);
        google[A].P = function (a) {
            O = a
        };
        L("google.loader.rfm", google[A].P);
        google[A].R = function (a) {
            for (var b in a) "string" == typeof b && (b && ":" == b[r](0) && !N[b]) && (N[b] = new U(b[B](1), a[b]))
        };
        L("google.loader.rpl", google[A].R);
        google[A].Q = function (a) {
            if ((a = a.specs) && a[x])
                for (var b = 0; b < a[x]; ++b) {
                    var c = a[b];
                    "string" == typeof c ? N[":" + c] = new V(c) : (c = new W(c[v], c.baseSpec, c.customSpecs), N[":" + c[v]] = c)
                }
        };
        L("google.loader.rm", google[A].Q);
        google[A].loaded = function (a) {
            N[":" + a.module].l(a)
        };
        L("google.loader.loaded", google[A].loaded);
        google[A].N = function () {
            return "qid=" + ((new Date)[w]().toString(16) + Math.floor(1E7 * Math.random()).toString(16))
        };
        L("google.loader.createGuidArg_", google[A].N);
        J("google_exportSymbol", J);
        J("google_exportProperty", K);
        google[A].a = {};
        L("google.loader.themes", google[A].a);
        google[A].a.H = "//www.google.com/cse/style/look/bubblegum.css";
        M(google[A].a, "BUBBLEGUM", google[A].a.H);
        google[A].a.J = "//www.google.com/cse/style/look/greensky.css";
        M(google[A].a, "GREENSKY", google[A].a.J);
        google[A].a.I = "//www.google.com/cse/style/look/espresso.css";
        M(google[A].a, "ESPRESSO", google[A].a.I);
        google[A].a.L = "//www.google.com/cse/style/look/shiny.css";
        M(google[A].a, "SHINY", google[A].a.L);
        google[A].a.K = "//www.google.com/cse/style/look/minimalist.css";
        M(google[A].a, "MINIMALIST", google[A].a.K);
        google[A].a.M = "//www.google.com/cse/style/look/v2/default.css";
        M(google[A].a, "V2_DEFAULT", google[A].a.M);

        function V(a) {
            this.b = a;
            this.o = [];
            this.n = {};
            this.e = {};
            this.f = {};
            this.j = g;
            this.c = -1
        }

        V[y].g = function (a, b) {
            var c = "";
            b != d && (b.language != d && (c += "&hl=" + k(b.language)), b.nocss != d && (c += "&output=" + k("nocss=" + b.nocss)), b.nooldnames != d && (c += "&nooldnames=" + k(b.nooldnames)), b.packages != d && (c += "&packages=" + k(b.packages)), b.callback != h && (c += "&async=2"), b.style != d && (c += "&style=" + k(b.style)), b.noexp != d && (c += "&noexp=true"), b.other_params != d && (c += "&" + b.other_params));
            if (!this.j) {
                google[this.b] && google[this.b].JSHash && (c += "&sig=" + k(google[this.b].JSHash));
                var e = [],
                    f;
                for (f in this.n) ":" == f[r](0) && e[p](f[B](1));
                for (f in this.e) ":" == f[r](0) && this.e[f] && e[p](f[B](1));
                c += "&have=" + k(e[C](","))
            }
            return google[A][u] + "/?file=" + this.b + "&v=" + a + google[A].AdditionalParams + c
        };

        V[y].t = function (a) {
            var b = h;
            a && (b = a.packages);
            var c = h;
            if (b)
                if ("string" == typeof b) c = [a.packages];
                else if (b[x]) {
                c = [];
                for (a = 0; a < b[x]; a++) "string" == typeof b[a] && c[p](b[a][q](/^\s*|\s*$/, "")[D]())
            }
            c || (c = ["default"]);
            b = [];
            for (a = 0; a < c[x]; a++) this.n[":" + c[a]] || b[p](c[a]);
            return b
        };

        n(V[y], function (a, b) {
            var c = this.t(b),
                e = b && b.callback != h;
            if (e) var f = new X(b.callback);
            for (var i = [], o = c[x] - 1; 0 <= o; o--) {
                var s = c[o];
                e && f.A(s);
                if (this.e[":" + s]) c.splice(o, 1), e && this.f[":" + s][p](f);
                else i[p](s)
            }
            if (c[x]) {
                b && b.packages && (b.packages = c.sort()[C](","));
                for (o = 0; o < i[x]; o++) s = i[o], this.f[":" + s] = [], e && this.f[":" + s][p](f);
                if (!b && O[":" + this.b] != h && O[":" + this.b].versions[":" + a] != h && !google[A].AdditionalParams && this.j) {
                    c = O[":" + this.b];
                    google[this.b] = google[this.b] || {};
                    for (var S in c.properties) S && ":" ==
                        S[r](0) && (google[this.b][S[B](1)] = c.properties[S]);
                    google[A].d("script", google[A][u] + c.path + c.js, e);
                    c.css && google[A].d("css", google[A][u] + c.path + c.css, e)
                } else(!b || !b.autoloaded) && google[A].d("script", this.g(a, b), e);
                this.j && (this.j = j, this.c = (new Date)[w](), 1 != this.c % 100 && (this.c = -1));
                for (o = 0; o < i[x]; o++) s = i[o], this.e[":" + s] = g
            }
        });

        V[y].l = function (a) {
            -1 != this.c && (ca("al_" + this.b, "jl." + ((new Date)[w]() - this.c), g), this.c = -1);
            this.o = this.o.concat(a.components);
            google[A][this.b] || (google[A][this.b] = {});
            google[A][this.b].packages = this.o.slice(0);
            for (var b = 0; b < a.components[x]; b++) {
                this.n[":" + a.components[b]] = g;
                this.e[":" + a.components[b]] = j;
                var c = this.f[":" + a.components[b]];
                if (c) {
                    for (var e = 0; e < c[x]; e++) c[e].B(a.components[b]);
                    delete this.f[":" + a.components[b]]
                }
            }
        };

        V[y].m = function (a, b) {
            return 0 == this.t(b)[x]
        };
        V[y].s = function () {
            return g
        };

        function X(a) {
            this.D = a;
            this.q = {};
            this.r = 0
        }
        X[y].A = function (a) {
            this.r++;
            this.q[":" + a] = g
        };
        X[y].B = function (a) {
            this.q[":" + a] && (this.q[":" + a] = j, this.r--, 0 == this.r && l[z](this.D, 0))
        };

        function W(a, b, c) {
            this.name = a;
            this.C = b;
            this.p = c;
            this.u = this.h = j;
            this.k = [];
            google[A].v[this[v]] = H(this.l, this)
        }

        G(W, V);
        n(W[y], function (a, b) {
            var c = b && b.callback != h;
            c ? (this.k[p](b.callback), b.callback = "google.loader.callbacks." + this[v]) : this.h = g;
            (!b || !b.autoloaded) && google[A].d("script", this.g(a, b), c)
        });
        W[y].m = function (a, b) {
            return b && b.callback != h ? this.u : this.h
        };
        W[y].l = function () {
            this.u = g;
            for (var a = 0; a < this.k[x]; a++) l[z](this.k[a], 0);
            this.k = []
        };
        var Y = function (a, b) {
            return a.string ? k(a.string) + "=" + k(b) : a.regex ? b[q](/(^.*$)/, a.regex) : ""
        };
        W[y].g = function (a, b) {
            return this.F(this.w(a), a, b)
        };
        W[y].F = function (a, b, c) {
            var e = "";
            a.key && (e += "&" + Y(a.key, google[A].ApiKey));
            a.version && (e += "&" + Y(a.version, b));
            b = google[A].Secure && a.ssl ? a.ssl : a.uri;
            if (c != h)
                for (var f in c) a.params[f] ? e += "&" + Y(a.params[f], c[f]) : "other_params" == f ? e += "&" + c[f] : "base_domain" == f && (b = "http://" + c[f] + a.uri[B](a.uri[t]("/", 7)));
            google[this[v]] = {}; - 1 == b[t]("?") && e && (e = "?" + e[B](1));
            return b + e
        };
        W[y].s = function (a) {
            return this.w(a).deferred
        };
        W[y].w = function (a) {
            if (this.p)
                for (var b = 0; b < this.p[x]; ++b) {
                    var c = this.p[b];
                    if (RegExp(c.pattern).test(a)) return c
                }
            return this.C
        };

        function U(a, b) {
            this.b = a;
            this.i = b;
            this.h = j
        }
        G(U, V);
        n(U[y], function (a, b) {
            this.h = g;
            google[A].d("script", this.g(a, b), j)
        });
        U[y].m = function () {
            return this.h
        };
        U[y].l = function () {};
        U[y].g = function (a, b) {
            if (!this.i.versions[":" + a]) {
                if (this.i.aliases) {
                    var c = this.i.aliases[":" + a];
                    c && (a = c)
                }
                if (!this.i.versions[":" + a]) throw I("Module: '" + this.b + "' with version '" + a + "' not found!");
            }
            return google[A].GoogleApisBase + "/libs/" + this.b + "/" + a + "/" + this.i.versions[":" + a][b && b.uncompressed ? "uncompressed" : "compressed"]
        };
        U[y].s = function () {
            return j
        };
        var da = j,
            Z = [],
            ea = (new Date)[w](),
            ga = function () {
                da || (Q(l, "unload", fa), da = g)
            },
            ha = function (a, b) {
                ga();
                if (!google[A].Secure && (!google[A].Options || google[A].Options.csi === j)) {
                    for (var c = 0; c < a[x]; c++) a[c] = k(a[c][D]()[q](/[^a-z0-9_.]+/g, "_"));
                    for (c = 0; c < b[x]; c++) b[c] = k(b[c][D]()[q](/[^a-z0-9_.]+/g, "_"));
                    l[z](H($, h, "//gg.google.com/csi?s=uds&v=2&action=" + a[C](",") + "&it=" + b[C](",")), 1E4)
                }
            },
            ca = function (a, b, c) {
                c ? ha([a], [b]) : (ga(), Z[p]("r" + Z[x] + "=" + k(a + (b ? "|" + b : ""))), l[z](fa, 5 < Z[x] ? 0 : 15E3))
            },
            fa = function () {
                if (Z[x]) {
                    var a =
                        google[A][u];
                    0 == a[t]("http:") && (a = a[q](/^http:/, "https:"));
                    $(a + "/stats?" + Z[C]("&") + "&nc=" + (new Date)[w]() + "_" + ((new Date)[w]() - ea));
                    Z.length = 0
                }
            },
            $ = function (a) {
                var b = new Image,
                    c = $.G++;
                $.z[c] = b;
                b.onload = b.onerror = function () {
                    delete $.z[c]
                };
                b.src = a;
                b = h
            };
        $.z = {};
        $.G = 0;
        J("google.loader.recordCsiStat", ha);
        J("google.loader.recordStat", ca);
        J("google.loader.createImageForLogging", $);
    })();

    google.loader.rm({
        "specs": ["feeds", "spreadsheets", "gdata", "visualization", {
            "name": "sharing",
            "baseSpec": {
                "uri": "http://www.google.com/s2/sharing/js",
                "ssl": null,
                "key": {
                    "string": "key"
                },
                "version": {
                    "string": "v"
                },
                "deferred": false,
                "params": {
                    "language": {
                        "string": "hl"
                    }
                }
            }
        }, "search", "orkut", "ads", "elements", {
            "name": "books",
            "baseSpec": {
                "uri": "http://books.google.com/books/api.js",
                "ssl": "https://encrypted.google.com/books/api.js",
                "key": {
                    "string": "key"
                },
                "version": {
                    "string": "v"
                },
                "deferred": true,
                "params": {
                    "callback": {
                        "string": "callback"
                    },
                    "language": {
                        "string": "hl"
                    }
                }
            }
        }, {
            "name": "friendconnect",
            "baseSpec": {
                "uri": "http://www.google.com/friendconnect/script/friendconnect.js",
                "ssl": null,
                "key": {
                    "string": "key"
                },
                "version": {
                    "string": "v"
                },
                "deferred": false,
                "params": {}
            }
        }, "identitytoolkit", "ima", {
            "name": "maps",
            "baseSpec": {
                "uri": "http://maps.google.com/maps?file\u003dgoogleapi",
                "ssl": "https://maps-api-ssl.google.com/maps?file\u003dgoogleapi",
                "key": {
                    "string": "key"
                },
                "version": {
                    "string": "v"
                },
                "deferred": true,
                "params": {
                    "callback": {
                        "regex": "callback\u003d$1\u0026async\u003d2"
                    },
                    "language": {
                        "string": "hl"
                    }
                }
            },
            "customSpecs": [{
                "uri": "http://maps.googleapis.com/maps/api/js",
                "ssl": "https://maps.googleapis.com/maps/api/js",
                "version": {
                    "string": "v"
                },
                "deferred": true,
                "params": {
                    "callback": {
                        "string": "callback"
                    },
                    "language": {
                        "string": "hl"
                    }
                },
                "pattern": "^(3|3..*)$"
            }]
        }, "payments", "wave", "annotations_v2", "earth", "language", {
            "name": "annotations",
            "baseSpec": {
                "uri": "http://www.google.com/reviews/scripts/annotations_bootstrap.js",
                "ssl": null,
                "key": {
                    "string": "key"
                },
                "version": {
                    "string": "v"
                },
                "deferred": true,
                "params": {
                    "callback": {
                        "string": "callback"
                    },
                    "language": {
                        "string": "hl"
                    },
                    "country": {
                        "string": "gl"
                    }
                }
            }
        }, "picker"]
    });

    google.loader.rfm({
        ":search": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/search/1.0/523aed65e4aba49d1d640dadc8a0c37c/",
            "js": "default+zh_CN.I.js",
            "css": "default+zh_CN.css",
            "properties": {
                ":JSHash": "523aed65e4aba49d1d640dadc8a0c37c",
                ":NoOldNames": false,
                ":Version": "1.0"
            }
        },
        ":language": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/language/1.0/895197a38226304ef49a03d324d6ca19/",
            "js": "default+zh_CN.I.js",
            "properties": {
                ":JSHash": "895197a38226304ef49a03d324d6ca19",
                ":Version": "1.0"
            }
        },
        ":feeds": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/feeds/1.0/77f89919ef841f93359ce886504e4e3f/",
            "js": "default+zh_CN.I.js",
            "css": "default+zh_CN.css",
            "properties": {
                ":JSHash": "77f89919ef841f93359ce886504e4e3f",
                ":Version": "1.0"
            }
        },
        ":spreadsheets": {
            "versions": {
                ":0": "1",
                ":0.4": "1"
            },
            "path": "/api/spreadsheets/0.4/87ff7219e9f8a8164006cbf28d5e911a/",
            "js": "default.I.js",
            "properties": {
                ":JSHash": "87ff7219e9f8a8164006cbf28d5e911a",
                ":Version": "0.4"
            }
        },
        ":ima": {
            "versions": {
                ":3": "1",
                ":3.0": "1"
            },
            "path": "/api/ima/3.0/28a914332232c9a8ac0ae8da68b1006e/",
            "js": "default.I.js",
            "properties": {
                ":JSHash": "28a914332232c9a8ac0ae8da68b1006e",
                ":Version": "3.0"
            }
        },
        ":wave": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/wave/1.0/3b6f7573ff78da6602dda5e09c9025bf/",
            "js": "default.I.js",
            "properties": {
                ":JSHash": "3b6f7573ff78da6602dda5e09c9025bf",
                ":Version": "1.0"
            }
        },
        ":annotations": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/annotations/1.0/b367e3f4388025885f0fd77f722f567e/",
            "js": "default+zh_CN.I.js",
            "properties": {
                ":JSHash": "b367e3f4388025885f0fd77f722f567e",
                ":Version": "1.0"
            }
        },
        ":earth": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/earth/1.0/109c7b2bae7fe6cc34ea875176165d81/",
            "js": "default.I.js",
            "properties": {
                ":JSHash": "109c7b2bae7fe6cc34ea875176165d81",
                ":Version": "1.0"
            }
        },
        ":picker": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/picker/1.0/9f12d82446e96eb628659bd51eee66cf/",
            "js": "default.I.js",
            "css": "default.css",
            "properties": {
                ":JSHash": "9f12d82446e96eb628659bd51eee66cf",
                ":Version": "1.0"
            }
        }
    });

    google.loader.rpl({
        ":scriptaculous": {
            "versions": {
                ":1.8.3": {
                    "uncompressed": "scriptaculous.js",
                    "compressed": "scriptaculous.js"
                },
                ":1.9.0": {
                    "uncompressed": "scriptaculous.js",
                    "compressed": "scriptaculous.js"
                },
                ":1.8.2": {
                    "uncompressed": "scriptaculous.js",
                    "compressed": "scriptaculous.js"
                },
                ":1.8.1": {
                    "uncompressed": "scriptaculous.js",
                    "compressed": "scriptaculous.js"
                }
            },
            "aliases": {
                ":1.8": "1.8.3",
                ":1": "1.9.0",
                ":1.9": "1.9.0"
            }
        },
        ":yui": {
            "versions": {
                ":2.6.0": {
                    "uncompressed": "build/yuiloader/yuiloader.js",
                    "compressed": "build/yuiloader/yuiloader-min.js"
                },
                ":2.9.0": {
                    "uncompressed": "build/yuiloader/yuiloader.js",
                    "compressed": "build/yuiloader/yuiloader-min.js"
                },
                ":2.7.0": {
                    "uncompressed": "build/yuiloader/yuiloader.js",
                    "compressed": "build/yuiloader/yuiloader-min.js"
                },
                ":2.8.0r4": {
                    "uncompressed": "build/yuiloader/yuiloader.js",
                    "compressed": "build/yuiloader/yuiloader-min.js"
                },
                ":2.8.2r1": {
                    "uncompressed": "build/yuiloader/yuiloader.js",
                    "compressed": "build/yuiloader/yuiloader-min.js"
                },
                ":2.8.1": {
                    "uncompressed": "build/yuiloader/yuiloader.js",
                    "compressed": "build/yuiloader/yuiloader-min.js"
                },
                ":3.3.0": {
                    "uncompressed": "build/yui/yui.js",
                    "compressed": "build/yui/yui-min.js"
                }
            },
            "aliases": {
                ":3": "3.3.0",
                ":2": "2.9.0",
                ":2.7": "2.7.0",
                ":2.8.2": "2.8.2r1",
                ":2.6": "2.6.0",
                ":2.9": "2.9.0",
                ":2.8": "2.8.2r1",
                ":2.8.0": "2.8.0r4",
                ":3.3": "3.3.0"
            }
        },
        ":swfobject": {
            "versions": {
                ":2.1": {
                    "uncompressed": "swfobject_src.js",
                    "compressed": "swfobject.js"
                },
                ":2.2": {
                    "uncompressed": "swfobject_src.js",
                    "compressed": "swfobject.js"
                }
            },
            "aliases": {
                ":2": "2.2"
            }
        },
        ":webfont": {
            "versions": {
                ":1.0.12": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.13": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.14": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.15": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.10": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.11": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.2": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.1": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.0": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.19": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.6": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.18": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.5": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.17": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.4": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.16": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.3": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.9": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.21": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.22": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.25": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.26": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.23": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                },
                ":1.0.24": {
                    "uncompressed": "webfont_debug.js",
                    "compressed": "webfont.js"
                }
            },
            "aliases": {
                ":1": "1.0.26",
                ":1.0": "1.0.26"
            }
        },
        ":ext-core": {
            "versions": {
                ":3.1.0": {
                    "uncompressed": "ext-core-debug.js",
                    "compressed": "ext-core.js"
                },
                ":3.0.0": {
                    "uncompressed": "ext-core-debug.js",
                    "compressed": "ext-core.js"
                }
            },
            "aliases": {
                ":3": "3.1.0",
                ":3.0": "3.0.0",
                ":3.1": "3.1.0"
            }
        },
        ":mootools": {
            "versions": {
                ":1.3.1": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.1.1": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.3.0": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.3.2": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.1.2": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.2.3": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.2.4": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.2.1": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.2.2": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.2.5": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.4.0": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.4.1": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                },
                ":1.4.2": {
                    "uncompressed": "mootools.js",
                    "compressed": "mootools-yui-compressed.js"
                }
            },
            "aliases": {
                ":1": "1.1.2",
                ":1.11": "1.1.1",
                ":1.4": "1.4.2",
                ":1.3": "1.3.2",
                ":1.2": "1.2.5",
                ":1.1": "1.1.2"
            }
        },
        ":jqueryui": {
            "versions": {
                ":1.8.0": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.2": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.1": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.15": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.14": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.13": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.12": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.11": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.10": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.17": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.16": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.6.0": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.9": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.7": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.8": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.7.2": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.5": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.7.3": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.6": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.7.0": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.7.1": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.8.4": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.5.3": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                },
                ":1.5.2": {
                    "uncompressed": "jquery-ui.js",
                    "compressed": "jquery-ui.min.js"
                }
            },
            "aliases": {
                ":1.8": "1.8.17",
                ":1.7": "1.7.3",
                ":1.6": "1.6.0",
                ":1": "1.8.17",
                ":1.5": "1.5.3",
                ":1.8.3": "1.8.4"
            }
        },
        ":chrome-frame": {
            "versions": {
                ":1.0.2": {
                    "uncompressed": "CFInstall.js",
                    "compressed": "CFInstall.min.js"
                },
                ":1.0.1": {
                    "uncompressed": "CFInstall.js",
                    "compressed": "CFInstall.min.js"
                },
                ":1.0.0": {
                    "uncompressed": "CFInstall.js",
                    "compressed": "CFInstall.min.js"
                }
            },
            "aliases": {
                ":1": "1.0.2",
                ":1.0": "1.0.2"
            }
        },
        ":prototype": {
            "versions": {
                ":1.7.0.0": {
                    "uncompressed": "prototype.js",
                    "compressed": "prototype.js"
                },
                ":1.6.0.2": {
                    "uncompressed": "prototype.js",
                    "compressed": "prototype.js"
                },
                ":1.6.1.0": {
                    "uncompressed": "prototype.js",
                    "compressed": "prototype.js"
                },
                ":1.6.0.3": {
                    "uncompressed": "prototype.js",
                    "compressed": "prototype.js"
                }
            },
            "aliases": {
                ":1.7": "1.7.0.0",
                ":1.6.1": "1.6.1.0",
                ":1": "1.7.0.0",
                ":1.6": "1.6.1.0",
                ":1.7.0": "1.7.0.0",
                ":1.6.0": "1.6.0.3"
            }
        },
        ":dojo": {
            "versions": {
                ":1.3.1": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.3.0": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.6.1": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.1.1": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.3.2": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.6.0": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.2.3": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.7.2": {
                    "uncompressed": "dojo/dojo.js.uncompressed.js",
                    "compressed": "dojo/dojo.js"
                },
                ":1.7.0": {
                    "uncompressed": "dojo/dojo.js.uncompressed.js",
                    "compressed": "dojo/dojo.js"
                },
                ":1.7.1": {
                    "uncompressed": "dojo/dojo.js.uncompressed.js",
                    "compressed": "dojo/dojo.js"
                },
                ":1.4.3": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.5.1": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.5.0": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.2.0": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.4.0": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                },
                ":1.4.1": {
                    "uncompressed": "dojo/dojo.xd.js.uncompressed.js",
                    "compressed": "dojo/dojo.xd.js"
                }
            },
            "aliases": {
                ":1.7": "1.7.2",
                ":1": "1.6.1",
                ":1.6": "1.6.1",
                ":1.5": "1.5.1",
                ":1.4": "1.4.3",
                ":1.3": "1.3.2",
                ":1.2": "1.2.3",
                ":1.1": "1.1.1"
            }
        },
        ":jquery": {
            "versions": {
                ":1.6.2": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.3.1": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.6.1": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.3.0": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.6.4": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.6.3": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.3.2": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.6.0": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.2.3": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.7.0": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.7.1": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.2.6": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.4.3": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.4.4": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.5.1": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.5.0": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.4.0": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.5.2": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.4.1": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                },
                ":1.4.2": {
                    "uncompressed": "jquery.js",
                    "compressed": "jquery.min.js"
                }
            },
            "aliases": {
                ":1.7": "1.7.1",
                ":1.6": "1.6.4",
                ":1": "1.7.1",
                ":1.5": "1.5.2",
                ":1.4": "1.4.4",
                ":1.3": "1.3.2",
                ":1.2": "1.2.6"
            }
        }
    });
}

(function () {
    if (!("google" in window)) {
        window.google = {}
    }
    if (!("earth" in window.google)) {
        window.google.earth = {}
    };
    if (!("google" in window)) {
        window.google = {}
    }
    if (!("idlglue" in window.google)) {
        window.google.idlglue = {}
    }
    window.google.idlglue.BROWSER_FIREFOX = "ff";
    window.google.idlglue.BROWSER_IE = "ie";
    window.google.idlglue.BROWSER_MOZILLA = "moz";
    window.google.idlglue.BROWSER_OPERA = "opera";
    window.google.idlglue.BROWSER_NETSCAPE = "netscape";
    window.google.idlglue.BROWSER_CHROME = "chrome";
    window.google.idlglue.BROWSER_SAFARI = "safari";
    window.google.idlglue.BROWSER_GOOGLE_EARTH = "google earth";
    window.google.idlglue.supportsNpapi =
        function (a) {
            var b = window.google.idlglue;
            return a == b.BROWSER_FIREFOX || a == b.BROWSER_MOZILLA || a == b.BROWSER_NETSCAPE || a == b.BROWSER_CHROME || a == b.BROWSER_OPERA || a == b.BROWSER_SAFARI || a == b.BROWSER_GOOGLE_EARTH
        };
    window.google.idlglue.PLATFORM_MAC = "mac";
    window.google.idlglue.PLATFORM_LINUX = "linux";
    window.google.idlglue.PLATFORM_WINDOWS = "windows";
    window.google.idlglue.PLUGIN_MAIN_CLSID = "F9152AEC-3462-4632-8087-EEE3C3CDDA24";
    window.google.idlglue.PLUGIN_MAIN_MIMETYPE = "application/geplugin";
    window.google.idlglue.findAvailableId =
        function (a) {
            var b = null;
            for (var d = 0; d < 100; d++) {
                var e = a + d;
                if (!document.getElementById(e)) {
                    b = e
                }
            }
            return b
        };
    window.google.idlglue.getPlatform = function () {
        var a = navigator.userAgent;
        if (a.indexOf("Windows") >= 0) {
            return window.google.idlglue.PLATFORM_WINDOWS
        }
        if (a.indexOf("Macintosh") >= 0) {
            return window.google.idlglue.PLATFORM_MAC
        }
        if (a.indexOf("Linux") >= 0) {
            return window.google.idlglue.PLATFORM_LINUX
        }
        return null
    };
    window.google.idlglue.getBrowser = function () {
        var a = navigator.appName,
            b = navigator.userAgent,
            d = window.google.idlglue,
            e = d.getPlatform();
        if (b.indexOf("Google Earth") >= 0) {
            return d.BROWSER_GOOGLE_EARTH
        } else if (b.indexOf("Opera") >= 0) {
            return d.BROWSER_OPERA
        } else if (b.indexOf("Firefox") >= 0 || b.indexOf("Minefield") >= 0) {
            return d.BROWSER_FIREFOX
        } else if (b.indexOf("Chrome") >= 0) {
            return d.BROWSER_CHROME
        } else if (b.indexOf("Safari") >= 0) {
            return d.BROWSER_SAFARI
        } else if (a.indexOf("Internet Explorer") >= 0) {
            return d.BROWSER_IE
        } else if (a.indexOf("Mozilla") >= 0) {
            return d.BROWSER_MOZILLA
        } else if (a.indexOf("Netscape") >= 0) {
            return d.BROWSER_NETSCAPE
        }
        return null
    };
    window.google.idlglue.getIeMajorVersion = function () {
        var a = navigator.userAgent,
            b = a.indexOf("MSIE ");
        if (b == -1) {
            return 0
        } else {
            return parseInt(a.substring(b + 5, a.indexOf(";", b)), 10)
        }
    };
    window.google.idlglue.isSupportedPlatform = function (a) {
        var b = window.google.idlglue;
        return a == b.PLATFORM_WINDOWS || a == b.PLATFORM_MAC
    };
    window.google.idlglue.isDeprecatedPlatform = function () {
        var a = navigator.userAgent,
            b = a.indexOf("PPC Mac") >= 0,
            d = false,
            e = /Mac OS X 10[_.]4[^0-9]/,
            f = e.exec(a),
            d = f && f.length > 0;
        return b || d
    };
    window.google.idlglue.isSupportedBrowser =
        function (a, b) {
            var d = window.google.idlglue;
            if (a == d.PLATFORM_WINDOWS) {
                return b == d.BROWSER_FIREFOX || b == d.BROWSER_IE || b == d.BROWSER_CHROME || b == d.BROWSER_MOZILLA || b == d.BROWSER_NETSCAPE || b == d.BROWSER_OPERA || b == d.BROWSER_GOOGLE_EARTH
            } else if (a == d.PLATFORM_MAC) {
                return b == d.BROWSER_FIREFOX || b == d.BROWSER_SAFARI || b == d.BROWSER_CHROME || b == d.BROWSER_OPERA || b == d.BROWSER_GOOGLE_EARTH
            } else if (a == d.PLATFORM_LINUX) {
                return b == d.BROWSER_FIREFOX || b == d.BROWSER_MOZILLA
            }
            return false
        };
    window.google.idlglue.isSupported = function () {
        var a =
            document.location.hash;
        if (a.indexOf("geplugin_browserok") != -1) return true;
        var b = window.google.idlglue,
            d = b.getPlatform(),
            e = b.getBrowser();
        if (b.isSupportedPlatform(d) && b.isSupportedBrowser(d, e)) {
            return true
        }
        return false
    };
    window.google.idlglue.logCsi = function (a, b, d, e) {
        var f = window.location.protocol == "https:";
        window.google.idlglue.logCsi2(a, b, f, d, e)
    };
    window.google.idlglue.logCsi2 = function (a, b, d, e, f) {
        if (e.length) {
            var c = "";
            for (var i = 0; i < e.length; i++) {
                var g = e[i];
                if (i > 0) {
                    c += ","
                }
                c += g[0] + "." + g[1]
            }
            var l = "http://csi.gstatic.com/csi";
            if (d) {
                l = "https://www.google.com/csi"
            }
            var h = l + "?v=2&s=" + a + "&rls=" + b + "&it=" + c;
            if (f) {
                h += "&" + f
            }
            window.google.idlglue.createImageForLogging(h)
        }
    };
    window.google.idlglue.createImageForLogging = function (a) {
		/*
        var b = new Image,
            d = window.google.idlglue.createImageForLogging.n++;
        window.google.idlglue.createImageForLogging.g[d] = b;
        b.onload = (b.onerror = function () {
            delete window.google.idlglue.createImageForLogging.g[d]
        });
        b.src = a;
        b = null
		*/
    };
    window.google.idlglue.createImageForLogging.g = {};
    window.google.idlglue.createImageForLogging.n =
        0;
    window.google.idlglue.showError = function (a, b, d) {
        var e = window.google.idlglue;
        if (!a.pluginDiv) {
            return
        }
        a.pluginDiv.style.left = "" + -screen.width * 2 + "px";
        a.pluginDiv.style.top = "" + -screen.height * 2 + "px";
        a.messageDiv.style.display = "";
        var f = "";
        if (d) {
            f = "&detail=" + encodeURIComponent(d)
        }
        a.messageDiv.innerHTML = '<iframe src="' + a.errorUrl + "#error=" + encodeURIComponent(b) + f + '" width="100%" height="100%" frameborder=0></iframe>';
        e.doErrorCleanup(a)
    };
    window.google.idlglue.doErrorCleanup = function (a) {
        var b = a.errorCleanupCallbacks;
        if (b) {
            for (var d = 0; d < b.length; d++) {
                b[d]()
            }
            a.errorCleanupCallbacks = null
        }
        if (a.pluginDiv.parentNode == a.positioningDiv) {
            a.positioningDiv.removeChild(a.pluginDiv)
        }
        a.iface = null;
        a.div = null;
        a.pluginDiv = null
    };
    window.google.idlglue.createPluginAsInnerHTML = function (a, b, d) {
        var e = window.google.idlglue;
        if (window.google.idlglue.supportsNpapi(a)) {
            b.innerHTML = '<embed type="' + e.PLUGIN_MAIN_MIMETYPE + '" style="margin:0px; padding:0px; width:100%; height:100%;"></embed>';
            return true
        } else if (a == e.BROWSER_IE) {
            b.innerHTML =
                '<object id="' + d + '" classid="CLSID:' + e.PLUGIN_MAIN_CLSID + '" style="margin:0px; padding:0px; width:100%; height:100%;"></object>';
            return true
        }
        b.innerHTML = "<div></div>";
        return false
    };
    window.google.idlglue.addErrorCleanupCallback = function (a, b) {
        if (!a.errorCleanupCallbacks) {
            a.errorCleanupCallbacks = []
        }
        a.errorCleanupCallbacks.push(b)
    };
    window.google.idlglue.create = function (a, b, d, e) {
        var f = window.google.idlglue;
        e = e || {};
        var c = f.getBrowser(),
            i = f.getPlatform(),
            g = f.isSupported(),
            l = (new Date).getTime(),
            h = document.createElement("div");
        h.style.position = "relative";
        h.style.width = "100%";
        h.style.height = "100%";
        h.style.overflow = "hidden";
        a.appendChild(h);
        if (i == f.PLATFORM_MAC) {
            var j = document.createElement("div");
            j.style.position = "absolute";
            j.style.width = "100%";
            j.style.height = "100%";
            j.style.background = "#FFF";
            h.appendChild(j)
        }






		//changed by yaodong
		//var xx = document.createElement("div");
		//yy = xx.style;	
        //yy.position = "relative";
		//yy.width = "50px";
		//yy.height = "50px";	
		//yy.background = "url(" + window.google.earth.l + ") no-repeat";	
		//yy.marginLeft = "auto";
		//yy.marginRight = "auto";
        //yy.marginTop = (document.body.clientHeight - 50)/2;

        //var m = document.createElement("div");   
        //m.appendChild(xx);
        //m.className = "bg"; 		
        //h.appendChild(m);
		//end change






        var m = document.createElement("div"),
            n = m.style;
        n.position = "relative";
        n.width = "100%";
        n.height = "100%";
        //n.background = "#E5E3DF url(" + window.google.earth.l + ") no-repeat scroll 50% 50%";
		n.background = "#FFFFFF url(" + window.google.earth.l + ") no-repeat scroll 50% 50%";
        h.appendChild(m);
        var o = document.createElement("div");
        n = o.style;
        n.position = "relative";
        n.left = "" + -screen.width * 2 + "px";
        n.top = "" + -screen.height * 2 + "px";
        n.width = "100%";
        n.height = "100%";
        h.appendChild(o);
        var k = {};
        k.div = o;
        k.pluginDiv = o;
        k.divInner = o;
        k.topDiv = a;
        k.positioningDiv = h;
        k.messageDiv = m;
        k.platform = i;
        k.browser = c;
        k.errorUrl = d;
        k.startLoadingTime = l;
        var p = f.findAvailableId("__idlglue_plugin__");
        if (!p) {
            f.showError(k, "ERR_NO_AVAILABLE_ID", "");
            return null
        }
        k.pluginId = p;
        o.id = "_idlglue_pluginDiv_" + p;










		//var ld=document.createElement("div");
        //ld.className="ld";
        //o.appendChild(ld);
		





		

        if (g && !f.isInstalled() && !f.isDeprecatedPlatform()) {
            if (e.skipDownloadButton) {
                if (e.autoDownload ==
                    undefined || e.autoDownload) {
                    f.showError(k, "INSTALLING", "")
                } else {
                    f.showError(k, "VIEW_INSTALLING", "")
                }
            } else {
                f.showError(k, "ERR_NOT_INSTALLED", "")
            }
            b(null);
            return
        }
        if (!f.isInstalled() && f.isDeprecatedPlatform()) {
            f.showError(k, "ERR_UNSUPPORTED_PLATFORM", "");
            b(null);
            return
        }
        if (!g && (!i || !f.isSupportedPlatform(i))) {
            f.showError(k, "ERR_UNSUPPORTED_PLATFORM", "");
            b(null);
            return
        }
        if (!g || !f.createPluginAsInnerHTML(c, o, p)) {
            f.showError(k, "ERR_UNSUPPORTED_BROWSER", "");
            b(null);
            return
        }
        var s = function (q, v) {
            window.setTimeout(function () {
                q.iface =
                    v.firstChild;
                if (!("getSelf" in q.iface)) {
                    f.showError(q, "ERR_CREATE_PLUGIN", "");
                    b(null)
                } else {
                    b(q)
                }
            }, 1)
        };
        s(k, o)
    };
    window.google.idlglue.getPluginContainerNode = function (a) {
        if (!a || !("getDiv_" in a)) {
            return null
        }
        var b = a.getDiv_();
        return b.parentNode.parentNode
    };
    window.google.idlglue.isInstalled = function () {
        try {
            var a = window.google.idlglue,
                b = a.getBrowser();
            if (window.google.idlglue.supportsNpapi(b)) {
                var d = navigator.mimeTypes[a.PLUGIN_MAIN_MIMETYPE];
                if (d && d.enabledPlugin) {
                    return true
                }
            } else if (b == a.BROWSER_IE) {
                var e =
                    document.createElement("div"),
                    f = a.findAvailableId("isInstalled_test");
                if (a.createPluginAsInnerHTML(b, e, f)) {
                    return e.firstChild.getSelf() != null
                }
            }
        } catch (c) {}
        return false
    };
    window.google.earth.ErrorCode = {
        ERR_OK: "ERR_OK",
        ERR_DESTROYED: "ERR_DESTROYED",
        ERR_CREATE_PLUGIN: "ERR_CREATE_PLUGIN",
        ERR_INVALID_DIV: "ERR_INVALID_DIV",
        ERR_NO_AVAILABLE_ID: "ERR_NO_AVAILABLE_ID",
        ERR_UNSUPPORTED_BROWSER: "ERR_UNSUPPORTED_BROWSER",
        ERR_UNSUPPORTED_PLATFORM: "ERR_UNSUPPORTED_PLATFORM",
        ERR_MAX_EARTH_PROCESSES: "ERR_MAX_EARTH_PROCESSES",
        ERR_SHUTOFF: "ERR_SHUTOFF",
        ERR_NOT_INSTALLED: "ERR_NOT_INSTALLED",
        ERR_INIT: "ERR_INIT",
        ERR_VERSION: "ERR_VERSION",
        ERR_API_KEY: "ERR_API_KEY",
        ERR_EARTH_NOT_READY: "ERR_EARTH_NOT_READY",
        ERR_BRIDGE: "ERR_BRIDGE",
        ERR_CREATE_EARTH: "ERR_CREATE_EARTH",
        ERR_CREATE_CONNECT_MUTEX: "ERR_CREATE_CONNECT_MUTEX",
        ERR_EARTH_CONNECT_TIMEOUT: "ERR_EARTH_CONNECT_TIMEOUT",
        ERR_BRIDGE_OTHER_SIDE_PROBLEM: "ERR_BRIDGE_OTHER_SIDE_PROBLEM",
        ERR_BRIDGE_TIMEOUT: "ERR_BRIDGE_TIMEOUT",
        ERR_PLUGIN_NOT_READY: "ERR_PLUGIN_NOT_READY",
        ERR_BAD_URL: "ERR_BAD_URL",
        ERR_DATABASE_LOGIN_FAILURE: "ERR_DATABASE_LOGIN_FAILURE",
        ERR_INVALID_LANGUAGE: "ERR_INVALID_LANGUAGE"
    };
    window.google.earth.ErrorCodeToString = {
        0: "ERR_OK",
        1: "ERR_DESTROYED",
        100: "ERR_CREATE_PLUGIN",
        101: "ERR_INVALID_DIV",
        102: "ERR_NO_AVAILABLE_ID",
        103: "ERR_UNSUPPORTED_BROWSER",
        104: "ERR_UNSUPPORTED_PLATFORM",
        105: "ERR_MAX_EARTH_PROCESSES",
        106: "ERR_SHUTOFF",
        107: "ERR_NOT_INSTALLED",
        200: "ERR_INIT",
        201: "ERR_VERSION",
        202: "ERR_API_KEY",
        203: "ERR_EARTH_NOT_READY",
        300: "ERR_BRIDGE",
        301: "ERR_CREATE_EARTH",
        302: "ERR_CREATE_CONNECT_MUTEX",
        303: "ERR_EARTH_CONNECT_TIMEOUT",
        304: "ERR_BRIDGE_OTHER_SIDE_PROBLEM",
        305: "ERR_BRIDGE_TIMEOUT",
        400: "ERR_PLUGIN_NOT_READY",
        401: "ERR_BAD_URL",
        402: "ERR_DATABASE_LOGIN_FAILURE",
        403: "ERR_INVALID_LANGUAGE"
    };

    (function () {
        function a(c, i, g, l) {
            var h = this;
            h.left = c != undefined ? c : -1;
            h.top = i != undefined ? i : -1;
            h.width = g != undefined ? g : -1;
            h.height = l != undefined ? l : -1
        }

        function b(c) {
            var i = c.offsetWidth,
                g = c.offsetHeight;
            if (c.getBoundingClientRect) {
                var l = c.getBoundingClientRect(),
                    h = l.left,
                    j = l.top,
                    m = c.ownerDocument;
                h += Math.max(m.documentElement.scrollLeft, m.body.scrollLeft);
                j += Math.max(m.documentElement.scrollTop, m.body.scrollTop);
                h += -m.documentElement.clientLeft;
                j += -m.documentElement.clientTop;
                return new a(h, j, i, g)
            }
            var h =
                0,
                j = 0;
            while (c) {
                h += c.offsetLeft;
                j += c.offsetTop;
                try {
                    c = c.offsetParent
                } catch (n) {
                    c = c.parentNode
                }
            }
            return new a(h, j, i, g)
        }

        function d(c) {
            var i = false;
            while (c) {
                if (c == document) {
                    return true
                }
                var g;
                if ("getComputedStyle" in window) {
                    g = window.getComputedStyle(c, "")
                } else if ("currentStyle" in c) {
                    g = c.currentStyle
                } else {
                    g = c.style
                } if (g.display == "none") {
                    return false
                }
                if (!i) {
                    if (g.visibility == "hidden") {
                        return false
                    } else if (g.visibility == "visible") {
                        i = true
                    }
                }
                c = c.parentNode
            }
            return true
        }
        f.ADDITION = "addition";
        f.PRE_REMOVAL = "pre_removal";
        f.REMOVAL = "removal";
        f.BOUNDS = "bounds";
        f.VISIBILITY = "visibility";
        f.GET_RECT_IN_PIXELS = "get_rect_in_pixels";

        function e() {
            var c = this;
            c.b = {}
        }
        e.prototype.c = false;
        e.prototype._dispatchCallback = function (c, i) {
            var g = this;
            if (g.c || !g._hasCallback(c)) {
                return null
            }
            g.c = true;
            try {
                var l = g.b[c](c, i)
            } catch (h) {}
            g.c = false;
            return l
        };
        e.prototype._setCallback = function (c, i) {
            if (i) {
                this.b[c] = i
            } else {
                delete this.b[c]
            }
        };
        e.prototype._hasCallback = function (c) {
            return c in this.b && this.b[c]
        };

        function f(c, i) {
            var g = this;
            g.node = c;
            g.rect =
                new a;
            g.visibility = d(c);
            c.i = "nodeObserverId_" + g.d;
            g.d++;
            g.i = c.i;
            if (i) {
                g.callbacks = i
            } else {
                g.callbacks = new e
            }
            var l = 250;
            g.j = setInterval(function () {
                g.k()
            }, l)
        }
        f.prototype.d = 0;
        f.prototype.k = function () {
            var c = this,
                i = false,
                g = c.node.parentNode;
            while (g) {
                if (g == document) {
                    i = true;
                    break
                }
                g = g.parentNode
            }
            if (!i) {
                c.callbacks._dispatchCallback(f.PRE_REMOVAL, c);
                c.callbacks._dispatchCallback(f.REMOVAL, c);
                c.destroy();
                return
            }
            var l = false,
                h = false;
            if (c.callbacks._hasCallback(f.BOUNDS)) {
                var j = c.rect,
                    m;
                if (c.callbacks._hasCallback(f.GET_RECT_IN_PIXELS)) {
                    m =
                        c.callbacks._dispatchCallback(f.GET_RECT_IN_PIXELS, c)
                } else {
                    m = b(c.node)
                }
                l = j.left != m.left || j.top != m.top || j.width != m.width || j.height != m.height;
                c.rect = m;
                if (l) {
                    c.callbacks._dispatchCallback(f.BOUNDS, c)
                }
            }
            if (c.callbacks._hasCallback(f.VISIBILITY)) {
                var n = d(c.node),
                    h = c.visibility != n;
                c.visibility = n;
                if (h) {
                    c.callbacks._dispatchCallback(f.VISIBILITY, c)
                }
            }
        };
        f.prototype.destroy = function () {
            var c = this;
            if (c.j != -1) {
                clearInterval(c.j)
            }
            c.callbacks = {}
        };
        google.idlglue.NodeObserver = f;
        google.idlglue.NodeObserverCallbacks =
            e;
        google.idlglue.Rect = a;
        google.idlglue.getElementRect = b
    })();

    window.google.earth.h = "";
    window.google.earth.setLanguage = function (a) {
        window.google.earth.h = a
    };
    window.google.earth.setErrorUrl = function (a) {
        window.google.earth.f = a
    };
    window.google.earth.setIsSecure = function (a) {
        window.google.earth.e = a
    };
    window.google.earth.setLoadingImageUrl = function (a) {
        window.google.earth.l = a
    };

    window.google.earth.createInstance = function (a, b, d, e) {
        var f = window.google.earth.ErrorCode,
            c;
        b = b || function () {};
        d = d || function () {};
        e = e || {};
        if (typeof a == "string") {
            c = document.getElementById(a)
        } else {
            c =
                a
        } if (!c) {
            d(f.ERR_INVALID_DIV);
            return
        }
        e.language = e.language || google.earth.h;
        e.isSecure = google.earth.e;
        e.allowEmptyClientId = true;
        var i = b;
        b = function (k) {
            var p = k.getLayerRoot().getLayerById(k.LAYER_BORDERS);
            if (p) {
                google.earth.addEventListener(p, "click", function (s) {
                    s.preventDefault()
                })
            }
            i(k)
        };
        var g = "";
        try {
            if (e.language) {
                g = "intl/" + e.language + "/"
            }
        } catch (l) {
		}
        var h = "http://www.google.com/";
        if (window.google.earth.e) {
            h = "https://www.google.com/"
        }
        var j = h + g + "earth/plugin/error.html";
        if ("database" in e && typeof e.database ==
            "string" && window.google.earth.f) {
            j = window.google.earth.f
        }
        var m = window.google.earth.stopIntrospectInstallation_(),
            n = window.google.earth.m(f, b, d, m, e),
            o = {
                skipDownloadButton: e.skipDownloadButton,
                autoDownload: e.autoDownload
            };
        window.google.idlglue.create(c, n, j, o)
    };

    window.google.earth.m = function (a, b, d, e, f) {
        return function (c) {
            if (c) {
                var i = b;
                b = function (l) {
                    var h = false;
                    google.earth.executeBatch(l, function () {
                        h = true
                    });
					/*
                    if (!h) {
                        var j = "SUCCESS_RECENT_INSTALL_RESTART";
                        window.google.idlglue.showError(c, j, "event bug");
                        d(j);
                        return
                    }
					*/
                    i(l)
                };
                var g = c.iface.getJavascriptInitCode_();
                eval(g)(c, b, d, f);
                if (c.pluginDiv.logStore) {
                    c.pluginDiv.logStore.prewarmTime = e.time;
                    c.pluginDiv.logStore.prewarmFinished = e.finished;
                    c.pluginDiv.logStore.didPrewarm = e.didPrewarm
                }
            } else {
                d(a.ERR_CREATE_PLUGIN)
            }
        }
    };

    window.google.earth.a = null;
    window.google.earth.introspectInstallation_ = function () {
        if (window.google.earth.a) return;
        var a = document.createElement("div");
        a.style.cssText = "visibility: hidden;position: absolute;width: 0px;height: 0px;";
        document.body.appendChild(a);
        var b = window.google.idlglue.findAvailableId("introspect-installation"),
            d = window.google.idlglue.getBrowser();
        if (window.google.idlglue.createPluginAsInnerHTML(d, a, b)) {
            if ("getSelf" in a.firstChild) {
                var e = a.firstChild.getSelf();
                if ("introspectInstallation_" in e) {
                    e.introspectInstallation_();
                    window.google.earth.a = a
                }
            }
        }
        if (!window.google.earth.a) document.body.removeChild(a)
    };
    if (document.getElementById("__maps-earth-introspect-installation__")) {
        window.google.earth.introspectInstallation_()
    }
    window.google.earth.stopIntrospectInstallation_ =
        function () {
            var a = {
                time: -1,
                finished: false
            };
            if (window.google.earth.a) {
                var b = window.google.earth.a,
                    d = b.firstChild.getSelf();
                d.stopIntrospectInstallation_();
                a = window.google.earth.queryIntrospectInstallation_();
                document.body.removeChild(b);
                window.google.earth.a = null
            }
            return a
        };
    window.google.earth.queryIntrospectInstallation_ = function () {
        var a = {
            time: -1,
            finished: false
        };
        if (window.google.earth.a) {
            var b = window.google.earth.a,
                d = b.firstChild.getSelf();
            try {
                a.time = d.getLogValue_(4);
                a.finished = d.getLogValue_(3)
            } catch (e) {
                a.didPrewarm =
                    true
            }
        }
        return a
    };
    window.google.earth.getPluginContainerNode = window.google.idlglue.getPluginContainerNode;
    window.google.earth.isSupported = window.google.idlglue.isSupported;
    window.google.earth.isInstalled = window.google.idlglue.isInstalled;
    window.google.earth.setIsSecure(window.location.protocol == "https:" || typeof window.google.loader == "object" && window.google.loader.Secure);
    if (window.google.earth.e) {
        window.google.earth.setLoadingImageUrl("./Images/loading.gif")
    } else {
        window.google.earth.setLoadingImageUrl("./Images/loading.gif")
    } if (window.google.earth.LoadArgs) {
        var t =
            window.google.earth.LoadArgs.split("&");
        for (var r = 0; r < t.length; r++) {
            if (t[r]) {
                var u = t[r].split("=");
                if (u.length == 2 && u[0] == "hl") {
                    window.google.earth.setLanguage(u[1])
                }
            }
        }
    };
    google.loader.loaded({
        "module": "earth",
        "version": "1.0",
        "components": ["default"]
    });
    google.loader.eval.earth = function () {
        eval(arguments[0]);
    };
    if (google.loader.eval.scripts && google.loader.eval.scripts['earth']) {
        (function () {
            var scripts = google.loader.eval.scripts['earth'];
            for (var i = 0; i < scripts.length; i++) {
                google.loader.eval.earth(scripts[i]);
            }
        })();
        google.loader.eval.scripts['earth'] = null;
    }
})();

if (window['google'] != undefined && window['google']['loader'] != undefined) {
    if (!window['google']['earth']) {
        window['google']['earth'] = {};
        google.earth.Version = '1.0';
        google.earth.JSHash = '109c7b2bae7fe6cc34ea875176165d81';
        google.earth.LoadArgs = 'file\75earth\46v\0751';
    }
    google.loader.writeLoadTag("script", "default.I.js", false);
}

var Points = [];
var bakupPoints = [];
var extractTimes = 0;
var polyParams = [];
var iconUrl = 'http://www.goodygis.com/earth/icons/ylw-pushpin.png';
var markerTitle = '地標';
google.load('earth', '1.x');
google.setOnLoadCallback(init);

function init() {
	//alert('init-GE');
    google.earth.createInstance('map3d', initCB, failureCB);
    loadEarth = true;
}

function initCB(pluginInstance) {
    ge = pluginInstance;
    ge.getWindow().setVisibility(true);
    setMapLayersStatus(true, true, true, true, true, true, false, false, false, false, false, false);
    gex = new GEarthExtensions(pluginInstance);
	
    google.earth.addEventListener(ge.getWindow(), 'mousemove', function (event) {
        var lat = event.getLatitude().toFixed(6);
        var lng = event.getLongitude().toFixed(6);
        var alt = ge.getGlobe().getGroundAltitude(lat, lng).toFixed(3);
        window.external.displayLatLngAlt(lat, lng, alt);
        if (mouseMsgflag) {
            window.external.showMsgTrackMouse();
        }
    });
	
    moveMapToPoint(new geo.Point(clat, clng), 5300000, 6, null);
	//alert("initCB-OK!");
    window.external.geSuccessLoadedCallback_();
}

function failureCB(errorCode) {
	//alert( 'failureCB: ' + errorCode );
    window.external.JSInitFailureCallback_('Google Earth加載失敗,多是網絡緣由!');
}

function setMapLayersStatus(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12) {
    ge.getOptions().setStatusBarVisibility(s1);
    ge.getOptions().setScaleLegendVisibility(s2);
    ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, s4);
    ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, s3);
    ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, s11);
    ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, s6);
    ge.getNavigationControl().setVisibility((s5 == true) ? ge.VISIBILITY_SHOW : ge.VISIBILITY_HIDE);
    ge.getSun().setVisibility(s7);
    ge.getOptions().setAtmosphereVisibility(s8);
    ge.getOptions().setOverviewMapVisibility(s9);
    ge.getOptions().setGridVisibility(s10);
    ge.getTime().setHistoricalImageryEnabled(s12);
}

function switchBalloon(flag) {
    ge.setBalloon(null);
}

function getUniqueId() {
    return "oid" + (new Date()).getTime() + parseInt(Math.random() * 100000);
}

function getObjectById(id) {
    var foundObject = null;
    gex.dom.walk({
        rootObject: ge,
        visitCallback: function () {
            if ('getId' in this && this.getId() == id) {
                foundObject = this;
                return false;
            }
        }
    });
    return foundObject;
}

function pad2(s) {
    return ((s.length < 2) ? '0' : '') + s;
}

function mergeColorOpacity(color, opacity) {
    color = color ? gex.util.parseColor(color) : 'ffffffff';
    if (!geo.util.isUndefined(opacity)) {
        color = pad2(Math.floor(255 * opacity).toString(16)) + color.substring(2);
    }
    return color;
}
function(a)
{
	a='+a+';
}
function drawPoint2(id, point, name, description) {
	pointStyle9.icon.href=licon;
    gex.dom.addPlacemark({
        id: id,
        name: name,
        point: point,
        description: description,
        style: pointStyle9
    });
  	
}

function drawPoint(id, point, name, description) {
    gex.dom.addPlacemark({
        id: id,
        name: name,
        point: point,
        description: description,
        style: pointStyle
    });
}
function drawPointNoIcon(id, point, name, description) {
    gex.dom.addPlacemark({
        id: id,
        name: name,
        point: point,
        description: description,
        style: pointNoIconStyle
    });
}

function drawPoint1(id, point, name, description) {
    return gex.dom.addPlacemark({
        id: id,
        name: name,
        point: point,
        description: description,
        style: pointStyle1
    });
}

function drawPointId(lat, lng, name, description, id) {
    gex.dom.addPlacemark({
        id: id,
        name: name,
        point: [lat, lng],
        description: description
    });
}

function drawPathCap(id, point, name, description) {
    gex.dom.addLineStringPlacemark({
        id: id,
        // name: ' ',
	    name:name,
        point: point,
        lineString: [point],
        description: description,
        //style: pathStyle
		style: lineStyle
    });
}

function addPathPoint(id, point) {
    getObjectById(id).getGeometry().getGeometries().getChildNodes().item(1).getCoordinates().pushLatLngAlt(point[0], point[1], point[2]);
}

function drawPathRearCap(id) {
    var geometriesObj = getObjectById(id).getGeometry().getGeometries();
    var coordinates = geometriesObj.getChildNodes().item(1).getCoordinates();
    var pointLength = coordinates.getLength();
    geometriesObj.appendChild(gex.dom.buildPoint(coordinates.get(pointLength - 1)));
}

function drawPath(id, points, name, description) {
    gex.dom.addLineStringPlacemark({
        id: id,
        name: name,
        lineString: points,
        description: description,
        style: pathStyle
    });
}

function drawRectangle(id, points, name, description) {
    gex.dom.addPolygonPlacemark(points, {
        id: id,
        name: name,
        description: description,
        style: {
            poly: {
                color: 'White',
                opacity: 0,
                fill: true,
                outline: true
            },
            line: pathStyle
        }
    });
}

function drawPolygonCap(id, points, name, description) {
    gex.dom.addPolygonPlacemark(points, {
        id: id,
        name: name,
        description: description,
        style: {
            poly: {
                color: 'White',
                opacity: 0,
                fill: true,
                outline: true
            },
            line: pathStyle
        }
    });
}

function addPolygonPoint(id, point) {
    getObjectById(id).getGeometry().getOuterBoundary().getCoordinates().pushLatLngAlt(point[0], point[1], point[2]);
}

function drawPolygon(id, points, name, description, isPolygon) {
    if (isPolygon == '0') {
        gex.dom.addPolygonPlacemark(points, {
            id: id,
            name: name,
            description: description,
            style: {
                poly: {
                    color: 'White',
                    opacity: 0.3,
                    fill: true,
                    outline: true
                },
                line: pathStyle
            }
        });
    } else {
        pathStyle = circleLineStyle;
        gex.dom.addLineStringPlacemark(points, {
            id: id,
            name: name,
            description: description,
            style: {
                line: pathStyle
            }
        });
    }
}
var downloadimgpolygonid = '';

function addPolygonOnEarth(tlat, blat, llng, rlng) {
    tlat = parseFloat(tlat);
    blat = parseFloat(blat);
    llng = parseFloat(llng);
    rlng = parseFloat(rlng);
    if (downloadimgpolygonid == '') {
        downloadimgpolygonid = getUniqueId();
        var points = [new geo.Point(tlat, llng, 0), new geo.Point(tlat, rlng, 0), new geo.Point(blat, rlng, 0), new geo.Point(blat, llng, 0)];
        pathStyle = polygonLineStyle1;
        //drawPolygon(downloadimgpolygonid, points, '多邊形', '影像下載範圍');
		drawPolygon(downloadimgpolygonid, points, lname, ldescription);
    } else {
        var dipobj = getObjectById(downloadimgpolygonid);
        var coords = dipobj.getGeometry().getOuterBoundary().getCoordinates();
        coords.clear();
        coords.pushLatLngAlt(tlat, llng, 0);
        coords.pushLatLngAlt(tlat, rlng, 0);
        coords.pushLatLngAlt(blat, rlng, 0);
        coords.pushLatLngAlt(blat, llng, 0);
    }
}

function createGeoPointByLatLngAlt(lat, lng, alt) {
    return new geo.Point(lat, lng, alt);
}

function getGeoPointAltitude(point) {
    return ge.getGlobe().getGroundAltitude(point.lat(), point.lng()).toFixed(3);
}

function getHorizontalDistance(startPoint, endPoint) {
    return startPoint.distance(endPoint);
}

function getVerticalDistance(startPoint, endPoint) {
    return abS(startPoint.altitude() - endPoint.altitude()).toFixed(2);
}

function getActualDistance(startPoint, endPoint) {
    return sqRt(sqIt(getHorizontalDistance(startPoint, endPoint)) + sqIt(getVerticalDistance(startPoint, endPoint))).toFixed(2);
}

function getPointLocationByDH(startPoint, endPoint, d) {
    return geo.math.destination(startPoint, {
        distance: parseFloat(d).div(getStarRadius(lastMapMod)),
        heading: startPoint.heading(endPoint)
    });
}

function getPointLocationByDHA(startPoint, d, angle) {
    return geo.math.destination(startPoint, {
        distance: parseFloat(d).div(getStarRadius(lastMapMod)),
        heading: angle
    });
}

function getMergeImageWidth(lng1, lat1, lng2, lat2) {
    return getHorizontalDistance(new geo.Point(lat1, lng1), new geo.Point(lat2, lng2));
}

function getMergeImageHeight(lng1, lat1, lng2, lat2) {
    return getHorizontalDistance(new geo.Point(lat1, lng1), new geo.Point(lat2, lng2));
}

function moveMapToPoint(destPoint, range, speed, heading) {
    if (speed == 6) {
        speed = ge.SPEED_TELEPORT;
    }
    var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
    lookAt.setLatitude(destPoint.lat());
    lookAt.setLongitude(destPoint.lng());
    if (heading != null) {
        lookAt.setHeading(heading);
    }
    lookAt.setTilt(0);
    lookAt.setRange(range);
    ge.getOptions().setFlyToSpeed(speed);
    ge.getView().setAbstractView(lookAt);
}

function rotateMap(angle) {
    var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
    lookAt.setHeading(angle);
    ge.getView().setAbstractView(lookAt);
}

function sleep(num) {
    var tempDate = new Date();
    var goneMsel = 0;
    while (goneMsel < num) {
        goneMsel = new Date() - tempDate;
    }
    return true;
}

function getCurrentDirectory() {
    var locHref = location.href;
    var locArray = locHref.split("/");
    delete locArray[locArray.length - 1];
    var dirTxt = locArray.join("/");
    return dirTxt;
}

function createTourKml(Points, duration, range) {
    var time;
    var kmlString = '<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2"><gx:Tour><name>Smooth tour Points</name><gx:Playlist>';
    for (var i = 0; i < Points.length; i++) {
        if (i == 0) {
            time = duration + 1;
        } else {
            time = duration;
        }
        kmlString += '<gx:FlyTo><gx:duration>10</gx:duration><gx:flyToMode>smooth</gx:flyToMode><LookAt><longitude>' + Points[i].lng() + '</longitude><latitude>' + Points[i].lat() + '</latitude><altitude>10</altitude><heading>0</heading><tilt>0</tilt><range>0</range><altitudeMode>relativeToGround</altitudeMode></LookAt></gx:FlyTo>';
    }
    kmlString += '</gx:Playlist></gx:Tour></kml>';
    return kmlString;
}

function setTourObject(kmlString) {
    var kmlObject = ge.parseKml(kmlString);
    ge.getFeatures().appendChild(kmlObject);
    walkKmlDom(kmlObject, function () {
        if (this.getType() == 'KmlTour') {
            tour = this;
            return false;
        }
    });
    if (!tour) {
        alert('No tour found!');
        return;
    }
    ge.getTourPlayer().setTour(tour);
}

function playTour() {
    ge.getTourPlayer().play();
}

function exitTour() {
    ge.getTourPlayer().setTour(null);
}

function getTrianglePoint(firstPoint, lastPoint) {
    var c = getHorizontalDistance(firstPoint, lastPoint);
    var angle1 = firstPoint.heading(new geo.Point(firstPoint.lat(), lastPoint.lng()));
    var angle2 = firstPoint.heading(lastPoint);
    var angle = Math.abs(angle1.sub(angle2));
    var a = c.mul(Math.cos(angle.mul(Math.PI).div(180)));
    return getPointLocationByDHA(firstPoint, a, angle1);
}

function getRectanglePoints(firstpoint, d, p) {
    pPoints[0] = firstpoint;
    pPoints[1] = getPointLocationByDHA(pPoints[0], d * p, hheading);
    pPoints[2] = getPointLocationByDHA(pPoints[1], 2 * d * (p - 1), vheading);
    pPoints[3] = getPointLocationByDHA(pPoints[0], 2 * d * (p - 1), vheading);
}

function searchLocation_e(lat, lng) {
    var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
    lookAt.setLatitude(parseFloat(lat));
    lookAt.setLongitude(parseFloat(lng));
    lookAt.setRange(10000);
    ge.getOptions().setFlyToSpeed(2);
    ge.getView().setAbstractView(lookAt);
    drawPointId(lat, lng, "目標點", "經度:" + lng + ",緯度:" + lat, getUniqueId());
}

function computePathDistance_e(obj) {
    var d = 0;
    var coordinates = [];
    var length = 0;
    try {
        if ('getType' in obj.getGeometry()) {
            if (obj.getGeometry().getType() == 'KmlLineString') {
                coordinates = obj.getGeometry().getCoordinates();
                length = coordinates.getLength();
                if (length > 1) {
                    for (var i = 1; i < length; i++) {
                        d = parseFloat(d).add(parseFloat(getHorizontalDistance(new geo.Point(coordinates.get(i - 1)), new geo.Point(coordinates.get(i))).toFixed(2)));
                    }
                }
            } else if (obj.getGeometry().getType() == 'KmlMultiGeometry') {
                if (obj.getGeometry().getGeometries().getChildNodes().item(1).getType() == 'KmlLineString') {
                    coordinates = obj.getGeometry().getGeometries().getChildNodes().item(1).getCoordinates();
                    length = coordinates.getLength();
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            d = parseFloat(d).add(parseFloat(getHorizontalDistance(new geo.Point(coordinates.get(i - 1)), new geo.Point(coordinates.get(i))).toFixed(2)));
                        }
                    }
                }
            }
        }
    } catch (err) {
        if (obj.getType() == 'KmlLineString') {
            coordinates = obj.getCoordinates();
            length = coordinates.getLength();
            if (length > 1) {
                for (var i = 1; i < length; i++) {
                    d = parseFloat(d).add(parseFloat(getHorizontalDistance(new geo.Point(coordinates.get(i - 1)), new geo.Point(coordinates.get(i))).toFixed(2)));
                }
            }
        } else if (obj.getType() == 'KmlMultiGeometry') {
            if (obj.getGeometries().getChildNodes().item(1).getType() == 'KmlLineString') {
                coordinates = obj.getGeometries().getChildNodes().item(1).getCoordinates();
                length = coordinates.getLength();
                if (length > 1) {
                    for (var i = 1; i < length; i++) {
                        d = parseFloat(d).add(parseFloat(getHorizontalDistance(new geo.Point(coordinates.get(i - 1)), new geo.Point(coordinates.get(i))).toFixed(2)));
                    }
                }
            }
        }
    }
    return d;
}

function getStarRadius(star) {
    var r = 6371000;
    var rMoon = 1737400;
    var rMars = 3397200;
    var ratio = 1;
    if (star == 'moon') {
        ratio = rMoon.div(r);
    } else if (star == 'mars') {
        ratio = rMars.div(r);
    } else {}
    return ratio;
}

function computeAreaAndC(obj) {
    var params = [0, 0];
    var coords = [];
    var type = '';
    var flag = true;
    try {
        type = obj.getGeometry().getType();
    } catch (err) {
        type = obj.getType();
        flag = false;
    }
    switch (type) {
    case 'KmlLinearRing':
    case 'KmlPolygon':
        if (flag) {
            coords = obj.getGeometry().getOuterBoundary().getCoordinates();
        } else {
            coords = obj.getOuterBoundary().getCoordinates();
        }
        if (coords.getLength() >= 3) {
            params = getPolygonAreaAndC(coords);
        }
        break;
    case 'KmlMultiGeometry':
        if (flag) {
            var geoms = obj.getGeometry().getGeometries();
        } else {
            var geoms = obj.getGeometries();
        }
        for (var j = 0; j < geoms.getChildNodes().getLength(); j++) {
            if (geoms.getChildNodes().item(j).getType() == 'KmlPolygon') {
                coords = geoms.getChildNodes().item(j).getOuterBoundary().getCoordinates();
            }
        }
        if (coords.getLength() >= 3) {
            params = getPolygonAreaAndC(coords);
        }
        break;
    default:
    }
    return params;
}

function getPolygonAreaAndC(geoPoints) {
    var params = [0, 0];
    var length = geoPoints.getLength();
    var firstGeoPoint = new geo.Point(geoPoints.get(0));
    var lastGeoPoint = new geo.Point(geoPoints.get(length - 1));
    var geoPointi = null;
    var geoPointii = null;
    var angle1 = 0;
    var angle2 = firstGeoPoint.heading(lastGeoPoint);
    var angle = 0;
    var d = 0;
    var c = 0;
    var x = [];
    var y = [];
    x.push(0);
    y.push(0);
    for (var i = 1; i < length; i++) {
        geoPointi = new geo.Point(geoPoints.get(i - 1));
        geoPointii = new geo.Point(geoPoints.get(i));
        d = getHorizontalDistance(geoPointi, geoPointii);
        c = getHorizontalDistance(firstGeoPoint, geoPointii);
        params[0] = parseFloat(params[0]).add(parseFloat(d));
        angle1 = firstGeoPoint.heading(geoPointii);
        angle = angle2.sub(angle1).add(360);
        x.push(Math.cos(angle.mul(Math.PI).div(180)).mul(c));
        y.push(Math.sin(angle.mul(Math.PI).div(180)).mul(c));
    }
    params[0] = parseFloat(params[0]).add(parseFloat(getHorizontalDistance(new geo.Point(geoPoints.get(0)), new geo.Point(geoPoints.get(length - 1)))));
    params[1] = getPolygonAreaByCoords(x, y);
    return params;
}

function getPolygonAreaByCoords(x, y) {
    var s = 0;
    var n = x.length;
    x[n] = x[0];
    y[n] = y[0];
    for (var i = 0; i < n - 1; i++) {
        s = s.add(x[i].mul(y[i + 1]).sub(x[i + 1].mul(y[i])));
    }
    if (n > 1) {
        s = s.add(x[n].mul(y[0]).sub(x[0].mul(y[n])));
    }
    s = Math.abs(s).mul(0.5);
    return s;
}
var pageStopRunFlag = false;

function cancelWebbrowserRun(key) {
    if (key == "stop") {
        cleartAllParams();
        pageStopRunFlag = true;
    } else {
        pageStopRunFlag = false;
    }
}

var currentWindKmlObject = null;
var currentLidarKmlObject = null;
var currentDrawKmlObject = null;
var currentGoogleMapKmlObject = null;
var currentRemarkKmlObject = null;
var currentBackwardTrajKmlObject = null;
var currentForwardTrajKmlObject = null;
var isAppendWind = false;
var isAppendLidar= false;
var isAppendGoogleMap = false;
var isAppendRemark = false;
function importKmlFilebyUrl(href, isWind, moveMap) { 
	isAppendWind = isWind;
    google.earth.fetchKml(ge, href,
		function (kmlObject) { 
        if (kmlObject) {
            if( isAppendWind )
			{
				if (currentWindKmlObject)
				{
					ge.getFeatures().removeChild(currentWindKmlObject);
				}
				currentWindKmlObject = ge.getFeatures().appendChild(kmlObject);
			}
			else
				ge.getFeatures().appendChild(kmlObject);

            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
				if( typeof(moveMap)!="undefined" && moveMap==true ){				
                    var box = gex.dom.computeBounds(kmlObject);
                    var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                    //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));				
                    //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
				    var boxHeight = getHorizontalDistance(new geo.Point(box.south(), box.east()), new geo.Point(box.north(), box.east())).toFixed(2);
				    var boxWidth = getHorizontalDistance(new geo.Point(box.south(), box.west()), new geo.Point(box.south(), box.east())).toFixed(2);
				    var range = Math.max(boxHeight, boxWidth);
				    moveMapToPoint(cp, range < 5000 ? 5000 : range, 0.3, null);
				}
            }
        }
    });
}
function importDrawKmlFilebyUrl(href/*, moveMap*/) {
    google.earth.fetchKml(ge, href,
		function (kmlObject) {
        if (kmlObject) {
				if (currentDrawKmlObject)
				{
					ge.getFeatures().removeChild(currentDrawKmlObject);
				}
				currentDrawKmlObject = ge.getFeatures().appendChild(kmlObject);
            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
				/*
				if( typeof(moveMap)!="undefined" && moveMap==true ){
                    var box = gex.dom.computeBounds(kmlObject);
                    var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                    //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                    //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
				    var boxHeight = getHorizontalDistance(new geo.Point(box.south(), box.east()), new geo.Point(box.north(), box.east())).toFixed(2);
				    var boxWidth = getHorizontalDistance(new geo.Point(box.south(), box.west()), new geo.Point(box.south(), box.east())).toFixed(2);
				    var range = Math.max(boxHeight, boxWidth);
				    moveMapToPoint(cp, range < 5000 ? 5000 : range, 0.3, null);
				}
				*/
            }
        }
    });
}
function importGoogleMapKmlFilebyUrl(href) { 
    google.earth.fetchKml(ge, href,
		function (kmlObject) {
        if (kmlObject) {  
				if (currentGoogleMapKmlObject)
				{
					ge.getFeatures().removeChild(currentGoogleMapKmlObject);
				}
				currentGoogleMapKmlObject = ge.getFeatures().appendChild(kmlObject);
            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
                //var box = gex.dom.computeBounds(kmlObject);
                //var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
            }
        }
    });
}
function importRemarkKmlFilebyUrl(href) { 
    google.earth.fetchKml(ge, href,
		function (kmlObject) {
        if (kmlObject) {
				if (currentRemarkKmlObject)
				{
					ge.getFeatures().removeChild(currentRemarkKmlObject);
				}
				currentRemarkKmlObject = ge.getFeatures().appendChild(kmlObject);
            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
                //var box = gex.dom.computeBounds(kmlObject);
                //var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
            }
        }
    });
}
function importBackwardTrajKmlFilebyUrl(href) { 
    google.earth.fetchKml(ge, href,
		function (kmlObject) {
        if (kmlObject) {
				if (currentBackwardTrajKmlObject)
				{
					ge.getFeatures().removeChild(currentBackwardTrajKmlObject);
				}
				currentBackwardTrajKmlObject = ge.getFeatures().appendChild(kmlObject);
            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
                //var box = gex.dom.computeBounds(kmlObject);
                //var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
            }
        }
    });
}
function importForwardTrajKmlFilebyUrl(href) { 
    google.earth.fetchKml(ge, href,
		function (kmlObject) {
        if (kmlObject) {
				if (currentForwardTrajKmlObject)
				{
					ge.getFeatures().removeChild(currentForwardTrajKmlObject);
				}
				currentForwardTrajKmlObject = ge.getFeatures().appendChild(kmlObject);
            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
                //var box = gex.dom.computeBounds(kmlObject);
                //var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
            }
        }
    });
}
function importLidarKmlFilebyUrl(href, moveMap) { 
    google.earth.fetchKml(ge, href,
		function (kmlObject) {
        if (kmlObject) {
				if (currentLidarKmlObject)
				{
					ge.getFeatures().removeChild(currentLidarKmlObject);
				}
				currentLidarKmlObject = ge.getFeatures().appendChild(kmlObject);	
            if (kmlObject.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject.getAbstractView());
            } else {
				if( typeof(moveMap)!="undefined" && moveMap==true ){
                    var box = gex.dom.computeBounds(kmlObject);
                    var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                    //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                    //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
				    var boxHeight = getHorizontalDistance(new geo.Point(box.south(), box.east()), new geo.Point(box.north(), box.east())).toFixed(2);
				    var boxWidth = getHorizontalDistance(new geo.Point(box.south(), box.west()), new geo.Point(box.south(), box.east())).toFixed(2);
				    var range = Math.max(boxHeight, boxWidth);
				    moveMapToPoint(cp, range < 5000 ? 5000 : range, 0.3, null);
				}
            }
        }
    });
}
//var currentWindKmlObject = null;
function importWindKmlFilebyUrl(href2/*, moveMap*/) {
    google.earth.fetchKml(ge, href2, 
		function (kmlObject2) { //alert("windKmlObject:" + kmlObject2);
        if (kmlObject2) {
            currentWindKmlObject = ge.getFeatures().appendChild(kmlObject2);
            if (kmlObject2.getAbstractView()) {
                ge.getView().setAbstractView(kmlObject2.getAbstractView());
            } else {
				/*
				if( typeof(moveMap)!="undefined" && moveMap==true ){
                    var box = gex.dom.computeBounds(kmlObject2);
                    var cp = new geo.Point((box.north() + box.south()) / 2, (box.east() + box.west()) / 2);
                    //var range = Math.max(getDistancebyTwoPoints(box.east(), box.south(), box.east(), box.north()), getDistancebyTwoPoints(box.east(), box.south(), box.west(), box.south()));
                    //moveMapToPoint(cp, range < 2000 ? 2000 : range, 6, null);
				    var boxHeight = getHorizontalDistance(new geo.Point(box.south(), box.east()), new geo.Point(box.north(), box.east())).toFixed(2);
				    var boxWidth = getHorizontalDistance(new geo.Point(box.south(), box.west()), new geo.Point(box.south(), box.east())).toFixed(2);
				    var range = Math.max(boxHeight, boxWidth);
				    moveMapToPoint(cp, range < 5000 ? 5000 : range, 0.3, null);
				}
				*/
            }
        }
    });
}

/*
function importLidarKmlFile_e(kmlString) {
    var flag = 0;
    var kmlObject = ge.parseKml(kmlString);

    if (kmlObject) {
        currentLidarKmlObject=ge.getFeatures().appendChild(kmlObject);
        if (kmlObject.getAbstractView()) {
            ge.getView().setAbstractView(kmlObject.getAbstractView());
        } else {
            moveMapToPoint(getFirstKmlObject(kmlString), 10000, 6, null);
        }
        flag = 1;
    }
    return flag;
}

function importWindKmlFile_e(kmlString) {
    var flag = 0;
    var kmlObject = ge.parseKml(kmlString);

    if (kmlObject) {
        currentWindKmlObject=ge.getFeatures().appendChild(kmlObject);
        if (kmlObject.getAbstractView()) {
            ge.getView().setAbstractView(kmlObject.getAbstractView());
        } else {
            moveMapToPoint(getFirstKmlObject(kmlString), 10000, 6, null);
        }
        flag = 1;
    }
    return flag;
}

function importDrawKmlFile_e(kmlString) {
    var flag = 0;
    var kmlObject = ge.parseKml(kmlString);
    if (kmlObject) {
        currentDrawKmlObject=ge.getFeatures().appendChild(kmlObject);
        if (kmlObject.getAbstractView()) {
            ge.getView().setAbstractView(kmlObject.getAbstractView());
        } else {
            moveMapToPoint(getFirstKmlObject(kmlString), 10000, 6, null); //放大地圖
        }
        flag = 1;
    }
    return flag;
}
*/

function clearWindObjects() {
    try {
		if (currentWindKmlObject)
		{
		    //alert("remove current Wind kml object!");
	        ge.getFeatures().removeChild(currentWindKmlObject);
		}
		else
		{	
			//alert("not found current Wind kml object!");
		}

    } catch (err) {}
}

function clearLidarObjects() {
    try {
		if (currentLidarKmlObject)
		{
	        ge.getFeatures().removeChild(currentLidarKmlObject);
		}
		else
		{	
		}

    } catch (err) {}
}

function clearDrawObjects() {
    try {
		if (currentDrawKmlObject)
		{
		    //alert("remove current Draw kml object!");
	        ge.getFeatures().removeChild(currentDrawKmlObject);
		}
		else
		{	
			//alert("not found current Draw kml object!");
		}

    } catch (err) {}
}

function clearGoogleMapObjects() {
    try {
		if (currentGoogleMapKmlObject)
		{
		    //alert("remove current google map kml object!");
	        ge.getFeatures().removeChild(currentGoogleMapKmlObject);
		}
		else
		{	
			//alert("not found current google map kml object!");
		}

    } catch (err) {}
}

function clearRemarkObjects() {
    try {
		if (currentRemarkKmlObject)
		{
		    //alert("remove current remark kml object!");
	        ge.getFeatures().removeChild(currentRemarkKmlObject);
		}
		else
		{	
			//alert("not found current remark kml object!");
		}

    } catch (err) {}
}

function clearBackwardTrajObjects() {
    try {
		if (currentBackwardTrajKmlObject)
		{
		    //alert("remove current Backward Traj kml object!");
	        ge.getFeatures().removeChild(currentBackwardTrajKmlObject);
		}
		else
		{	
			//alert("not found current Backward Traj kml object!");
		}

    } catch (err) {}
}

function clearForwardTrajObjects() {
    try {
		if (currentForwardTrajKmlObject)
		{
		    //alert("remove current Forward Traj kml object!");
	        ge.getFeatures().removeChild(currentForwardTrajKmlObject);
		}
		else
		{	
			//alert("not found current Forward Traj kml object!");
		}

    } catch (err) {}
}

function createNetWorkLink(href) {
    var link = ge.createLink('');
    link.setHref(href);
    var networkLink = ge.createNetworkLink('');
    networkLink.set(link, true, true);
    ge.getFeatures().appendChild(networkLink);
}

function importKmlFile_e(kmlString) {
	//alert('importKmlFile_e '+kmlString);
    var flag = 0;
    var kmlObject = ge.parseKml(kmlString);
    if (kmlObject) {
        ge.getFeatures().appendChild(kmlObject);
        if (kmlObject.getAbstractView()) {
            ge.getView().setAbstractView(kmlObject.getAbstractView());
        } else {
            moveMapToPoint(getFirstKmlObject(kmlString), 10000, 6, null);
        }
        flag = 1;
    }
    return flag;
}

function getFirstKmlObject(kmlString) {
    var xmlDoc2 = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc2.async = 'false';
    xmlDoc2.loadXML(kmlString);
    var DocRoot = xmlDoc2.documentElement;
    var coords = DocRoot.selectSingleNode('//coordinates').text.Trim().split(' ');
    var coord = coords[0].split(',');
    coords = [];
    DocRoot = null;
    xmlDoc2 = null;
    kmlString = '';
    return new geo.Point(parseFloat(coord[1]), parseFloat(coord[0]), parseFloat(coord[2]));
}

//原來的導出KML
/*  function getGEKml_e() {
    var output = '';
    var kmlString = '<?xml version="1.0" encoding="UTF-8"?>\r\n<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">\r\n<Document>\r\n';
    var nodes = ge.getFeatures().getChildNodes();	
    var nodesCount = nodes.getLength();
    try {
        var xmlDoc2 = new ActiveXObject('Microsoft.XMLDOM');
        xmlDoc2.async = 'false';
        var DocRoot = null;
        for (var i = 0; i < nodesCount; i++) {
            xmlDoc2.loadXML(nodes.item(i).getKml());
            DocRoot = xmlDoc2.documentElement;
            if (!DocRoot.selectSingleNode('//Document')) {
                kmlString += (DocRoot.selectSingleNode('//Placemark').xml + '\r\n').replace('xmlns="http://www.opengis.net/kml/2.2"', '');
            } else {
                var docNodes = DocRoot.selectNodes('//Document/*');
                var docNodesCount = docNodes.length;
                for (var j = 0; j < docNodesCount; j++) {
                    kmlString += (docNodes[j].xml + '\r\n').replace('xmlns="http://www.opengis.net/kml/2.2"', '');
                }
            }
        }
        kmlString += '</Document>\r\n</kml>';
        kmlString = formatKmlForHtml(kmlString);
    } catch (err) {
        alert('error');
    }
    DocRoot = null;
    xmlDoc2 = null;
    return kmlString;
} 
*/ 

//修改後,只導出繪圖信息的版本
function getGEKml_e() {
    var output = '';
    var kmlString = '<?xml version="1.0" encoding="UTF-8"?>\r\n<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">\r\n<Document>\r\n';
    var nodes = ge.getFeatures().getChildNodes();
    var nodesCount = nodes.getLength();
    try {
        var xmlDoc2 = new ActiveXObject('Microsoft.XMLDOM');
        xmlDoc2.async = 'false';
        var DocRoot = null;
        for (var i = 0; i < nodesCount; i++) {
			if(nodes.item(i).getType()=='KmlPlacemark')
			{
				xmlDoc2.loadXML(nodes.item(i).getKml());
				DocRoot = xmlDoc2.documentElement;
            if (!DocRoot.selectSingleNode('//Document')) {
                kmlString += (DocRoot.selectSingleNode('//Placemark').xml + '\r\n').replace('xmlns="http://www.opengis.net/kml/2.2"', '');
            } else {
                var docNodes = DocRoot.selectNodes('//Document/*');
                var docNodesCount = docNodes.length;
                for (var j = 0; j < docNodesCount; j++) {
                    kmlString += (docNodes[j].xml + '\r\n').replace('xmlns="http://www.opengis.net/kml/2.2"', '');
                }
            }
				
			}
            
        }
        kmlString += '</Document>\r\n</kml>';
        kmlString = formatKmlForHtml(kmlString);
    } catch (err) {
        alert('error');
    }
    DocRoot = null;
    xmlDoc2 = null;
    return kmlString;
} 

function formatKmlForHtml(output) {
    output = output.replace(/</g, '&lt;').replace(/>/g, '&gt;');
    output = output.replace(/\t/g, '  ');
    output = output.replace(/\" xmlns/g, '\"\n     xmlns');
    return output;
}

function returnPointJson(point) {
    return '{w:"' + point.lat().toFixed(6) + '",j:"' + point.lng().toFixed(6) + '",a:"' + ge.getGlobe().getGroundAltitude(point.lat(), point.lng()).toFixed(3) + '"},';
}

function returnDLZXPointJson(point, name, type) {
    return '{n:"' + name + '",w:"' + point.lat().toFixed(6) + '",j:"' + point.lng().toFixed(6) + '",a:"' + ge.getGlobe().getGroundAltitude(point.lat(), point.lng()).toFixed(3) + '",t:"' + type + '"},';
}

function returnDLZXAPointJson(point) {
    var json = '';
    var flag = false;
    var alt = ge.getGlobe().getGroundAltitude(point.lat(), point.lng()).toFixed(3);
    if (DLZX[4] != 'J') {
        if (DLZX[3]) {
            if (parseFloat(DLZX[2]) - parseFloat(alt) > 0) {
                json = '{n:"Z' + zxz + '",w:"' + DLZX[0] + '",j:"' + DLZX[1] + '",a:"' + DLZX[2] + '",t:"1"},';
                zxz++;
                flag = false;
            } else {
                json = '{n:"' + fzd + '",w:"' + DLZX[0] + '",j:"' + DLZX[1] + '",a:"' + DLZX[2] + '",t:"2"},';
                fzd++;
                flag = true;
            }
        } else {
            json = '{n:"' + fzd + '",w:"' + DLZX[0] + '",j:"' + DLZX[1] + '",a:"' + DLZX[2] + '",t:"2"},';
            fzd++;
            if (parseFloat(DLZX[2]) - parseFloat(alt) > 0) {
                flag = false;
            } else {
                flag = true;
            }
        }
    }
    DLZX = [point.lat().toFixed(6), point.lng().toFixed(6), alt, flag, ''];
    return json;
}

function returnDLZXBPointJson(point, name, type) {
    var flag = false;
    var json = '';
    var alt = ge.getGlobe().getGroundAltitude(point.lat(), point.lng()).toFixed(3);
    if (DLZX[4] != 'J') {
        if (DLZX[3]) {
            if (parseFloat(DLZX[2]) - parseFloat(alt) > 0) {
                json = '{n:"Z' + zxz + '",w:"' + DLZX[0] + '",j:"' + DLZX[1] + '",a:"' + DLZX[2] + '",t:"1"},';
                zxz++;
                flag = false;
            } else {
                json = '{n:"' + fzd + '",w:"' + DLZX[0] + '",j:"' + DLZX[1] + '",a:"' + DLZX[2] + '",t:"2"},';
                fzd++;
                flag = true;
            }
        } else {
            json = '{n:"' + fzd + '",w:"' + DLZX[0] + '",j:"' + DLZX[1] + '",a:"' + DLZX[2] + '",t:"2"},';
            fzd++;
            if (parseFloat(DLZX[2]) - parseFloat(alt) > 0) {
                flag = false;
            } else {
                flag = true;
            }
        }
    }
    DLZX = [point.lat().toFixed(6), point.lng().toFixed(6), alt, flag, 'J'];
    json += returnDLZXPointJson(point, name, type);
    return json;
}

function searchLatLngByLocation_e(a) {
    if (lastMapMod != 'earth') {
        window.external.showMessageCallback_('請切換到地球模式進行地名搜索!');
        return false;
    }
    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address=' + a + '&sensor=false', function (json) {
        if (json['status'] == 'OK') {
            var lat = json['results'][0]['geometry']['location']['lat'];
            var lng = json['results'][0]['geometry']['location']['lng'];
            searchLocation_e(lat, lng);
        }
    });
}
lastMapMod = 'earth';
var rubbishPoints = [];
var figType = '';
var lWidth='5';
var lColor='Red';
var lOpacity='1';
var licon='';
var lname;
var ldescription;
function drawParameter(name,description,lineWidth,lineColor,lineOpacity,icon,iconType)
{
	lname=name;
	ldescription=description;
	lWidth=lineWidth;
	lColor=lineColor;
	lOpacity=lineOpacity;
	licon=icon;
	markerTitle = iconType;
}
function drawFigure_e(figuretype) {
    chushihuaDrawFig_e();
    figType = figuretype;
    pathStyle = lineStyle;
    doWhat = 0;
    markerTitle = '地標';
}
var cPoints = [];

function drawControlPoints(figuretype) {
    chushihuaDrawFig_e();
    figType = figuretype;
    doWhat = 0;
    markerTitle = '控制點';
}

function clearDrawControlPoints() {
    markerTitle = '地標';
    cPoints = [];
}

function addEventListenerDrawFig_e() {
    try {
        google.earth.removeEventListener(ge.getGlobe(), 'mousedown', clickRightMouseDrawFig);
        google.earth.addEventListener(ge.getGlobe(), 'mousedown', clickRightMouseDrawFig);
    } catch (e) {}
}

function removeEventListenerDrawFig_e() {
    if (figType != 'point') {
        chushihuaDrawFig_e();
    }
    figType = '';
    try {
        google.earth.removeEventListener(ge.getGlobe(), 'mousedown', clickRightMouseDrawFig);
        doWhat = 0;
    } catch (e) {}
}
var doWhat = 0;

function clickObjectDo_e(key) {
    doWhat = key;
    chushihuaDrawFig_e();
}
var objm = 0;

function selectObjectToIdentify(key, m) {
    if (lastMapMod != 'earth') {
        alert('請切換到谷歌地球三維模式!');
    }
    bakupPoints = [];
    objm = m;
    if (m == 1 || m == 2) {
        clickObjectDo_e(key);
        addEventListenerDrawFig_e();
    } else if (m == 3) {
        identifyAllPlacemark('KmlPoint');
        selectObjectInfos('地標', '點', bakupPoints.length, 0);
    } else {}
}
var objPoints = [];
var objectId = '';
var cases_e = {
    'word': drawPointNOIconFunc_e,
    'point': drawPointFunc_e,
    'line': drawLineFunc_e,
    'rectangle': drawRetangleFunc_e,
    'polygon': drawPolygonFunc_e
};

//鼠標事件處理 
var clickRightMouseDrawFig = function (event) {
    if (event.getButton() == 2 && doWhat == 0) {
        if (cases_e[figType]) {
            cases_e[figType](event);
        }
    } else if (event.getButton() == 0 && doWhat == 1 && event.getTarget().getType() == 'KmlPlacemark') {
        removeObject(event.getTarget());
        doWhat = 0;
		window.external.exitDeleteMode();
    } else if (event.getButton() == 0 && doWhat == 2 && event.getTarget().getType() == 'KmlPlacemark') {
        editObject(event.getTarget());
    } else if (event.getButton() == 0 && doWhat == 3 && event.getTarget().getType() == 'KmlPlacemark') {
        selectMeasureObject(event.getTarget());
    } else if (event.getButton() == 0 && doWhat == 0 && event.getTarget().getType() == 'KmlPlacemark') {
        identifyObject(event.getTarget());
        getObjectBounds(event.getTarget());
        getPathIdentify(event.getTarget());
    }
}

function drawPointNOIconFunc_e(event) {
    drawPointNoIcon(getUniqueId(), [event.getLatitude(), event.getLongitude(), 0], '地標', '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
}

function drawPointFunc_e(event) {
    var pid = getUniqueId();
    drawPoint2(pid, [event.getLatitude(), event.getLongitude(), 0], markerTitle, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
   //drawPoint2(pid, [event.getLatitude(), event.getLongitude(), 0], markerTitle, ldescription);
    if (markerTitle == '控制點') {
        cPoints.push(pid);
    }
}

function drawLineFunc_e(event) {
	lineStyle.line.color=lColor;
	lineStyle.line.width=lWidth;
	lineStyle.line.opacity=lOpacity;
    if (objectId == '') {
        objectId = getUniqueId();
       // drawPathCap(objectId, [event.getLatitude(), event.getLongitude(), 0], '路徑', '這是路徑');
	   drawPathCap(objectId, [event.getLatitude(), event.getLongitude(), 0], lname, ldescription);
    } else {
        addPathPoint(objectId, [event.getLatitude(), event.getLongitude(), 0]);
    }
}

function drawRetangleFunc_e(event) {
	rectangleLineStyle.width=lWidth;	
	rectangleLineStyle.color=lColor;
	rectangleLineStyle.opacity=lOpacity;
    if (objectId == '') {
        objectId = getUniqueId();
        //drawPoint(objectId, [event.getLatitude(), event.getLongitude(), 0], '矩形', '這是矩形');
		drawPoint(objectId, [event.getLatitude(), event.getLongitude(), 0], lname, ldescription);
        rubbishPoints.push(objectId);
    } else {
        var obj = getObjectById(objectId);
        var geometry = obj.getGeometry();
        var p0 = new geo.Point(geometry.getLatitude(), geometry.getLongitude(), geometry.getAltitude());
        removeObject(obj);
        rubbishPoints = [];
        var p2 = new geo.Point(event.getLatitude(), event.getLongitude(), 0);
        var p1 = getTrianglePoint(p0, p2);
        var p3 = getTrianglePoint(p2, p0);
        pathStyle = rectangleLineStyle;
     /*    drawRectangle(objectId + 'rec', [
            [p0.lat(), p0.lng(), 0],
            [p1.lat(), p1.lng(), 0],
            [p2.lat(), p2.lng(), 0],
            [p3.lat(), p3.lng(), 0]
        ], '矩形', '這是矩形'); */
		drawRectangle(objectId + 'rec', [
            [p0.lat(), p0.lng(), 0],
            [p1.lat(), p1.lng(), 0],
            [p2.lat(), p2.lng(), 0],
            [p3.lat(), p3.lng(), 0]
        ], lname,ldescription); 
        objectId = '';
    }
}

function drawPolygonFunc_e(event) {
	polygonLineStyle.width=lWidth;
	polygonLineStyle.color=lColor;
	polygonLineStyle.opacity=lOpacity;
    if (objectId == '') {
        objectId = getUniqueId();
        drawPoint(objectId, [event.getLatitude(), event.getLongitude(), 0], '多邊形', '這是多邊形');
        rubbishPoints.push(objectId);
    } else {
        var obj = getObjectById(objectId);
        var geometry = obj.getGeometry();
        if ('KmlPoint' == geometry.getType()) {
            objectId += 'poy';
            pathStyle = polygonLineStyle;
           /*  drawPolygonCap(objectId, [
                [geometry.getLatitude(), geometry.getLongitude(), 0]
            ], '多邊形', '這是多邊形'); */
			drawPolygonCap(objectId, [
                [geometry.getLatitude(), geometry.getLongitude(), 0]
            ], lname, ldescription);
            removeObject(obj);
            rubbishPoints = [];
        }
        addPolygonPoint(objectId, [event.getLatitude(), event.getLongitude(), 0]);
    }
}

function drawCircleFunc_e(c, r, a1, a2, des, name, isCircle) {
	circleLineStyle.width=lWidth;
	circleLineStyle.color=lColor;
	circleLineStyle.opacity=lOpacity;
	fanLineStyle.width=lWidth;
	fanLineStyle.color=lColor;
	fanLineStyle.opacity=lOpacity;
    var n = 500;
    var cs = c.split(',');
    var cPoint = new geo.Point(parseFloat(cs[1]), parseFloat(cs[0]));
    var r = parseFloat(r);
    var a1 = parseFloat(a1);
    var a2 = parseFloat(a2);
    objPoints = [];
    if (Math.abs(a2.sub(a1)) >= 360) {
        for (var i = 0; i < n; i++) {
            objPoints.push(getPointLocationByDHA(cPoint, r, (360 / n) * i));
        }
        if (isCircle == '1') {
            objPoints.push(getPointLocationByDHA(cPoint, r, 360));
        }
        pathStyle = circleLineStyle;
        drawPolygon(getUniqueId(), objPoints, (name == '') ? '圓' : name, des, isCircle);
        objPoints = [];
    } else {
        if (isCircle == '0') {
            objPoints.push(cPoint);
        }
        var ad = a2.sub(a1);
        var adabs = Math.abs(ad);
        n = adabs * n.div(360);
        for (var i = 0; i < n; i++) {
            objPoints.push(getPointLocationByDHA(cPoint, r, a1.add(ad / n * i)));
        }
        pathStyle = fanLineStyle;
        drawPolygon(getUniqueId(), objPoints, (name == '') ? '扇形' : name, des, isCircle);
        objPoints = [];
    }
    removeEventListenerSetCircleParams_e();
    chushihuaDrawFig_e();
}
var pointStyle = {
    label: {
        scale: 1,
        color: 'White',
        opacity: 1
    },
    icon: {
		stockIcon:'pushpin/ylw-pushpin',
        color: 'White',
        opacity: 1,
        scale: 1.1
    }
};
var pointStyle9 = {
    label: {
        scale: 1,
        color: 'White',
        opacity: 1
    },
    icon: {
		href:'http://www.goodygis.com/earth/icons/xuexiao.png',
        color: 'White',
        opacity: 1,
        scale: 2
    }
};
var pointStyle1 = {
    label: {
        scale: 1,
        color: 'White',
        opacity: 1
    },
    icon: {
        stockIcon: 'shapes/flag',
        color: 'White',
        opacity: 1,
        scale: 1.1
    }
};
var pointNoIconStyle = {
    label: {
        scale: 1,
        color: 'White',
        opacity: 1
    },
    icon: {
        stockIcon: 'shapes/placemark_circle',
        color: '0dffffff',
        scale: 1.1
    }
};
var lineStyle = {
    line: {
        width: 3,
        opacity: 1,
        color: 'Red'
    },
    icon: {
        stockIcon: 'paddle/red-circle'
    }
};
var rulerStyle = {
    line: {
        width: 6,
        opacity: 0.3,
        color: 'Red'
    },
    icon: {
        stockIcon: 'paddle/blu-stars'
    }
};
var rectangleLineStyle = {
    width: 3,
    opacity: 1,
    color: 'Blue'
};
var polygonLineStyle = {
    width: 3,
    opacity: 1,
    color: 'Yellow'
};
var polygonLineStyle1 = {
    width: 3,
    opacity: 1,
    color: '#00f9f9'
};
var circleLineStyle = {
    width: 3,
    opacity: 1,
    color: 'Fuchsia'
};
var fanLineStyle = {
    width: 3,
    opacity: 1,
    color: 'Lime'
};
var pathStyle = lineStyle;

function chushihuaDrawFig_e() {
    if (objectId != '') {
        var obj = getObjectById(objectId);
        if ('KmlPoint' == obj.getGeometry().getType()) {
            for (var i = 0; i < rubbishPoints.length; i++) {
                removeObject(getObjectById(rubbishPoints[i]));
            }
        } else if ('KmlMultiGeometry' == obj.getGeometry().getType()) {
            if (obj.getGeometry().getGeometries().getChildNodes().item(1).getCoordinates().getLength() == 1) {
                removeObject(obj);
            } else {
                drawPathRearCap(objectId);
            }
        } else if ('KmlPolygon' == obj.getGeometry().getType() && obj.getGeometry().getOuterBoundary().getCoordinates().getLength() == 2) {
            removeObject(obj);
        }
    }
    if (rubbishPoints.length > 0) {
        for (var i = 0; i < rubbishPoints.length; i++) {
            removeObject(getObjectById(rubbishPoints[i]));
        }
    }
    rubbishPoints = [];
    objectId = '';
}

function removeLastObj(n) {
    var nodes = ge.getFeatures().getChildNodes();
    if (nodes.getLength() > 0) {
        ge.getFeatures().removeChild(nodes.item(nodes.getLength() - n));
    }
}

function getLastObj() {
    var nodes = ge.getFeatures().getChildNodes();
    return nodes.item(nodes.getLength() - 1);
}

function removeObject(obj) {
    gex.dom.removeObject(obj);
    downloadimgpolygonid = '';
    obj = null;
    window.external.setMousemoveMsgByWeb('', false);
}

function removeThisObject() {
    getObjectType();
    if (objPoints.length > 0) {
        chushihuaDrawFig_e();
    }
}

function clearAllObjs_e() {
    clearAllObjects();
}

function cancelLineLastStep_e() {
    if (objectId != '') {
        var obj = getObjectById(objectId);
        if ('KmlMultiGeometry' == obj.getGeometry().getType()) {
            var coordinates = obj.getGeometry().getGeometries().getChildNodes().item(1).getCoordinates();
            if (coordinates.getLength() > 1) {
                coordinates.pop();
            } else {
                removeObject(obj);
                objectId = '';
                rubbishPoints = [];
            }
        } else if ('KmlPolygon' == obj.getGeometry().getType()) {
            var coordinates = obj.getGeometry().getOuterBoundary().getCoordinates();
            if (coordinates.getLength() > 2) {
                coordinates.pop();
            } else {
                removeObject(obj);
                objectId = '';
                rubbishPoints = [];
            }
        }
    }
}

function addEventListenerMeasureDistance_e() {
    drawFigure_e('line');
    try {
        google.earth.addEventListener(ge.getGlobe(), 'mousedown', clickRightMouseDrawFig);
        google.earth.addEventListener(ge.getGlobe(), 'mousedown', clickRightMouseMeasureDistance_e);
    } catch (e) {}
    pathStyle = rulerStyle;
}

function removeEventListenerMeasureDistance_e() {
    figType = '';
    chushihuaDrawFig_e();
    doWhat = 0;
    try {
        google.earth.removeEventListener(ge.getGlobe(), 'mousedown', clickRightMouseMeasureDistance_e);
    } catch (e) {}
}

function subMeasureDistance_e() {
    cancelLineLastStep_e();
    if (objectId != '') {
        goBackMeasureDistance();
    }
}
var clickRightMouseMeasureDistance_e = function (event) {
    if (event.getButton() == 2) {
        window.external.measureDistanceCallback_(computePathDistance_e(getObjectById(objectId)));
    }
}

function goBackMeasureDistance() {
    window.external.measureDistanceCallback_(computePathDistance_e(getObjectById(objectId)));
}

function selectMeasureObject(obj) {
    switch (obj.getGeometry().getType()) {
    case 'KmlMultiGeometry':
        var geoms = obj.getGeometry().getGeometries();
        for (var j = 0; j < geoms.getChildNodes().getLength(); j++) {
            if (geoms.getChildNodes().item(j).getType() == 'KmlLineString') {
                window.external.measureObjectCallback_(0, 0, computePathDistance_e(geoms.getChildNodes().item(j)));
            } else if (geoms.getChildNodes().item(j).getType() == 'KmlPolygon') {
                var params = computeAreaAndC(geoms.getChildNodes().item(j));
                window.external.measureObjectCallback_(params[0], params[1], 0);
            }
        }
        break;
    case 'KmlLineString':
        window.external.measureObjectCallback_(0, 0, computePathDistance_e(obj));
        break;
    case 'KmlLinearRing':
    case 'KmlPolygon':
        var params = computeAreaAndC(obj);
        window.external.measureObjectCallback_(params[0], params[1], 0);
        break;
    default:
    }
}

function identifyAllPlacemark(KmlType) {
    gex.dom.walk({
        rootObject: ge,
        visitCallback: function () {
            if ('getType' in this && this.getType() == 'KmlPlacemark') {
                if (this.getGeometry().getType() == KmlType) {
                    bakupPoints.push({
                        key: this.getName(),
                        value: new geo.Point(this.getGeometry())
                    });
                }
            }
        }
    });
}

function identifyObject(obj) {
    if (objm == 1) {
        bakupPoints = [];
        switch (obj.getGeometry().getType()) {
        case 'KmlPoint':
            bakupPoints.push({
                key: obj.getName(),
                value: new geo.Point(obj.getGeometry())
            });
            selectObjectInfos(obj.getName(), '點', 1, 0);
            break;
        case 'KmlLineString':
            var coords = obj.getGeometry().getCoordinates();
            var length = coords.getLength();
            for (var i = 0; i < length; i++) {
                bakupPoints.push(new geo.Point(coords.get(i)));
            }
            selectObjectInfos(obj.getName(), '線', 1, 1);
            break;
        case 'KmlPolygon':
            var polygonCoords = [];
            var coords = obj.getGeometry().getOuterBoundary().getCoordinates();
            var length = coords.getLength();
            var lats = [];
            var lngs = [];
            for (var i = 0; i < length; i++) {
                lats.push(coords.get(i).getLatitude());
                lngs.push(coords.get(i).getLongitude());
                polygonCoords.push(getPointByLatLng(coords.get(i).getLatitude(), coords.get(i).getLongitude()));
            }
            var latsMax = lats.max();
            var latsMin = lats.min();
            var lngsMax = lngs.max();
            var lngsMin = lngs.min();
            bakupPoints = [createGeoPointByLatLngAlt(latsMax, lngsMin, 0), createGeoPointByLatLngAlt(latsMax, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMin, 0)];
            selectObjectInfos(obj.getName(), '面', 1, 2);
            polygonBoundery = addPolygonOnMap(polygonCoords);
            window.external.showDownloadImageRegion(latsMax, latsMin, lngsMin, lngsMax);
            break;
        case 'KmlMultiGeometry':
            var objtype = '線';
            var figuretype = 1;
            var geoms = obj.getGeometry().getGeometries();
            for (var j = 0; j < geoms.getChildNodes().getLength(); j++) {
                if (geoms.getChildNodes().item(j).getType() == 'KmlLineString') {
                    objtype = '線';
                    figuretype = 1;
                    var coords = geoms.getChildNodes().item(j).getCoordinates();
                    var length = coords.getLength();
                    for (var i = 0; i < length; i++) {
                        bakupPoints.push(new geo.Point(coords.get(i)));
                    }
                } else if (geoms.getChildNodes().item(j).getType() == 'KmlPolygon') {
                    objtype = '面';
                    figuretype = 2;
                    var coords = geoms.getChildNodes().item(j).getOuterBoundary().getCoordinates();
                    var length = coords.getLength();
                    var lats = [];
                    var lngs = [];
                    var polygonCoords = [];
                    for (var i = 0; i < length; i++) {
                        lats.push(coords.get(i).getLatitude());
                        lngs.push(coords.get(i).getLongitude());
                        polygonCoords.push(getPointByLatLng(coords.get(i).getLatitude(), coords.get(i).getLongitude()));
                    }
                    var latsMax = lats.max();
                    var latsMin = lats.min();
                    var lngsMax = lngs.max();
                    var lngsMin = lngs.min();
                    bakupPoints = [createGeoPointByLatLngAlt(latsMax, lngsMin, 0), createGeoPointByLatLngAlt(latsMax, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMin, 0)];
                }
            }
            selectObjectInfos(obj.getName(), objtype, 1, figuretype);
            if (figuretype == 2) {
                polygonBoundery = addPolygonOnMap(polygonCoords);
            }
            break;
        default:
        }
    } else if (objm == 2) {
        if (obj.getGeometry().getType() == 'KmlPoint') {
            bakupPoints.push({
                key: obj.getName(),
                value: new geo.Point(obj.getGeometry())
            });
            selectObjectInfos(obj.getName(), '點', bakupPoints.length, 0);
        } else {}
    }
}

function selectObjectInfos(name, type, num, extractType) {
    var isExtract = '否';
    if (num > 0) {
        isExtract = '是';
    }
    window.external.autoIdentifyObjectsCallback_(name, type, isExtract, num, extractType);
}
var activeTextBox = '';

function addEventListenerSetCircleParams_e(textBox) {
    try {
        google.earth.addEventListener(ge.getGlobe(), 'mousemove', moveMouseGetCoords_e);
        google.earth.addEventListener(ge.getGlobe(), 'mousedown', clickRightMouseGetCoords_e);
    } catch (e) {}
    activeTextBox = textBox;
}

function removeEventListenerSetCircleParams_e() {
    try {
		google.earth.removeEventListener(ge.getGlobe(), 'mousemove', moveMouseGetCoords_e);
        google.earth.removeEventListener(ge.getGlobe(), 'mousedown', clickRightMouseGetCoords_e);
    } catch (e) {}
    activeTextBox = '';
}
var centerPointName = '';
var moveMouseGetCoords_e = function (event) {
    var param = '';
    switch (activeTextBox) {
    case 'textBox1':
        centerPointName = '圓心';
        param = event.getLongitude().toFixed(6) + ',' + event.getLatitude().toFixed(6);
        break;
    case 'textBox2':
        centerPointName = '半徑';
        var centerPoint = (window.external.getTextBoxValue('textBox1')).split(',');
        if (centerPoint != '') {
            param = getHorizontalDistance(new geo.Point(parseFloat(centerPoint[1]), parseFloat(centerPoint[0])), new geo.Point(event.getLatitude(), event.getLongitude())).toFixed(2);
        } else {
            activeTextBox = 'textBox6';
        }
        break;
    case 'textBox3':
        centerPointName = '起始位置';
        var centerPoint = (window.external.getTextBoxValue('textBox1')).split(',');
        if (centerPoint != '') {
            param = new geo.Point(parseFloat(centerPoint[1]), parseFloat(centerPoint[0])).heading(new geo.Point(event.getLatitude(), event.getLongitude())).toFixed(2);
        } else {
            activeTextBox = 'textBox6';
        }
        break;
    case 'textBox4':
        centerPointName = '結束位置';
        var centerPoint = (window.external.getTextBoxValue('textBox1')).split(',');
        if (centerPoint != '') {
            param = new geo.Point(parseFloat(centerPoint[1]), parseFloat(centerPoint[0])).heading(new geo.Point(event.getLatitude(), event.getLongitude())).toFixed(2);
        } else {
            activeTextBox = 'textBox6';
        }
        break;
    case 'textBox14':
        centerPointName = '源點';
        param = event.getLongitude() + ',' + event.getLatitude();
        break;
    case 'textBox15':
        centerPointName = '目標點';
        param = event.getLongitude() + ',' + event.getLatitude();
        break;
    default:
    }
    window.external.inputTextBoxCoordsCallback_(activeTextBox, param);
}
var circleCenterId = '';
var circleRadiusId = '';
var circleStartAngleId = '';
var circleEndAngleId = '';
var originalPointId = '';
var targetPointId = '';
var clickRightMouseGetCoords_e = function (event) {
    if (event.getButton() == 2) {
        removeEventListenerSetCircleParams_e();
        if (centerPointName == '圓心') {
            if (circleCenterId != '') {
                removeObject(getObjectById(circleCenterId));
            }
            circleCenterId = getUniqueId();
            rubbishPoints.push(circleCenterId);
            drawPoint(circleCenterId, [event.getLatitude(), event.getLongitude(), 0], centerPointName, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
        } else if (centerPointName == '半徑') {
            if (circleRadiusId != '') {
                removeObject(getObjectById(circleRadiusId));
            }
            circleRadiusId = getUniqueId();
            rubbishPoints.push(circleRadiusId);
            drawPoint(circleRadiusId, [event.getLatitude(), event.getLongitude(), 0], centerPointName, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
        } else if (centerPointName == '起始位置') {
            if (circleStartAngleId != '') {
                removeObject(getObjectById(circleStartAngleId));
            }
            circleStartAngleId = getUniqueId();
            rubbishPoints.push(circleStartAngleId);
            drawPoint(circleStartAngleId, [event.getLatitude(), event.getLongitude(), 0], centerPointName, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
        } else if (centerPointName == '結束位置') {
            if (circleEndAngleId != '') {
                removeObject(getObjectById(circleEndAngleId));
            }
            circleEndAngleId = getUniqueId();
            rubbishPoints.push(circleEndAngleId);
            drawPoint(circleEndAngleId, [event.getLatitude(), event.getLongitude(), 0], centerPointName, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
        } else if (centerPointName == '源點') {
            if (originalPointId != '') {
                removeObject(getObjectById(originalPointId));
            }
            originalPointId = getUniqueId();
            rubbishPoints.push(originalPointId);
            drawPoint(originalPointId, [event.getLatitude(), event.getLongitude(), 0], centerPointName, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
        } else if (centerPointName == '目標點') {
            if (targetPointId != '') {
                removeObject(getObjectById(targetPointId));
            }
            targetPointId = getUniqueId();
            rubbishPoints.push(targetPointId);
            drawPoint(targetPointId, [event.getLatitude(), event.getLongitude(), 0], centerPointName, '經度:' + event.getLongitude().toFixed(6) + ',緯度:' + event.getLatitude().toFixed(6));
        } else {
            return false;
        }
    }
}

function dragPlacemark() {
    removeEventListenerDrawFig_e();
    if (eObj != null) {
        gex.edit.makeDraggable(eObj, {
            bounce: false,
            dropCallback: function () {}, draggingStyle: pointStyle
        });
    }
    doWhat = 2;
}

function endEditPlacemark_e() {
    gex.edit.endDraggable(eObj);
    eObj = null;
    addEventListenerDrawFig_e();
}

function modifyPlacemark_e(name, description,lineWidth,lineColor,lineOpacity) {
	//function modifyPlacemark_e(name, description){
    eObj.setName(name);
    eObj.setDescription(description);
	
	eObj.getStyleSelector().getLineStyle().setWidth(lineWidth);	
	eObj.getStyleSelector().getLineStyle().getColor().set(mergeColorOpacity(lineColor, lineOpacity));
}
function modifyPoint_e(name, description,icon) {	
    eObj.setName(name);
    eObj.setDescription(description);	
	eObj.getStyleSelector().getIconStyle().getIcon().setHref(icon);
}
var eObj = null;



//'word': drawPointNOIconFunc_e,
//'point': drawPointFunc_e,
//'line': drawLineFunc_e,
//'rectangle': drawRetangleFunc_e,
//'polygon': drawPolygonFunc_e

//編輯選擇的對象
function editObject(obj) {
    var id = '';
    var name = '';
    var des = '';
	//alert(obj.getGeometry().getType());
    if (obj.getGeometry().getType() == 'KmlPolygon' ||
		obj.getGeometry().getType() == 'KmlMultiGeometry' || obj.getGeometry().getType() == 'KmlLineString' ) {
        eObj = obj;
		//alert(obj.getStyleSelector().getIconStyle().getIcon().getHref());得到圖標的地址
		//alert(obj.getStyleSelector().getLineStyle().getWidth());得到線的寬度
		//alert(obj.getStyleSelector().getLineStyle().getColor().get());得到線的顏色和透明度,是一個八位的字符串,前兩位是透明度,後面六位是顏色,分別是藍、綠、紅
		window.external.editOthersCallback_(obj.getName(), obj.getDescription(),obj.getStyleSelector().getLineStyle().getWidth(),obj.getStyleSelector().getLineStyle().getColor().get());
    }  else if(obj.getGeometry().getType() == 'KmlPoint' )
	{
		eObj = obj;
		window.external.editKmlPointCallback_(obj.getName(),obj.getDescription(),obj.getStyleSelector().getIconStyle().getIcon().getHref());//
		
	} 
	else if ('getId' in obj && obj.getGeometry().getType() == 'KmlLineString') {} 
	else if ('getId' in obj && obj.getGeometry().getType() == 'KmlLinearRing') {} 
	else if ('getId' in obj && obj.getGeometry().getType() == 'KmlPolygon') {} 
	else if ('getId' in obj && obj.getGeometry().getType() == 'KmlModel') {} 
	else {}
}

function updatePoint(oid, labelName, description, labelColor, labelScale, labelOpacity, iconColor, iconScale, iconOpacity, systemIcon, ownIcon, altitude, altitudeMode) {
    var obj = getObjectById(oid);
    obj.setName(labelName);
    obj.setDescription(description);
    obj.getStyleSelector().getIconStyle().setScale(iconScale);
}

function updateLine(oid, lineName, lineDescription, lineWidth, lineColor, lineOpacity) {
    var obj = getObjectById(oid);
    obj.setName(lineName);
    obj.setDescription(lineDescription);
    obj.getStyleSelector().getLineStyle().setWidth(lineWidth);
    obj.getStyleSelector().getLineStyle().getColor().set(mergeColorOpacity(lineColor, lineOpacity));
}

function updatePolygon(oid, lineName, lineDescription, lineWidth, lineColor, lineOpacity, polyColor, polyOpacity) {
    var obj = getObjectById(oid);
    obj.setName(lineName);
    obj.setDescription(lineDescription);
    obj.getStyleSelector().getLineStyle().setWidth(lineWidth);
    obj.getStyleSelector().getLineStyle().getColor().set(mergeColorOpacity(lineColor, lineOpacity));
    obj.getStyleSelector().getPolyStyle().getColor().set(mergeColorOpacity(polyColor, polyOpacity));
}

function removePointById(id) {
    gex.dom.walk({
        rootObject: ge,
        visitCallback: function () {
            if ('getType' in this && this.getType() == 'KmlPlacemark') {
                if ('getType' in this.getGeometry() && this.getGeometry().getType() == 'KmlPoint') {
                    if ('getId' in this && this.getId() == id) {
                        removeObject(this);
                    }
                }
            }
        }
    });
}

function removePointByName(name) {
    gex.dom.walk({
        rootObject: ge,
        visitCallback: function () {
            if ('getType' in this && this.getType() == 'KmlPlacemark') {
                if ('getType' in this.getGeometry() && this.getGeometry().getType() == 'KmlPoint') {
                    if ('getName' in this && this.getName() == name) {
                        removeObject(this);
                    }
                }
            }
        }
    });
}

function getObjectType() {
    gex.dom.walk({
        rootObject: ge,
        visitCallback: function () {
            if ('getType' in this && this.getType() == 'KmlPlacemark') {
                if (this.getGeometry().getType() == 'KmlPoint') {} else if (this.getGeometry().getType() == 'KmlLineString') {}
            }
        }
    });
}

function removeOldPoly() {
    var nodes = ge.getFeatures().getChildNodes();
    var nodeslength = nodes.getLength();
    for (var i = 2; i < nodeslength; i++) {
        ge.getFeatures().removeChild(nodes.item(i));
    }
}

function clearAllObjects() {
    try {
        gex.dom.clearFeatures();
        bakupPoints = [];
        Points = [];
        objectId = '';
        cPoints = [];
    } catch (err) {}
}
//修改後的所有清除
function clearAllDrawObjects() {
    var nodes=ge.getFeatures().getChildNodes();
	var nodeslength=nodes.getLength();
    for (var i = 0; i < nodeslength; i++) {
		if(nodes.item(i).getType()=='KmlPlacemark')
		{
			ge.getFeatures().removeChild(nodes.item(i));
		}
	}
		bakupPoints = [];
        Points = [];
        objectId = '';
        cPoints = [];
}
function removeLastObject(num) {
    var nodes = ge.getFeatures().getChildNodes();
    var nodeslength = nodes.getLength();
    if (nodeslength == 1) {
        ge.getFeatures().removeChild(nodes.item(0));
    } else {
        for (var i = nodeslength - num; i < nodeslength && i >= 0; i++) {
            ge.getFeatures().removeChild(nodes.item(i));
        }
    }
    bakupPoints.pop();
}

function setOriginPoints() {
    cancelWebbrowserRun('run');
    Points = bakupPoints.slice(0);
    pmCount = Points.length;
    extractTimes = 0;
    pPoints = [];
    aPoints = [];
    xNum = 0;
    yNum = 0;
    fzd = 1;
    zxz = 1;
    DLZX = [];
    pbounds = null;
    ppaths = null;
}

function cleartAllParams() {
    pCount = 0;
    extractTimes = 0;
    pPoints = [];
    xNum = 0;
    yNum = 0;
}

function setEarthState(point, flySpeed, range) {
    if (flySpeed == 6) {
        flySpeed = ge.SPEED_TELEPORT;
    }
    moveMapToPoint(point, range, flySpeed, null);
}

function calPointsNum() {
    setOriginPoints();
    if (Points.length == 0) {
        alert('對不起,請設置要提取高程的對象!');
        return;
    }
    window.external.calPointsOverCallback_(Points.length, '');
}

function calLinesPointsNum(d) {
    setOriginPoints();
    if (Points.length == 0) {
        alert('請設置路線!');
        return;
    }
    try {
        var PACount;
        var pCount = 0;
        var HD = 0;
        var D = 0;
        var setPointsNum = Points.length;
        for (var i = 1; i < setPointsNum; i++) {
            HD = getHorizontalDistance(Points[i - 1], Points[i]);
            D = parseFloat(D).add(parseFloat(HD));
        }
        PACount = Math.floor(parseFloat(D).div(parseFloat(d)));
        pCount = pCount + PACount + 1;
        if (window.external.isBaohanGuaiDian() == '1') {
            pCount = pCount + setPointsNum - 2;
        }
        window.external.calPointsOverCallback_(pCount, D.toFixed(2));
    } catch (err) {
	}
}

function calLineVertexPointsNum() {
    setOriginPoints();
    var length = Points.length;
    if (length == 0) {
        alert('請設置路線!');
        return;
    }
    var HD = 0;
    var D = 0;
    for (var i = 1; i < length; i++) {
        HD = getHorizontalDistance(Points[i - 1], Points[i]);
        D = parseFloat(D).add(parseFloat(HD));
    }
    window.external.calPointsOverCallback_(length, D.toFixed(2));
}

function calDLinesPointsNum(d, w) {
    setOriginPoints();
    if (Points.length == 0) {
        alert('請設置路線!');
        return;
    }
    try {
        d = parseFloat(d);
        w = parseFloat(w);
        var PACount;
        var pCount = 0;
        var HD = 0;
        var D = 0;
        var setPointsNum = Points.length;
        for (var i = 1; i < setPointsNum; i++) {
            HD = getHorizontalDistance(Points[i - 1], Points[i]);
            pCount += Math.floor(HD.div(d)) + 1;
        }
        pCount += 1;
        if (window.external.isBaohanGuaiDian() == '1') {
            pCount = pCount + setPointsNum - 2;
        }
        window.external.calPointsOverCallback_((2 * Math.floor(w / d) + 1) * pCount, D.toFixed(2));
    } catch (err) {
	}
}
var pPoints = [];
var aPoints = [];

function calPolyPointsNum(d) {
    var stats = []
    setOriginPoints();
    if (Points.length == 0) {
        window.external.stopRun('請繪製並選擇矩形或者多邊形!');
        return;
    }
    try {
        var aPoly = getHorizontalDistance(Points[0], Points[1]).toFixed(2);
        var bPoly = getHorizontalDistance(Points[0], Points[3]).toFixed(2);
        var temp = 0;
        if (parseFloat(aPoly) < parseFloat(bPoly)) {
            temp = bPoly;
            bPoly = aPoly;
            aPoly = temp;
            Points = [Points[0], Points[3], Points[2], Points[1]];
            rotateMap(0);
        } else {
            rotateMap(90);
        }
        var aNum = Math.ceil(parseFloat(aPoly).div(parseFloat(d))) + 1;
        var bNum = Math.ceil(parseFloat(bPoly).div(parseFloat(d))) + 1;
        var pointsNum = parseFloat(aNum).mul(parseFloat(bNum));
        var area = parseFloat(aPoly).mul(parseFloat(bPoly));
        aPoints[0] = getPointLocationByDH(Points[0], Points[1], d / 5);
        aPoints[1] = getPointLocationByDH(Points[1], Points[2], d / 5);
        aPoints[3] = getPointLocationByDH(Points[3], Points[2], d / 5);
        aPoints[0] = getPointLocationByDH(aPoints[0], aPoints[3], d / 5);
        aPoints[2] = Points[2];
        polyParams = [aPoints[0], aPoints[0], aNum, bNum, aNum, area, pointsNum];
        pPoints[0] = aPoints[0];
        var pArea = computeAreaAndC(polygonContourObj);
        try {
            window.external.calPointsOverCallback_(parseInt(pArea[1] / area * pointsNum), pArea[1]);
        } catch (err) {
		}
        pbounds = polygonBoundery.getBounds();
        ppaths = polygonBoundery.getPaths();
    } catch (err) {
	}
}

function extractPointsElevationsQuick() {
    var data = '[';
    var placemarkCount = Points.length;
    for (var i = 0; i < placemarkCount; i++) {
        data += '{n:"' + Points[i].key + '",w:"' + Points[i].value.lat().toFixed(6) + '",j:"' + Points[i].value.lng().toFixed(6) + '",a:"' + ge.getGlobe().getGroundAltitude(Points[i].value.lat(), Points[i].value.lng()).toFixed(3) + '"},';
    }
    data += ']';
    window.external.extractElevationsOKCallback_(data, placemarkCount);
    data = '';
}
var pmCount = 0;

function extractPointsElevations(v, t) {
    pCount = 0;
    extractPointElevation(v, t);
}

function extractPointElevation(v, t) {
    if (pageStopRunFlag == true) {
        pageStopRunFlag = false;
        return;
    }
    var range = 10;
    if (pCount == 0) {
        moveMapToPoint(Points[0].value, range, 6, null);
        data = '[';
        pCount++;
        setTimeout('extractPointElevation(' + v + ',' + window.external.getExtractEleDylaytime() + ')', t);
        return false;
    }
    data += '{n:"' + Points[0].key + '",w:"' + Points[0].value.lat().toFixed(6) + '",j:"' + Points[0].value.lng().toFixed(6) + '",a:"' + ge.getGlobe().getGroundAltitude(Points[0].value.lat(), Points[0].value.lng()).toFixed(3) + '"},';
    if (Points.length > 0) {
        Points.splice(0, 1);
    }
    window.external.extractingElevationsCallback_(data, pCount);
    data = '';
    if (Points.length > 0) {
        moveMapToPoint(Points[0].value, range, 6, null);
        pCount++;
        setTimeout('extractPointElevation(' + v + ',' + window.external.getExtractEleDylaytime() + ')', t);
        return false;
    } else {
        window.external.extractElevationsOKCallback_(']', pCount);
        pCount = 0;
    }
    data = '';
}
var DD = 0;

function extractPathVertexElevations(v, t) {
    pCount = 0;
    DD = 0;
    extractPathVertexElevation(v, t);
}

function extractPathVertexElevation(v, t) {
    if (pageStopRunFlag == true) {
        pageStopRunFlag = false;
        return;
    }
    var range = 10;
    if (pCount == 0) {
        DD = 0;
        moveMapToPoint(Points[0], range, 6, null);
        data = '[';
        pCount++;
        setTimeout('extractPathVertexElevation(' + v + ',' + window.external.getExtractEleDylaytime() + ')', t);
        return false;
    }
    data += '{w:"' + Points[0].lat().toFixed(6) + '",j:"' + Points[0].lng().toFixed(6) + '",a:"' + ge.getGlobe().getGroundAltitude(Points[0].lat(), Points[0].lng()).toFixed(3) + '",d:"' + DD.toFixed(2) + '"},';
    var length = Points.length;
    if (length > 0) {
        if (length > 1) {
            DD = DD.add(getHorizontalDistance(Points[0], Points[1]));
        }
        Points.splice(0, 1);
    }
    window.external.extractingElevationsCallback_(data, pCount);
    data = '';
    if (Points.length > 0) {
        moveMapToPoint(Points[0], range, 6, null);
        pCount++;
        setTimeout('extractPathVertexElevation(' + v + ',' + t + ')', t);
        return false;
    } else {
        DD = 0;
        window.external.extractElevationsOKCallback_(']', pCount);
        pCount = 0;
    }
    data = '';
}

function extractPathVertexElevationsQuick() {
    var data = '[';
    var placemarkCount = Points.length;
    var D = 0;
    for (var i = 0; i < placemarkCount; i++) {
        data += '{w:"' + Points[i].lat().toFixed(6) + '",j:"' + Points[i].lng().toFixed(6) + '",a:"' + ge.getGlobe().getGroundAltitude(Points[i].lat(), Points[i].lng()).toFixed(3) + '",d:"' + D.toFixed(2) + '"},';
        if (i + 1 < placemarkCount) {
            D = D.add(getHorizontalDistance(Points[i], Points[i + 1]));
        }
    }
    data += ']';
    window.external.extractElevationsOKCallback_(data, placemarkCount);
    data = '';
    D = 0;
}
var data = '';
var pCount = 0;

function extractLinesElevations(d, p, v, t, dlzx) {
    var range = 2 * d * p + 20;
    moveMapToPoint(Points[0], range, 5, null);
    data = '[';
    pCount = 0;
    if (dlzx == "1") {
        setTimeout('extractDLZXPathElevation(' + d + ',' + p + ',' + range + ',' + v + ',' + t + ');', 2000);
    } else {
        setTimeout('extractPathElevation(' + d + ',' + p + ',' + range + ',' + v + ',' + t + ');', 2000);
    }
}
var fzd = 1;
var zxz = 1;
var DLZX = [];

function extractDLZXPathElevation(d, p, range, v, t) {
    var PACount = 0;
    var HD = 0;
    var iPoint = null;
    var movePoint = null;
    var heading;
    if (extractTimes == 0) {
        pCount = 1;
        extractTimes++;
        data += returnDLZXPointJson(Points[0], 'J1', 0);
        DLZX = [Points[0].lat().toFixed(6), Points[0].lng().toFixed(6), ge.getGlobe().getGroundAltitude(Points[0].lat(), Points[0].lng()).toFixed(3), false, 'J'];
    }
    var setPointsNum = Points.length;
    for (var i = 1; i < setPointsNum; i++) {
        PACount = 0;
        HD = Points[i - 1].distance(Points[i]);
        if (parseFloat(HD) > parseFloat(d)) {
            PACount = Math.floor(parseFloat(HD).div(parseFloat(d)));
            iPoint = Points[i - 1];
            movePoint = geo.math.destination(iPoint, {
                distance: d * p,
                heading: iPoint.heading(Points[i])
            });
            for (var j = p; j <= PACount + p; j = j + p) {
                moveMapToPoint(movePoint, range, v);
                sleep(window.external.getExtractEleDylaytime());
                for (var z = p; z >= 1 && j - z < PACount; z--) {
                    iPoint = geo.math.destination(iPoint, {
                        distance: d,
                        heading: iPoint.heading(Points[i])
                    });
                    pCount++;
                    data += returnDLZXAPointJson(iPoint);
                    if (pCount % p == 0) {
                        window.external.extractingElevationsCallback_(data, pCount);
                        if (pCount % 65000 == 0) {
                            Points.splice(0, i, iPoint);
                            window.external.extractElevationsCallback_(']', pCount);
                            data = '';
                            return false;
                        }
                        data = '';
                    }
                    if (pageStopRunFlag == true) {
                        pageStopRunFlag = false;
                        return;
                    }
                }
                if (j + p > PACount) {
                    movePoint = Points[i];
                    if (j > PACount) {
                        iPoint = Points[i];
                    }
                } else {
                    movePoint = geo.math.destination(iPoint, {
                        distance: d * (p + 1),
                        heading: iPoint.heading(Points[i])
                    });
                }
            }
        }
        pCount++;
        data += returnDLZXBPointJson(Points[i], 'J' + (i + 1), 0);
        DLZX = [Points[i].lat().toFixed(6), Points[i].lng().toFixed(6), ge.getGlobe().getGroundAltitude(Points[i].lat(), Points[i].lng()).toFixed(3), false, 'J'];
        if (pCount % p == 0) {
            window.external.extractingElevationsCallback_(data, pCount);
            if (pCount % 65000 == 0) {
                Points.splice(0, i);
                window.external.extractElevationsCallback_(']', pCount);
                data = '';
                return false;
            }
            data = '';
        }
    }
    data += ']';
    window.external.extractElevationsOKCallback_(data, pCount);
    data = '';
}

function extractPathElevation(d, p, range, v, t) {
    var PACount = 0;
    var HD = 0;
    var e = 0;
    var iPoint = null;
    var movePoint = null;
    var heading = 0;
    window.external.extractingElevationsCallback_('', 0);
    var isGD = window.external.isBaohanGuaiDian() == '1' ? true : false;
    if (extractTimes == 0) {
        pCount = 1;
        extractTimes++;
        data += returnPointJson(Points[0]);
    }
    var setPointsNum = Points.length;
    for (var i = 1; i < setPointsNum; i++) {
        iPoint = Points[i - 1];
        heading = Points[i - 1].heading(Points[i]);
        HD = getHorizontalDistance(Points[i - 1], Points[i]).add(e);
        for (var j = 1; j <= HD.div(d); j++) {
            if (j == 1) {
                iPoint = getPointLocationByDHA(iPoint, d.sub(e), heading);
            } else {
                iPoint = getPointLocationByDHA(iPoint, d, heading);
            }
            pCount++;
            data += returnPointJson(iPoint);
            if (pCount % 10 == 0) {
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    Points.splice(0, i, iPoint);
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
            }
            if (pageStopRunFlag == true) {
                pageStopRunFlag = false;
                return;
            }
            if ((pCount - 2) % p == 0) {
                var HDD = 0;
                HDD = HDD.add(getHorizontalDistance(iPoint, Points[i]));
                if (HDD >= p * d) {
                    movePoint = getPointLocationByDHA(iPoint, p * d, iPoint.heading(Points[i]));
                } else {
                    HDD = (p * d).sub(HDD);
                    for (var k = i; k < 1000000000000; k++) {
                        if (k < setPointsNum - 1) {
                            var dd = getHorizontalDistance(Points[k], Points[k + 1]);
                            if (HDD <= dd) {
                                movePoint = getPointLocationByDHA(Points[k], HDD, Points[k].heading(Points[k + 1]));
                                break;
                            } else {
                                HDD = HDD.sub(dd);
                            }
                        } else {
                            movePoint = Points[setPointsNum - 1];
                            break;
                        }
                    }
                }
                heading = iPoint.heading(Points[i]);
                moveMapToPoint(movePoint, range, v, null);
                sleep(window.external.getExtractEleDylaytime());
            }
        }
        e = HD % d;
        if (isGD) {
            pCount++;
            data += returnPointJson(Points[i]);
            if (pCount % 10 == 0) {
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    Points.splice(0, i, iPoint);
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
            }
        }
    }
    data += ']';
    window.external.extractElevationsOKCallback_(data, pCount);
    data = '';
}

function extractLinesElevationsQuick(d) {
    data = '[';
    var PACount = 0;
    pCount = 0;
    var HD = 0;
    var e = 0;
    var heading = 0;
    var iPoint = null;
    window.external.extractingElevationsCallback_('', 0);
    var isGD = window.external.isBaohanGuaiDian() == '1' ? true : false;
    if (extractTimes == 0) {
        pCount = 1;
        extractTimes++;
        data += returnPointJson(Points[0]);
    }
    var setPointsNum = Points.length;
    for (var i = 1; i < setPointsNum; i++) {
        iPoint = Points[i - 1];
        heading = Points[i - 1].heading(Points[i]);
        HD = getHorizontalDistance(Points[i - 1], Points[i]).add(e);
        for (var j = 1; j <= parseInt(HD.div(d)); j++) {
            if (j == 1) {
                iPoint = getPointLocationByDHA(iPoint, parseFloat(d).sub(e), heading);
            } else {
                iPoint = getPointLocationByDHA(iPoint, d, heading);
            }
            pCount++;
            data += returnPointJson(iPoint);
            if (pCount % 1000 == 0) {
                heading = iPoint.heading(Points[i]);
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    Points.splice(0, i, iPoint);
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
            }
            if (pageStopRunFlag == true) {
                pageStopRunFlag = false;
                return;
            }
        }
        e = HD % d;
        if (isGD) {
            pCount++;
            data += returnPointJson(Points[i]);
            if (pCount % 1000 == 0) {
                heading = iPoint.heading(Points[i]);
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    Points.splice(0, i, iPoint);
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
            }
        }
    }
    window.external.extractElevationsOKCallback_(data + ']', pCount);
    data = '';
    pCount = 0;
}

function extractDLinesElevationsQuick(d, w) {
    d = parseFloat(d);
    w = parseFloat(w);
    data = '[';
    pCount = 0;
    var HD = 0;
    var vn = Math.floor(w / d);
    var hn = 0;
    var heading = 0;
    var iPoint = null;
    var vn1Point;
    var vn2Point;
    window.external.extractingElevationsCallback_('', 0);
    if (extractTimes == 0) {
        extractTimes++;
    }
    var setPointsNum = Points.length;
    for (var i = 0; i < setPointsNum - 1; i++) {
        if (i == 0) {
            heading = Points[0].heading(Points[1]);
            HD = getHorizontalDistance(Points[0], Points[1]);
            hn = Math.floor(HD / d);
        } else {
            heading = Points[i].heading(Points[i + 1]);
            HD = getHorizontalDistance(Points[i], Points[i + 1]);
            hn = Math.floor(HD / d);
        }
        for (var j = 0; j <= hn + 1; j++) {
            if (j == 0) {
                if (i == 0) {
                    iPoint = Points[0];
                } else {
                    continue;
                }
            } else if (j == hn + 1) {
                iPoint = Points[i + 1];
                if (i < setPointsNum - 2) {
                    heading = Points[i + 1].heading(Points[i + 2]);
                }
            } else {
                iPoint = getPointLocationByDHA(iPoint, d, heading);
            }
            data += returnPointJson(iPoint);
            pCount++;
            if (pCount % 1000 == 0) {
                heading = iPoint.heading(Points[i + 1]);
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    Points.splice(0, i, iPoint);
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
                if (pageStopRunFlag == true) {
                    pageStopRunFlag = false;
                    return;
                }
            }
            for (var g = 1; g <= vn; g++) {
                var vn1Point = getPointLocationByDHA(iPoint, d * g, heading + 90);
                data += returnPointJson(vn1Point);
                pCount++;
                if (pCount % 1000 == 0) {
                    window.external.extractingElevationsCallback_(data, pCount);
                    if (pCount % 65000 == 0) {
                        Points.splice(0, i, iPoint);
                        window.external.extractElevationsCallback_(']', pCount);
                        data = '';
                        return false;
                    }
                    data = '';
                    if (pageStopRunFlag == true) {
                        pageStopRunFlag = false;
                        return;
                    }
                }
                var vn2Point = getPointLocationByDHA(iPoint, d * g, heading - 90);
                data += returnPointJson(vn2Point);
                pCount++;
                if (pCount % 1000 == 0) {
                    window.external.extractingElevationsCallback_(data, pCount);
                    if (pCount % 65000 == 0) {
                        Points.splice(0, i, iPoint);
                        window.external.extractElevationsCallback_(']', pCount);
                        data = '';
                        return false;
                    }
                    data = '';
                    if (pageStopRunFlag == true) {
                        pageStopRunFlag = false;
                        return;
                    }
                }
            }
        }
    }
    window.external.extractElevationsOKCallback_(data + ']', pCount);
    data = '';
    pCount = 0;
}

function extractDLinesElevations(d, p, v, t, w) {
    var range = 2 * d * p + 20;
    moveMapToPoint(Points[0], range, 5, null);
    pCount = 0;
    setTimeout('extractDPathElevation(' + d + ',' + p + ',' + range + ',' + v + ',' + t + ',' + w + ');', 2000);
}

function extractDPathElevation(d, p, range, v, t, w) {
    data = '[';
    pCount = 0;
    var HD = 0;
    var vn = Math.floor(w / d);
    var hn = 0;
    var heading = 0;
    var iPoint = null;
    var vn1Point;
    var vn2Point;
    var movePoint;
    window.external.extractingElevationsCallback_('', 0);
    if (extractTimes == 0) {
        extractTimes++;
    }
    var setPointsNum = Points.length;
    for (var i = 0; i < setPointsNum - 1; i++) {
        if (i == 0) {
            heading = Points[0].heading(Points[1]);
            HD = getHorizontalDistance(Points[0], Points[1]);
            hn = Math.floor(HD / d);
        } else {
            heading = Points[i].heading(Points[i + 1]);
            HD = getHorizontalDistance(Points[i], Points[i + 1]);
            hn = Math.floor(HD / d);
        }
        for (var j = 0; j <= hn + 1; j++) {
            if (j == 0) {
                if (i == 0) {
                    iPoint = Points[0];
                } else {
                    continue;
                }
            } else if (j == hn + 1) {
                iPoint = Points[i + 1];
                if (i < setPointsNum - 2) {
                    heading = Points[i + 1].heading(Points[i + 2]);
                }
            } else {
                iPoint = getPointLocationByDHA(iPoint, d, heading);
            }
            if (j % p == 0) {
                movePoint = geo.math.destination(iPoint, {
                    distance: d * p,
                    heading: heading
                });
                moveMapToPoint(movePoint, range, v, null);
                sleep(window.external.getExtractEleDylaytime());
            }
            data += returnPointJson(iPoint);
            pCount++;
            if (pCount % 20 == 0) {
                heading = iPoint.heading(Points[i + 1]);
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    Points.splice(0, i, iPoint);
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
                if (pageStopRunFlag == true) {
                    pageStopRunFlag = false;
                    return;
                }
            }
            for (var g = 1; g <= vn; g++) {
                var vn1Point = getPointLocationByDHA(iPoint, d * g, heading + 90);
                data += returnPointJson(vn1Point);
                pCount++;
                if (pCount % 20 == 0) {
                    window.external.extractingElevationsCallback_(data, pCount);
                    if (pCount % 65000 == 0) {
                        Points.splice(0, i, iPoint);
                        window.external.extractElevationsCallback_(']', pCount);
                        data = '';
                        return false;
                    }
                    data = '';
                    if (pageStopRunFlag == true) {
                        pageStopRunFlag = false;
                        return;
                    }
                }
                var vn2Point = getPointLocationByDHA(iPoint, d * g, heading - 90);
                data += returnPointJson(vn2Point);
                pCount++;
                if (pCount % 20 == 0) {
                    window.external.extractingElevationsCallback_(data, pCount);
                    if (pCount % 65000 == 0) {
                        Points.splice(0, i, iPoint);
                        window.external.extractElevationsCallback_(']', pCount);
                        data = '';
                        return false;
                    }
                    data = '';
                    if (pageStopRunFlag == true) {
                        pageStopRunFlag = false;
                        return;
                    }
                }
            }
        }
    }
    window.external.extractElevationsOKCallback_(data + ']', pCount);
    data = '';
}
var hheading;
var vheading;
var pbounds;
var ppaths;

function extractPolyElevations(d, p, v, t) {
    var range = 2 * d * p + 200;
    if (extractTimes == 0) {
        hheading = polyParams[0].heading(aPoints[1]);
        vheading = polyParams[0].heading(aPoints[3]);
        getRectanglePoints(pPoints[0], d, p);
        pPoints[4] = 0;
        pPoints[5] = 0;
    }
    moveMapToPoint(getPointLocationByDHA(pPoints[1], d * (p - 1), vheading), range, 5, null);
    setTimeout('extractPolyElevation(' + d + ',' + p + ',' + range + ',' + v + ',' + t + ');', 2000);
}
var qpoint = null;
var hpoint = null;
var qqpoint = null;
var xNum = 0;
var yNum = 0;

function extractPolyElevation(d, p, range, v, t) {
    var aNum = polyParams[2];
    var bNum = polyParams[3];
    pCount = 0;
    var xpoint = null;
    var ypoint = null;
    var mpoint = null;
    var point = null;
    var data = '[';
    window.external.extractingElevationsCallback_('', 0);
    for (var i = yNum; i < bNum; i = i + 2 * p - 1) {
        for (var j = xNum; j < aNum; j = j + p) {
            if (j == 0) {
                qpoint = pPoints[3];
            }
            ypoint = pPoints[0];
            for (var y = pPoints[4]; y <= 2 * (p - 1); y++) {
                if (i + y + 2 > bNum) {
                    break;
                }
                xpoint = getPointLocationByDHA(ypoint, d * y, vheading);
                for (var x = pPoints[5]; x < p; x++) {
                    if (j + x + 2 > aNum) {
                        break;
                    }
                    point = getPointLocationByDHA(xpoint, d * x, hheading);
                    var coordinate = getPointByLatLng(point.lat(), point.lng());
                    if (!isContainsLatLng(pbounds, ppaths, coordinate)) {
                        continue;
                    }
                    pCount++;
                    data += returnPointJson(point);
                    if (pCount % 100 == 0) {
                        window.external.extractingElevationsCallback_(data, pCount);
                        if (pCount % 65000 == 0) {
                            yNum = i;
                            xNum = j;
                            pPoints[4] = y;
                            pPoints[5] = x + 1;
                            extractTimes++;
                            window.external.extractElevationsCallback_(']', pCount);
                            data = '';
                            return false;
                        }
                        data = '';
                    }
                    if (pageStopRunFlag == true) {
                        pageStopRunFlag = false;
                        return;
                    }
                }
                pPoints[5] = 0;
            }
            pPoints[4] = 0;
            xNum = 0;
            getRectanglePoints(pPoints[1], d, p);
            mpoint = getPointLocationByDHA(pPoints[1], d * (p - 1), vheading);
            moveMapToPoint(mpoint, range, 5, null);
            if (pCount == 0 || pCount % 100 != 0) {
                window.external.extractingElevationsCallback_('', pCount);
            }
            sleep(window.external.getExtractEleDylaytime());
        }
        getRectanglePoints(getPointLocationByDHA(qpoint, d, vheading), d, p);
        mpoint = getPointLocationByDHA(pPoints[1], d * (p - 1), vheading);
        moveMapToPoint(mpoint, range, 5, null);
        sleep(window.external.getExtractEleDylaytime());
    }
    yNum = 0;
    moveMapToPoint(polyParams[0], d * aNum, 5, null);
    window.external.extractElevationsOKCallback_(data + ']', pCount);
    data = '';
}

function extractPolyElevationsQuick(d) {
    var pCount = 0;
    var pjCount;
    var data = '[';
    var jPoint = null;
    var iPoint = null;
    var aNum = polyParams[2];
    var bNum = polyParams[3];
    iPoint = polyParams[0];
    window.external.extractingElevationsCallback_('', 0);
    for (var i = 1; i < bNum; i++) {
        for (var j = 1; j < aNum; j++) {
            if (j == 1) {
                if (extractTimes == 0) {
                    jPoint = iPoint;
                } else {
                    jPoint = polyParams[1];
                    extractTimes = 0;
                }
            } else {
                jPoint = getPointLocationByDHA(jPoint, d, jPoint.heading(aPoints[1]));
            }
            var coordinate = getPointByLatLng(jPoint.lat(), jPoint.lng());
            if (!isContainsLatLng(pbounds, ppaths, coordinate)) {
                continue;
            }
            pCount++;
            data += returnPointJson(jPoint);
            if (pCount % 1000 == 0) {
                window.external.extractingElevationsCallback_(data, pCount);
                if (pCount % 65000 == 0) {
                    polyParams[0] = iPoint;
                    if (j == aNum) {
                        polyParams[1] = getPointLocationByDHA(iPoint, d, iPoint.heading(aPoints[3]));
                    } else {
                        polyParams[1] = getPointLocationByDHA(jPoint, d, jPoint.heading(aPoints[1]));
                    }
                    polyParams[3] = bNum - i + 1;
                    polyParams[2] = aNum - j;
                    extractTimes++;
                    window.external.extractElevationsCallback_(']', pCount);
                    data = '';
                    return false;
                }
                data = '';
            }
            if (pageStopRunFlag == true) {
                pageStopRunFlag = false;
                return;
            }
        }
        aNum = polyParams[4];
        iPoint = getPointLocationByDHA(iPoint, d, iPoint.heading(aPoints[3]));
        aPoints[1] = getPointLocationByDHA(aPoints[1], d, aPoints[1].heading(aPoints[2]));
    }
    window.external.extractElevationsOKCallback_(data + ']', pCount);
    data = '';
}

function getCorrectCoordsParams(opLng, opLat, tpLng, tpLat) {
    var oPoint = new geo.Point(opLat, opLng);
    var tPoint = new geo.Point(tpLat, tpLng);
    var heading = oPoint.heading(tPoint);
    var d = getHorizontalDistance(oPoint, tPoint);
    return d + ',' + heading;
}

function correctFigCoords_e(d, h, flag) {
    gex.dom.walk({
        rootObject: ge,
        visitCallback: function () {
            if ('getType' in this && this.getType() == 'KmlPlacemark') {
                correctCoords(this, d, h, flag);
            }
        }
    });
}

function correctCoords(obj, d, heading, flag) {
    var destPoint = null;
    var paths = [];
    switch (obj.getGeometry().getType()) {
    case 'KmlPoint':
        if (flag == 0) {
            if (obj.getName() == '源點' || obj.getName() == '目標點') {
                return;
            }
            destPoint = getPointLocationByDHA(new geo.Point(obj.getGeometry()), d, heading);
        } else if (flag == 1) {
            var p = window.external.M2W(obj.getGeometry().getLatitude() + ',' + obj.getGeometry().getLongitude());
            var ps = p.split(',');
            destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
        } else {
            var p = window.external.W2M(obj.getGeometry().getLatitude() + ',' + obj.getGeometry().getLongitude());
            var ps = p.split(',');
            destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
        }
        obj.getGeometry().setLatitude(destPoint.lat());
        obj.getGeometry().setLongitude(destPoint.lng());
        break;
    case 'KmlLineString':
        var coords = obj.getGeometry().getCoordinates();
        var length = coords.getLength();
        if (flag == 0) {
            for (var i = 0; i < length; i++) {
                paths.push(getPointLocationByDHA(new geo.Point(coords.get(i)), d, heading));
            }
        } else {
            var sl = '';
            for (var i = 0; i < length; i++) {
                sl += i > 0 ? ';' : '';
                sl += coords.get(i).getLatitude() + ',' + coords.get(i).getLongitude();
            }
            if (flag == 1) {
                var pl = window.external.M2W(sl);
            } else {
                var pl = window.external.W2M(sl);
            }
            sl = '';
            var pls = pl.split(';');
            pl = '';
            for (var i = 0; i < length; i++) {
                var cl = pls[i].split(',');
                paths.push(new geo.Point(parseFloat(cl[0]), parseFloat(cl[1])));
            }
        }
        coords.clear();
        for (var i = 0; i < length; i++) {
            coords.pushLatLngAlt(paths[i].lat(), paths[i].lng(), 0);
        }
        paths = [];
        break;
    case 'KmlPolygon':
        var coords = obj.getGeometry().getOuterBoundary().getCoordinates();
        var length = coords.getLength();
        if (flag == 0) {
            for (var i = 0; i < length; i++) {
                paths.push(getPointLocationByDHA(new geo.Point(coords.get(i)), d, heading));
            }
        } else {
            var sl = '';
            for (var i = 0; i < length; i++) {
                sl += i > 0 ? ';' : '';
                sl += coords.get(i).getLatitude() + ',' + coords.get(i).getLongitude();
            }
            if (flag == 1) {
                var pl = window.external.M2W(sl);
            } else {
                var pl = window.external.W2M(sl);
            }
            sl = '';
            var pls = pl.split(';');
            pl = '';
            for (var i = 0; i < length; i++) {
                var cl = pls[i].split(',');
                paths.push(new geo.Point(parseFloat(cl[0]), parseFloat(cl[1])));
            }
        }
        coords.clear();
        for (var i = 0; i < length; i++) {
            coords.pushLatLngAlt(paths[i].lat(), paths[i].lng(), 0);
        }
        paths = [];
        break;
    case 'KmlMultiGeometry':
        var geoms = obj.getGeometry().getGeometries();
        for (var j = 0; j < geoms.getChildNodes().getLength(); j++) {
            if (geoms.getChildNodes().item(j).getType() == 'KmlLineString') {
                var coords = geoms.getChildNodes().item(j).getCoordinates();
                var length = coords.getLength();
                paths = [];
                if (flag == 0) {
                    for (var i = 0; i < length; i++) {
                        paths.push(getPointLocationByDHA(new geo.Point(coords.get(i)), d, heading));
                    }
                } else {
                    var sl = '';
                    for (var i = 0; i < length; i++) {
                        sl += i > 0 ? ';' : '';
                        sl += coords.get(i).getLatitude() + ',' + coords.get(i).getLongitude();
                    }
                    if (flag == 1) {
                        var pl = window.external.M2W(sl);
                    } else {
                        var pl = window.external.W2M(sl);
                    }
                    sl = '';
                    var pls = pl.split(';');
                    pl = '';
                    for (var i = 0; i < length; i++) {
                        var cl = pls[i].split(',');
                        paths.push(new geo.Point(parseFloat(cl[0]), parseFloat(cl[1])));
                    }
                }
                coords.clear();
                for (var i = 0; i < length; i++) {
                    coords.pushLatLngAlt(paths[i].lat(), paths[i].lng(), 0);
                }
            } else if (geoms.getChildNodes().item(j).getType() == 'KmlPoint') {
                if (flag == 0) {
                    destPoint = getPointLocationByDHA(new geo.Point(geoms.getChildNodes().item(j).getLatitude(), geoms.getChildNodes().item(j).getLongitude()), d, heading);
                } else if (flag == 1) {
                    var p = window.external.M2W(geoms.getChildNodes().item(j).getLatitude() + ',' + geoms.getChildNodes().item(j).getLongitude());
                    var ps = p.split(',');
                    destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                } else {
                    var p = window.external.W2M(geoms.getChildNodes().item(j).getLatitude() + ',' + geoms.getChildNodes().item(j).getLongitude());
                    var ps = p.split(',');
                    destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                }
                geoms.getChildNodes().item(j).setLatitude(destPoint.lat());
                geoms.getChildNodes().item(j).setLongitude(destPoint.lng());
            }
        }
        paths = [];
        break;
    default:
    }
}

function correctKmlCoords(d, heading, kmlString, flag) {
    var destPoint = null;
    try {
        var xmlDoc2 = new ActiveXObject('Microsoft.XMLDOM');
        xmlDoc2.async = 'false';
        xmlDoc2.loadXML(kmlString);
        var DocRoot = xmlDoc2.documentElement;
        var pmArray = DocRoot.selectNodes('//coordinates');
        var pmCount = pmArray.length;
        var alts = [];
        for (var i = 0; i < pmCount; i++) {
            var coords = pmArray[i].text.Trim().replace(/\n/g, ' ').replace(/\s+/g, ' ').split(' ');
            var coordCount = coords.length;
            var coordStr = '';
            if (flag == 0) {
                for (var j = 0; j < coordCount; j++) {
                    var coord = coords[j].split(',');
                    destPoint = getPointLocationByDHA(new geo.Point(parseFloat(coord[1]), parseFloat(coord[0]), parseFloat(coord[2])), d, heading);
                    coordStr += destPoint.lng() + ',' + destPoint.lat() + ',' + destPoint.altitude() + ' ';
                }
            } else {
                var s = '';
                for (var j = 0; j < coordCount; j++) {
                    var coord = coords[j].split(',');
                    s += j > 0 ? ';' : '';
                    s += coord[1] + ',' + coord[0];
                    alts[j] = coord[2];
                }
                var p = window.external.M2W(s);
                s = '';
                var ps = p.split(';');
                p = '';
                for (var j = 0; j < coordCount; j++) {
                    var cl = ps[j].split(',');
                    coordStr += cl[1] + ',' + cl[0] + ',' + alts[j] + ' ';
                }
                alts = [];
            }
            pmArray[i].text = coordStr;
        }
    } catch (err) {
        alert('解析KMl文件錯誤,請檢測文件格式!');
    }
    var kml = '<?xml version="1.0" encoding="UTF-8"?>\r\n' + DocRoot.xml;
    DocRoot = null;
    xmlDoc2 = null;
    return formatKmlForHtml(kml);;
}
var polygonBoundery = null;
var polygonContourObj = null;

function getObjectBounds(obj) {
    var polygonCoords = [];
    polygonBoundery = null;
    polygonContourObj = null;
    if (obj.getGeometry().getType() == 'KmlPolygon') {
        var coords = obj.getGeometry().getOuterBoundary().getCoordinates();
        var length = coords.getLength();
        var lats = [];
        var lngs = [];
        var boundery = (length + 1) + ',' + 0;
        for (var i = 0; i < length; i++) {
            lats.push(coords.get(i).getLatitude());
            lngs.push(coords.get(i).getLongitude());
            boundery += '\r\n' + coords.get(i).getLongitude().toFixed(8) + ' ' + coords.get(i).getLatitude().toFixed(8);
            polygonCoords.push(getPointByLatLng(coords.get(i).getLatitude(), coords.get(i).getLongitude()));
        }
        boundery += '\r\n' + coords.get(0).getLongitude().toFixed(8) + ' ' + coords.get(0).getLatitude().toFixed(8);
        var latsMax = lats.max();
        var latsMin = lats.min();
        var lngsMax = lngs.max();
        var lngsMin = lngs.min();
        bakupPoints = [createGeoPointByLatLngAlt(latsMax, lngsMin, 0), createGeoPointByLatLngAlt(latsMax, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMin, 0)];
        if (length > 2) {
            window.external.getContourRegionCallback_(boundery);
            polygonBoundery = addPolygonOnMap(polygonCoords);
            polygonContourObj = obj;
        }
    } else if (obj.getGeometry().getType() == 'KmlMultiGeometry') {
        var geoms = obj.getGeometry().getGeometries();
        for (var j = 0; j < geoms.getChildNodes().getLength(); j++) {
            if (geoms.getChildNodes().item(j).getType() == 'KmlPolygon') {
                var coords = geoms.getChildNodes().item(j).getOuterBoundary().getCoordinates();
                var length = coords.getLength();
                var lats = [];
                var lngs = [];
                var boundery = (length + 1) + ',' + 0;
                for (var i = 0; i < length; i++) {
                    lats.push(coords.get(i).getLatitude());
                    lngs.push(coords.get(i).getLongitude());
                    boundery += '\r\n' + coords.get(i).getLongitude().toFixed(8) + ' ' + coords.get(i).getLatitude().toFixed(8);
                    polygonCoords.push(getPointByLatLng(coords.get(i).getLatitude(), coords.get(i).getLongitude()));
                }
                boundery += '\r\n' + coords.get(0).getLongitude().toFixed(8) + ' ' + coords.get(0).getLatitude().toFixed(8);
                var latsMax = lats.max();
                var latsMin = lats.min();
                var lngsMax = lngs.max();
                var lngsMin = lngs.min();
                bakupPoints = [createGeoPointByLatLngAlt(latsMax, lngsMin, 0), createGeoPointByLatLngAlt(latsMax, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMax, 0), createGeoPointByLatLngAlt(latsMin, lngsMin, 0)];
                if (length > 2) {
                    window.external.getContourRegionCallback_(boundery);
                    polygonBoundery = addPolygonOnMap(polygonCoords);
                    polygonContourObj = obj;
                }
            }
        }
    } else {
        window.external.identifyRegionFailed();
    }
}

function addPolygonOnMap(coords) {
    return new google.maps.Polygon({
        title: '',
        paths: coords,
        strokeColor: "#FF0000",
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: "#FF0000",
        fillOpacity: 0.05
    });
}
var cps = [];

function extractControlPoints(d) {
    if (cps.length > 0) {
        var v = 6;
        var t = 3000;
        pCount = 0;
        data = '';
        moveMapToPoint(cps[0].value, 10, 6, null);
        setTimeout('extractControlPoint(' + v + ',' + t + ')', 2000);
    } else {
        extractPolyElevationsForContour(d);
    }
}

function extractControlPoint(v, t) {
    var range = 10;
    var p = cps.shift();
    pCount++;
    data += p.key + ',' + p.value.lng().toFixed(6) + ',' + p.value.lat().toFixed(6) + ',' + ge.getGlobe().getGroundAltitude(p.value.lat(), p.value.lng()).toFixed(3) + '\r\n';
    if (cps.length > 0) {
        moveMapToPoint(cps[0].value, range, 6, null);
        setTimeout('extractControlPoint(' + v + ',' + t + ')', t);
    } else {
        window.external.extractControlPointsOKCallBack_(data, pCount);
        data = '';
        pCount = 0;
    }
}

function getControlPointsCount() {
    cps = [];
    var length = cPoints.length;
    var p = null;
    var n = 0;
    for (var i = 0; i < length; i++) {
        p = getObjectById(cPoints[i]);
        if (p != null) {
            cps.push({
                key: p.getName(),
                value: new geo.Point(p.getGeometry().getLatitude(), p.getGeometry().getLongitude())
            });
            n++;
        }
    }
    return n;
}

function extractPolyElevationsForContour(d) {
    d = parseFloat(d);
    calPolyPointsNum(d);
    if (window.external.stopProduce(calPolyPointsNumForContour()) == '0') {
        return;
    }
    var p = 20;
    var v = 6;
    var t = 5;
    var range = 2 * d * p + 200;
    if (extractTimes == 0) {
        hheading = polyParams[0].heading(Points[1]);
        vheading = polyParams[0].heading(Points[3]);
        getRectanglePoints(pPoints[0], d, p);
        pPoints[4] = 0;
        pPoints[5] = 0;
    }
    moveMapToPoint(getPointLocationByDHA(pPoints[1], d * (p - 1), vheading), range, 5, null);
    setTimeout('extractPolyElevationForContour(' + d + ',' + p + ',' + range + ',' + v + ',' + t + ');', 2000);
}

function extractPolyElevationForContour(d, p, range, v, t) {
    var aNum = polyParams[2];
    var bNum = polyParams[3];
    pCount = 0;
    var xpoint = null;
    var ypoint = null;
    var mpoint = null;
    var point = null;
    var data = '';
    var xyh = '';
    var alts = [];
    for (var i = yNum; i < bNum; i = i + 2 * p - 1) {
        for (var j = xNum; j < aNum; j = j + p) {
            if (j == 0) {
                qpoint = pPoints[3];
            }
            ypoint = pPoints[0];
            for (var y = pPoints[4]; y <= 2 * (p - 1); y++) {
                if (i + y + 1 > bNum) {
                    break;
                }
                xpoint = getPointLocationByDHA(ypoint, d * y, vheading);
                for (var x = pPoints[5]; x < p; x++) {
                    if (j + x + 1 > aNum) {
                        break;
                    }
                    point = getPointLocationByDHA(xpoint, d * x, hheading);
                    var coordinate = getPointByLatLng(point.lat(), point.lng());
                    if (!isContainsLatLng(pbounds, ppaths, coordinate)) {
                        continue;
                    }
                    pCount++;
                    var altitude = ge.getGlobe().getGroundAltitude(point.lat(), point.lng()).toFixed(3);
                    alts.push(altitude);
                    data += point.lng().toFixed(6) + ' ' + point.lat().toFixed(6) + ' ' + altitude + '\r\n';
                    if (pCount % 100 == 0) {
                        window.external.waiteTime(1);
                        window.external.returnContourPoints(data, '');
                        data = '';
                    }
                }
                pPoints[5] = 0;
            }
            pPoints[4] = 0;
            xNum = 0;
            getRectanglePoints(pPoints[1], d, p);
            mpoint = getPointLocationByDHA(pPoints[1], d * (p - 1), vheading);
            moveMapToPoint(mpoint, range, 5, null);
            if (pCount == 0 || pCount % 100 != 0) {
                window.external.waiteTime(1);
            }
            sleep(t);
        }
        var altMin = alts.min();
        var altMax = alts.max();
        alts = [];
        alts.push(altMin);
        alts.push(altMax);
        getRectanglePoints(getPointLocationByDHA(qpoint, d, vheading), d, p);
        mpoint = getPointLocationByDHA(pPoints[1], d * (p - 1), vheading);
        moveMapToPoint(mpoint, range, 5, null);
        if (pCount == 0 || pCount % 100 != 0) {
            window.external.waiteTime(1);
        }
        sleep(t);
    }
    yNum = 0;
    moveMapToPoint(polyParams[0], d * aNum, 5, null);
    window.external.getContourElevationOkCallback_(Points[0].lng().toFixed(6) + ',' + Points[2].lng().toFixed(6) + ',' + Points[2].lat().toFixed(6) + ',' + Points[0].lat().toFixed(6), Math.floor(alts.min() / 10) * 10 + ',' + Math.ceil(alts.max()), data, xyh);
    data = '';
    alts = [];
}

function calPolyPointsNumForContour() {
    var area = polyParams[5];
    var totalPointsCount = polyParams[6];
    var polygonArea = computeAreaAndC(polygonContourObj);
    return parseInt(polygonArea[1] / area * totalPointsCount);
}

function appendContourKml(contourKml) {
    importKmlFile_e(contourKml);
}
var profileLineObj = null;
var profilePaths = [];

function getPathIdentify(obj) {
    profileLineObj = null;
    profilePaths = [];
    var flag = '失敗';
    switch (obj.getGeometry().getType()) {
    case 'KmlLineString':
        var coords = obj.getGeometry().getCoordinates();
        var length = coords.getLength();
        for (var i = 0; i < length; i++) {
            profilePaths.push(new geo.Point(coords.get(i)));
        }
        flag = '成功';
        profileLineObj = obj;
        break;
    case 'KmlMultiGeometry':
        var geoms = obj.getGeometry().getGeometries();
        for (var j = 0; j < geoms.getChildNodes().getLength(); j++) {
            if (geoms.getChildNodes().item(j).getType() == 'KmlLineString') {
                var coords = geoms.getChildNodes().item(j).getCoordinates();
                var length = coords.getLength();
                for (var i = 0; i < length; i++) {
                    profilePaths.push(new geo.Point(coords.get(i)));
                }
            }
        }
        flag = '成功';
        profileLineObj = obj;
        break;
    default:
    }
    window.external.getPathObjectCallBack_(flag);
}

function extractPointsElevationsForProfile(d, p, range, v, t) {
    var PACount = 0;
    var DD = 0;
    var D = 0;
    var dh = 0;
    var HD = 0;
    var alt = 0;
    var e = 0;
    data = '[';
    var iPoint = null;
    var movePoint = null;
    var heading = 0;
    if (extractTimes == 0) {
        pCount = 1;
        extractTimes++;
        alt = ge.getGlobe().getGroundAltitude(profilePaths[0].lat(), profilePaths[0].lng()).toFixed(3);
        data += returnProfileJson(0, alt);
    }
    var setPointsNum = profilePaths.length;
    for (var i = 1; i < setPointsNum; i++) {
        iPoint = profilePaths[i - 1];
        heading = profilePaths[i - 1].heading(profilePaths[i]);
        dh = getHorizontalDistance(profilePaths[i - 1], profilePaths[i]);
        HD = dh.add(e);
        DD = DD.add(dh);
        for (var j = 1; j <= HD.div(d); j++) {
            if (j == 1) {
                iPoint = getPointLocationByDHA(iPoint, d.sub(e), heading);
            } else {
                iPoint = getPointLocationByDHA(iPoint, d, heading);
            }
            pCount++;
            D = D.add(d);
            alt = ge.getGlobe().getGroundAltitude(iPoint.lat(), iPoint.lng()).toFixed(3);
            data += returnProfileJson(D, alt);
            if (pCount % p == 0) {
                window.external.waiteTime(50);
            }
            if ((pCount - 2) % p == 0) {
                var HDD = 0;
                HDD = HDD.add(getHorizontalDistance(iPoint, profilePaths[i]));
                if (HDD >= p * d) {
                    movePoint = getPointLocationByDHA(iPoint, p * d, iPoint.heading(profilePaths[i]));
                } else {
                    HDD = (p * d).sub(HDD);
                    for (var k = i; k < 100000000000; k++) {
                        if (k < setPointsNum - 1) {
                            var dd = getHorizontalDistance(profilePaths[k], profilePaths[k + 1]);
                            if (HDD <= dd) {
                                movePoint = getPointLocationByDHA(profilePaths[k], HDD, profilePaths[k].heading(profilePaths[k + 1]));
                                break;
                            } else {
                                HDD = HDD.sub(dd);
                            }
                        } else {
                            movePoint = profilePaths[setPointsNum - 1];
                            break;
                        }
                    }
                }
                heading = iPoint.heading(profilePaths[i]);
                moveMapToPoint(movePoint, range, v, null);
                sleep(t);
            }
        }
        e = HD % d;
        pCount++;
        alt = ge.getGlobe().getGroundAltitude(profilePaths[i].lat(), profilePaths[i].lng()).toFixed(3);
        data += returnProfileJson(D.add(getHorizontalDistance(iPoint, profilePaths[i])), alt);
    }
    data += returnProfileJson(DD, alt);
    window.external.getProfileElevationOkCallback_(data + ']', d.toFixed(2));
    data = '';
}

function extractPathElevationsForProfile(d) {
    if (profileLineObj == null) {
        alert('請設置剖面路徑!');
        return;
    }
    d = parseFloat(d);
    var p = 20;
    var v = 6;
    var t = 500;
    var range = 2 * d * p + 20;
    moveMapToPoint(profilePaths[0], range, 5, null);
    pCount = 0;
    setTimeout('extractPointsElevationsForProfile(' + d + ',' + p + ',' + range + ',' + v + ',' + t + ');', 2000);
}

function returnProfileJson(d, alt) {
    return '{d:"' + d + '",alt:"' + alt + '"},';
}
var profilePMObj = null;

function showProfilePlacemark(d, alt) {
    if (d < 0) {
        return;
    }
    var point = getPointByDistanceFromPath(d);
    if (point != null) {
        var name = '距離:' + (d / 1000).toFixed(2) + '公里\r\n海拔:' + alt + '米。';
        if (profilePMObj == null) {
            profilePMObj = drawPoint1(getUniqueId(), point, name, '');
        } else {
            profilePMObj.getGeometry().setLatitude(point.lat());
            profilePMObj.getGeometry().setLongitude(point.lng());
            profilePMObj.setName(name);
        }
    }
}

function getPointByDistanceFromPath(D) {
    var d = 0;
    var point = null;
    var pointsNum = profilePaths.length;
    for (var i = 0; i < pointsNum - 1; i++) {
        d = getHorizontalDistance(profilePaths[i], profilePaths[i + 1]);
        D = parseFloat(D).sub(d);
        if (D <= 0) {
            point = getPointLocationByDHA(profilePaths[i], d.add(D), profilePaths[i].heading(profilePaths[i + 1]));
            break;
        }
    }
    return point;
}

function disposeProfilePoints() {
    profilePaths = [];
    profilePMObj = null;
    profileLineObj = null;
}

function getPolygonBounderyString() {
    if (polygonBoundery == null) {
        return '';
    }
    var path = polygonBoundery.getPath();
    var length = path.length;
    var pathStr = '';
    for (var i = 0; i < length; i++) {
        if (i > 0) {
            pathStr += ';';
        }
        var pathi = path.getAt(i);
        pathStr += pathi.lat() + ',' + pathi.lng();
        if (i == length - 1) {
            pathStr += ';' + path.getAt(0).lat() + ',' + path.getAt(0).lng();
        }
    }
    return pathStr;
}

function setRandomPoints(n) {
    var pbounds = polygonBoundery.getBounds();
    var ppaths = polygonBoundery.getPaths();
    var minLat = pbounds.getSouthWest().lat();
    var maxLat = pbounds.getNorthEast().lat();
    var minLng = pbounds.getSouthWest().lng();
    var maxLng = pbounds.getNorthEast().lng();
    var diffLat = maxLat - minLat;
    var diffLng = maxLng - minLng;
    for (var i = 0; i < n; i++) {
        var lat = Math.random() * diffLat + minLat;
        var lng = Math.random() * diffLng + minLng;
        if (!isContainsLatLng(pbounds, ppaths, getPointByLatLng(lat, lng))) {
            i--;
            continue;
        } else {
            drawPoint(getUniqueId(), [lat, lng, 0], '點_' + i, '經度:' + lng + ',緯度:' + lat);
        }
    }
}
var ciPolygon = null;
var ciPoints = [];

function addRectangleOnEarth(latMin, latMax, lngMin, lngMax) {
    ciPoints[0] = new geo.Point(latMax, lngMin);
    ciPoints[1] = new geo.Point(latMax, lngMax);
    ciPoints[2] = new geo.Point(latMin, lngMax);
    ciPoints[3] = new geo.Point(latMin, lngMin);
    try {
        removeObject(ciPolygon);
    } catch (error) {}
    ciPolygon = null;
    ciPolygon = gex.dom.addPolygonPlacemark(ciPoints, {
        id: getUniqueId(),
        name: '影像下載',
        description: '影像下載範圍',
        style: {
            poly: {
                color: 'White',
                opacity: 0,
                fill: false,
                outline: true
            },
            line: pathStyle
        }
    });
}
var tcPoints = [];
var w = h = 256;
var xn = yn = 0;

function cutEarthTiles(width, height) {
    var centerX = width / 2;
    var centerY = height / 2;
    var centerPoint1 = gethitTestResult(centerX, centerY);
    moveToPoint(centerPoint1, '');
    tcPoints[0] = centerPoint1;
    xn = yn = 0;
}
var mn = 0

function moveXTileWindow(width, height) {
    var centerX = width / 2;
    var centerY = height / 2;
    var centerPoint = new geo.Point(gethitTestResult(centerX, centerY).lat(), gethitTestResult(centerX + w / 2, centerY).lng());
    moveToPoint(centerPoint, '');
    if (mn == 0) {
        mn++;
        moveXTileWindow(width, height);
    } else {
        mn = 0;
        setTimeout('getScreenMap(' + xn + ',' + yn + ')', 100);
        xn++;
    }
}

function moveYTileWindow(width, height) {
    moveToPoint(tcPoints[0], '');
    var centerX = width / 2;
    var centerY = height / 2;
    var centerPoint = new geo.Point(gethitTestResult(centerX, centerY + h / 2).lat(), gethitTestResult(centerX, centerY).lng());
    moveToPoint(centerPoint, '');
    tcPoints[0] = centerPoint;
    if (mn == 0) {
        mn++;
        moveYTileWindow(width, height);
    } else {
        mn = 0;
        xn = 0;
        yn++;
        setTimeout('getScreenMap(' + xn + ',' + yn + ')', 100);
    }
}

function getScreenCenter() {
    var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
    var lat = lookAt.getLatitude();
    var lng = lookAt.getLongitude();
    return new geo.Point(lat, lng);
}

function moveToPoint(point, alt) {
    var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
    camera.setLatitude(point.lat());
    camera.setLongitude(point.lng());
    camera.setTilt(0);
    camera.setRoll(0);
    camera.setHeading(0);
    if (alt != '' && alt > 0) {
        camera.setAltitude(alt);
    }
    ge.getView().setAbstractView(camera);
}

function gethitTestResult(x, y) {
    var hitTestResult = ge.getView().hitTest(x, ge.UNITS_PIXELS, y, ge.UNITS_PIXELS, ge.HIT_TEST_GLOBE);
    return new geo.Point(hitTestResult.getLatitude(), hitTestResult.getLongitude());
}

function addPoint(name, description, point) {
    drawPoint(getUniqueId(), [point.lat(), point.lng(), 0], name, description);
}

function addTileAnglePoint(centerX, centerY) {
    var ltPoint = gethitTestResult(centerX - w / 2, centerY - h / 2);
    addPoint('左上', 'qqwewe', ltPoint);
    var rtPoint = gethitTestResult(centerX + w / 2, centerY - h / 2);
    addPoint('右上', 'qqwewe', rtPoint);
    var rbPoint = gethitTestResult(centerX + w / 2, centerY + h / 2);
    addPoint('右下', 'qqwewe', rbPoint);
    var lbPoint = gethitTestResult(centerX - w / 2, centerY + h / 2);
    addPoint('左下', 'qqwewe', lbPoint);
}

function getScreenMap(xn, yn) {
    window.external.cutWindowImage(xn, yn);
}

function getCurrentEarthCameraAltitude() {
    var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
    var alt = parseInt(camera.getAltitude());
    if (alt < 200) {
        alt = 200;
    }
    camera.setAltitude(alt);
    ge.getView().setAbstractView(camera);
    return alt;
}

function setCurrentEarthCameraAltitude(cameraAlt) {
    var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
    camera.setAltitude(cameraAlt);
    ge.getView().setAbstractView(camera);
}
var colsCount = rowsCount = 0;

function calculateEarthTiles(width, height, w, h, alt) {
    alt = parseInt(alt);
    var cx = width / 2;
    var cy = height / 2;
    var lng0 = (ciPoints[2].lng() + ciPoints[3].lng()) / 2;
    var lat0 = ciPoints[2].lat();
    var p0 = new geo.Point(lat0, lng0);
    moveToPoint(p0, alt);
    colsCount = 2 * getColsTilesCount(lat0, lng0, ciPoints[2].lng(), alt, cx, cy, w);
    moveToPoint(p0, alt);
    rowsCount = getRowsTilesCount(lat0, lng0, ciPoints[1].lat(), alt, cx, cy, h);
    moveToPoint(p0, alt);
    var latc = getCenterLat(p0, alt, cx, cy - h / 2);
    moveToPoint(new geo.Point(latc, lng0), alt);
    var rb = getBounderyLeftRight(latc, alt, cx + w / 2, cy);
    moveToPoint(new geo.Point(latc, lng0), alt);
    var lb = getBounderyLeftRight(latc, alt, cx - w / 2, cy);
    moveToPoint(p0, alt);
    var bb = getBounderyTopBottom(p0, cx, cy + w / 2, alt);
    var tcPoint = rPoints[rPoints.length - 1];
    moveToPoint(tcPoint, alt);
    var tb = getBounderyTopBottom(tcPoint, cx, cy - w / 2, alt);
    moveMapToPoint(new geo.Point((ciPoints[0].lat() + ciPoints[3].lat()) / 2, (ciPoints[0].lng() + ciPoints[1].lng()) / 2), getHorizontalDistance(new geo.Point(ciPoints[0].lat(), ciPoints[0].lng()), new geo.Point(ciPoints[2].lat(), ciPoints[2].lng())), 6, null);
    window.external.showCutEarthtiles(rowsCount * colsCount, rowsCount, colsCount, tb.lng(), tb.lat(), bb.lng(), bb.lat(), lb.lng(), lb.lat(), rb.lng(), rb.lat(), getHorizontalDistance(lb, rb).toFixed(0), getHorizontalDistance(tb, bb).toFixed(0));
}

function getCenterLat(p0, alt, cx, y) {
    var lng = p0.lng();
    var n = 1;
    var p = tp = null;
    while (n < rowsCount) {
        tp = gethitTestResult(cx, y);
        p = new geo.Point(tp.lat(), lng);
        moveToPoint(p, alt);
        n++;
    }
    return p.lat();
}

function getBounderyTopBottom(p, cx, y, alt) {
    var tp = gethitTestResult(cx, y);
    var point = new geo.Point(tp.lat(), p.lng());
    return point;
}

function getBounderyLeftRight(lat, alt, x, cy) {
    var n = 1;
    var p = tp = null;
    while (n <= colsCount) {
        tp = gethitTestResult(x, cy);
        p = new geo.Point(lat, tp.lng());
        moveToPoint(p, alt);
        n++;
    }
    return p;
}

function getColsTilesCount(lat, lng, bounderyLng, alt, cx, cy, w) {
    var p = tp = null;
    var n = k = 0;
    var x = cx + w / 2;
    p = new geo.Point(lat, lng);
    while (lng <= bounderyLng) {
        if (n % 2 != 0) {
            k++;
        }
        n++;
        tp = gethitTestResult(x, cy);
        p = new geo.Point(lat, tp.lng());
        moveToPoint(p, alt);
        lng = p.lng();
    }
    if (n % 2 != 0) {
        return k + 1;
    }
    return k;
}
var rPoints = [];

function getRowsTilesCount(lat, lng, bounderyLat, alt, cx, cy, h) {
    var p = tp = null;
    rPoints = [];
    var n = k = 1;
    var y = cy - h / 2;
    p = new geo.Point(lat, lng);
    while (lat <= bounderyLat) {
        if (n % 2 != 0) {
            rPoints.push(p);
            k++;
        }
        n++;
        tp = gethitTestResult(cx, y);
        p = new geo.Point(tp.lat(), lng);
        moveToPoint(p, alt);
        lat = p.lat();
    }
    p = rPoints[rPoints.length - 1];
    moveToPoint(p, alt);
    tp = gethitTestResult(cx, y);
    p = new geo.Point(tp.lat(), lng);
    if (p.lat() <= bounderyLat) {
        moveToPoint(p, alt);
        tp = gethitTestResult(cx, y);
        p = new geo.Point(tp.lat(), lng);
        rPoints.push(p);
        moveToPoint(p, alt);
        return k;
    }
    return k - 1;
}
var t = 0;

function startToCutEarthTiles(width, height, w, alt, delayTime) {
    alt = parseInt(alt);
    delay = parseInt(delayTime);
    var cx = width / 2;
    var cy = height / 2;
    var x = cx + w / 2;
    var lng0 = (ciPoints[2].lng() + ciPoints[3].lng()) / 2;
    var lat0 = ciPoints[2].lat();
    var p0 = new geo.Point(lat0, lng0);
    moveToPoint(p0, alt);
    xn = 1;
    yn = 0;
    t = 0;
    redyCutTile(width, height, w, x, cy, alt, delay);
}

function redyCutTile(width, height, w, x, cy, alt, delay) {
    if (xn == 1 && yn == 0 && w > 0) {
        etCount = 0;
    }
    var p = rPoints[t];
    t++;
    moveToPoint(p, alt);
    var tp = gethitTestResult(x, cy);
    cp = new geo.Point(p.lat(), tp.lng());
    moveToPoint(cp, alt);
    setTimeout('beginToCutTile(' + width + ',' + height + ',' + w + ',' + x + ',' + cy + ',' + alt + ',' + delay + ')', delay);
}
var cp = null;
var etCount = 0;

function beginToCutTile(width, height, w, x, cy, alt, delay) {
    if (waitProcessRun == true) {
        waitProcessRun = false;
        return;
    }
    getScreenMap((w <= 0) ? -xn : xn, yn);
    etCount++;
    window.external.cutingEarthTilesCallBack(etCount);
    if (pageStopRunFlag == true) {
        pageStopRunFlag = false;
        return;
    }
    if (xn < colsCount / 2) {
        xn++;
    } else {
        xn = 1;
        yn++;
        if (yn >= rowsCount) {
            yn = 0;
            if (w <= 0) {
                moveMapToPoint(new geo.Point((ciPoints[0].lat() + ciPoints[3].lat()) / 2, (ciPoints[0].lng() + ciPoints[1].lng()) / 2), getHorizontalDistance(new geo.Point(ciPoints[0].lat(), ciPoints[0].lng()), new geo.Point(ciPoints[2].lat(), ciPoints[2].lng())), 6, null);
                window.external.cutEarthTilesOK();
                return;
            }
            startToCutEarthTiles(width, height, -w, alt, delay);
            return;
        }
        redyCutTile(width, height, w, x, cy, alt, delay);
        return;
    }
    var tp = gethitTestResult(x, cy);
    var p = new geo.Point(cp.lat(), tp.lng());
    moveToPoint(p, alt);
    tp = gethitTestResult(x, cy);
    p = new geo.Point(p.lat(), tp.lng());
    moveToPoint(p, alt);
    cp = p;
    setTimeout('beginToCutTile(' + width + ',' + height + ',' + w + ',' + x + ',' + cy + ',' + alt + ',' + delay + ')', parseInt(window.external.getCutEarthTileDelayTime()));
}
var waitProcessRun = false;

function waitProcessRun() {
    waitProcessRun = true;
}

function continueWebbrowserRun(width, height, w, alt, delay) {
    beginToCutTile(width, height, w, width / 2 + w / 2, height / 2, alt, delay);
}

function sliceCutEarthMap(tLat, bLat, lLng, rLng, rowsCount, colsCount) {
    var diffLat = tLat - bLat;
    var diffLng = rLng - lLng;
    var latMax, latMin, lngMin, lngMax;
    if (rowsCount > 1) {
        removeSliceMaps();
        var dLat = diffLat / rowsCount;
        var dLng = diffLng / colsCount;
        for (var i = 0; i < rowsCount; i++) {
            for (var j = 0; j < colsCount; j++) {
                latMax = tLat - i * dLat;
                latMin = tLat - (i + 1) * dLat;
                lngMin = lLng + j * dLng;
                lngMax = lLng + (j + 1) * dLng
                addSliceMap(latMin, latMax, lngMin, lngMax);
            }
        }
    }
}
var sliceMapPoints = [];

function addSliceMap(latMin, latMax, lngMin, lngMax) {
    var ps = [];
    ps[0] = new geo.Point(latMax, lngMin);
    ps[1] = new geo.Point(latMax, lngMax);
    ps[2] = new geo.Point(latMin, lngMax);
    ps[3] = new geo.Point(latMin, lngMin);
    var id = getUniqueId();
    sliceMapPoints.push(id);
    gex.dom.addPolygonPlacemark(ps, {
        id: id,
        name: '影像下載',
        description: '影像下載範圍',
        style: {
            poly: {
                color: 'White',
                opacity: 0,
                fill: false,
                outline: true
            },
            line: {
                width: 1,
                opacity: 1,
                color: '#ffffff'
            }
        }
    });
}

function removeSliceMaps() {
    var length = sliceMapPoints.length;
    for (var i = 0; i < length; i++) {
        removeObject(getObjectById(sliceMapPoints.shift()));
    }
}

function removeDEMRegin(id) {
    removeObject(getObjectById(demRectangleIds[id]));
    var length = demRectangleIds.length;
    var k = 0;
    var dems = demRectangleIds;
    demRectangleIds = [];
    for (var i = 0; i < length; i++) {
        if (i != id) {
            demRectangleIds[k] = dems[i];
            k++;
        }
    }
}

function clearAllDEMRegin() {
    var length = demRectangleIds.length;
    for (var i = 0; i < length; i++) {
        removeObject(getObjectById(demRectangleIds.shift()));
    }
}
var demRectangleIds = [];

function addDEMReginOnEarth(bLat, tLat, lLng, rLng) {
    var ps = [];
    ps[0] = new geo.Point(parseFloat(tLat), parseFloat(lLng));
    ps[1] = new geo.Point(parseFloat(tLat), parseFloat(rLng));
    ps[2] = new geo.Point(parseFloat(bLat), parseFloat(rLng));
    ps[3] = new geo.Point(parseFloat(bLat), parseFloat(lLng));
    var id = getUniqueId();
    demRectangleIds.push(id);
    gex.dom.addPolygonPlacemark(ps, {
        id: id,
        name: 'DEM',
        description: 'DEM',
        style: {
            poly: {
                color: 'Red',
                opacity: 0,
                fill: false,
                outline: true
            },
            line: {
                width: 1,
                opacity: 1,
                color: '#ffffff'
            }
        }
    });
}

function selectObjectToIdentify_m(key, m) {
    alert('提取高程信息需切換到谷歌地球三維模式!');
}
var trafficLayer = null;
var bikeLayer = null;
var weatherLayer = null;
var cloudLayer = null;

function setMapZoom(zoom) {
    gotoLocationbyPoint(map.getCenter(), parseInt(zoom));
}

function setMapLookAt(zoom) {
    var point;
    if (downloadImagePath != null) {
        point = downloadImagePath.getPath().getAt(0);
    } else {
        point = map.getCenter();
    }
    gotoLocationbyPoint(point, parseInt(zoom));
}

function setMapStatus(s1, s2, s3, s4) {
    if (s1 == true) {
        trafficLayer = new google.maps.TrafficLayer();
        trafficLayer.setMap(map);
    } else {
        trafficLayer.setMap(null);
    }
    if (s2 == true) {
        bikeLayer = new google.maps.BicyclingLayer();
        bikeLayer.setMap(map);
    } else {
        bikeLayer.setMap(null);
    }
    if (s3 == true) {
        weatherLayer = new google.maps.weather.WeatherLayer({
            temperatureUnits: google.maps.weather.TemperatureUnit.CELCIUS
        });
        weatherLayer.setMap(map);
    } else {
        weatherLayer.setMap(null);
    }
    if (s4 == true) {
        cloudLayer = new google.maps.weather.CloudLayer();
        cloudLayer.setMap(map);
    } else {
        cloudLayer.setMap(null);
    }
}
var markersArray = [];
var infoWindowArray = [];
var rubbishObject_m = [];

function getMySatelliteTileAddress(lng, lat, digits) {
    var PI = 3.1415926535897;
    var x = (180.0 + parseFloat(lng)) / 360.0;
    var y = -parseFloat(lat) * PI / 180;
    y = 0.5 * Math.log((1 + Math.sin(y)) / (1 - Math.sin(y)));
    y *= 1.0 / (2 * PI);
    y += 0.5;
    var quad = "t";
    var lookup = "qrts";
    while (digits--) {
        x -= Math.floor(x);
        y -= Math.floor(y);
        quad = quad + '/' + lookup.substr((x >= 0.5 ? 1 : 0) + (y >= 0.5 ? 2 : 0), 1);
        x *= 2;
        y *= 2;
    }
    return quad;
}

function tile2long(x, z) {
    return (x / Math.pow(2, z) * 360 - 180);
}

function tile2lat(y, z) {
    var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
    return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))));
}

function GetQuadtreeAddress(lng, lat, digits) {
    var PI = 3.1415926535897;
    var x = (180.0 + parseFloat(lng)) / 360.0;
    var y = -parseFloat(lat) * PI / 180;
    y = 0.5 * Math.log((1 + Math.sin(y)) / (1 - Math.sin(y)));
    y *= 1.0 / (2 * PI);
    y += 0.5;
    var quad = "t";
    var lookup = "qrts";
    while (digits--) {
        x -= Math.floor(x);
        y -= Math.floor(y);
        quad = quad + lookup.substr((x >= 0.5 ? 1 : 0) + (y >= 0.5 ? 2 : 0), 1);
        x *= 2;
        y *= 2;
    }
    return quad;
}

function searchLatLngByLocation_m(a) {
    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address=' + a + '&sensor=false', function (json) {
        if (json['status'] == 'OK') {
            var myLatlng = new google.maps.LatLng(json['results'][0]['geometry']['location']['lat'], json['results'][0]['geometry']['location']['lng']);
            searchLocation_m(myLatlng.lat(), myLatlng.lng());
        }
    });
}

function gotoLocationbyPoint(myLatlng, zoom) {
    map.setCenter(myLatlng);
    map.setZoom(zoom);
}

function drawMarker(myLatlng) {
    var marker = new google.maps.Marker({
        icon: iconUrl,
        position: myLatlng,
        map: map,
        title: "I am here!"
    });
    addMarkerersArray('marker', marker);
    var markerInfo = new NameOverlay(myLatlng, marker.getTitle(), map);
    addMarkerersArray('markerInfo', markerInfo);
    google.maps.event.addListener(marker, "click", function () {
        if (doWhat_m == 1) {
            removeObjectByClick(this);
            if (markerInfo != null) {
                removeObjectByClick(markerInfo);
            }
        } else if (doWhat_m == 2) {
            if (markerInfo != null) {
                editMarker(this, markerInfo);
            }
        }
    });
}

function searchLocation_m(lat, lng) {
    var myLatlng = new google.maps.LatLng(lat, lng);
    gotoLocationbyPoint(myLatlng, 10);
    drawMarker(myLatlng);
}

function importKmlFile_m(kmlString) {
    var flag = 1;
    var xmlDoc2 = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc2.async = 'false';
    xmlDoc2.loadXML(kmlString);
    var DocRoot = xmlDoc2.documentElement;
    var pms = DocRoot.selectNodes('//Placemark');
    var pmsLength = pms.length;
    var coords = [];
    try {
        for (var i = 0; i < pmsLength; i++) {
            var pm = pms[i];
            var name = (pm.selectSingleNode('name')) ? pm.selectSingleNode('name').text.Trim() : '';
            var type = '';
            if (pm.selectSingleNode('Point')) {
                type = 'point';
                var description = (pm.selectSingleNode('description')) ? pm.selectSingleNode('description').text.Trim() : '描述';
                iconUrl = (pm.selectSingleNode('Style/IconStyle/Icon/href')) ? pm.selectSingleNode('Style/IconStyle/Icon/href').text : 'http://www.goodygis.com/earth/icons/ylw-pushpin.png';
                var coordinates = (pm.selectSingleNode('Point')) ? pm.selectSingleNode('Point/coordinates').text.Trim() : '';
                if (coordinates != '') {
                    coords = coordinates.split(',');
                    addMarker(name, getPointByLatLng(coords[1], coords[0]), description);
                } else {
                    flag = 0;
                }
            } else if (pm.selectSingleNode('LineString')) {
                type = 'line';
                var coordinates = (pm.selectSingleNode('LineString')) ? pm.selectSingleNode('LineString//coordinates').text.Trim() : '';
                if (coordinates != '') {
                    var coordss = coordinates.replace(/\n/g, ' ').replace(/\s+/g, ' ').split(' ');
                    var coordssLength = coordss.length;
                    var lineCoords = [];
                    for (var j = 0; j < coordssLength; j++) {
                        coords = coordss[j].split(',');
                        lineCoords.push(getPointByLatLng(coords[1], coords[0]));
                    }
                    addLine(name, lineCoords);
                } else {
                    flag = 0;
                }
            } else if (pm.selectSingleNode('Polygon')) {
                type = 'polygon';
                var coordinates = (pm.selectSingleNode('Polygon')) ? pm.selectSingleNode('Polygon//coordinates').text.Trim() : '';
                if (coordinates != '') {
                    var coordss = coordinates.replace(/\n/g, ' ').replace(/\s+/g, ' ').split(' ');
                    var coordssLength = coordss.length;
                    var polygonCoords = [];
                    for (var j = 0; j < coordssLength; j++) {
                        coords = coordss[j].split(',');
                        polygonCoords.push(getPointByLatLng(coords[1], coords[0]));
                    }
                    addPolygon(name, polygonCoords);
                } else {
                    flag = 0;
                }
            } else if (pm.selectSingleNode('MultiGeometry')) {
                type = 'MultiGeometry';
                var lineStrings = pm.selectNodes('MultiGeometry//LineString') ? pm.selectNodes('MultiGeometry//LineString') : '';
                var lineLength = lineStrings.length;
                if (lineLength > 0) {
                    for (var x = 0; x < lineLength; x++) {
                        var coordinates = lineStrings[x].selectSingleNode('coordinates').text.Trim();
                        var coordss = coordinates.replace(/\n/g, ' ').replace(/\s+/g, ' ').split(' ');
                        var coordssLength = coordss.length;
                        var lineCoords = [];
                        for (var j = 0; j < coordssLength; j++) {
                            coords = coordss[j].split(',');
                            lineCoords.push(getPointByLatLng(coords[1], coords[0]));
                        }
                        addLine(name, lineCoords);
                    }
                } else {
                    flag = 0;
                }
            } else {
                flag = 0;
                alert('提示:系統未識別該圖形,目前只能導入點、線和麪圖形!');
            }
        }
        gotoLocationbyPoint(getPointByLatLng(coords[1], coords[0]), 15);
    } catch (err) {
        flag = 0;
    }
    DocRoot = null;
    xmlDoc2 = null;
    kmlString = '';
    return flag;
}

function getGEKml_m() {
    var kmlString = '';
    if (markersArray) {
        for (var i = 0; i < markersArray.length; i++) {
            var obj = markersArray[i];
            if (obj.key == 'marker') {
                var markerLatLng = obj.value.position;
                var description = getInfoWindowContent(markerLatLng);
                kmlString += '    <Placemark>\r\n' + '        <name>' + ((obj.value.title == 'undefined' || obj.value.title == null) ? '地標' : obj.value.title) + '</name>\r\n' + '        <description>' + ((description == '') ? '描述' : description) + '</description>\r\n' + '        <Style><IconStyle><Icon><href>' + ((obj.value.getIcon() == 'undefined' || obj.value.getIcon() == null) ? 'http://www.goodygis.com/earth/icons/ylw-pushpin.png' : obj.value.getIcon()) + '</href></Icon></IconStyle></Style>\r\n';
                kmlString += '        <Point><coordinates>' + markerLatLng.lng() + ',' + markerLatLng.lat() + ',0</coordinates></Point>\r\n';
                kmlString += '    </Placemark>\r\n';
            } else if (obj.key == 'line') {
                kmlString += '    <Placemark>\r\n' + '        <name>' + ((obj.value.title == 'undefined' || obj.value.title == null) ? '路線' : obj.value.title) + '</name>\r\n';
                kmlString += '          <Style><LineStyle><color>' + mergeColorOpacity(obj.value.strokeColor, obj.value.strokeOpacity) + '</color><width>' + obj.value.strokeWeight + '</width></LineStyle></Style>\r\n';
                var lineCoords = obj.value.getPath();
                var lineCoordsStr = '';
                for (var j = 0; j < lineCoords.length; j++) {
                    lineCoordsStr += lineCoords.getAt(j).lng() + ',' + lineCoords.getAt(j).lat() + ',0 ';
                }
                kmlString += '        <LineString>\r\n' + '            <tessellate>1</tessellate>\r\n' + '            <coordinates>' + lineCoordsStr + '</coordinates>\r\n' + '        </LineString>\r\n';
                kmlString += '    </Placemark>\r\n';
            } else if (obj.key == 'polygon') {
                kmlString += '    <Placemark>\r\n' + '        <name>' + ((obj.value.title == 'undefined' || obj.value.title == null) ? '多邊形' : obj.value.title) + '</name>\r\n';
                kmlString += '     <Style><LineStyle><color>' + mergeColorOpacity(obj.value.strokeColor, obj.value.strokeOpacity) + '</color><width>' + (obj.value.strokeWeight + 1) + '</width></LineStyle><PolyStyle><color>' + mergeColorOpacity(obj.value.fillColor, obj.value.fillOpacity) + '</color><fill>1</fill><outline>1</outline></PolyStyle></Style>\r\n';
                var polygonCoords = obj.value.getPath();
                var polygonCoordsStr = '';
                for (var j = 0; j < polygonCoords.length; j++) {
                    polygonCoordsStr += polygonCoords.getAt(j).lng() + ',' + polygonCoords.getAt(j).lat() + ',0 ';
                    if (j == polygonCoords.length - 1 && polygonCoords.getAt(j).lng() != polygonCoords.getAt(0).lng() && polygonCoords.getAt(j).lat() != polygonCoords.getAt(0).lat()) {
                        polygonCoordsStr += polygonCoords.getAt(0).lng() + ',' + polygonCoords.getAt(0).lat() + ',0';
                    }
                }
                kmlString += '        <Polygon>\r\n' + '            <tessellate>1</tessellate>\r\n' + '            <outerBoundaryIs>\r\n' + '                <LinearRing>\r\n' + '                    <coordinates>' + polygonCoordsStr + '</coordinates>\r\n' + '                </LinearRing>\r\n' + '            </outerBoundaryIs>\r\n' + '        </Polygon>\r\n';
                kmlString += '    </Placemark>\r\n';
            } else if (obj.key == 'retangle') {
                kmlString += '    <Placemark>\r\n' + '        <name>' + ((obj.value.title == 'undefined' || obj.value.title == null) ? '矩形' : obj.value.title) + '</name>\r\n';
                kmlString += '     <Style><LineStyle><color>' + mergeColorOpacity(obj.value.strokeColor, obj.value.strokeOpacity) + '</color><width>' + (obj.value.strokeWeight + 1) + '</width></LineStyle><PolyStyle><color>' + mergeColorOpacity(obj.value.fillColor, obj.value.fillOpacity) + '</color><fill>1</fill><outline>1</outline></PolyStyle></Style>\r\n';
                var polygonCoords = obj.value.getBounds();
                var polygonCoordsStr = polygonCoords.getSouthWest().lng() + ',' + polygonCoords.getSouthWest().lat() + ',0 ' + polygonCoords.getSouthWest().lng() + ',' + polygonCoords.getNorthEast().lat() + ',0 ' + polygonCoords.getNorthEast().lng() + ',' + polygonCoords.getNorthEast().lat() + ',0 ' + polygonCoords.getNorthEast().lng() + ',' + polygonCoords.getSouthWest().lat() + ',0 ' + polygonCoords.getSouthWest().lng() + ',' + polygonCoords.getSouthWest().lat() + ',0';
                kmlString += '        <Polygon>\r\n' + '            <tessellate>1</tessellate>\r\n' + '            <outerBoundaryIs>\r\n' + '                <LinearRing>\r\n' + '                    <coordinates>' + polygonCoordsStr + '</coordinates>\r\n' + '                </LinearRing>\r\n' + '            </outerBoundaryIs>\r\n' + '        </Polygon>\r\n';
                kmlString += '    </Placemark>\r\n';
            } else if (obj.key == 'circle') {
                alert('本系統暫時不能導出圓!');
                continue;
                kmlString += '    <Placemark>\r\n' + '        <name>' + ((obj.value.title == 'undefined' || obj.value.title == null) ? '圓' : obj.value.title) + '</name>\r\n';
                var polygonCoords = obj.value.getPath();
                var polygonCoordsStr = '';
                for (var j = 0; j < polygonCoords.length; j++) {
                    polygonCoordsStr += polygonCoords.getAt(j).lng() + ',' + polygonCoords.getAt(j).lat() + ',0 ';
                }
                kmlString += '        <Polygon>\r\n' + '            <tessellate>1</tessellate>\r\n' + '            <outerBoundaryIs>\r\n' + '                <LinearRing>\r\n' + '                    <coordinates>' + polygonCoordsStr + '</coordinates>\r\n' + '                </LinearRing>\r\n' + '            </outerBoundaryIs>\r\n' + '        </Polygon>\r\n';
                kmlString += '    </Placemark>\r\n';
            }
        }
        if (kmlString != '') {
            kmlString = '<?xml version="1.0" encoding="UTF-8"?>\r\n<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">\r\n<Document>\r\n' + kmlString;
            kmlString += '  </Document>\r\n' + '</kml>';
            kmlString = formatKmlForHtml(kmlString);
        }
    }
    return kmlString;
}

function getPointByCoord(coord) {
    return new google.maps.LatLng(coord);
}

function getPointByLatLng(lat, lng) {
    return new google.maps.LatLng(lat, lng);
}

function addMarker(title, markerCoord, description) {
    var marker = new google.maps.Marker({
        icon: iconUrl,
        position: markerCoord,
        title: title,
        draggable: false,
        map: map
    });
    var markerInfo = new NameOverlay(markerCoord, marker.getTitle(), map);
    addMarkerersArray('marker', marker);
    addMarkerersArray('markerInfo', markerInfo);
    var infowindow = new google.maps.InfoWindow({
        content: description
    });
    addInfoWindowArray(markerCoord.lat() + "|" + markerCoord.lng(), infowindow);
    google.maps.event.addListener(marker, "click", function () {
        if (doWhat_m == 0) {
            infowindow.open(map, marker);
        } else if (doWhat_m == 1) {
            removeObjectByClick(this);
            if (markerInfo != null) {
                removeObjectByClick(markerInfo);
            }
        } else if (doWhat_m == 2) {
            if (markerInfo != null) {
                editMarker(this, markerInfo);
            }
        }
    });
}

function removeObjectByClick(obj) {
    obj.setMap(null);
    doWhat_m = 0;
    removeObjectFromArray(obj);
    window.external.setMousemoveMsgByWeb('', false);
}

function addLine(title, lineCoords) {
    var path = new google.maps.Polyline({
        title: title,
        path: lineCoords,
        strokeColor: "#FF0000",
        strokeOpacity: 1.0,
        strokeWeight: 2,
        map: map
    });
    addMarkerersArray('line', path);
    google.maps.event.addListener(path, "click", function () {
        if (doWhat_m == 0) {
            getPathInfos(this);
        } else if (doWhat_m == 1) {
            removeObjectByClick(this);
        } else if (doWhat_m == 3) {
            measureObjectLength(this);
        }
    });
}

function addPolygon(title, polygonCoords) {
    var polygon = new google.maps.Polygon({
        title: title,
        paths: polygonCoords,
        strokeColor: "#FF0000",
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: "#FF0000",
        fillOpacity: 0.1,
        map: map
    });
    addMarkerersArray('polygon', polygon);
    google.maps.event.addListener(polygon, "click", function () {
        if (doWhat_m == 0) {
            showPolygonBox(this);
        } else if (doWhat_m == 1) {
            removeObjectByClick(this);
        } else if (doWhat_m == 3) {
            measureObjectAreaC(this);
        }
    });
}

function addMarkerersArray(type, m) {
    markersArray.push({
        key: type,
        value: m
    });
}

function clearOverlays() {
    if (markersArray) {
        for (var i = 0; i < markersArray.length; i++) {
            markersArray[i].value.setMap(null);
        }
    }
}

function addInfoWindowArray(key, obj) {
    infoWindowArray.push({
        key: key,
        value: obj
    });
}

function getInfoWindowContent(markerLatLng) {
    var content = '';
    if (infoWindowArray) {
        var keyStr = markerLatLng.lat() + '|' + markerLatLng.lng();
        for (var i = 0; i < infoWindowArray.length; i++) {
            if (infoWindowArray[i].key == keyStr) {
                content = infoWindowArray[i].value.getContent();
                break;
            }
        }
    }
    return content;
}

function setMarkerInfoWindowContent(markerLatLng, content) {
    if (infoWindowArray) {
        var keyStr = markerLatLng.lat() + '|' + markerLatLng.lng();
        for (var i = 0; i < infoWindowArray.length; i++) {
            if (infoWindowArray[i].key == keyStr) {
                content = infoWindowArray[i].value.setContent(content);
                break;
            }
        }
    }
}

function showOverlays() {
    if (markersArray) {
        for (var i = 0; i < markersArray.length; i++) {
            markersArray[i].value.setMap(map);
        }
    }
}

function deleteOverlays() {
    if (markersArray) {
        for (var i = 0; i < markersArray.length; i++) {
            markersArray[i].value.setMap(null);
        }
        markersArray.length = 0;
    }
    polygonBox = null;
}

function clearAllObjs_m() {
    deleteOverlays();
    endDrawOneFig();
}

function removeObjectFromArray(obj) {
    if (markersArray) {
        for (var i = 0; i < markersArray.length; i++) {
            if (markersArray[i].value == obj) {
                markersArray.splice(i, 1);
                return;
            }
        }
    }
}

function modifyMarkerersArray(obj, nobj) {
    if (markersArray) {
        for (var i = 0; i < markersArray.length; i++) {
            if (markersArray[i].value == obj) {
                obj.setMap(null);
                markersArray[i].value = nobj;
                return;
            }
        }
    }
}
var figType_m = '';

function drawFigure_m(figuretype) {
    doWhat_m = 0;
    if (figuretype != 'point' || (figuretype == 'point' && figType_m != figuretype)) {
        endDrawOneFig();
    }
    figType_m = figuretype;
}

function chushihuaDrawFig_m() {
    endDrawOneFig();
}
var cases_m = {
    'point': drawPointFunc_m,
    'line': drawLineFunc_m,
    'rectangle': drawRetangleFunc_m,
    'polygon': drawPolygonFunc_m
};

function addEventListenerDrawFig_m() {
    try {
        google.maps.event.clearListeners(map, 'rightclick', clickMouseFunction);
        google.maps.event.addListener(map, 'rightclick', clickMouseFunction);
    } catch (err) {
	}
}

function removeEventListenerDrawFig_m() {
    if (figType_m != 'point') {
        chushihuaDrawFig_m();
    }
    figType_m = '';
    try {
        google.maps.event.clearListeners(map, 'rightclick', clickMouseFunction);
        doWhat_m = 0;
    } catch (e) {
	}
}
var doWhat_m = 0;
var clickMouseFunction = function (event) {
    if (doWhat_m == 0) {
        if (cases_m[figType_m]) {
            cases_m[figType_m](event);
        }
    }
}

function drawPointFunc_m(event) {
    addMarker(markerTitle, event.latLng, '描述');
    var latLng = map.getCenter();
    var textOverlay = new TextOverlay(latLng, "<span style=\"color:#ff0000; width:auto;\">我愛你AAAAAAAAAAAAAAAAaaa!</span>");
    map.addOverlay(textOverlay);
}
var line = null;

function drawLineFunc_m(event) {
    if (line == null) {
        line = new google.maps.Polyline({
            editable: true,
            strokeColor: '#FF0000',
            strokeOpacity: 1.0,
            strokeWeight: 3,
            map: map
        });
        addMarkerersArray('line', line);
        google.maps.event.addListener(line, "click", function () {
            if (doWhat_m == 0) {
                getPathInfos(this);
            } else if (doWhat_m == 1) {
                removeObjectByClick(this);
            } else if (doWhat_m == 3) {
                measureObjectLength(this);
            }
        });
    }
    line.getPath().push(event.latLng);
}
var retangle = null;

function drawRetangleFunc_m(event) {
    if (retangle == null) {
        var retangleCap = new google.maps.Marker({
            position: event.latLng,
            title: '端點',
            map: map,
            visible: false
        });
        rubbishObject_m.push(retangleCap);
        retangle = new google.maps.Rectangle({
            clickable: true,
            editable: true,
            strokeColor: '#0000FF',
            strokeOpacity: 1.0,
            strokeWeight: 3,
            fillOpacity: 0.1,
            map: map
        });
        addMarkerersArray('retangle', retangle);
        google.maps.event.addListener(retangle, "mousedown", function () {
            if (doWhat_m == 1) {
                removeObjectByClick(this);
            } else if (doWhat_m == 0) {
                getRetangleBounds(this);
            } else if (doWhat_m == 3) {
                measureRetangleAreaC(this);
            }
        });
        google.maps.event.addListener(retangle, "bounds_changed", function () {
            if (doWhat_m == 0) {
                getRetangleBounds(this);
            }
        });
    }
    var p1LatLng = rubbishObject_m[rubbishObject_m.length - 1].getPosition();
    var maxLat = [event.latLng.lat(), p1LatLng.lat()].max();
    var minLat = [event.latLng.lat(), p1LatLng.lat()].min();
    var maxLng = [event.latLng.lng(), p1LatLng.lng()].max();
    var minLng = [event.latLng.lng(), p1LatLng.lng()].min();
    retangle.setBounds(new google.maps.LatLngBounds(getPointByLatLng(maxLat, minLng), getPointByLatLng(minLat, maxLng)));
}

function getRetangleBounds(obj) {
    var bounds = obj.getBounds();
    var maxLat = [bounds.getSouthWest().lat(), bounds.getNorthEast().lat()].max();
    var minLat = [bounds.getSouthWest().lat(), bounds.getNorthEast().lat()].min();
    var maxLng = [bounds.getSouthWest().lng(), bounds.getNorthEast().lng()].max();
    var minLng = [bounds.getSouthWest().lng(), bounds.getNorthEast().lng()].min();
    var pathStr = maxLat + ',' + minLng + ';' + maxLat + ',' + maxLng + ';' + minLat + ',' + maxLng + ';' + minLat + ',' + minLng;
    window.external.setMapBoundsCallback_(maxLat, minLat, minLng, maxLng, pathStr);
}
var polygon = null;

function drawPolygonFunc_m(event) {
    if (polygon == null) {
        polygon = new google.maps.Polygon({
            clickable: true,
            editable: true,
            strokeColor: "#FF0000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#FF0000",
            fillOpacity: 0.1,
            map: map
        });
        addMarkerersArray('polygon', polygon);
        google.maps.event.addListener(polygon, "click", function () {
            if (doWhat_m == 0) {
                showPolygonBox(this);
            } else if (doWhat_m == 1) {
                removeObjectByClick(this);
            } else if (doWhat_m == 3) {
                measureObjectAreaC(this);
            }
        });
    }
    polygon.getPath().push(event.latLng);
}
var polygonBox = null;

function showPolygonBox(obj) {
    var path = obj.getPath();
    var length = path.length;
    var lngTmp, latTmp, pathStr = '';
    var minLng = maxLng = path.getAt(0).lng();
    var minLat = maxLat = path.getAt(0).lat();
    var pathStr = minLat + ',' + minLng;
    for (var i = 1; i < length; i++) {
        var pathi = path.getAt(i);
        pathStr += ';' + pathi.lat() + ',' + pathi.lng();
        lngTmp = pathi.lng();
        minLng = (lngTmp < minLng) ? lngTmp : minLng;
        maxLng = (lngTmp > maxLng) ? lngTmp : maxLng;
        latTmp = pathi.lat();
        minLat = (latTmp < minLat) ? latTmp : minLat;
        maxLat = (latTmp > maxLat) ? latTmp : maxLat;
    }
    var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(minLat, minLng), new google.maps.LatLng(maxLat, maxLng));
    if (polygonBox != null) {
        polygonBox.setBounds(bounds);
    } else {
        polygonBox = new google.maps.Rectangle({
            clickable: true,
            editable: true,
            strokeColor: '#0000FF',
            strokeOpacity: 1.0,
            strokeWeight: 3,
            fillOpacity: 0.35,
            map: map,
            bounds: bounds
        });
        google.maps.event.addListener(polygonBox, "click", function () {
            if (doWhat_m == 1) {
                polygonBox = null;
                removeObjectByClick(this);
            } else if (doWhat_m == 3) {
                measureObjectAreaC(this);
            }
        });
        google.maps.event.addListener(polygonBox, "bounds_changed", function () {
            if (doWhat_m == 0) {
                getRetangleBounds(this);
            }
        });
        addMarkerersArray('retangle', polygonBox);
    }
    window.external.setMapBoundsCallback_(maxLat, minLat, minLng, maxLng, pathStr);
}

function getMapZoom() {
    return map.getZoom();
}

function removeEventListenerDrawFig_m() {
    figType_m = '';
    try {
        doWhat_m = 0;
        endDrawOneFig();
        google.maps.event.clearListeners(map, 'rightclick', clickMouseFunction);
    } catch (e) {
        alert("請等待加載地圖!");
    }
}

function endDrawOneFig() {
    if (line != null) {
        line.setEditable(false);
        line = null;
    }
    if (retangle != null) {
        retangle.setEditable(false);
        retangle = null;
    }
    if (polygon != null) {
        polygon.setEditable(false);
        if (polygon.getPath().length < 3) {
            polygon.setMap(null);
        }
        polygon = null;
    }
    if (rubbishObject_m.length > 0) {
        for (var i = 0; i < rubbishObject_m.length; i++) {
            rubbishObject_m[i].setMap(null);
        }
        rubbishObject_m = [];
    }
}

function cancelLineLastStep_m() {
    if (line != null) {
        line.getPath().pop();
        if (line.getPath().length < 2) {
            line.setMap(null);
            line = null;
        }
    }
    if (polygon != null) {
        polygon.getPath().pop();
        if (polygon.getPath().length < 3) {
            polygon.setMap(null);
            polygon = null;
        }
    }
}

function addEventListenerSetCircleParams_m(textBox) {
    try {
        google.maps.event.addListener(map, 'mousemove', moveMouseGetCoords_m);
        google.maps.event.addListener(map, 'rightclick', clickRightMouseGetCoords_m);
    } catch (e) {
        alert("請等待加載地圖!");
    }
    activeTextBox = textBox;
}

function removeEventListenerSetCircleParams_m() {
    try {
        google.maps.event.clearListeners(map, 'mousemove', moveMouseGetCoords_m);
        getMouseCoordinates();
    } catch (e) {
        alert("請等待加載地圖!");
    }
    activeTextBox = '';
}

var moveMouseGetCoords_m = function (event) {
    var param = '';
    switch (activeTextBox) {
    case 'textBox1':
        centerPointName = '圓心';
        param = event.latLng.lng().toFixed(6) + ',' + event.latLng.lat().toFixed(6);
        break;
    case 'textBox2':
        centerPointName = '半徑';
        var centerPoint = (window.external.getTextBoxValue('textBox1')).split(',');
        if (centerPoint != '') {
            try {
                param = google.maps.geometry.spherical.computeDistanceBetween(getPointByLatLng(parseFloat(centerPoint[1]), parseFloat(centerPoint[0])), getPointByLatLng(event.latLng.lat(), event.latLng.lng())).toFixed(2);
            } catch (err) {
                try {
                    param = new geo.Point(parseFloat(centerPoint[1]), parseFloat(centerPoint[0])).distance(new geo.Point(event.latLng.lat(), event.latLng.lng())).toFixed(2);
                } catch (errr) {}
            }
        } else {
            activeTextBox = 'textBox6';
        }
        break;
    case 'textBox3':
        break;
    case 'textBox4':
        break;
    case 'textBox14':
        centerPointName = '源點';
        param = event.latLng.lng() + ',' + event.latLng.lat();
        break;
    case 'textBox15':
        centerPointName = '目標點';
        param = event.latLng.lng() + ',' + event.latLng.lat();
        break;
    default:
    }
    window.external.inputTextBoxCoordsCallback_(activeTextBox, param);
}

var circleCenter = null;
var circleRadius = null;
var originalPoint = null;
var targetPoint = null;
var clickRightMouseGetCoords_m = function (event) {
    removeEventListenerSetCircleParams_m();
    if (centerPointName == '圓心') {
        if (circleCenter != null) {
            circleCenter.setMap(null);
        }
        circleCenter = new google.maps.Marker({
            position: event.latLng,
            title: centerPointName,
            map: map
        });
        rubbishObject_m.push(circleCenter);
    } else if (centerPointName == '半徑') {
        if (circleRadius != null) {
            circleRadius.setMap(null);
        }
        circleRadius = new google.maps.Marker({
            position: event.latLng,
            title: centerPointName,
            map: map
        });
        rubbishObject_m.push(circleRadius);
    } else if (centerPointName == '源點') {
        if (originalPoint != null) {
            originalPoint.setMap(null);
        }
        originalPoint = new google.maps.Marker({
            position: event.latLng,
            title: centerPointName,
            map: map
        });
        rubbishObject_m.push(originalPoint);
        originalPoint.setDraggable(true);
        google.maps.event.addListener(originalPoint, 'dragend', function () {
            window.external.inputTextBoxCoordsCallback_('textBox14', this.getPosition().lng() + ',' + this.getPosition().lat());
        });
    } else if (centerPointName == '目標點') {
        if (targetPoint != null) {
            targetPoint.setMap(null);
        }
        targetPoint = new google.maps.Marker({
            position: event.latLng,
            title: centerPointName,
            map: map
        });
        rubbishObject_m.push(targetPoint);
        targetPoint.setDraggable(true);
        google.maps.event.addListener(targetPoint, 'dragend', function () {
            window.external.inputTextBoxCoordsCallback_('textBox15', this.getPosition().lng() + ',' + this.getPosition().lat());
        });
    }
    centerPointName = '';
}

function drawCircleFunc_m(c, r, a1, a2, des, title) {
    var cs = c.split(',');
    var centerLatLng = getPointByLatLng(cs[1], cs[0]);
    var circle = new google.maps.Circle({
        title: title,
        strokeColor: "#FF0000",
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: "#FF0000",
        fillOpacity: 0.35,
        map: map,
        center: centerLatLng,
        radius: parseFloat(r)
    });
    endDrawOneFig();
    addMarkerersArray('circle', circle);
    google.maps.event.addListener(circle, "click", function () {
        if (doWhat_m == 1) {
            removeObjectByClick(this);
        } else if (doWhat_m == 3) {
            measureCircletAreaC(this);
        }
    });
}

function clickObjectDo_m(key) {
    doWhat_m = key;
    endDrawOneFig();
}

function addEventListenerMeasureDistance_m() {
    line = null;
    drawFigure_m('line');
    try {
        addEventListenerDrawFig_m();
        google.maps.event.addListener(map, 'rightclick', clickRightMouseMeasureDistance_m);
    } catch (err) {
        alert("請等待加載地圖!");
    }
}

function removeEventListenerMeasureDistance_m() {
    figType_m = '';
    chushihuaDrawFig_m();
    doWhat_m = 0;
    line = null;
    try {} catch (err) {
        alert("請等待加載地圖!");
    }
}
var clickRightMouseMeasureDistance_m = function (event) {
    if (line != null) {
        if (line.getPath().length > 1) {
            line.setEditable(false);
        }
        window.external.measureDistanceCallback_(computePathDistance_m(line));
    }
}

function computePathDistance_m(obj) {
    return google.maps.geometry.spherical.computeLength(obj.getPath()).toFixed(2);
}

function computeArea(obj) {
    return google.maps.geometry.spherical.computeArea(obj.getPath()).toFixed(2);
}

function subMeasureDistance_m() {
    cancelLineLastStep_m();
    var length = 0;
    if (line != null) {
        length = computePathDistance_m(line);
    }
    window.external.measureDistanceCallback_(length);
}

function measureObjectLength(obj) {
    window.external.measureObjectCallback_(0, 0, computePathDistance_m(obj));
}

function measureObjectAreaC(obj) {
    window.external.measureObjectCallback_(computePathDistance_m(obj), computeArea(obj), 0);
}

function measureCircletAreaC(obj) {
    window.external.measureObjectCallback_(2 * Math.PI.mul(obj.getRadius()), Math.PI.mul(obj.getRadius()).mul(obj.getRadius()), 0);
}

function measureRetangleAreaC(obj) {
    var path = [];
    var paths = obj.getBounds();
    path.push(paths.getSouthWest());
    path.push(getPointByLatLng(paths.getNorthEast().lat(), paths.getSouthWest().lng()));
    path.push(paths.getNorthEast());
    path.push(getPointByLatLng(paths.getNorthEast().lat(), paths.getNorthEast().lng()));
    window.external.measureObjectCallback_(google.maps.geometry.spherical.computeLength(path).toFixed(2), google.maps.geometry.spherical.computeArea(path).toFixed(2), 0);
}
var eMarker = null;
var weMarker = null;

function editMarker(obj, wObj) {
    eMarker = obj;
    weMarker = wObj;
    eMarker.setDraggable(true);
    window.external.editPointPlacemarkCallback_(eMarker.getTitle(), getInfoWindowContent(eMarker.getPosition()));
    removeEventListenerDrawFig_m();
    doWhat_m = 2;
}

function modifyPlacemark_m(title, description) {
    eMarker.setTitle(title);
    setMarkerInfoWindowContent(eMarker.getPosition(), description);
    removeObjectByClick(weMarker);
    var markerInfo = new NameOverlay(eMarker.getPosition(), title, map);
    addMarkerersArray('markerInfo', markerInfo);
    google.maps.event.addListener(eMarker, "click", function () {
        if (doWhat_m == 0) {
            removeObjectByClick(markerInfo);
        } else if (doWhat_m == 2) {
            editMarker(this, markerInfo);
        }
    });
    doWhat_m = 2;
}

function endEditPlacemark_m() {
    eMarker.setDraggable(false);
    eMarker = null;
    addEventListenerDrawFig_m();
}

function correctFigCoords_m(d, h, flag) {
    if (markersArray) {
        var destPoint = null;
        var paths = [];
        for (var i = 0; i < markersArray.length; i++) {
            var obj = markersArray[i];
            if (obj.key == 'marker') {
                var markerLatLng = obj.value.getPosition();
                if (flag == 0) {
                    destPoint = getPointLocationByDHA(new geo.Point(markerLatLng.lat(), markerLatLng.lng()), d, h);
                } else if (flag == 1) {
                    var p = window.external.M2W(markerLatLng.lat() + ',' + markerLatLng.lng());
                    var ps = p.split(',');
                    destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                } else {
                    var p = window.external.W2M(markerLatLng.lat() + ',' + markerLatLng.lng());
                    var ps = p.split(',');
                    destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                }
                obj.value.setPosition(getPointByLatLng(destPoint.lat(), destPoint.lng()));
            } else if (obj.key == 'line') {
                var lineCoords = obj.value.getPath();
                var length = lineCoords.length;
                if (flag == 0) {
                    for (var j = 0; j < length; j++) {
                        destPoint = getPointLocationByDHA(new geo.Point(lineCoords.getAt(j).lat(), lineCoords.getAt(j).lng()), d, h);
                        paths.push(getPointByLatLng(destPoint.lat(), destPoint.lng()));
                    }
                } else {
                    var sl = '';
                    for (var j = 0; j < length; j++) {
                        sl += j > 0 ? ';' : '';
                        sl += lineCoords.getAt(j).lat() + ',' + lineCoords.getAt(j).lng();
                    }
                    if (flag == 1) {
                        var pl = window.external.M2W(sl);
                    } else {
                        var pl = window.external.W2M(sl);
                    }
                    sl = '';
                    var pls = pl.split(';');
                    pl = '';
                    for (var j = 0; j < length; j++) {
                        var cl = pls[j].split(',');
                        paths.push(getPointByLatLng(parseFloat(cl[0]), parseFloat(cl[1])));
                    }
                }
                obj.value.setPath(paths);
                paths = [];
            } else if (obj.key == 'polygon') {
                var polygonCoords = obj.value.getPath();
                if (flag == 0) {
                    for (var j = 0; j < polygonCoords.length; j++) {
                        destPoint = getPointLocationByDHA(new geo.Point(polygonCoords.getAt(j).lat(), polygonCoords.getAt(j).lng()), d, h);
                        paths.push(getPointByLatLng(destPoint.lat(), destPoint.lng()));
                        if (j == polygonCoords.length - 1 && polygonCoords.getAt(j).lng() != polygonCoords.getAt(0).lng() && polygonCoords.getAt(j).lat() != polygonCoords.getAt(0).lat()) {
                            destPoint = getPointLocationByDHA(new geo.Point(polygonCoords.getAt(0).lat(), polygonCoords.getAt(0).lng()), d, h);
                            paths.push(getPointByLatLng(destPoint.lat(), destPoint.lng()));
                        }
                    }
                } else {
                    var sp = '';
                    for (var j = 0; j < polygonCoords.length; j++) {
                        sp += j > 0 ? ';' : '';
                        sp += polygonCoords.getAt(j).lat() + ',' + polygonCoords.getAt(j).lng();
                    }
                    if (flag == 1) {
                        var pp = window.external.M2W(sp);
                    } else {
                        var pp = window.external.W2M(sp);
                    }
                    sp = '';
                    var pps = pp.split(';');
                    pp = '';
                    for (var j = 0; j < polygonCoords.length; j++) {
                        var cl = pps[j].split(',');
                        paths.push(getPointByLatLng(parseFloat(cl[0]), parseFloat(cl[1])));
                    }
                }
                obj.value.setPath(paths);
                paths = [];
            } else if (obj.key == 'retangle') {
                var polygonCoords = obj.value.getBounds();
                if (flag == 0) {
                    destPoint = getPointLocationByDHA(new geo.Point(polygonCoords.getSouthWest().lat(), polygonCoords.getSouthWest().lng()), d, h);
                    var destPoint1 = getPointLocationByDHA(new geo.Point(polygonCoords.getNorthEast().lat(), polygonCoords.getNorthEast().lng()), d, h);
                } else {
                    if (flag == 1) {
                        var p = window.external.M2W(polygonCoords.getSouthWest().lat() + ',' + polygonCoords.getSouthWest().lng());
                        var ps = p.split(',');
                        destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                        var p1 = window.external.M2W(polygonCoords.getNorthEast().lat() + ',' + polygonCoords.getNorthEast().lng());
                        ps = p1.split(',');
                        destPoint1 = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                    } else {
                        var p = window.external.W2M(polygonCoords.getSouthWest().lat() + ',' + polygonCoords.getSouthWest().lng());
                        var ps = p.split(',');
                        destPoint = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                        var p1 = window.external.W2M(polygonCoords.getNorthEast().lat() + ',' + polygonCoords.getNorthEast().lng());
                        ps = p1.split(',');
                        destPoint1 = new geo.Point(parseFloat(ps[0]), parseFloat(ps[1]));
                    }
                }
                obj.value.setBounds(new google.maps.LatLngBounds(getPointByLatLng(destPoint.lat(), destPoint.lng()), getPointByLatLng(destPoint1.lat(), destPoint1.lng())));
            } else if (obj.key == 'circle') {
                alert('本系統暫時不支持圓座標校訂!');
            }
        }
    }
}

function convertPointToWord(flag) {
    if (markersArray) {
        if (flag == "1") {
            for (var i = 0; i < markersArray.length; i++) {
                var shap = markersArray[i].value.getShape();
                if (shap != 'circle' && shap != 'poly' && shap != 'rect')
                    markersArray[i].value.setMap(null);
            }
        } else {
            for (var i = 0; i < markersArray.length; i++) {
                var shap = markersArray[i].value.getShape();
                if (shap != 'circle' && shap != 'poly' && shap != 'rect')
                    markersArray[i].value.setMap(map);
            }
        }
    }
}

function addPolygonOnMap_m(topLat, bottomLat, leftLng, rightLng) {
    gotoLocationbyPoint(new google.maps.LatLng(topLat, leftLng), 10);
    var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(bottomLat, leftLng), new google.maps.LatLng(topLat, rightLng));
    if (polygonBox != null) {
        polygonBox.setBounds(bounds);
    } else {
        polygonBox = new google.maps.Rectangle({
            clickable: true,
            editable: true,
            strokeColor: '#0000FF',
            strokeOpacity: 1.0,
            strokeWeight: 3,
            fillOpacity: 0.35,
            map: map,
            bounds: bounds
        });
        google.maps.event.addListener(polygonBox, "click", function () {
            if (doWhat_m == 1) {
                polygonBox = null;
                removeObjectByClick(this);
            } else if (doWhat_m == 3) {
                measureObjectAreaC(this);
            }
        });
        google.maps.event.addListener(polygonBox, "bounds_changed", function () {
            if (doWhat_m == 0) {
                getRetangleBounds(this);
            }
        });
        addMarkerersArray('retangle', polygonBox);
    }
    google.maps.event.addListener(retangle, "mousedown", function () {
        if (doWhat_m == 1) {
            removeObjectByClick(this);
        } else if (doWhat_m == 0) {
            getRetangleBounds(this);
        } else if (doWhat_m == 3) {
            measureRetangleAreaC(this);
        }
    });
    google.maps.event.addListener(retangle, "bounds_changed", function () {
        if (doWhat_m == 0) {
            getRetangleBounds(this);
        }
    });
}

function getMapTypeId() {
    return map.getMapTypeId();
}
var downloadImagePath = null;
var dipPoints = [];

function getPathInfos(obj) {
    var state = 1;
    var length = 0;
    var guaidian = 0;
    try {
        length = computePathDistance_m(obj);
        guaidian = obj.getPath().getLength();
        downloadImagePath = obj;
    } catch (err) {
        state = 0;
    }
    window.external.returnPathInfos(state, length, guaidian);
}
var dpoints = [];

function getDownloadImagePathInfos() {
    var s = "";
    dipPoints = [];
    if (downloadImagePath != null) {
        var path = downloadImagePath.getPath();
        var length = path.length;
        var minLng = path.getAt(0).lng();
        var maxLng = minLng;
        var minLat = path.getAt(0).lat();
        var maxLat = minLat;
        var lngTmp, latTmp;
        dipPoints[0] = new geo.Point(path.getAt(0).lat(), path.getAt(0).lng());
        for (var i = 1; i < length; i++) {
            lngTmp = path.getAt(i).lng();
            minLng = (lngTmp < minLng) ? lngTmp : minLng;
            maxLng = (lngTmp > maxLng) ? lngTmp : maxLng;
            latTmp = path.getAt(i).lat();
            minLat = (latTmp < minLat) ? latTmp : minLat;
            maxLat = (latTmp > maxLat) ? latTmp : maxLat;
            dipPoints[i] = new geo.Point(path.getAt(i).lat(), path.getAt(i).lng());
        }
        s = minLng + ' ' + maxLng + ' ' + minLat + ' ' + maxLat;
    }
    return s;
}
var ddipPoint = [];

function convertPathCoords() {
    var pathJson = window.external.modifyCoords(getPathPointJson(dipPoints));
    var ps = pathJson.split(' ');
    pathJson = '';
    var length = ps.length;
    var c = null;
    ddipPoint = [];
    for (var i = 0; i < length; i++) {
        c = ps.shift().split(',');
        ddipPoint[i] = new geo.Point(parseFloat(c[1]), parseFloat(c[0]));
    }
    window.external.convertPathCoordsCallBack_();
}

function getPathPointJson(p) {
    var str = '';
    var length = p.length;
    for (var i = 0; i < length; i++) {
        str += p[i].lng() + ',' + p[i].lat() + ' ';
    }
    return str.Trim();
}
var lastdipPoint = null;

function getTilesXY(d, p, k) {
    d = parseInt(d);
    p = parseInt(p);
    var point = dpoints.shift();
    if (k == '0') {
        lastdipPoint = point;
        return point.lng() + ' ' + point.lat();
    }
    var iPoint = lastdipPoint;
    var s = '';
    var D = getHorizontalDistance(iPoint, point);
    var length = Math.floor(D.div(d));
    for (var i = 1; i <= length; i++) {
        iPoint = getPointLocationByDHA(iPoint, 2 * p * d, iPoint.heading(point));
        s += iPoint.lng() + ' ' + iPoint.lat() + '|';
    }
    s += point.lng() + ' ' + point.lat();
    lastdipPoint = point;
    return s;
}

function setPathPoints(key) {
    if (key == '1') {
        dpoints = ddipPoint.slice(0);
    } else {
        dpoints = dipPoints.slice(0);
    }
    ddipPoint = [];
}

function clearDownloadImagePoint() {
    dipPoints = [];
    dpoints = [];
}
Array.prototype.max = function () {
    return Math.max.apply({}, this)
}
Array.prototype.min = function () {
    return Math.min.apply({}, this)
}
String.prototype.Trim = function () {
    return this.replace(/(^\s*)|(\s*$)/g, "");
}
String.prototype.LTrim = function () {
    return this.replace(/(^\s*)/g, "");
}
String.prototype.RTrim = function () {
    return this.replace(/(\s*$)/g, "");
}

function FloatAdd(arg1, arg2) {
    var r1, r2, m;
    try {
        r1 = arg1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2))
    return (arg1 * m + arg2 * m) / m
}

function abS(number) {
    return Math.abs(number);
}

function sqRt(number) {
    return Math.sqrt(number);
}

function sqIt(number) {
    return number * number;
}

function accDiv(arg1, arg2) {
    var t1 = 0,
        t2 = 0,
        r1, r2;
    try {
        t1 = arg1.toString().split(".")[1].length
    } catch (e) {}
    try {
        t2 = arg2.toString().split(".")[1].length
    } catch (e) {}
    with(Math) {
        r1 = Number(arg1.toString().replace(".", ""))
        r2 = Number(arg2.toString().replace(".", ""))
        return (r1 / r2) * pow(10, t2 - t1);
    }
}
Number.prototype.div = function (arg) {
    return accDiv(this, arg);
}

function accMul(arg1, arg2) {
    var m = 0,
        s1 = arg1.toString(),
        s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length
    } catch (e) {}
    try {
        m += s2.split(".")[1].length
    } catch (e) {}
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
}
Number.prototype.mul = function (arg) {
    return accMul(arg, this);
}

function accAdd(arg1, arg2) {
    var r1, r2, m;
    try {
        r1 = arg1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2))
    return (arg1 * m + arg2 * m) / m
}
Number.prototype.add = function (arg) {
    return accAdd(arg, this);
}

function accSub(arg1, arg2) {
    return accAdd(arg1, -arg2);
}
Number.prototype.sub = function (arg) {
    return accSub(this, arg);
}
if (!google.maps.Polygon.prototype.getBounds) {
    google.maps.Polygon.prototype.getBounds = function (latLng) {
        var bounds = new google.maps.LatLngBounds();
        var paths = this.getPaths();
        var path;
        for (var p = 0; p < paths.getLength(); p++) {
            path = paths.getAt(p);
            for (var i = 0; i < path.getLength(); i++) {
                bounds.extend(path.getAt(i));
            }
        }
        return bounds;
    }
}

google.maps.Polygon.prototype.containsLatLng = function (latLng) {
    var bounds = this.getBounds();
    if (bounds != null && !bounds.contains(latLng)) {
        return false;
    }
    var inPoly = false;
    var numPaths = this.getPaths().getLength();
    for (var p = 0; p < numPaths; p++) {
        var path = this.getPaths().getAt(p);
        var numPoints = path.getLength();
        var j = numPoints - 1;
        for (var i = 0; i < numPoints; i++) {
            var vertex1 = path.getAt(i);
            var vertex2 = path.getAt(j);
            if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
                if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
                    inPoly = !inPoly;
                }
            }
            j = i;
        }
    }
    return inPoly;
}

function isContainsLatLng(bounds, paths, latLng) {
    if (bounds != null && !bounds.contains(latLng)) {
        return false;
    }
    var inPoly = false;
    var numPaths = paths.getLength();
    for (var p = 0; p < numPaths; p++) {
        var path = paths.getAt(p);
        var numPoints = path.getLength();
        var j = numPoints - 1;
        for (var i = 0; i < numPoints; i++) {
            var vertex1 = path.getAt(i);
            var vertex2 = path.getAt(j);
            if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
                if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
                    inPoly = !inPoly;
                }
            }
            j = i;
        }
    }
    return inPoly;
}
NameOverlay.prototype = new google.maps.OverlayView();

function NameOverlay(point, name, map) {
    this.point_ = point;
    this.name_ = name;
    this.map_ = map;
    this.div_ = null;
    this.setMap(map);
}
NameOverlay.prototype.onAdd = function () {
    var div = document.createElement('DIV');
    div.style.border = "none";
    div.style.position = "absolute";
    var span = document.createElement("span");
    var text = document.createTextNode(this.name_);
    span.appendChild(text);
    div.appendChild(span);
    this.div_ = div;
    var panes = this.getPanes();
    panes.overlayImage.appendChild(div);
}
NameOverlay.prototype.setName = function (name) {
    this.name_ = name;
    this.onAdd();
    this.draw();
}
NameOverlay.prototype.draw = function () {
    var center = this.getProjection().fromLatLngToDivPixel(this.point_);
    this.div_.style.color = 'blue';
    this.div_.style.left = center.x + 15;
    this.div_.style.top = center.y - 40;
    this.div_.style.width = '200px';
}
NameOverlay.prototype.onRemove = function () {
    this.div_.parentNode.removeChild(this.div_);
    this.div_ = null;
}

function getRandomNum(Min, Max) {
    var Range = Max - Min;
    var Rand = Math.random();
    return (Min + Math.round(Rand * Range));
}

function getNormalizedCoord(coord, zoom) {
    var y = coord.y;
    var x = coord.x;
    var tileRange = 1 << zoom;
    if (y < 0 || y >= tileRange) {
        return null;
    }
    if (x < 0 || x >= tileRange) {
        x = (x % tileRange + tileRange) % tileRange;
    }
    return {
        x: x,
        y: y
    };
}

function google_fromLnglatToXY(lat, lng, zoom) {
    var lngLat = new google.maps.LatLng(lat, lng);
    var point = map.getProjection().fromLatLngToPoint(lngLat);
    var x = point.x / 256.0 * Math.pow(2, zoom);
    var y = point.y / 256.0 * Math.pow(2, zoom);
    return x + ',' + y;
}

function google_fromXYToLnglat(x, y, zoom) {
    var point = new google.maps.Point(x / Math.pow(2, zoom) * 256.0, y / Math.pow(2, zoom) * 256.0);
    var lngLat = map.getProjection().fromPointToLatLng(point);
    return [lngLat.lat(), lngLat.lng()];
}

function tdt_fromXYToLnglat(x, y, zoom) {
    var lng = x / Math.pow(2, zoom) * 360 - 180;
    var lat = 90 - y / (0.5 * Math.pow(2, zoom)) * 180;
    return lat + ',' + lng;
}

function tdt_fromLnglatToXY(lat, lng, zoom) {
    var x = (180 + lng) / 360 * Math.pow(2, zoom);
    var y = (90 - lat) / 180 * 0.5 * Math.pow(2, zoom);
    return x + ',' + y;
}

function googleTileXYToBingTileXY(x, y, z) {
    var quadDigits = [];
    for (var i = z; i > 0; --i) {
        var digit = '0';
        var mask = 1 << (i - 1);
        if ((x & mask) != 0) {
            digit++;
        }
        if ((y & mask) != 0) {
            digit++;
            digit++;
        }
        quadDigits.push(digit);
    }
    var quadKey = quadDigits.join("");
    return quadKey;
}

function googleTileXYToQQTileXY(x, y, z) {
    var tileZ = z;
    var tileX = x;
    var tileY = y;
    var scope = new Array(0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0, 7, 0, 7, 0, 15, 0, 15, 0, 31, 0, 31, 0, 63, 4, 59, 0, 127, 12, 115, 0, 225, 28, 227, 356, 455, 150, 259, 720, 899, 320, 469, 1440, 1799, 650, 929, 2880, 3589, 1200, 2069, 5760, 7179, 2550, 3709, 11520, 14349, 5100, 7999, 23060, 28689, 10710, 15429, 46120, 57369, 20290, 29849, 89990, 124729, 41430, 60689, 184228, 229827, 84169, 128886);
    var f = tileZ * 4;
    var i = scope[f++];
    var j = scope[f++];
    var l = scope[f++];
    var scope = scope[f];
    if (tileX >= i && tileX <= j && tileY >= l && tileY <= scope) {
        tileY = Math.pow(2, tileZ) - 1 - tileY;
        var tileNo = tileZ + "/" + Math.floor(tileX / 16) + "/" + Math.floor(tileY / 16) + "/" + tileX + "_" + tileY + this.tileFormat;
    }
    return tileNo;
}

function googleTileXYToBaiduTileXY(x, y, z) {
    var offsetX = Math.pow(2, z - 1);
    var offsetY = offsetX - 1;
    var numX = x - offsetX;
    var numY = (-y) + offsetY;
    var num = (x + y) % 8 + 1;
    x = (numX + '').replace("-", "M");
    y = (numY + '').replace("-", "M");
    return x + ',' + y;
}

function googleTileXYToSogouTileXY(x, y, z) {
    var tilez = z - 1;
    var offsetX = Math.pow(2, tilez);
    var offsetY = offsetX - 1;
    var bx = x;
    var by = y;
    var numX = bx - offsetX;
    var numY = (-by) + offsetY;
    tilez = tilez + 1;
    var zoomLevel = 729 - tilez;
    if (zoomLevel == 710) zoomLevel = 792;
    var blo = Math.floor(numX / 200);
    var bla = Math.floor(numY / 200);
    var blos, blas;
    if (blo < 0)
        blos = "M" + (-blo);
    else
        blos = "" + blo; if (bla < 0)
        blas = "M" + (-bla);
    else
        blas = "" + bla;
    x = numX.toString().replace("-", "M");
    y = numY.toString().replace("-", "M");
    return x + ',' + y;
}

function LocalMapType(name, alt, minZoom, maxZoom, url, tf) {
    this.tileSize = new google.maps.Size(256, 256);
    this.name = name;
    this.alt = alt;
    this.maxZoom = parseInt(maxZoom);
    this.minZoom = parseInt(minZoom);
    this.url = url;
    this.tf = tf;
    this.getTile = function (coord, zoom, ownerDocument) {
        var img = ownerDocument.createElement("img");
        img.style.width = this.tileSize.width + "px";
        img.style.height = this.tileSize.height + "px";
        img.onerror = function () {
            img.src = "../myMaps/mapback.jpg";
        }
        img.src = this.url + "/map/" + zoom + "/" + coord.x + "/" + coord.y + this.tf;
        return img;
    };
}

var localMapType = null;

function googleMapLayers(name, sl, tl, type, hl, gl, minZ, maxZ) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = maxZ;
    this.minZoom = minZ;
    this.name = name;
    this.type = type;
    this.sl = sl;
    this.tl = tl;
    this.hl = hl;
    this.gl = gl;
    this.getTileUrl = function (coord, zoom, ownerDocument) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var sn = getRandomNum(0, 3);
        return 'http://mt' + sn + '.google.' + this.sl + '/vt/' + this.tl + 'lyrs=' + this.type + '&hl=' + this.hl + '&gl=' + this.gl + '&src=app&x=' + coord.x + '&y=' + coord.y + '&z=' + zoom + '&s=Galileo';
    };
}

var server = mapserverno == 0 ? 'cn' : 'com';
var lang = maplag == 0 ? 'zh-CN' : 'en';
var diff = mapdiff == 0 ? 'en' : 'CN';
var googlemapType = new google.maps.ImageMapType(new googleMapLayers('谷歌地圖', server, '', 'm@207000000', lang, diff, 2, 20));
var googlesatType = new google.maps.ImageMapType(new googleMapLayers('谷歌衛圖', server, '', 's@125', lang, diff, 2, 20));
var googlehybType = googlesatType;
var googlesatlabelType = new googleMapLayers('谷歌混合地圖', server, 'imgtp=png32&', 'h@207000000', lang, diff, 2, 20);
var googlesatlabeltile = function (coord, zoom, ownerDocument) {
    var normalizedCoord = getNormalizedCoord(coord, zoom);
    if (!normalizedCoord) {
        return null;
    }
    var img = ownerDocument.createElement("img");
    img.style.width = this.tileSize.width + "px";
    img.style.height = this.tileSize.height + "px";
    img.onerror = function () {}
    var sn = getRandomNum(0, 3);
    img.src = 'http://mt' + sn + '.google.' + this.sl + '/vt/' + this.tl + 'lyrs=' + this.type + '&hl=' + this.hl + '&gl=' + this.gl + '&src=app&x=' + coord.x + '&y=' + coord.y + '&z=' + zoom + '&s=Galileo';
    return img;
};

googlesatlabelType.getTile = googlesatlabeltile;
var googleterType = new google.maps.ImageMapType(new googleMapLayers('谷歌地形圖', server, '', 't@130,r@207000000', lang, diff, 2, 15));

function tpgMapLayers(name, minZ, maxZ) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = maxZ;
    this.minZoom = minZ;
    this.name = name;
    this.getTileUrl = function (coord, zoom, ownerDocument) {
        var box = '';
        var x = coord.x;
        var y = coord.y;
        var d = 20037508.34279;
        box = 2 * d * x / Math.pow(2, zoom) - d;
        box += ',' + (-2 * d * (y + 1) / Math.pow(2, zoom) + d);
        box += ',' + (2 * d * (x + 1) / Math.pow(2, zoom) - d);
        box += ',' + (-2 * d * y / Math.pow(2, zoom) + d);
        return 'http://78.46.61.141/cgi-bin/tilecache-2.11/tilecache.py?LAYERS=topomapper_gmerc&FORMAT=image%2Fjpeg&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A900913&BBOX=' + box + '&WIDTH=256&HEIGHT=256';
    };
}

var tpgmapType = new google.maps.ImageMapType(new tpgMapLayers('掃描地形圖', 2, 18));

function bingMapLayers(name, u1, u2, u3) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = 18;
    this.minZoom = 2;
    this.name = name;
    this.getTileUrl = function (coord, zoom, ownerDocument) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var z = zoom;
        var quadDigits = [];
        for (var i = z; i > 0; --i) {
            var digit = '0';
            var mask = 1 << (i - 1);
            if ((x & mask) != 0) {
                digit++;
            }
            if ((y & mask) != 0) {
                digit++;
                digit++;
            }
            quadDigits.push(digit);
        }
        var quadKey = quadDigits.join("");
        var sn = getRandomNum(0, 3);
        return u1 + sn + u2 + quadKey + u3;
    };
}

var bingmapType = new google.maps.ImageMapType(new bingMapLayers('必應地圖(國內)', 'http://r', '.tiles.ditu.live.com/tiles/r', '.png?g=96&mkt=zh-cn'));
var bingsatType = new google.maps.ImageMapType(new bingMapLayers('必應衛圖', 'http://ecn.t', '.tiles.virtualearth.net/tiles/a', '.jpeg?g=1135&n=z'));
var binghybType = new google.maps.ImageMapType(new bingMapLayers('必應混合地圖', 'http://ecn.t', '.tiles.virtualearth.net/tiles/h', '.jpeg?g=1135&n=z'));

function tdtMapLayers(name, type, minZ, maxZ) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = maxZ;
    this.minZoom = minZ;
    this.name = name;
    this.type = type;
    this.getTileUrl = function (coord, level, ownerDocument) {
        var normalizedCoord = getNormalizedCoord(coord, level);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var maptype = '';
        if (this.type == "EMap") {
            maptype = "vec_w";
        } else if (this.type == "RMap") {
            maptype = "img_w";
        } else if (this.type == "TMap") {
            maptype = "ter_w";
        }
        var sn = getRandomNum(0, 7);
        return 'http://tile' + sn + '.chinaonmap.com/DataServer?T=' + maptype + '&X=' + x + '&Y=' + y + '&L=' + level;
    };
}

var tdtmapType = new google.maps.ImageMapType(new tdtMapLayers('天地圖地圖', 'EMap', 2, 18));
var tdtsatType = new google.maps.ImageMapType(new tdtMapLayers('天地圖衛圖', 'RMap', 2, 18));
var tdtterType = new google.maps.ImageMapType(new tdtMapLayers('天地圖地形圖', 'TMap', 2, 14));

function tdtAnnoLayers(name, type, minZ, maxZ) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = maxZ;
    this.minZoom = minZ;
    this.name = name;
    this.type = type;
    this.getTile = function (coord, level, ownerDocument) {
        var normalizedCoord = getNormalizedCoord(coord, level);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var maptype = '';
        if (this.type == "EAnno") {
            maptype = "cva_w";
        } else if (this.type == "RAnno") {
            maptype = "cia_w";
        } else if (this.type == "TAnno") {
            maptype = "cta_w";
        }
        var img = ownerDocument.createElement("img");
        img.style.width = this.tileSize.width + "px";
        img.style.height = this.tileSize.height + "px";
        img.onerror = function () {}
        var sn = getRandomNum(0, 7);
        img.src = 'http://tile' + sn + '.chinaonmap.com/DataServer?T=' + maptype + '&X=' + x + '&Y=' + y + '&L=' + level;
        return img;
    };
}

var tdtmaplabelType = new tdtAnnoLayers('天地圖地圖註記', 'EAnno', 2, 18);
var tdtsatlabelType = new tdtAnnoLayers('天地圖衛圖註記', 'RAnno', 2, 18);
var tdtterlabelType = new tdtAnnoLayers('天地圖地形圖註記', 'TAnno', 2, 14);

function qqMapLayers(name, type, tileFormat) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = 18;
    this.minZoom = 4;
    this.name = name;
    this.type = type;
    this.tileFormat = tileFormat;
    this.getTileUrl = function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var tileZ = zoom;
        var tileX = coord.x;
        var tileY = coord.y;
        var scope = new Array(0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0, 7, 0, 7, 0, 15, 0, 15, 0, 31, 0, 31, 0, 63, 4, 59, 0, 127, 12, 115, 0, 225, 28, 227, 356, 455, 150, 259, 720, 899, 320, 469, 1440, 1799, 650, 929, 2880, 3589, 1200, 2069, 5760, 7179, 2550, 3709, 11520, 14349, 5100, 7999, 23060, 28689, 10710, 15429, 46120, 57369, 20290, 29849, 89990, 124729, 41430, 60689, 184228, 229827, 84169, 128886);
        var f = tileZ * 4;
        var i = scope[f++];
        var j = scope[f++];
        var l = scope[f++];
        var scope = scope[f];
        if (tileX >= i && tileX <= j && tileY >= l && tileY <= scope) {
            tileY = Math.pow(2, tileZ) - 1 - tileY;
            var tileNo = tileZ + "/" + Math.floor(tileX / 16) + "/" + Math.floor(tileY / 16) + "/" + tileX + "_" + tileY + this.tileFormat;
        }
        var sn = getRandomNum(0, 3);
        return 'http://p' + sn + '.map.soso.com/' + this.type + '/' + tileNo;
    };
}

var sosomapType = new google.maps.ImageMapType(new qqMapLayers('搜搜地圖', 'maptiles', '.png'));
var sososatType = new google.maps.ImageMapType(new qqMapLayers('搜搜衛圖', 'sateTiles', '.jpg'));
var sososatlabelType = new qqMapLayers('搜搜衛圖標籤', 'sateTranTiles', '.png');
sososatlabelType.getTile = function (coord, zoom, ownerDocument) {
    var normalizedCoord = getNormalizedCoord(coord, zoom);
    if (!normalizedCoord) {
        return null;
    }
    var img = ownerDocument.createElement("img");
    img.style.width = this.tileSize.width + "px";
    img.style.height = this.tileSize.height + "px";
    var tileZ = zoom;
    var tileX = coord.x;
    var tileY = coord.y;
    var scope = new Array(0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0, 7, 0, 7, 0, 15, 0, 15, 0, 31, 0, 31, 0, 63, 4, 59, 0, 127, 12, 115, 0, 225, 28, 227, 356, 455, 150, 259, 720, 899, 320, 469, 1440, 1799, 650, 929, 2880, 3589, 1200, 2069, 5760, 7179, 2550, 3709, 11520, 14349, 5100, 7999, 23060, 28689, 10710, 15429, 46120, 57369, 20290, 29849, 89990, 124729, 41430, 60689, 184228, 229827, 84169, 128886);
    var f = tileZ * 4;
    var i = scope[f++];
    var j = scope[f++];
    var l = scope[f++];
    var scope = scope[f];
    if (tileX >= i && tileX <= j && tileY >= l && tileY <= scope) {
        tileY = Math.pow(2, tileZ) - 1 - tileY;
        var tileNo = tileZ + "/" + Math.floor(tileX / 16) + "/" + Math.floor(tileY / 16) + "/" + tileX + "_" + tileY + this.tileFormat;
    }
    var sn = getRandomNum(0, 3);
    img.src = 'http://p' + sn + '.map.soso.com/' + this.type + '/' + tileNo;
    return img;
};

function mapabcMapLayers(name, url, type) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = 18;
    this.minZoom = 2;
    this.name = name;
    this.url = url;
    this.type = type;
    this.getTileUrl = function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var z = zoom;
        var sn = getRandomNum(1, 4);
        return 'http://web' + this.url + '0' + sn + '.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=' + this.type + '&x=' + x + '&y=' + y + '&z=' + z;
    };
}

var mapabcmapType = new google.maps.ImageMapType(new mapabcMapLayers('高德地圖', 'rd', '7'));
var mapabcsatType = new google.maps.ImageMapType(new mapabcMapLayers('高德衛圖', 'st', '6'));
var mapabcsatlabelType = new mapabcMapLayers('高德衛圖標籤', 'st', '8');
mapabcsatlabelType.getTile = function (coord, zoom, ownerDocument) {
    var normalizedCoord = getNormalizedCoord(coord, zoom);
    if (!normalizedCoord) {
        return null;
    }
    var img = ownerDocument.createElement("img");
    img.style.width = this.tileSize.width + "px";
    img.style.height = this.tileSize.height + "px";
    var x = coord.x;
    var y = coord.y;
    var z = zoom;
    var sn = getRandomNum(1, 4);
    img.src = 'http://web' + this.url + '0' + sn + '.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=' + this.type + '&x=' + x + '&y=' + y + '&z=' + z;
    return img;
};

var wyMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var bx = coord.x;
        var by = coord.y;
        var z = zoom;
        var nGrade = Math.ceil((zoom - 5) / 4);
        var nPreRow = 0;
        var nPreCol = 0;
        var nPreSize = 0;
        var path = "";
        for (var i = 0; i < nGrade; ++i) {
            var nSize = 1 << 4 * (nGrade - i);
            var nRow = parseInt((bx - nPreRow * nPreSize) / nSize + "");
            var nCol = parseInt((by - nPreCol * nPreSize) / nSize + "");
            path = path + ((nRow > 9 ? (nRow) : ("0" + nRow)) + "" + (nCol > 9 ? (nCol) : ("0" + nCol)) + "/");
            nPreRow = nRow;
            nPreCol = nCol;
            nPreSize = nSize;
        }
        var id = (((bx) & ((1 << 20) - 1)) + (((by) & ((1 << 20) - 1)) * Math.pow(2, 20)) + (((zoom) & ((1 << 8) - 1)) * Math.pow(2, 40)));
        var sn = getRandomNum(1, 4);
        return 'http://cache8.51ditu.com/' + zoom + '/' + path + id + '.png';
    }, tileSize: new google.maps.Size(256, 256),
    maxZoom: 18,
    minZoom: 4,
    name: "51地圖"
});

function baiduMapLayers(name, type) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = 18;
    this.minZoom = 3;
    this.name = name;
    this.type = type;
    this.getTileUrl = function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var offsetX = Math.pow(2, zoom - 1);
        var offsetY = offsetX - 1;
        var numX = coord.x - offsetX;
        var numY = (-coord.y) + offsetY;
        var num = (coord.x + coord.y) % 8 + 1;
        var x = (numX + '').replace("-", "M");
        var y = (numY + '').replace("-", "M");
        return 'http://q' + num + '.baidu.com/it/u=x=' + x + ';y=' + y + ';z=' + zoom + this.type;
    };
}

var baidumapType = new google.maps.ImageMapType(new baiduMapLayers('百度地圖', ';v=015;type=web&fm=44'));
var baidusatType = new google.maps.ImageMapType(new baiduMapLayers('百度衛圖', ';v=009;type=sate&fm=46'));
var baidusatlabelType = new baiduMapLayers('百度衛圖 標籤', ';v=015;type=trans&fm=47');
baidusatlabelType.getTile = function (coord, zoom, ownerDocument) {
    var normalizedCoord = getNormalizedCoord(coord, zoom);
    if (!normalizedCoord) {
        return null;
    }
    var img = ownerDocument.createElement("img");
    img.style.width = this.tileSize.width + "px";
    img.style.height = this.tileSize.height + "px";
    var offsetX = Math.pow(2, zoom - 1);
    var offsetY = offsetX - 1;
    var numX = coord.x - offsetX;
    var numY = (-coord.y) + offsetY;
    var num = (coord.x + coord.y) % 8 + 1;
    var x = (numX + '').replace("-", "M");
    var y = (numY + '').replace("-", "M");
    img.src = 'http://q' + num + '.baidu.com/it/u=x=' + x + ';y=' + y + ';z=' + zoom + this.type;
    return img;
};

var eMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var z = 13 - zoom;
        var x, y, m;
        m = Math.pow(2, zoom) / 2;
        x = coord.x - m;
        y = coord.y - m;
        var sn = getRandomNum(1, 4);
        return 'http://cpic2.edushi.com/cn/beijing/zh-chs/mappic/png' + z + '/' + x + ',' + y + '.png';
    }, tileSize: new google.maps.Size(256, 256),
    maxZoom: 13,
    minZoom: 10,
    name: "E都市"
});

function sogouMapLayers(name, url, type, tileFormat) {
    this.tileSize = new google.maps.Size(256, 256);
    this.maxZoom = 18;
    this.minZoom = 3;
    this.name = name;
    this.url = url;
    this.type = type;
    this.tileFormat = tileFormat;
    this.getTileUrl = function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var tilez = zoom - 1;
        var offsetX = Math.pow(2, tilez);
        var offsetY = offsetX - 1;
        var bx = coord.x;
        var by = coord.y;
        var numX = bx - offsetX;
        var numY = (-by) + offsetY;
        tilez = tilez + 1;
        var zoomLevel = 729 - tilez;
        if (zoomLevel == 710) zoomLevel = 792;
        var blo = Math.floor(numX / 200);
        var bla = Math.floor(numY / 200);
        var blos, blas;
        if (blo < 0)
            blos = "M" + (-blo);
        else
            blos = "" + blo; if (bla < 0)
            blas = "M" + (-bla);
        else
            blas = "" + bla;
        var x = numX.toString().replace("-", "M");
        var y = numY.toString().replace("-", "M");
        var sn = getRandomNum(0, 3);
        return 'http://' + this.url + sn + '.go2map.com/' + this.type + zoomLevel + "/" + blos + "/" + blas + "/" + x + "_" + y + this.tileFormat;
    };
}

var sogoumapType = new google.maps.ImageMapType(new sogouMapLayers('搜狗地圖', 'p', 'seamless1/0/174/', '.GIF'));
var sogousatType = new google.maps.ImageMapType(new sogouMapLayers('搜狗衛圖', 'hbpic', 'seamless/0/180/', '.JPG'));
var sogousatlabelType = new sogouMapLayers('搜狗衛圖標籤', 'hbpic', 'seamless/0/179/', '.png');
sogousatlabelType.getTile = function (coord, zoom, ownerDocument) {
    var normalizedCoord = getNormalizedCoord(coord, zoom);
    if (!normalizedCoord) {
        return null;
    }
    var img = ownerDocument.createElement("img");
    img.style.width = this.tileSize.width + "px";
    img.style.height = this.tileSize.height + "px";
    var tilez = zoom - 1;
    var offsetX = Math.pow(2, tilez);
    var offsetY = offsetX - 1;
    var bx = coord.x;
    var by = coord.y;
    var numX = bx - offsetX;
    var numY = (-by) + offsetY;
    tilez = tilez + 1;
    var zoomLevel = 729 - tilez;
    if (zoomLevel == 710) zoomLevel = 792;
    var blo = Math.floor(numX / 200);
    var bla = Math.floor(numY / 200);
    var blos, blas;
    if (blo < 0)
        blos = "M" + (-blo);
    else
        blos = "" + blo; if (bla < 0)
        blas = "M" + (-bla);
    else
        blas = "" + bla;
    var x = numX.toString().replace("-", "M");
    var y = numY.toString().replace("-", "M");
    var sn = getRandomNum(0, 3);
    img.src = 'http://' + this.url + sn + '.go2map.com/' + this.type + zoomLevel + "/" + blos + "/" + blas + "/" + x + "_" + y + this.tileFormat;
    return img;
};

var yahooMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var z = zoom;
        return 'http://img.ditu.aliyun.com/get_png?v=v4&x=' + x + '&y=' + y + '&z=' + z;
    }, tileSize: new google.maps.Size(256, 256),
    maxZoom: 18,
    minZoom: 3,
    name: "雅虎地圖"
});

var yahooSatType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
            return null;
        }
        var x = coord.x;
        var y = coord.y;
        var z = zoom;
        return 'http://img.ditu.aliyun.com/get_png?v=v4&x=' + x + '&y=' + y + '&z=' + z;
    }, tileSize: new google.maps.Size(256, 256),
    maxZoom: 18,
    minZoom: 2,
    name: "雅虎地圖"
});

function CopyrightMapType() {
    this.tileSize = new google.maps.Size(256, 256);
}

CopyrightMapType.prototype.getTile = function (coord, zoom, ownerDocument) {
    var div = ownerDocument.createElement('div');
    div.innerHTML = '<br><br><br><br><br><br><br><p align="center">Copyright ©2013 谷地GoodyGIS</p>';
    div.style.width = this.tileSize.width + 'px';
    div.style.height = this.tileSize.height + 'px';
    div.style.fontSize = '14';
    div.style.color = '#0000ff';
    div.style.borderStyle = 'solid';
    div.style.borderWidth = '1px';
    div.style.borderColor = '#AAAAAA';
    return div;
};

  

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!DOCTYPE html>
<head>
    <title></title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <META NAME="Author" CONTENT="WangYaodong">
    <META NAME="Keywords" CONTENT="">
    <META NAME="Description" CONTENT=", google earth, google map">
    <meta http-equiv="X-UA-Compatible" content="IE=8">
    <style type="text/css">
    html { height: 100% } 
    body { height: 100%; width: 100%; margin: 0px; padding: 0px }

    .bg{
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: url(./Images/background.jpg) no-repeat #000;
        z-index: -1;
        filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='./Images/background.jpg', sizingMethod='scale');
    }

    .ld{
         position:absolute;
        left:30px;
        top:20px;
        width: 128px;
        height: 128px;
        background:url(ld.png) no-repeat;
        z-index: 1000001;
    }

    .displayMap { width: 100%; height: 100% }
    .hideMap { width: 0; height: 0 }
</style>
    <script type="text/javascript">
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/rv:([\d.]+)\) like gecko/)) ? Sys.ie = s[1] :
(s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
(s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;

if (Sys.ie) 
{
    //alert('你是使用IE'+Sys.ie); 
    //window.location.href="map.html"; 
}
else if (Sys.firefox)
{
    //alert('你是使用Firefox'+Sys.firefox); 
    window.location.href="error.html"; 
}
else if (Sys.chrome)
{
    //alert('你是使用Chrome'+Sys.chrome); 
    window.location.href="error.html"; 
}
else if (Sys.opera)
{
    //alert('你是使用Opera'+Sys.opera); 
    window.location.href="error.html"; 
}
else if (Sys.safari)
{
    //alert('你是使用Safari'+Sys.safari); 
    window.location.href="error.html"; 
}
else
{
    window.location.href="error.html"; 
}
</script>
    <script type="text/javascript">
var mapserverno=0;
var maplag=0;
var mapdiff=0;
var map=null;
var googlemapver='m@207000000';
var googlesatver='s@125';
var googlehybver='h@207000000';
var googleterver='t@130,r@207000000';

function getMapServerandLag(){
    var serverlag=window.external.getMapServerandLag_callback().split(',');
    mapserverno=serverlag[0];
    maplag=serverlag[1];
    mapdiff=serverlag[2];
}

function setMapServerandLag(server,lag,diff){
    mapserverno=server;
    maplag=lag;
    mapdiff=diff;
}

getMapServerandLag();

function setGoogleMapVersion(map,sat,hyb,ter){
    if(map!='')
        googlemapver=map;
    if(sat!='')
        googlesatver=sat;
    if(hyb!='')
        googlehybver=hyb;
    if(ter!='')
        googleterver=ter;
}
</script>
    <script type="text/javascript" src="./googlemapapi/mapapi.js"></script>
    <script type="text/javascript" src='./Js/earth.js'></script>
    <script type="text/javascript" src="./Js/jquery.min.js"></script>
    <script type="text/javascript" src='./Js/extensions-0.2.1.pack.js'></script>
    <script type="text/javascript">

/*
        <![CDATA[ */
var loadEarth=false;
var loadMap=false;
var loadMyMap=false;
var mouseMsgflag=false;
var lastMapMod='earth';
var centerPoint=null;
var ge=null;
var gex=null;
var mod='m';
var mymapDir='';
var mymapZoomMax=0;
var mymapZoomMin=0;
var clat=31.8;
var clng=117.2;
var mapzoom=4;
var maplayerprojection='GoogleProjection';

function setMapLayers(maplayer){
    if(map!=null){map.mapTypes.set('maplayer',eval(maplayer.split('_')[1]+'Type'));map.setMapTypeId('maplayer');clearMapOverlayers();}
}

function setSatLayers(maplayer,overLabel){
    setMapLayers(maplayer);if(overLabel!=''){addMapOverlayer(overLabel);}
}

function setMapOverlayers(overlayer){
    map.overlayMapTypes.insertAt(0,eval(overlayer.split('_')[1]+'Type'));
}

function clearMapOverlayers(){
    map.overlayMapTypes.clear();
}

function removeMapOverlayers(key){
    map.overlayMapTypes.removeAt(key);
}

function addMapOverlayer(overlayer){
    setMapOverlayers(overlayer);
}

function setMapLang(no,id){
    maplag=no;lang=maplag==0?'zh-CN':'en';updataGGMapLayers(id);
}

function setMapServer(no,id){
    mapserverno=no;server=mapserverno==0?'cn':'com';updataGGMapLayers(id);
}

function setMapDiff(no,id){
    mapdiff=no;diff=mapdiff==0?'en':'CN';updataGGMapLayers(id);
}

function updataGGMapLayers(id){
    googlemapType=new google.maps.ImageMapType(new googleMapLayers('谷歌地圖',server,'',googlemapver,lang,diff,2,20));
    googlesatType=new google.maps.ImageMapType(new googleMapLayers('谷歌衛圖',server,'',googlesatver,lang,diff,2,20));
    googlehybType=googlesatType;googlesatlabelType=new googleMapLayers('谷歌混合地圖',server,'imgtp=png32&',googlehybver,lang,diff,2,20);
    googlesatlabelType.getTile=googlesatlabeltile;googleterType=new google.maps.ImageMapType(new googleMapLayers('谷歌地形圖',server,'',googleterver,lang,diff,2,15));

    if(id<4&&map!=null){
        clearMapOverlayers();
        map.mapTypes.set('googlemap',googlemapType);
        map.mapTypes.set('googlesat',googlesatType);
        map.mapTypes.set('googlehyb',googlehybType);
        map.mapTypes.set('googleter',googleterType);
        if(id==0){
            map.setMapTypeId('googlemap');
        }else if(id==1){
            map.setMapTypeId('googlesat');}else if(id==2){map.setMapTypeId('googlehyb');map.overlayMapTypes.insertAt(0,googlesatlabelType);}else if(id==3){map.setMapTypeId('googleter');
        }
    }
}

function setMapMod(mapMod){
    if(mapMod=='map'){
        showMap();
    }else if(mapMod=='mymap'){
    }
    else{
        showEarth();
    }
}

function showEarth(){
    $('#map').attr('class','hideMap');
    $('#map3d').attr('class','displayMap');
    lastMapMod='earth';
}

var myOptions=null;

function loadedMap(){
    var myLatlng=new google.maps.LatLng(clat,clng);
    myOptions={zoom:mapzoom,center:myLatlng,scaleControl:true,mapTypeId:google.maps.MapTypeId.ROADMAP,panControl:true,
        panControlOptions:{position:google.maps.ControlPosition.RIGHT_TOP},zoomControl:true,
        zoomControlOptions:{style:google.maps.ZoomControlStyle.LARGE,position:google.maps.ControlPosition.RIGHT_TOP},
        streetViewControl:true,streetViewControlOptions:{position:google.maps.ControlPosition.RIGHT_TOP}}
    document.getElementById('map').innerHTML='';
    map=new google.maps.Map(document.getElementById("map"),myOptions);
    getMouseCoordinates();
    getMapLookAt();
    loadMap=true;
    lastMapMod='map';
    //alert("loadmap");
}

function showMap(){
    $('#map3d').attr('class','hideMap');
    $('#map').attr('class','displayMap');
    if(!loadMap){
        loadedMap();
    }
    //alert("showmap");
}

function setMymapParams(name,tf,lat,lng,dir,zMax,zMin){
    var mymapurl='../myMaps/'+dir;var picEtx=(tf=='')?'.jpg':tf;
    gotoLocationbyPoint(new google.maps.LatLng(parseFloat(lat),parseFloat(lng)),parseInt(zMin));
    localMapType=new LocalMapType('本地','本地地圖',zMin,zMax,mymapurl,picEtx);
    clearMapOverlayers();
    map.overlayMapTypes.insertAt(0,localMapType);
}

function getMouseCoordinates(){
    google.maps.event.addListener(map,'mousemove',
    function(event){
        var lat=event.latLng.lat().toFixed(6);
        var lng=event.latLng.lng().toFixed(6);
        var alt=0;
        try{
            alt=ge.getGlobe().getGroundAltitude(lat,lng).toFixed(2);
        }
        catch(err){
        }
        window.external.displayLatLngAlt(lat,lng,alt);
        if(mouseMsgflag){
            window.external.showMsgTrackMouse();
        }
    });
}

function getMapLookAt(){
    google.maps.event.addListener(map,'bounds_changed',
        function(){
            var mapCenter=map.getCenter();
            clat=mapCenter.lat();
            clng=mapCenter.lng();
            mapzoom=map.getZoom();
            window.external.showMapZoom(mapzoom);
        }
    );
}

function setMapLookAt(zoom){
    gotoLocationbyPoint(new google.maps.LatLng(clat,clng),zoom);
}

function setOnEventListenerShowMsgMousemove(flag){
    mouseMsgflag=flag;
}

function setIconUrl(icon,title){
    iconUrl=icon;
    markerTitle=title;
    if(lastMapMod=='earth'){
        pointStyle={label:{scale:1, color:'White', opacity:1}, 
                    icon:{href:iconUrl, color:'White', opacity:1, scale:1.1}};
    }
}

function importNetMap(mapname,url,tileformat,minZoom,maxZoom,centerLat,centerLng){
    gotoLocationbyPoint(new google.maps.LatLng(parseFloat(centerLat),parseFloat(centerLng)),parseInt(minZoom));
    localMapType=new LocalMapType(mapname,'遠程地圖',parseInt(minZoom),parseInt(maxZoom),url,tileformat);
    clearMapOverlayers();
    map.overlayMapTypes.insertAt(0,localMapType);
}

/*
var n=0;
function freshWebPage(){
    if(n===0){
        window.location.reload();
        n=1;
        alert("refresh0 " + n);
    }

    alert("refresh1");
}
*/

function freshWebPage(){
    //alert("refresh1");
    window.location.reload();
}

function document.onkeydown(){
    if(event.keyCode==116){
        event.keyCode=0;event.cancelBubble=true;return false;
    }
}

function document.oncontextmenu(){
    return false;
}

/* ]]> */

    </script>
</head>
<body>
    <div class='displayMap' id="map3d"></div>
    <div class='hideMap' id="map"></div>
</body>
</html>

 

網上有不少關於googleearth開發的博文,可是雜亂,不繫統。但願這篇文章能幫助到您。

相關文章
相關標籤/搜索