#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma version=1.0.0 // to help with version control STATIC STRCONSTANT kstrVersion_Number="1.0.0" //Code to create KMLs that are either lines or a set of markers. The markers can be colored and/or sized by some f(z) wave. //All waves must be in the same data folder. Adding support for multiple data folders is possible, but a pain. You would // need to make the panel a lot bigger to handle long wave names and paths, and I don't want to do that. //Requires the use of the panel. All function names start with KML_. //Somewhat tested, use at your own risk, etc, etc, etc... //20220902: KJZ: I modified this from the version from Ken Aikin at NOAA. I cleaned up the panel and added a little more flexibility for the marker size. // There is still much to do. I also fixed a bug related to converting the Igor 16-bit colors into Google Earth 8 bit colors. If the Igor color was 0, // then the GE color code would be negative, which messed up the KML. //20220902: New ipf name, removed all unused functions, goal is to combine the KML line ipf with the KML marker ipf. //20220903: Rearranged controls to add a Time wave dropdown menu. Changed all control functions to use STRUCTS. Cleaned up the names // of some of the variables. //20220904: Further rearrangement of the controls for a more compact layout. Started adding support for custom color table waves. Code cleanup for the // optional altitude waves. Now no longer creates a dummy wave of 0s. Removed unneeded waves from the line KML function. So far seems to work. //20220904a: Redid the Line KML to hopefully play nicer with Google Earth. Before, you had to change something on the Style, Color tab in GE to change the // line color and size in GE. Fixed now. Major rewrite of KML_Line_Button_Make_File to be cleaner. Have two ways to zap the NaNs, not sure which is // better. Added support for color table waves. Removed the creaton of the M_Colors wave (so no waves are created when you make the kml). Cleaned up // KML_Marker_Button_Make_File as well. All seems to work. Removed the Reverse Matrix function (now done with MatrixOp). //20220905: Redid the marker function so instead of using a fixed number of styles/bins it calculates the exact color and marker size based on the f(z) value, // akin to what Igor actually does for f(z). Added support for making markers of one size and color. Changed several controls. Added ability to scale // colors and sizes by the log of f(z). Added checks for the bin sizes being the same and the markers sizes being the same. Will abort in either case. // Added a circle icon to the symbol list. Circle icon will always have a black rim. Redid the symbol list so you have the option of two predefined GE // symbols (circle and shaded dot) and three non-GE symbols (circle, square, diamond). The three non-GE symbols don't have a black outline but require // a separate png file where the shape is defined. The code to make the custom symbols is a little sketchy, but I have other things to do and it's close // enough. Rearranged controls so the color scale box is bigger for long graph names. Removed the Symbol popup procedure. Made the f(z) wave optional. //20220906: New way of getting the custom icons. Now I make a graph with a text box with a black Igor marker, save that graph, load it into Igor, convert // the matrix into the proper form (white for the marker, transparent outside), and then save the wave (not the graph). It's kludgy, but now you can // access all the precreated Igor markers. Right now only have access to circles, squares, diamonds, and hexagons. I supposed I could have used the // drawing tools, but the process would be the same. Using the built in markers was easier than coming up with the code to draw various shapes. // Fixed a bug in the single color/size marker code related to the altitude. Added ExtendedData (KML field) that lists the experiment name, the lat, lon, // alt, and f(z) waves as well as the resolution. Added support for log colors to the color scale graph creation code. Added error checks to the CS graph // code (might not be done). Added check to see if the KML already exists. Maybe added a check so if your f(z) wave is none but the Color as f(z) and Marker // size as f(z) boxes are checked it will just ignore the color/marker stuff. //20220907: Added help text for various controls. //20220908: Bug fixes for flag logic in both the lines and markers code. Added support for a time slider bar for the marker code based on Dave Thomson's LV // code. Made the time slider bar show the whole time range at startup. Changed the XML version from 2.0 to 2.2. //20220928: Renamed the "bin" controls, strings, and variables since I'm not using bins anymore. //20221130: Changed the default GUI font and size so the panel looks the same in MacOS and Windows (in theory). Renamed one function so it's less then 32 characters. //20230605: Minor tweaks to the control locations and appearance to try and make it place nice on both MacOS and Windows. //20230606: Rearragned things again. Panel is a little shorter and narrower. Added a help notebook. //20230628: Minor tweaks. //20230802: Reordered controls to have more space between the popups. Renamed controls so it's easier to get lists. Renamed the string setvars to _SetStr_ // Added a window hook for the popups and some setvars. //20230803: Tweaks to the help text. Changed the setvar scrolll hook code so you can increment by 10x the normal increment if you hold down the command/control key. //20230810: Added a popup proc to automatically get the min/max for the F(z) wave. //Version 1.0.0 First public release //Built in Google Earth icons can be found here: http://kml4earth.appspot.com/icons.html STATIC CONSTANT kvDefault_Notebook_Size=12 //Controls the default (minimum) font size in the help notebook STATIC CONSTANT kvScroll_Direction=-1 //Change this to -1 if the scroll direction offends you STATIC STRCONSTANT kstrGoogle_Earth_Symbols="GE circle;GE shaded_dot;" STATIC STRCONSTANT kstrIgor_Symbols="Circle;Square;Diamond;Hexagon;" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MENU "Useful Tools" SUBMENU "KML Panel" "Make panel", KML_Panel_Creation() "-" "Get help", KML_Get_Help("") END END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Makes the panel FUNCTION KML_Panel_Creation() DefaultGUIFont/Mac all={"Arial", 12, 0} DefaultGUIFont/Win all={"Arial", 12, 0} String strWindow_Name=UniqueName("KML_Panel_", 9, 0) NewPanel/N=$strWindow_Name/W=(73,158,487,609) as strWindow_Name TitleBox P0_TitleBox,pos={13.00,1.00},size={87,17},title="KML Creator "+kstrVersion_Number,fSize=14,frame=0,fStyle=1 Button P0_Button_1dot_Wave_Selection,pos={374.00,4},size={35.00,15.00},proc=KML_Panel_Button_Get_Help,title="Help",help={"Opens the help notebook"},fSize=11,fStyle=1,fColor=(49151,65535,49151) GroupBox P0_GroupBox_Waves,pos={6.00,15.00},size={403,148.00},title="Waves",frame=0 PopupMenu P0_Pop_Wave_Latitude,pos={61,31.00},size={99,17.00},title="Latitude:",fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WaveList(\"*\", \";\", \"TEXT:0,DIMS:1\"), \";\", 16)",appearance={default,all} PopupMenu P0_Pop_Wave_Longitude,pos={50,53.00},size={110,17.00},title="Longitude:",fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WaveList(\"*\", \";\", \"TEXT:0,DIMS:1\"), \";\", 16)",appearance={default,all} PopupMenu P0_Pop_Wave_Altitude,pos={10.00,75.00},size={150.00,17.00},title="Altitude (optional):",fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WaveList(\"*\", \";\", \"TEXT:0,DIMS:1\"), \";\", 16)",appearance={default,all} PopupMenu P0_Pop_Wave_Altitude,help={"If you select \"none\" then the points will be on the ground instead of at the actual altitude."} PopupMenu P0_Pop_Wave_Fz,pos={30.00,97.00},size={130.00,23.00},proc=KML_Marker_Pop_Fz,title="F(z) (optional):",fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WaveList(\"*\", \";\", \"TEXT:0,DIMS:1\"), \";\", 16)",appearance={default,all} PopupMenu P0_Pop_Wave_Fz, help={"If you select \"none\" then the markers will be the same size and color."} PopupMenu P0_Pop_Wave_Time,pos={22,119.00},size={138.00,17.00},title="Time (optional):",fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WaveList(\"*\", \";\", \"TEXT:0,DIMS:1\"), \";\", 16)",appearance={default,all} SetVariable P0_SetVar_DataRes,pos={10.00,141.00},size={144.00,17.00},bodyWidth=45,title="Use every N pnts:",fSize=12,limits={1,inf,1},value=_NUM:10 SetVariable P0_SetVar_UTC_Offset,pos={160.00,141.00},size={114.00,17.00},bodyWidth=50,title="UTC Offset",fSize=12,limits={-12,14,1},value=_NUM:0 SetVariable P0_SetVar_UTC_Offset,help={"Only needed if you have a time wave."} TabControl P0_Tab_Control,pos={1.00,165.00},size={414,283},tabLabel(0)="Line",tabLabel(1)="Markers",value= 0,proc=KML_Panel_Tab_Control //Tab 0 GroupBox T0_GroupBox_Line_Settings,pos={6.00,193},size={160,71.00},title="Line settings",frame=0 SetVariable T0_SetVar_Line_Width,pos={14.00,215.00},size={108.00,19.00},bodyWidth=50,title="Line width",fSize=12,limits={0,inf,0.1},value= _NUM:2 PopupMenu T0_Pop_Line_Color,pos={17.00,240.00},size={105.00,17.00},title="Line color",fSize=12,mode=2,popColor= (65535,65535,65535),value= #"\"*COLORPOP*\"" Button T0_Button_2dot_Line,pos={178.00,206.00},size={35.00,15.00},proc=KML_Panel_Button_Get_Help,title="Help",help={"Opens the help notebook"},fSize=11,fStyle=1,fColor=(49151,65535,49151) TitleBox T0_Title_Time_Note,pos={9.00,269.00},size={276.00,32.00},title="I haven't figued out how to add timestamps to lines.\rSelecting a timewave won't do anything.",frame=0 SetVariable T0_SetStr_File_Name,pos={9,310.00},size={400,18.00},bodyWidth=341,title="File name",fSize=12,value= _STR:"", help={"Don't add the .kml extension to the file name."} TitleBox T0_Title_File_Name_Note,pos={331,330.00},size={82.00,15.00},title="Don't add .kml",fSize=12,frame=0 Button T0_Button_Make_KML,pos={9.00,340},size={120,25.00},title="Make KML file",proc=KML_Line_Button_Make_File,appearance={os9,all},fSize=16,fstyle=1,fColor=(0,0,65535),valueColor=(65535,65535,65535) //Tab 1 Button T1_Button_3dot_Markers,pos={374.00,186.00},size={35.00,15.00},proc=KML_Panel_Button_Get_Help,title="Help",help={"Opens the help notebook"},fSize=11,fStyle=1,fColor=(49151,65535,49151),disable=1 //Fz values GroupBox T1_GroupBox_Fz_Valuess,pos={6.00,193},size={140,80},title="Fz min/max",frame=0,disable=1 SetVariable T1_SetVar_Fz_Min,pos={17,210.00},size={123,19.00},bodyWidth=100,title="Min",fSize=12,value= _NUM:0,disable=1,limits={-inf,inf,0} SetVariable T1_SetVar_Fz_Min,help={"Must be a real number (no NaNs or Infs).\rIf doing log scaling, must be a postive number."} SetVariable T1_SetVar_Fz_Max,pos={15,230.00},size={125,19.00},bodyWidth=100,title="Max",fSize=12,value= _NUM:0,disable=1,limits={-inf,inf,0} SetVariable T1_SetVar_Fz_Max,help={"Must be a real number (no NaNs or Infs).\rIf doing log scaling, must be a postive number."} Button T1_Button_Get_Min_Max_Values,pos={60,250.00},size={80,20.00},proc=KML_Marker_Button_Fz_Min_Max,title="Get min/max",disable=1 Button T1_Button_Get_Min_Max_Values,help={"Gets the min/max values from the f(z) wave, assuming it exists."} //Markers GroupBox T1_GroupBox_Markers,pos={153.00,193.00},size={256.00,80.00},title="Markers",frame=0,disable=1 String strMarker_List="\""+kstrGoogle_Earth_Symbols+kstrIgor_Symbols+"\"" PopupMenu T1_Pop_Symbol,pos={158.00,208},size={113.00,17.00},title="Symbol:",fSize=12,mode=1,popvalue="GE circle",value= #strMarker_List,disable=1 PopupMenu T1_Pop_Symbol help={"GE circle has a black border, and GE shaded_dot has shading, so you don't quite\rget the color you want. The other shapes are only one color."} CheckBox T1_Check_SizeFz,pos={158,230},size={122.00,23.00},title="Marker size as f(z)",fSize=14,value= 1,proc=KML_Marker_Check_Fz_Size_Color,disable=1 CheckBox T1_Check_Log_Size,pos={300,230},size={64.00,16.00},title="Log size",fSize=12,value= 0,disable=1 CheckBox T1_Check_Log_Size,help={"If checked (and both Fz min and max values are positive), then use log\rscaling for the marker sizes. If unchecked (or either min/max values\rare negative), use linear scaling."} SetVariable T1_SetVar_Marker_Size_Min,pos={161,249.00},size={108,18.00},bodyWidth=60,title="Min size",fSize=12,value= _NUM:0.5,limits={0,inf,0.1},disable=1 SetVariable T1_SetVar_Marker_Size_Max,pos={285,249},size={110,18.00},bodyWidth=60,title="Max size",fSize=12,value= _NUM:2.5,limits={0,inf,0.1},disable=1 SetVariable T1_SetVar_Marker_Size_Default,pos={161,249},size={116,18.00},bodyWidth=50,title="Marker size",fSize=12,value= _NUM:1,limits={0,inf,0.1},disable=1 //Colors GroupBox T1_GroupBox_Colors,pos={6,272},size={403,62},title="Colors",frame=0,disable=1 CheckBox T1_Check_ColorFz,pos={13,289},size={97.00,17.00},title="Color as f(z)",fSize=14,value= 1,proc=KML_Marker_Check_Fz_Size_Color,disable=1 PopupMenu T1_Pop_Marker_Color,pos={12,309},size={82.00,17.00},title="Marker color",fSize=12,mode=2,popColor= (65535,65535,65535),value= #"\"*COLORPOP*\"",disable=1 CheckBox T1_Check_Reverse_Colors,pos={117,289},size={101.00,16.00},title="Reverse colors",fSize=12,value= 0,disable=1 CheckBox T1_Check_Log_Colors,pos={225,289},size={76.00,16.00},title="Log colors",fSize=12,value= 0,disable=1 CheckBox T1_Check_Log_Colors,help={"If checked (and both Fz min and max values are positive), then use log\rscaling for the marker sizes. If unchecked (or either min/max values\rare negative), use linear scaling."} CheckBox T1_Check_Custom_Color_Table,pos={13,311},size={61.00,16.00},title="Custom",fSize=12,value= 0,proc=KML_Marker_Check_Fz_Size_Color,disable=1 CheckBox T1_Check_Custom_Color_Table, help={"You need to load/create the custom color table before it can be used.\rIgor has a lot of color tables stored as .ibw files in the Igor Pro folder,\rwhich can be accessed from the Help menu."} PopupMenu T1_Pop_Color_Table,pos={83,309.00},size={250.00,20.00},bodyWidth=250,fSize=12,mode=2,value=#"\"*COLORTABLEPOP*\"",disable=1 PopupMenu T1_Pop_Custom_Color_Table_Wave,pos={83,309},size={58.00,23.00},fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WaveList(\"*\", \";\", \"TEXT:0,DIMS:2\"), \";\", 16)",disable=1 PopupMenu T1_Pop_Custom_Color_Table_Wave, help={"This only selects 2-D non-text waves."} //Color scale GroupBox T1_GroupBox_Color_Scale,pos={6.00,334},size={403,60.00},title="Color scale",frame=0,disable=1 CheckBox T1_Check_Color_Scale,pos={14,351.00},size={80.00,16.00},title="Color scale",fSize=12,value= 0,proc=KML_Marker_Check_Fz_Size_Color,disable=1 PopupMenu T1_Pop_Color_Scale_Label_Side,pos={99,349.00},size={80,23.00},title="Side",fSize=12,mode=1,popvalue="Left",value= #"\"Left;Right;Top;Bottom\"",disable=1 CheckBox T1_Check_Transparent,pos={203,351.00},size={86.00,16.00},title="Transparent",fSize=12,value= 0,disable=1 CheckBox T1_Check_Transparent,help={"Makes any white colors on the plot transparent\rwhen loaded into Google Earth."} Button T1_Button_Make_Color_Scale_Plot,pos={297,348},size={60,20.00},proc=KML_Marker_Button_Make_CS_Plot,title="Make plot",fSize=10,fStyle=1,disable=1 Button T1_Button_Make_Color_Scale_Plot, help={"Makes a plot that will get used as the color scale in Google Earth.\rYou will want to tweak the settings to make it look nice."} PopupMenu T1_Pop_CS_Graph,pos={14,369},size={160.00,22.00},title="Graph",fSize=12,mode=1,popvalue="none",value= #"\"none;\"+sortlist(WinList(\"*\", \";\", \"WIN:1\"))",disable=1 SetVariable T1_SetStr_File_Name,pos={9,399.00},size={400,18.00},bodyWidth=341,title="File name",fSize=12,value= _STR:"",disable=1 SetVariable T1_SetStr_File_Name, help={"Don't add the .kml extension to the file name."} TitleBox T1_Title_File_Name_Note,pos={331,419},size={82.00,15.00},title="Don't add .kml",fSize=12,frame=0,disable=1 Button T1_Button_Make_KML,pos={9.00,418.00},size={120.00,25.00},proc=KML_Marker_Button_Make_File,title="Make KML file",disable=1,appearance={os9,all},fSize=16,fstyle=1,fColor=(0,0,65535),valueColor=(65535,65535,65535) SetWindow kwTopWin,hook(KML_Scroll_Hook)=KML_Panel_Scroll_Hook END ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION KML_Panel_Scroll_Hook(s) STRUCT WMWinHookStruct &s STRSWITCH(s.eventName) CASE "mouseWheel": String strWindow_Name=s.winName Variable vMouse_X_Pos=s.mouseLoc.h Variable vMouse_Y_Pos=s.mouseLoc.v Variable vScroll_Mode=s.wheelDy<0 Variable vIncrement=SelectNumber(vScroll_Mode, -1, 1)*kvScroll_Direction //Checks to see if we are on a setvariable WAVE/T twSetVar_Controls=ListToTextWave(ControlNameList(strWindow_Name, ";", "*_SetVar_*"), ";") Variable vNum_SetVars=numpnts(twSetVar_Controls) Variable iSetVar_Dex=0, vSetVar_Flag=0 DO String strSetVar_Ctrl_Name=twSetVar_Controls[iSetVar_Dex] //Loop over the setvars until we find the active one the mouse is over ControlInfo/W=$strWindow_Name $strSetVar_Ctrl_Name vSetVar_Flag=(vMouse_X_Pos>=V_left && vMouse_X_Pos<=(V_left+V_Width) && vMouse_Y_Pos>=(V_top) && vMouse_Y_Pos<=(V_top+V_Height) && V_disable==0) iSetVar_Dex+=1 WHILE(!vSetVar_Flag && iSetVar_Dex=V_left && vMouse_X_Pos<=(V_left+vWidth_Mod) && vMouse_Y_Pos>=(V_top) && vMouse_Y_Pos<=(V_top+V_Height) && V_disable==0) iPop_Dex+=1 WHILE(!vPop_Flag && iPop_Dex=0 && vSetVar_Limits_Stop>=0) String strSetVar_Limits=S_Recreation[vSetVar_Limits_Start+8, vSetVar_Limits_Stop-1] Variable vSetVar_Min=str2num(StringFromList(0, strSetVar_Limits, ",")) Variable vSetVar_Max=str2num(StringFromList(1, strSetVar_Limits, ",")) Variable vSetVar_Increment=str2num(StringFromList(2, strSetVar_Limits, ","))*SelectNumber(s.eventmod & 8, 1, 10) IF(cmpstr(StringFromList(2, strSetVar_Limits, ","), "0")!=0) //A little redundant, but better safe than sorry Variable vSetVar_New_Value=limit(vSetVar_Value+vSetVar_Increment*vIncrement, vSetVar_Min, vSetVar_Max) SetVariable/Z $strSetVar_Ctrl_Name, win=$strWindow_Name, value=_NUM:vSetVar_New_Value ENDIF ENDIF ENDIF IF(vPop_Flag) IF(StringMatch(strPop_Ctrl_Name, "*P0_Pop_Wave_*")) String strAll_Waves="none;"+sortlist(WaveList("*", ";", "TEXT:0,DIMS:1")) Variable vNum_Pop_Items=ItemsInList(strAll_Waves) ControlInfo/W=$strWindow_Name $strPop_Ctrl_Name Variable vPop_New_Value=limit(V_Value-vIncrement, 1, vNum_Pop_Items) String strPop_New_Value=StringFromList(vPop_New_Value-1, strAll_Waves) PopUpMenu/Z $strPop_Ctrl_Name, win=$strWindow_Name, mode=vPop_New_Value ControlUpdate/W=$strWindow_Name $strPop_Ctrl_Name IF(StringMatch(strPop_Ctrl_Name, "P0_Pop_Wave_Fz") && vPop_New_Value==(V_Value-vIncrement)) STRUCT WMPopupAction Fz_pa Fz_pa.win=strWindow_Name Fz_pa.eventCode=2 Fz_pa.popStr=strPop_New_Value KML_Marker_Pop_Fz(Fz_pa) ENDIF ELSEIF(cmpstr(strPop_Ctrl_Name, "T1_Pop_Symbol")==0) vNum_Pop_Items=ItemsInList(kstrGoogle_Earth_Symbols)+ItemsInList(kstrIgor_Symbols) ControlInfo/W=$strWindow_Name T1_Pop_Symbol vPop_New_Value=limit(V_Value-vIncrement, 1, vNum_Pop_Items) //Minus increment so scrolling down goes down the popup list (which is actually increasing the index) PopUpMenu/Z T1_Pop_Symbol, win=$strWindow_Name, mode=vPop_New_Value ControlUpdate/W=$strWindow_Name T1_Pop_Symbol ELSEIF(cmpstr(strPop_Ctrl_Name, "T1_Pop_Color_Table")==0) Variable vNum_Color_Tables=ItemsInList(CTabList()) ControlInfo/W=$strWindow_Name T1_Pop_Color_Table vPop_New_Value=limit(V_Value-vIncrement, 1, vNum_Color_Tables) //Minus increment so scrolling down goes down the popup list (which is actually increasing the index) PopUpMenu/Z T1_Pop_Color_Table, win=$strWindow_Name, mode=vPop_New_Value ControlUpdate/W=$strWindow_Name T1_Pop_Color_Table ELSEIF(cmpstr(strPop_Ctrl_Name, "T1_Pop_Color_Scale_Label_Side")==0) ControlInfo/W=$strWindow_Name T1_Pop_Color_Scale_Label_Side vPop_New_Value=limit(V_Value-vIncrement, 1, 4) PopUpMenu/Z T1_Pop_Color_Scale_Label_Side, win=$strWindow_Name, mode=vPop_New_Value ControlUpdate/W=$strWindow_Name T1_Pop_Color_Table ELSEIF(cmpstr(strPop_Ctrl_Name, "T1_Pop_CS_Graph")==0) String strAll_Graph_Windows="none;"+sortlist(WinList("*", ";", "WIN:1")) Variable vNum_Graph_Windows=ItemsInList(strAll_Graph_Windows) ControlInfo/W=$strWindow_Name T1_Pop_CS_Graph vPop_New_Value=limit(V_Value-vIncrement, 1, vNum_Graph_Windows) strPop_New_Value=StringFromList(vPop_New_Value-1, strAll_Graph_Windows) PopUpMenu/Z T1_Pop_CS_Graph, win=$strWindow_Name, mode=vPop_New_Value ControlUpdate/W=$strWindow_Name T1_Pop_CS_Graph ENDIF ENDIF BREAK ENDSWITCH END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Makes the KML where the track is just a line FUNCTION KML_Panel_Button_Get_Help(ba) : ButtonControl STRUCT WMButtonAction &ba SWITCH(ba.eventcode) CASE 2: String strControl_Name=ba.ctrlName String strSection=RemoveListItem(0, RemoveListItem(0, strControl_Name, "_"), "_") strSection=ReplaceString("dot", strSection, ".") strSection=ReplaceString("_", strSection, " ") strSection="* "+strSection IF(strlen(WinList("KML_Creator_Pane_Help",";","WIN:16")) > 0 ) DoWindow/F KML_Creator_Pane_Help ELSE KML_Get_Help("") ENDIF //I can't encode the whole section name in the control name (unless I use User_Data, which is a pain), so I have to make the note book and then go to the right spot Notebook KML_Creator_Pane_Help, findText={strSection,9} Notebook KML_Creator_Pane_Help, findText={"*", 9} GetSelection notebook, KML_Creator_Pane_Help, 1 Notebook KML_Creator_Pane_Help, selection={(V_startParagraph,0),(V_endParagraph,V_EndPos)} BREAK ENDSWITCH Return 0 END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION KML_Get_Help(String strSection) String nb="KML_Creator_Pane_Help" //nb is the Igor name when you make the notebook commands, so using this to avoid a bunch of replacements. IF(strlen(WinList(nb,";","WIN:16"))>0) DoWindow/F $nb IF(strlen(strSection)>0) Notebook $nb, findText={strSection,9} ENDIF return 0 ELSE String strUpdate_Date="Glorious 25th of May, Year of the Dancing Dog" String strIpf_path=FunctionPath(GetRTStackInfo(1)) GetFileFolderInfo/Q/Z strIpf_path IF(V_Flag==0 && V_IsFile) strUpdate_Date=Secs2Date(V_modificationDate, -2) ENDIF NewNotebook/N=$nb/F=1/V=1/K=1/ENCG={3,1}/OPTS=4 Notebook $nb showRuler=0 Notebook $nb newRuler=Normal, justification=0, margins={0,0,670}, spacing={0,0,0}, tabs={}, rulerDefaults={"Arial",kvDefault_Notebook_Size,0,(0,0,0)} Notebook $nb ruler=Normal, fSize=kvDefault_Notebook_Size+3, fStyle=1, text="KML Creator documentation, v"+kstrVersion_Number+"\r" Notebook $nb text="" Notebook $nb fSize=-1, fStyle=-1, text="Last updated "+strUpdate_Date+"\r" Notebook $nb text="\r" Notebook $nb fSize=kvDefault_Notebook_Size+1, fStyle=1, text="Table of Contents\r" Notebook $nb fSize=-1, fStyle=-1, text="0. " NotebookAction commands=("Notebook " + nb + " findText={\"* 0. Panel features *\",1}"), linkStyle=1, quiet=1, title="Panel features" Notebook $nb fSize=-1, fStyle=-1, text="\r1. " NotebookAction commands=("Notebook " + nb + " findText={\"* 1. Wave selection *\",1}"), linkStyle=1, quiet=1, title="Wave selection" Notebook $nb fSize=-1, fStyle=-1, text="\r2. " NotebookAction commands=("Notebook " + nb + " findText={\"* 2. Line *\",1}"), linkStyle=1, quiet=1, title="Line" Notebook $nb fSize=-1, fStyle=-1, text="\r3. " NotebookAction commands=("Notebook " + nb + " findText={\"* 3. Markers *\",1}"), linkStyle=1, quiet=1, title="Markers" Notebook $nb text="\r\r" Notebook $nb text="\r" Notebook $nb fSize=kvDefault_Notebook_Size+1, fStyle=1, text="* 0. Panel features *", fSize=-1, fStyle=0, text=" " NotebookAction commands=("Notebook " + nb + " selection={(0,0),(0,0)}\rNotebook " + nb + " findText={\"\",1}"), linkStyle=1, quiet=1, title="(return to top)" Notebook $nb text="\r" Notebook $nb text="Mouse wheel scrolling works for all popups except the color palette selector. Mouse wheel scrolling also works for set variables with increment arrows. " Notebook $nb text="Hold down the control/command key to increment by 10x the default increment. \r" Notebook $nb text="\r\r" Notebook $nb fSize=kvDefault_Notebook_Size+1, fStyle=1, text="* 1. Wave selection *", fSize=-1, fStyle=0, text=" " NotebookAction commands=("Notebook " + nb + " selection={(0,0),(0,0)}\rNotebook " + nb + " findText={\"\",1}"), linkStyle=1, quiet=1, title="(return to top)" Notebook $nb text="\r" Notebook $nb text="Select the waves you want to use. ALL waves used (position waves, time waves, color table waves) need to be in the current data folder. " Notebook $nb text="The f(z) and time wave options will not do anything if you make a line kml. \r" Notebook $nb text="\r" Notebook $nb text="Adding every point to the KML will probably be overkill, and there is an option to average the position data down. Select 1 if you want all the points to be in the KML. \r" Notebook $nb text="\r" Notebook $nb text="If you are using a timewave, enter the UTC offset of the time wave. This will ensure that the times in Google Earth are correct. \r" Notebook $nb text="\r\r" Notebook $nb fSize=kvDefault_Notebook_Size+1, fStyle=1, text="* 2. Line *", fSize=-1, fStyle=0, text=" " NotebookAction commands=("Notebook " + nb + " selection={(0,0),(0,0)}\rNotebook " + nb + " findText={\"\",1}"), linkStyle=1, quiet=1, title="(return to top)" Notebook $nb text="\r" Notebook $nb text="This option makes a KML file with the track as a continuous line. You can add a altitude wave if desired. " Notebook $nb text="The only things you can change are the line color and width. " Notebook $nb text="I haven't figured out how to make the line anything other than one color, and I haven't figured out how to add the time slider bar for lines, " Notebook $nb text="so selecting an f(z) trace or a time trace won't do anything. \r" Notebook $nb text="\r\r" Notebook $nb fSize=kvDefault_Notebook_Size+1, fStyle=1, text="* 3. Markers *", fSize=-1, fStyle=0, text=" " NotebookAction commands=("Notebook " + nb + " selection={(0,0),(0,0)}\rNotebook " + nb + " findText={\"\",1}"), linkStyle=1, quiet=1, title="(return to top)" Notebook $nb text="\r" Notebook $nb text="This option will make a KML file with the track as markers. You can color and size the markers by some f(z) trace, similar to the f(z) options in the Modify Trace Appearance window. \r" Notebook $nb text="\r" Notebook $nb text="If you select a time wave a slider bar will appear in Google Earth to animate the track. \r" Notebook $nb text="\r" Notebook $nb text="For the markers, you can use one of the " NotebookAction commands=("BrowseUrl/Z \"http://kml4earth.appspot.com/icons.html\""), linkStyle=1, quiet=1, title="Google Earth built-in options", helpText="http://kml4earth.appspot.com/icons.html" Notebook $nb text=", or one of the Igor shapes. Only a few Igor shapes are in the code right now, but in principle any shape can be added. " Notebook $nb text="If you use an Igor shape, the code will create a png file with the shape template. This png file must accompany the KML. \r" Notebook $nb text="\r" Notebook $nb text="You can use one of the built-in Igor color tables, or you can use a custom one. Igor has a ton of other color tables available as .ibw files in the " NotebookAction commands=("DoIgorMenu \"Help\", \"Show Igor Pro Folder\""), linkStyle=1, quiet=1, title="Igor Pro Folder", helpText="Opens the Igor Pro folder on the disk" Notebook $nb text=". " Notebook $nb text="You will need to load the .ibw file into the experiment, and it needs to be in the same data folder as the position waves. " Notebook $nb text="More information about color tables is here: " NotebookAction commands=("DisplayHelpTopic/Z \"Color Table Waves in the Igor Pro Folder\""), linkStyle=1, quiet=1, title="Color Table Waves in the Igor Pro Folder", helpText="Opens the help for Color Table waves" Notebook $nb text="." Notebook $nb text="\r\r" Notebook $nb text="If you want a color scale for the f(z) values, you will need to create a graph with the color scale. " Notebook $nb text="Select which side you want the color scale labels. Choosing left or right will make a vertically oriented color scale, while top and bottom will make a horizontal color scale. " Notebook $nb text="Select whether you want the background to be transparent or not, and then click the Make plot button. A graph of the color scale will appear that you can customize. " Notebook $nb text="When you make the kml file, the code will save a png of the graph, which will then get linked to the kml. This png file also needs to be in the same folder as the kml. " Notebook $nb findText={"KML Creator documentation",9} //sets the notebook position to the top Notebook $nb selection={(0,0),(0,0)} ENDIF END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Shows and hides various controls based on the tab selection FUNCTION KML_Panel_Tab_Control(tca) : TabControl STRUCT WMTabControlAction &tca SWITCH( tca.eventCode ) CASE 2: // mouse up String strWindow_Name=tca.win String strControls_2_Disable=ControlNameList(strWindow_Name,";", "T*") //Makes a list of all the controls on the tabs Took out the Panel_Red_Baron in the ControlNameList command. Not sure it's needed String strControls_2_Enable=ControlNameList(strWindow_Name,";", "T"+num2str(tca.tab)+"*") //Makes a list of the controls on the active tab ModifyControlList strControls_2_Disable, win=$strWindow_Name, disable=1 //Disables all the controls on all the tabs ModifyControlList strControls_2_Enable, win=$strWindow_Name, disable=0 IF(tca.tab==1) STRUCT WMCheckBoxAction cba cba.eventcode=2 cba.win=strWindow_Name cba.ctrlName="T1_Check_SizeFz" ControlInfo/W=$strWindow_Name T1_Check_SizeFz cba.checked=V_Value KML_Marker_Check_Fz_Size_Color(cba) cba.ctrlName="T1_Check_ColorFz" ControlInfo/W=$strWindow_Name T1_Check_ColorFz cba.checked=V_Value KML_Marker_Check_Fz_Size_Color(cba) ENDIF BREAK CASE -1: // control being killed BREAK ENDSWITCH return 0 END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION KML_Panel_SetVar_Control(sva) : SetVariableControl STRUCT WMSetVariableAction &sva SWITCH( sva.eventCode ) CASE 1: // mouse up CASE 2: // Enter key CASE 3: // Live update Variable dval = sva.dval String sval = sva.sval BREAK CASE 4: CASE 5: String strWindow_Name=sva.win String strControl_Name=sva.ctrlName ControlInfo/W=$strWindow_Name strControl_Name CASE -1: // control being killed BREAK ENDSWITCH return 0 END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Makes the KML where the track is just a line FUNCTIOn KML_Line_Button_Make_File(ba) : ButtonControl STRUCT WMButtonAction &ba SWITCH(ba.eventcode) CASE 2: Close/A String strWindow_Name=ba.win ControlInfo/W=$strWindow_Name P0_Pop_Wave_Latitude String strLatitude_Wave = S_Value ControlInfo/W=$strWindow_Name P0_Pop_Wave_Longitude String strLongitude_Wave = S_Value ControlInfo/W=$strWindow_Name P0_SetVar_DataRes Variable vResolution = V_Value WAVE/Z Latitude_Wave=$strLatitude_Wave, Longitude_Wave=$strLongitude_Wave IF(!WaveExists(Latitude_Wave) || !WaveExists(Longitude_Wave)) DoAlert/T="ERROR ID-10T", 0, "One or more waves don't exist!" Return -1 ENDIF Variable vNum_Data_Pnts = numpnts(Latitude_Wave) Variable vNum_KML_Pnts=ceil(vNum_Data_Pnts/vResolution) //This should be okay IF((numpnts(Longitude_Wave)!= vNum_Data_Pnts)) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF Make/O/B/U/FREE/N=(vNum_Data_Pnts) Flag_Wave=numtype(Latitude_Wave[p])==0 && numtype(Longitude_Wave[p])==0 Make/O/D/FREE/N=(vNum_KML_Pnts) Latitude_Wave_KML=Latitude_Wave[p*vResolution] Make/O/D/FREE/N=(vNum_KML_Pnts) Longitude_Wave_KML=Longitude_Wave[p*vResolution] String strInfo="Experiment name:"+IgorInfo(1)+";Resolution:"+num2str(vResolution)+";Latitude wave:"+strLatitude_Wave+";Longitude wave:"+strLongitude_Wave+";" ControlInfo/W=$strWindow_Name P0_Pop_Wave_Altitude String strAltitude_Wave = S_Value Variable vAltitude_Flag=cmpstr(strAltitude_Wave, "none")!=0 IF(vAltitude_Flag) WAVE/Z Altitude_Wave=$strAltitude_Wave IF(numpnts(Altitude_Wave)!= vNum_Data_Pnts) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF Flag_Wave=Flag_Wave[p] && numtype(Altitude_Wave[p])==0 Make/O/D/FREE/N=(vNum_KML_Pnts) Altitude_Wave_KML=Altitude_Wave[p*vResolution] strInfo+="Altitude wave:"+strAltitude_Wave+";" ENDIF ControlInfo/W=$strWindow_Name P0_Pop_Wave_Time String strTime_Wave=S_Value Variable vTime_Flag=cmpstr(strTime_Wave, "none")!=0 IF(vTime_Flag) WAVE/Z Time_Wave=$strTime_Wave IF(numpnts(Time_Wave)!= vNum_Data_Pnts) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF Flag_Wave=Flag_Wave[p] && numtype(Time_Wave[p])==0 Make/O/T/FREE/N=(vNum_KML_Pnts) TimeStamp_GE_Format_KML=Secs2Date(Time_Wave[p*vResolution], -2)+"T"+Secs2Time(Time_Wave[p*vResolution], 3) strInfo+="Time wave:"+strTime_Wave+";" ControlInfo/W=$strWindow_Name P0_SetVar_UTC_Offset Variable vUTC_Offset=V_Value String strUTC_Offset sprintf strUTC_Offset, "%+0.2d", vUTC_Offset strUTC_Offset+=":00" IF(cmpstr(strUTC_Offset, "+00:00")==0) strUTC_Offset="Z" ENDIF ELSE strUTC_Offset="Z" ENDIF Make/O/D/FREE/N=(vNum_KML_Pnts) Flag_Wave_KML=Flag_Wave[p*vResolution] Extract/O/FREE Latitude_Wave_KML, Latitude_Wave_KML, Flag_Wave_KML Extract/O/FREE Longitude_Wave_KML, Longitude_Wave_KML, Flag_Wave_KML IF(vAltitude_Flag) Extract/O/FREE Altitude_Wave_KML, Altitude_Wave_KML, Flag_Wave_KML ELSE Make/O/D/FREE/N=(numpnts(Latitude_Wave_KML)) Altitude_Wave_KML=0 ENDIF IF(vTime_Flag) Extract/O/T/FREE TimeStamp_GE_Format_KML, TimeStamp_GE_Format_KML, Flag_Wave_KML TimeStamp_GE_Format_KML=TimeStamp_GE_Format_KML+strUTC_Offset ENDIF vNum_KML_Pnts=numpnts(Latitude_Wave_KML) WaveStats/Q Latitude_Wave_KML Variable vLat_Avg = V_avg Variable vLat_Min=V_Min Variable vLat_Max=V_Max WaveStats/Q Longitude_Wave_KML Variable vLon_Avg = V_avg Variable vLon_Min=V_Min Variable vLon_Max=V_Max Variable vHeight_Scale_Factor=2.5 //This seems to work Variable vHeight=vHeight_Scale_Factor*max(KML_Get_Bounds(vLat_Max, vLon_Avg, vLat_Min, vLon_Avg), KML_Get_Bounds(vLat_Avg, vLon_Min, vLat_Avg, vLon_Max)) ControlInfo/W=$strWindow_Name T0_SetVar_Line_Width Variable vLine_Width=V_Value ControlInfo/W=$strWindow_Name T0_Pop_Line_Color String strLine_Color=KML_Convert_RGB_to_Hex(V_Red, V_Green, V_Blue) ControlInfo/W=$strWindow_Name T0_SetStr_File_Name String strFile_Name=S_Value IF(strlen(strFile_Name)==0) Prompt strFile_Name, "File name (no extension)" DoPrompt "Enter a file name", strFile_Name IF(V_Flag) Return -1 ENDIF SetVariable T0_SetStr_File_Name, value=_STR:strFile_Name ENDIF strFile_Name+=".kml" NewPath/O/M="Choose folder to save kml file in:"/Q pKML_Path IF(V_flag!=0) Return -1 ENDIF PathInfo pKML_Path String strKML_Path=S_Path GetFileFolderInfo/P=pKML_Path/Q/Z strFile_Name IF(V_Flag==0) DoAlert/T="READ CAREFULLY!!!!!" 1, "READ CAREFULLY!!!!\r\rThe file already exists! Do you want to OVERWRITE the file (YES) or CANCEL (NO)?\r\rREAD CAREFULLY!" IF(V_Flag==2) Return -1 ENDIF ENDIF Variable refnum Open/P=pKML_Path/C="IGR0" refNum as strFile_Name //Ken made a long string, with one line of Igor code for each line of KML code, and then printed that string to the file. I'm not sure why you would do that versus just using fprintf for each line. fprintf refNum, "\r" fprintf refNum, "\r" fprintf refNum, "\r" fprintf refNum, " "+strFile_Name+"\r" fprintf refnum, " "+strInfo+"\r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " normal\r" fprintf refNum, " #s_ylw-pushpin\r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " highlight\r" fprintf refNum, " #s_ylw-pushpin_hl\r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " \r" fprintf refNum, " 1\r" fprintf refNum, " \r" fprintf refNum, " %.10f\r", vLon_Avg fprintf refNum, " %.10f\r", vLat_Avg fprintf refNum, " 0\r" fprintf refNum, " 0\r" fprintf refNum, " 0\r" fprintf refNum, " %d\r", vHeight fprintf refNum, " \r" fprintf refNum, " #m_ylw-pushpin\r" fprintf refNum, " \r" fprintf refNum, " 1\r" fprintf refNum, " 1\r" fprintf refNum, " relativeToGround\r" fprintf refNum, " \r" wfprintf refNum, "%0.8f,%0.8f,%0.8f\r", Longitude_Wave_KML, Latitude_Wave_KML, Altitude_Wave_KML fprintf refNum, "\r \r \r \r\r\r" Close refNum KillPath/Z pKML_Path Print "Done creating "+strKML_Path+strFile_Name BREAK ENDSWITCH END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Enables or disables various controls based on checkbox selections FUNCTION KML_Marker_Check_Fz_Size_Color(cba) : CheckBoxControl STRUCT WMCheckBoxAction &cba SWITCH(cba.eventcode) CASE 2: String strControlName=cba.ctrlName String strWindow_Name=cba.win STRSWITCH(cba.ctrlName) CASE "T1_Check_SizeFz": SetVariable T1_SetVar_Marker_Size_Min, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) SetVariable T1_SetVar_Marker_Size_Max, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) CheckBox T1_Check_Log_Size, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) SetVariable T1_SetVar_Marker_Size_Default, win=$strWindow_Name, disable=SelectNumber(cba.checked, 0, 1) BREAK CASE "T1_Check_ColorFz": PopupMenu T1_Pop_Color_Table, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) CheckBox T1_Check_Custom_Color_Table, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) CheckBox T1_Check_Reverse_Colors, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) Checkbox T1_Check_Log_Colors, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) GroupBox T1_GroupBox_Color_Scale,win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) CheckBox T1_Check_Color_Scale, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) ControlInfo/W=$strWindow_Name T1_Check_Color_Scale Button T1_Button_Make_Color_Scale_Plot, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, SelectNumber(V_Value, 2,0)) PopupMenu T1_Pop_Color_Scale_Label_Side, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, SelectNumber(V_Value, 2,0)) CheckBox T1_Check_Transparent, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, SelectNumber(V_Value, 2,0)) PopupMenu T1_Pop_CS_Graph, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, SelectNumber(V_Value, 2,0)) ControlInfo/W=$strWindow_Name T1_Check_Custom_Color_Table PopUpMenu T1_Pop_Custom_Color_Table_Wave, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, SelectNumber(V_Value, 1,0)) PopUpMenu T1_Pop_Color_Table, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, SelectNumber(V_Value, 0,1)) PopupMenu T1_Pop_Marker_Color, win=$strWindow_Name, disable=SelectNumber(cba.checked, 0, 1) BREAK CASE "T1_Check_Color_Scale": Button T1_Button_Make_Color_Scale_Plot, win=$strWindow_Name, disable=SelectNumber(cba.checked, 2, 0) CheckBox T1_Check_Transparent, win=$strWindow_Name, disable=SelectNumber(cba.checked, 2, 0) PopupMenu T1_Pop_CS_Graph, win=$strWindow_Name, disable=SelectNumber(cba.checked, 2, 0) PopupMenu T1_Pop_Color_Scale_Label_Side, win=$strWindow_Name, disable=SelectNumber(cba.checked, 2, 0) BREAK CASE "T1_Check_Custom_Color_Table": PopUpMenu T1_Pop_Custom_Color_Table_Wave, win=$strWindow_Name, disable=SelectNumber(cba.checked, 1, 0) PopUpMenu T1_Pop_Color_Table, win=$strWindow_Name, disable=SelectNumber(cba.checked, 0, 1) BREAK ENDSWITCH BREAK ENDSWITCH END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION KML_Marker_Pop_Fz(pa) : PopupMenuControl STRUCT WMPopupAction &pa SWITCH( pa.eventCode ) CASE 2: // mouse up String strWindow_Name=pa.win String strFz_Wave = pa.popStr WAVE/Z Fz_Wave=$strFz_Wave IF(WaveExists(Fz_Wave)) WaveStats/Q/M=1 Fz_Wave IF(V_npnts==0) Print Secs2Date(DateTime, -2)+" "+Secs2Time(DateTime, 3)+" F(z) wave has no valid points!" SetVariable T1_SetVar_Fz_Min, win=$strWindow_Name, value=_NUM:NaN //Wavemin and Wavemax choke on infs SetVariable T1_SetVar_Fz_Max, win=$strWindow_Name, value=_NUM:NaN Return -1 ENDIF SetVariable T1_SetVar_Fz_Min, win=$strWindow_Name, value=_NUM:V_Min //Wavemin and Wavemax choke on infs SetVariable T1_SetVar_Fz_Max, win=$strWindow_Name, value=_NUM:V_Max ELSE SetVariable T1_SetVar_Fz_Min, win=$strWindow_Name, value=_NUM:NaN //Wavemin and Wavemax choke on infs SetVariable T1_SetVar_Fz_Max, win=$strWindow_Name, value=_NUM:NaN IF(!StringMatch(strFz_Wave, "None")) Print Secs2Date(DateTime, -2)+" "+Secs2Time(DateTime, 3)+" F(z) wave doesn't exist!" ENDIF ENDIF BREAK ENDSWITCH END //Gets the min and max of the F(z) wave FUNCTION KML_Marker_Button_Fz_Min_Max(ba) : ButtonControl STRUCT WMButtonAction &ba SWITCH(ba.eventcode) CASE 2: String strWindow_Name=ba.win ControlInfo/W=$strWindow_Name P0_Pop_Wave_Fz WAVE/Z Fz_Wave=$S_Value IF(WaveExists(Fz_Wave)) WaveStats/Q/M=1 Fz_Wave IF(V_npnts==0) DoAlert/T="ERROR ID-10T" 0, "F(z) wave has no valid points!" Return -1 ENDIF SetVariable T1_SetVar_Fz_Min, win=$strWindow_Name, value=_NUM:V_Min //Wavemin and Wavemax choke on infs SetVariable T1_SetVar_Fz_Max, win=$strWindow_Name, value=_NUM:V_Max ELSE DoAlert/T="ERROR ID-10T" 0, "F(z) wave doesn't exist!" ENDIF BREAK ENDSWITCH END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Makes a plot for the color scale in the KML FUNCTION KML_Marker_Button_Make_CS_Plot(ba) : ButtonControl STRUCT WMButtonAction &ba SWITCH(ba.eventcode) CASE 2: String strWindow_Name=ba.win ControlInfo/W=$strWindow_Name T1_Check_Custom_Color_Table Variable vCustom_Color_Table=V_Value IF(vCustom_Color_Table) ControlInfo/W=$strWindow_Name T1_Pop_Custom_Color_Table_Wave WAVE/Z Color_Table_Wave=$S_Value IF(!WaveExists(Color_Table_Wave)) DoAlert/T="ERROR ID-10T" 0, "Invalid color table wave!" Return -1 ENDIF Variable vNum_Colors=DimSize(Color_Table_Wave, 0) ELSE //Get the color table wave and then convert it into a free wave ControlInfo/W=$strWindow_Name T1_Pop_Color_Table String strColor_Table=S_Value String strCurrent_Data_Folder=GetDataFolder(1) NewDataFolder/O/S root:Stupidly_Named_Temp_Folder ColorTab2Wave $strColor_Table WAVE/Z M_Colors vNum_Colors=DimSize(M_Colors, 0) SetDataFolder $strCurrent_Data_Folder KillDataFolder/Z root:Stupidly_Named_Temp_Folder ENDIF ControlInfo/W=$strWindow_Name T1_Check_Reverse_Colors Variable vReverse_Colors = V_Value ControlInfo/W=$strWindow_Name T1_Check_Log_Colors Variable vLog_Colors=V_Value ControlInfo/W=$strWindow_Name T1_SetVar_Fz_Min Variable vFz_Min=V_Value ControlInfo/W=$strWindow_Name T1_SetVar_Fz_Max Variable vFz_Max=V_Value String strFz_Min, strFz_Max //Don't want to compare floats. sprintf strFz_Min, "%0.6f", vFz_Min sprintf strFz_Max, "%0.6f", vFz_Max IF(numtype(vFz_Min)!=0 || numtype(vFz_Max)!=0) DoAlert/T="ERROR ID-10T" 0, "Fz value limits must be real numbers!" Return -1 ENDIF IF(cmpstr(strFz_Min, strFz_Max)==0) DoAlert/T="ERROR ID-10T" 0, "Min and max fz values must be different" Return -1 ENDIF IF(vLog_Colors) IF(vFz_Max<=0 || vFz_Min<=0) Print "One or both of the Fz limits is less than or equal to zero! Using linear scaling of the colors!" vLog_Colors=0 ENDIF ENDIF ControlInfo/W=$strWindow_Name T1_Pop_Color_Scale_Label_Side String strCS_Label_Side=S_Value Make/O/D/N=(vNum_Colors) KML_Color_Table_Wave_Y=1, KML_Color_Table_Wave_X IF(vLog_Colors) SetScale/I x log(vFz_Min),log(vFz_Max),"", KML_Color_Table_Wave_X KML_Color_Table_Wave_X=10^x ELSE SetScale/I x vFz_Min,vFz_Max,"", KML_Color_Table_Wave_X KML_Color_Table_Wave_X=x ENDIF String strGraph_Name STRSWITCH(strCS_Label_Side) CASE "Left": strGraph_Name=UniqueName("CS_Left_Label_Vertical_", 6, 0) Display/N=$strGraph_Name /W=(248,200,298,310)/K=1 /VERT KML_Color_Table_Wave_Y vs KML_Color_Table_Wave_X as strGraph_Name ModifyGraph margin(left)=23,margin(bottom)=3,margin(top)=1,margin(right)=1,width=8.64,height=108 ModifyGraph mode=7 ModifyGraph hbFill=2 IF(vCustom_Color_Table) ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,ctableRGB, vReverse_Colors, Color_Table_Wave} ELSE ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,$strColor_Table, vReverse_Colors} ENDIF ModifyGraph logZColor=vLog_Colors ModifyGraph tick(bottom)=3 ModifyGraph mirror=2 ModifyGraph noLabel(bottom)=2 ModifyGraph fSize(left)=6 ModifyGraph log(left)=vLog_Colors ModifyGraph standoff=0 ModifyGraph axisOnTop=1 ModifyGraph btLen=4 SetAxis left vFz_Min,vFz_Max SetAxis bottom 0,1 BREAK CASE "Right": strGraph_Name=UniqueName("CS_Right_Label_Vertical_", 6, 0) Display/N=$strGraph_Name /W=(325,201,375,311)/K=1 /VERT/R KML_Color_Table_Wave_Y vs KML_Color_Table_Wave_X as strGraph_Name ModifyGraph margin(left)=1,margin(bottom)=3,margin(top)=1,margin(right)=23,width=8.64 ModifyGraph height=108 ModifyGraph mode=7 ModifyGraph hbFill=2 IF(vCustom_Color_Table) ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,ctableRGB, vReverse_Colors, Color_Table_Wave} ELSE ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,$strColor_Table, vReverse_Colors} ENDIF ModifyGraph logZColor=vLog_Colors ModifyGraph tick(bottom)=3 ModifyGraph mirror=2 ModifyGraph noLabel(bottom)=2 ModifyGraph fSize(right)=6 ModifyGraph log(right)=vLog_Colors ModifyGraph standoff=0 ModifyGraph axisOnTop=1 ModifyGraph btLen=4 SetAxis right vFz_Min,vFz_Max SetAxis bottom 0,1 BREAK CASE "Top": strGraph_Name=UniqueName("CS_Top_Label_Horizonal_", 6, 0) Display/N=$strGraph_Name/W=(254,292,370,316)/K=1 /T KML_Color_Table_Wave_Y vs KML_Color_Table_Wave_X as strGraph_Name ModifyGraph margin(left)=1,margin(bottom)=1,margin(top)=14,margin(right)=7,width=108 ModifyGraph height=8.64 ModifyGraph mode=7 ModifyGraph hbFill=2 IF(vCustom_Color_Table) ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,ctableRGB, vReverse_Colors, Color_Table_Wave} ELSE ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,$strColor_Table, vReverse_Colors} ENDIF ModifyGraph logZColor=vLog_Colors ModifyGraph tick(left)=3 ModifyGraph mirror(left)=1,mirror(top)=2 ModifyGraph noLabel(left)=2 ModifyGraph fSize(top)=6 ModifyGraph log(top)=vLog_Colors ModifyGraph standoff=0 ModifyGraph axisOnTop=1 ModifyGraph btLen(top)=4 SetAxis left 0,1 BREAK CASE "Bottom": strGraph_Name=UniqueName("CS_Bottom_Label_Horizonal_", 6, 0) Display/N=$strGraph_Name/W=(253,251,369,375)/K=1 KML_Color_Table_Wave_Y vs KML_Color_Table_Wave_X as strGraph_Name ModifyGraph margin(left)=1,margin(bottom)=14,margin(top)=1,margin(right)=7,width=108 ModifyGraph height=8.64 ModifyGraph mode=7 ModifyGraph hbFill=2 IF(vCustom_Color_Table) ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,ctableRGB, vReverse_Colors, Color_Table_Wave} ELSE ModifyGraph zColor(KML_Color_Table_Wave_Y)={KML_Color_Table_Wave_X,*,*,$strColor_Table, vReverse_Colors} ENDIF ModifyGraph logZColor=vLog_Colors ModifyGraph tick(left)=3 ModifyGraph mirror(left)=1,mirror(bottom)=2 ModifyGraph noLabel(left)=2 ModifyGraph fSize(bottom)=6 ModifyGraph log(bottom)=vLog_Colors ModifyGraph standoff=0 ModifyGraph axisOnTop=1 ModifyGraph btLen(bottom)=4 SetAxis left 0,1 BREAK ENDSWITCH String strGraph_Name_List=WinList("*", ";", "WIN:1") Variable vNum_Graphs=ItemsInList(strGraph_Name_List) String strGraph_Name_List_Sorted=SortList(strGraph_Name_List) Variable vGraph_Index=WhichListItem(strGraph_Name, strGraph_Name_List_Sorted) PopupMenu T1_Pop_CS_Graph,win=$strWindow_Name, value= #"\"none;\"+sortlist(WinList(\"*\", \";\", \"WIN:1\"))", mode=vGraph_Index+2,popvalue=strGraph_Name ControlUpdate/W=$strWindow_Name T1_Pop_CS_Graph BREAK ENDSWITCH END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Makes the KML file with markers for the track FUNCTIOn KML_Marker_Button_Make_File(ba) : ButtonControl STRUCT WMButtonAction &ba SWITCH(ba.eventcode) CASE 2: Close/A String strWindow_Name=ba.win ControlInfo/W=$strWindow_Name P0_Pop_Wave_Latitude String strLatitude_Wave = S_Value ControlInfo/W=$strWindow_Name P0_Pop_Wave_Longitude String strLongitude_Wave = S_Value WAVE/Z Latitude_Wave=$strLatitude_Wave, Longitude_Wave=$strLongitude_Wave IF(!WaveExists(Latitude_Wave) || !WaveExists(Longitude_Wave)) DoAlert/T="ERROR ID-10T", 0, "One or more waves don't exist!" Return -1 ENDIF Variable vNum_Data_Pnts = numpnts(Latitude_Wave) ControlInfo/W=$strWindow_Name P0_SetVar_DataRes Variable vResolution = V_Value Variable vNum_KML_Pnts=ceil(vNum_Data_Pnts/vResolution) //This should be okay IF((numpnts(Longitude_Wave)!= vNum_Data_Pnts)) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF Make/O/D/FREE/N=(vNum_KML_Pnts) Latitude_Wave_KML=Latitude_Wave[p*vResolution] Make/O/D/FREE/N=(vNum_KML_Pnts) Longitude_Wave_KML=Longitude_Wave[p*vResolution] Make/O/B/U/FREE/N=(numpnts(Latitude_Wave)) Flag_Wave=(numtype(Latitude_Wave[p])==0) && numtype(Longitude_Wave[p])==0 String strInfo="Experiment name:"+IgorInfo(1)+";Resolution:"+num2str(vResolution)+";Latitude wave:"+strLatitude_Wave+";Longitude wave:"+strLongitude_Wave+";" ControlInfo/W=$strWindow_Name P0_Pop_Wave_Altitude String strAltitude_Wave = S_Value Variable vAltitude_Flag=cmpstr(strAltitude_Wave, "none")!=0 IF(vAltitude_Flag) WAVE/Z Altitude_Wave=$strAltitude_Wave IF(numpnts(Altitude_Wave)!= vNum_Data_Pnts) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF Flag_Wave=Flag_Wave[p] && numtype(Altitude_Wave[p])==0 Make/O/D/FREE/N=(vNum_KML_Pnts) Altitude_Wave_KML=Altitude_Wave[p*vResolution] strInfo+="Altitude wave:"+strAltitude_Wave+";" ENDIF ControlInfo/W=$strWindow_Name P0_Pop_Wave_Time String strTime_Wave=S_Value Variable vTime_Flag=cmpstr(strTime_Wave, "none")!=0 IF(vTime_Flag) WAVE/Z Time_Wave=$strTime_Wave IF(numpnts(Time_Wave)!= vNum_Data_Pnts) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF Flag_Wave=Flag_Wave[p] && numtype(Time_Wave[p])==0 Make/O/T/FREE/N=(vNum_KML_Pnts) TimeStamp_GE_Format_KML=Secs2Date(Time_Wave[p*vResolution], -2)+"T"+Secs2Time(Time_Wave[p*vResolution], 3) strInfo+="Time wave:"+strTime_Wave+";" ControlInfo/W=$strWindow_Name P0_SetVar_UTC_Offset Variable vUTC_Offset=V_Value String strUTC_Offset sprintf strUTC_Offset, "%+0.2d", vUTC_Offset strUTC_Offset+=":00" IF(cmpstr(strUTC_Offset, "+00:00")==0) strUTC_Offset="Z" ENDIF ELSE strUTC_Offset="Z" ENDIF ControlInfo/W=$strWindow_Name P0_Pop_Wave_Fz String strFz_Wave = S_Value Variable vFz_Flag=cmpstr(strFz_Wave, "none")!=0 IF(vFz_Flag) WAVE/Z Fz_Wave=$strFz_Wave IF(numpnts(Fz_Wave)!= vNum_Data_Pnts) DoAlert/T="ERROR ID-10T", 0, "Waves must all have same number of points!" Return -1 ENDIF ControlInfo/W=$strWindow_Name T1_SetVar_Fz_Min Variable vFz_Min = V_Value ControlInfo/W=$strWindow_Name T1_SetVar_Fz_Max Variable vFz_Max = V_Value IF(numtype(vFz_Min)!=0 || numtype(vFz_Max)!=0) DoAlert/T="ERROR ID-10T" 0, "Fz limits must be real numbers!" Return -1 ENDIF String strFz_Min, strFz_Max //Don't want to compare floats. sprintf strFz_Min, "%0.6f", vFz_Min sprintf strFz_Max, "%0.6f", vFz_Max IF(cmpstr(strFz_Min, strFz_Max)==0) DoAlert/T="ERROR ID-10T" 0, "Min and max Fz values must be different" Return -1 ENDIF Flag_Wave=Flag_Wave[p] && numtype(Fz_Wave[p])==0 Make/O/D/FREE/N=(vNum_KML_Pnts) Fz_Wave_KML=Fz_Wave[p*vResolution] strInfo+="F(z) wave:"+strFz_Wave+";" ENDIF Make/O/D/FREE/N=(vNum_KML_Pnts) Flag_Wave_KML=Flag_Wave[p*vResolution] Extract/O/FREE Latitude_Wave_KML, Latitude_Wave_KML, Flag_Wave_KML Extract/O/FREE Longitude_Wave_KML, Longitude_Wave_KML, Flag_Wave_KML IF(vFz_Flag) Extract/O/FREE Fz_Wave_KML, Fz_Wave_KML, Flag_Wave_KML ENDIF IF(vAltitude_Flag) Extract/O/FREE Altitude_Wave_KML, Altitude_Wave_KML, Flag_Wave_KML ELSE Make/O/D/FREE/N=(numpnts(Latitude_Wave_KML)) Altitude_Wave_KML=0 ENDIF IF(vTime_Flag) Extract/O/T/FREE TimeStamp_GE_Format_KML, TimeStamp_GE_Format_KML, Flag_Wave_KML TimeStamp_GE_Format_KML=TimeStamp_GE_Format_KML+strUTC_Offset String strTime_Start=TimeStamp_GE_Format_KML[0] String strTime_Stop=TimeStamp_GE_Format_KML[numpnts(TimeStamp_GE_Format_KML)-1] ENDIF vNum_KML_Pnts=numpnts(Latitude_Wave_KML) WaveStats/Q Latitude_Wave_KML Variable vLat_Avg = V_avg Variable vLat_Min=V_Min Variable vLat_Max=V_Max WaveStats/Q Longitude_Wave_KML Variable vLon_Avg = V_avg Variable vLon_Min=V_Min Variable vLon_Max=V_Max Variable vHeight_Scale_Factor=2.5 //This seems to work Variable vHeight=vHeight_Scale_Factor*max(KML_Get_Bounds(vLat_Max, vLon_Avg, vLat_Min, vLon_Avg), KML_Get_Bounds(vLat_Avg, vLon_Min, vLat_Avg, vLon_Max)) // if color-coding is checked, get the color table into a wave for use with this data Variable vColor_Scale=0 //Need to declare this here because it can get invoked from the top layer of the code ControlInfo/W=$strWindow_Name T1_Check_ColorFz Variable vColor_Flag = V_Value IF(vColor_Flag) ControlInfo/W=$strWindow_Name T1_Check_Custom_Color_Table IF(V_Value) ControlInfo/W=$strWindow_Name T1_Pop_Custom_Color_Table_Wave WAVE/Z Color_Table_Wave=$S_Value IF(!WaveExists(Color_Table_Wave)) DoAlert/T="ERROR ID-10T" 0, "Invalid color table wave!" Return -1 ENDIF ELSE ControlInfo/W=$strWindow_Name T1_Pop_Color_Table String strColor_Table=S_Value String strCurrent_Data_Folder=GetDataFolder(1) NewDataFolder/O/S root:Stupidly_Named_Temp_Folder ColorTab2Wave $strColor_Table WAVE/Z M_Colors Duplicate/O/FREE M_Colors, Color_Table_Wave SetDataFolder $strCurrent_Data_Folder KillDataFolder/Z root:Stupidly_Named_Temp_Folder ENDIF Variable vNum_Colors=DimSize(Color_Table_Wave, 0) ControlInfo/W=$strWindow_Name T1_Check_Reverse_Colors IF(V_Value) MatrixOp/O/FREE Color_Table_Wave=ReverseCols(Color_Table_Wave) ENDIF ControlInfo/W=$strWindow_Name T1_Check_Log_Colors Variable vLog_Colors=V_Value IF(!vLog_Colors) Variable vColor_Slope=(vNum_Colors-1)/(vFz_Max-vFz_Min) Variable vColor_Intercept=0-vColor_Slope*vFz_Min ELSE IF(vFz_Max<=0 || vFz_Min<=0) Print "One or both of the Fz limits is less than or equal to zero! Using linear scaling of the colors!" vLog_Colors=0 vColor_Slope=(vNum_Colors-1)/(vFz_Max-vFz_Min) vColor_Intercept=0-vColor_Slope*vFz_Min ELSE vColor_Slope=(vNum_Colors-1)/(log(vFz_Max)-log(vFz_Min)) vColor_Intercept=0-vColor_Slope*log(vFz_Min) ENDIF ENDIF ControlInfo/W=$strWindow_Name T1_Check_Color_Scale vColor_Scale=V_Value IF(vColor_Scale) ControlInfo/W=$strWindow_Name T1_Pop_CS_Graph String strColor_Scale_Graph_Name=S_Value IF(WinType(strColor_Scale_Graph_Name)==0) DoAlert/T="ERROR ID-10T" 0, "Invalid color scale graph!" Return -1 ENDIF ControlInfo/W=$strWindow_Name T1_Check_Transparent Variable vTransparent_Color_Scale=V_Value ENDIF ELSE ControlInfo/W=$strWindow_Name T1_Pop_Marker_Color String strMarker_Hex_Color_Default=KML_Convert_RGB_to_Hex(V_Red, V_Green, V_Blue) ENDIF ControlInfo/W=$strWindow_Name T1_Check_SizeFz Variable vSize_Flag = V_Value String strMarker_Size_Min, strMarker_Size_Max ControlInfo/W=$strWindow_Name T1_SetVar_Marker_Size_Min Variable vMarker_Size_1=V_Value ControlInfo/W=$strWindow_Name T1_SetVar_Marker_Size_Max Variable vMarker_Size_2=V_Value Variable vMarker_Size_Min=min(vMarker_Size_1, vMarker_Size_2) Variable vMarker_Size_Max=max(vMarker_Size_1, vMarker_Size_2) sprintf strMarker_Size_Min, "%0.6f", vMarker_Size_Min sprintf strMarker_Size_Max, "%0.6f", vMarker_Size_Max IF(cmpstr(strMarker_Size_Min, strMarker_Size_Max)==0) DoAlert/T="ERROR ID-10T" 0, "Min and max marker sizes must be different" Return -1 ENDIF ControlInfo/W=$strWindow_Name T1_Check_Log_Size Variable vLog_Size=V_Value IF(!vLog_Size) Variable vMarker_Slope=(vMarker_Size_Max-vMarker_Size_Min)/(vFz_Max-vFz_Min) Variable vMarker_Intercept=vMarker_Size_Min-vMarker_Slope*vFz_Min ELSE IF(vMarker_Size_Min==0 || vMarker_Size_Max==0) Print "One or more marker sizes is zero. Using linear scaling of the marker sizes!" vLog_Size=0 vMarker_Slope=(vMarker_Size_Max-vMarker_Size_Min)/(vFz_Max-vFz_Min) vMarker_Intercept=vMarker_Size_Min-vMarker_Slope*vFz_Min ELSE vMarker_Slope=(vMarker_Size_Max-vMarker_Size_Min)/(log(vFz_Max)-log(vFz_Min)) vMarker_Intercept=vMarker_Size_Min-vMarker_Slope*log(vFz_Min) ENDIF ENDIF ControlInfo/W=$strWindow_Name T1_SetVar_Marker_Size_Default Variable vMarker_Size_Default=V_Value //This is redundant, but I should add a notice to the user if this happens IF(!vFz_Flag && (vColor_Flag || vSize_Flag)) //The logic for the fz_flag, color_flag, and size_flag is a little fuzzy, but I think it's fine and I don't plan to fix it DoAlert/T="ERROR ID-10T" 0, "You cannot color/size by f(z) if your f(z) wave does not exist!" Return -1 ENDIF ControlInfo/W=$strWindow_Name T1_SetStr_File_Name String strFile_Name=S_Value IF(strlen(strFile_Name)==0) Prompt strFile_Name, "File name (no extension)" DoPrompt "Enter a file name", strFile_Name IF(V_Flag) Return -1 ENDIF SetVariable T0_SetStr_File_Name, value=_STR:strFile_Name ENDIF strFile_Name+=".kml" //Get the folder path and do anything that creates files after all the checks that could lead to aborting the function NewPath/O/M="Choose folder to save kml file in:"/Q pKML_Path IF(V_flag!=0) Return -1 ENDIF PathInfo pKML_Path String strKML_Path=S_Path GetFileFolderInfo/P=pKML_Path/Q/Z strFile_Name IF(V_Flag==0) DoAlert/T="READ CAREFULLY!!!!!" 1, "READ CAREFULLY!!!!\r\rThe file already exists! Do you want to OVERWRITE the file (YES) or CANCEL (NO)?\r\rREAD CAREFULLY!" IF(V_Flag==2) Return -1 ENDIF ENDIF ControlInfo/W=$strWindow_Name T1_Pop_Symbol String strSymbol = S_Value String strKML_Symbol_Line IF(strsearch(strSymbol, "GE ", 0)==0) //Icons defined in GE. Have black outlines. STRSWITCH(strSymbol) CASE "GE shaded_dot": strKML_Symbol_Line= "http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png" BREAK CASE "GE circle": strKML_Symbol_Line= "http://maps.google.com/mapfiles/kml/pal2/icon26.png" BREAK // CASE "GE square": //This doesn't seem to work // strKML_Symbol_Line= "http://maps.google.com/mapfiles/kml/pal2/icon15.png" // BREAK DEFAULT: strKML_Symbol_Line= "http://maps.google.com/mapfiles/kml/pal2/icon26.png" BREAK ENDSWITCH ELSE strKML_Symbol_Line=""+RemoveEnding(strFile_Name, ".kml")+"_Icon.png" Variable vNum_Pixels=501 //The icon image size doesn't matter. If the scale size in GE is the same then a 50x50 pixel icon will be the same size as a 500x500 pixel icon Variable vCenter=floor(vNum_Pixels/2) Make/O/D/FREE/N=(vNum_Pixels,vNum_Pixels,4) mShape=65535 //GE changes any white in the icon to the desired color, but it does not change other colors. STRSWITCH(strSymbol) //Makes icons without an outline using the predefined Igor markers. It's a little kludgy, but way more flexible that trying to make the shapes by hand. CASE "Diamond": Display /W=(536,602,628,694)/N=Dummy_Graph_For_Marker/K=1 as "Dummy_Graph_For_Marker" ModifyGraph margin(left)=1,margin(bottom)=1,margin(top)=1,margin(right)=1,width=90 ModifyGraph height=90 TextBox/C/N=text0/F=0/M/H={15,2,10}/B=1/A=MC/X=0.00/Y=0.00 "\\K(0,0,0)\\Z99\\W5018" BREAK CASE "Circle": Display /W=(511,381,585,455)/N=Dummy_Graph_For_Marker/K=1 as "Dummy_Graph_For_Marker" ModifyGraph margin(left)=1,margin(bottom)=1,margin(top)=1,margin(right)=1,width=72 ModifyGraph height=72 TextBox/C/N=text0/F=0/M/H={15,2,10}/B=1/A=MC/X=0.00/Y=0.00 "\\K(0,0,0)\\Z99\\W5019" BREAK CASE "Square": //No idea why I have to do this, but if it's all 65535 then it doesn't work Display /W=(511,381,585,455)/N=Dummy_Graph_For_Marker/K=1 as "Dummy_Graph_For_Marker" ModifyGraph margin(left)=1,margin(bottom)=1,margin(top)=1,margin(right)=1,width=72 ModifyGraph height=72 TextBox/C/N=text0/F=0/M/H={15,2,10}/B=1/A=MC/X=0.00/Y=0.00 "\\K(0,0,0)\\Z99\\W5016" BREAK CASE "Hexagon": Display /W=(616,848,679,911)/N=Dummy_Graph_For_Marker/K=1 as "Dummy_Graph_For_Marker" ModifyGraph margin(left)=1,margin(bottom)=1,margin(top)=1,margin(right)=1,width=61.2 ModifyGraph height=61.2 TextBox/C/N=text0/F=0/M/H={15,2,10}/B=1/A=MC/X=0.00/Y=0.00 "\\K(0,0,0)\\Z99\\W5055" BREAK ENDSWITCH DoUpdate/W=Dummy_Graph_For_Marker SavePICT/O/E=-5/B=288/WIN=Dummy_Graph_For_Marker/P=pKML_Path as RemoveEnding(strFile_Name, ".kml")+"_Icon.png" //Save the graph with the marker. Use the eventual name for the icon so we don't have to kill the file later. KillWindow/Z Dummy_Graph_For_Marker //Kill the graph ImageLoad/T=png/O/Q/N=Dummy_Marker_Matrix_Wave/P=pKML_Path RemoveEnding(strFile_Name, ".kml")+"_Icon.png" //Load the image as a matrix WAVE/Z Dummy_Marker_Matrix_Wave Make/O/D/FREE/N=(DimSize(Dummy_Marker_Matrix_Wave,0), DimSize(Dummy_Marker_Matrix_Wave,1), 4) mMarker //Convert the image matrix to the proper form (white inside the marker, transparent outside) mMarker[][][0]=Dummy_Marker_Matrix_Wave[p][q][0]>100 ? 0 : 65535 //I probably could use layers 1 and 2 as well, but this works. mMarker[][][1]=Dummy_Marker_Matrix_Wave[p][q][0]>100 ? 0 : 65535 mMarker[][][2]=Dummy_Marker_Matrix_Wave[p][q][0]>100 ? 0 : 65535 mMarker[][][3]=Dummy_Marker_Matrix_Wave[p][q][0]>100 ? 0 : 65535 ImageSave/T="png"/O/P=pKML_Path mMarker as RemoveEnding(strFile_Name, ".kml")+"_Icon.png" //Save the wave as an image. Overwrite instead of killing the file. KillWaves/Z Dummy_Marker_Matrix_Wave ENDIF IF(vColor_Scale) SavePICT/O/E=-5/TRAN=(vTransparent_Color_Scale)/B=288/P=pKML_Path/WIN=$strColor_Scale_Graph_Name as RemoveEnding(strFile_Name, ".kml")+"_Color_Scale.png" ENDIF Variable refnum Open/P=pKML_Path refNum as strFile_Name // Prompt for file name to save into. fprintf refNum, "\r" fprintf refNum, "\r" fprintf refNum, "\r" fprintf refnum, " "+strInfo+"\r" fprintf refNum, " "+strFile_Name+"\r" Variable iKML_Index IF(vSize_Flag || vColor_Flag) fprintf refNum, "\r" //write this string to file FOR(iKML_Index=0;iKML_Index\r" IF(vTime_Flag) fprintf refNum, " "+TimeStamp_GE_Format_KML[iKML_Index]+"\r" ENDIF fprintf refNum, " \r" IF(vAltitude_Flag) //Alt fprintf refNum, " \r %0.8f,%0.8f,%0.8f\r absolute\r \r\r", Longitude_Wave_KML[iKML_Index], Latitude_Wave_KML[iKML_Index], Altitude_Wave_KML[iKML_Index] ELSE //No alt fprintf refNum, " \r %0.8f,%0.8f,0\r \r\r", Longitude_Wave_KML[iKML_Index], Latitude_Wave_KML[iKML_Index] ENDIF ENDFOR fprintf refNum, "\r" //There was a square bracket after the >, that might be a typo ELSE //If you want single color/size markers. This is copied from a KML modified in Google Earth so each marker has the same style. fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " normal\r" fprintf refnum, " #mySym1\r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " highlight\r" fprintf refnum, " #mySym11\r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refNum, "\r" //write this string to file FOR(iKML_Index=0;iKML_Index\r" IF(vTime_Flag) fprintf refNum, " "+TimeStamp_GE_Format_KML[iKML_Index]+"\r" ENDIF fprintf refNum, " #mySym10\r" fprintf refNum, " \r" IF(vAltitude_Flag) //Alt fprintf refnum, " %0.8f,%0.8f,%0.8f\r absolute\r", Longitude_Wave_KML[iKML_Index], Latitude_Wave_KML[iKML_Index], Altitude_Wave_KML[iKML_Index] ELSE fprintf refNum, " %0.8f,%0.8f,0\r", Longitude_Wave_KML[iKML_Index], Latitude_Wave_KML[iKML_Index] ENDIF fprintf refNum, " \r" fprintf refNum, " \r" ENDFOR fprintf refNum, "\r" //There was a square bracket after the >, that might be a typo ENDIF fprintf refNum, "\r" fprintf refNum, " %.10f\r", vLon_Avg fprintf refNum, " %.10f\r", vLat_Avg fprintf refNum, " %d\r", vHeight fprintf refNum, " 0\r" fprintf refNum, " 0\r" IF(vTime_Flag) fprintf refNum, " \r" fprintf refNum, " "+strTime_Start+"\r" fprintf refNum, " "+strTime_Stop+"\r" fprintf refNum, " \r" ENDIF fprintf refNum, "\r" IF(vColor_Scale) fprintf refnum, " \r" fprintf refnum, " Scale\r" fprintf refnum, " "+RemoveEnding(strFile_Name, ".kml")+"_Color_Scale.png"+"\r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " \r" fprintf refnum, " \r" ENDIF fprintf refNum, "\r\r" Close refNum KillPath/Z pKML_Path Print "Done creating "+strKML_Path+strFile_Name BREAK ENDSWITCH END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Converts the three 16-bit color values to 8 bit and then to one hex code in Google Earth format (BGR) FUNCTION/S KML_Convert_RGB_to_Hex(VARIABLE vRed, VARIABLE vGreen, VARIABLE vBlue) Variable vRed_8bit=round(((vRed-1)/256)-1) //Negative numbers don't convert nicely, but non-integers are fine. Going to round anyways. Variable vGreen_8bit=round(((vGreen-1)/256)-1) Variable vBlue_8bit=round(((vBlue-1)/256)-1) String strHex_Color_Red, strHex_Color_Green, strHex_Color_Blue sprintf strHex_Color_Red, "%02X", SelectNumber(vRed_8bit<0, vRed_8bit, 0) //GE uses 256 as full color value. Igor uses 65535 sprintf strHex_Color_Green, "%02X",SelectNumber(vGreen_8bit<0, vGreen_8bit, 0) //uses 2 characters if 0 sprintf strHex_Color_Blue, "%02X", SelectNumber(vBlue_8bit<0, vBlue_8bit, 0) String strHex_Color = "ff"+strHex_Color_Blue+strHex_Color_Green+strHex_Color_Red //GE uses BGR hex color Return strHex_Color END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Computes the straight line distance through the Earth between two points. Would probably be better to use the Haversine equation to get the distance FUNCTION KML_Get_Bounds(VARIABLE vLat1, VARIABLE vLon1, VARIABLE vLat2, VARIABLE vLon2) variable vEarth_rad = 6373e3 // meters Variable vRad_Conversion=pi/180 Variable vX1=vEarth_rad*cos(vLat1*vRad_Conversion)*cos(vLon1*vRad_Conversion) Variable vY1=vEarth_rad*cos(vLat1*vRad_Conversion)*sin(vLon1*vRad_Conversion) Variable vZ1=vEarth_rad*sin(vLat1*vRad_Conversion) Variable vX2=vEarth_rad*cos(vLat2*vRad_Conversion)*cos(vLon2*vRad_Conversion) Variable vY2=vEarth_rad*cos(vLat2*vRad_Conversion)*sin(vLon2*vRad_Conversion) Variable vZ2=vEarth_rad*sin(vLat2*vRad_Conversion) Variable vDistance=sqrt((vX2-vX1)^2+(vY2-vY1)^2+(vZ2-vZ1)^2) Return vDistance END //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////