Langy Posted February 21, 2014 Share Posted February 21, 2014 To cut a long story short I'm trying to make an app that has to ready anything from 1 to a vast number of XML files from a website. I started out in vb.net (not used it much but can often muddle through apps) found that too complicated for what I wanted, then Excel but it hung every time after about 5 downloads of XML files. So I've come to AutoIT as I use it for a fair bit of scripting to modify settings on our users computers. One of the things I need to do in my app is read in around 6000 sites in one XML file, the user chooses one and then I need to calculate the distance and direction from the selected site for all the rest. Now those 6000 sites only really have to be loaded once as I will end up making a new XML file only storing the sites the users select. Now when I try to load all 6000 sites to start with in the code below it starts off really quick as I can monitor it with GUICtrlSetData($lblStatus2,UBound($Sites,1)) reporting back to my splash screen. However as time goes on the records take longer and longer to get through. The whole process takes about 2 minutes. So any assistance on speeding that up would be great. Basically I need to load the sites into an array which I can then use to create a list view based on a users search criteria. For $oLocations In $oXML.selectNodes("/Locations") $sDirRefID = $oLocations.getAttribute("id") For $oSite In $oLocations.selectNodes("Location") $Sites[UBound($Sites,1)-1][0] = $oSite.getAttribute("id") $Sites[UBound($Sites,1)-1][1] = $oSite.getAttribute("name") $Sites[UBound($Sites,1)-1][2] = $oSite.getAttribute("latitude") $Sites[UBound($Sites,1)-1][3] = $oSite.getAttribute("longitude") $Sites[UBound($Sites,1)-1][4] = $oSite.getAttribute("elevation") $Sites[UBound($Sites,1)-1][5] = $oSite.getAttribute("region") $Sites[UBound($Sites,1)-1][6] = $oSite.getAttribute("unitaryAuthArea") $Sites[UBound($Sites,1)-1][7] = $oSite.getAttribute("nationalPark") If Int(UBound($Sites,1)/100) = UBound($Sites,1)/100 Then GUICtrlSetData($lblStatus2,UBound($Sites,1)) EndIf ReDim $Sites[UBound($Sites,1)+1][10] Next Next So my next dilema which I spent several hours on today was to work out the distance and direction between the sites. That took me a few hours in Excel to start with and converting the distance to AutoIT was quite easy as in the code below. Func Distance($LatD,$LongD) $HomeLat = 54.9425 $HomeLong = -2.7349 $rad1 = _Radian(90-$HomeLat) $cos1 = Cos($rad1) $sin1 = Sin($rad1) $DISTANCE = ACos(Cos(_Radian(90-$HomeLat))*Cos(_Radian(90-$LatD))+Sin(_Radian(90-$HomeLat))*Sin(_Radian(90-$LatD))*Cos(_Radian($HomeLong-$LongD)))*6371 Return $DISTANCE EndFunc The next thing was the direction. I got a nice script running at work using the _Atlan2 code that was in math.au3. However I've installed a newer version of AutoIT at home on my laptop and went to run the code tonight only to find the _Atlan2 has been removed. So some hunting around on actual equations and I've come up with below to replace it. Any thoughts on this from anyone most appreciated. Func Direction($LatD,$LongD) $HomeLat = 54.9425 $HomeLong = -2.7349 $y = $HomeLat - $LatD $x = $HomeLong - $LongD $bear = ATan2($y,$x) $degB = 180 + _Degree($bear) Return $degB EndFunc Func ATan2($x, $y) Local Const $PI = 3.14159265358979 If $x > 0 Then Return ATan($y / $x) ElseIf $x < 0 Then Return ATan($y / $x) - _Radian(180) ElseIf $x = 0 Then If $y > 0 Then Return 90 ElseIf $y < 0 Then Return -90 ElseIf $y=0 Then Return 0 EndIf Else MsgBox( 16, "Error - Division by zero", "Domain Error in Function: ATan2()" & @LF & "$x and $y cannot both equal zero" ) SetError( 1 ) EndIf EndFunc I'm not a newbie, but can get most basic programming done in vb, vba, asp, asp.net and AutoIT to name a few. I may not set the procedures out like hardcore programmers, but it works and always willing to learn. I find that you learn more when faced with problems like this where you have to find an answer. Thanks in advance for any assistance. Link to comment Share on other sites More sharing options...
Bowmore Posted February 22, 2014 Share Posted February 22, 2014 This should solve your first problem, the slow load. ReDim is a slow function so it's best to not use it every time you add a new record. Add new array space in big blocks and remove any unused rows when you have finished loading. Local $iSite = 0 Local $Sites[5000][10] ;Make the array big enough to hold the estimated number of rows $iSitesMaxIdx = UBound($Sites,1)-1 ; save the size of array so you don't have to call UBound all the time For $oLocations In $oXML.selectNodes("/Locations") $sDirRefID = $oLocations.getAttribute("id") For $oSite In $oLocations.selectNodes("Location") $Sites[$iSite][0] = $oSite.getAttribute("id") $Sites[$iSite][1] = $oSite.getAttribute("name") $Sites[$iSite][2] = $oSite.getAttribute("latitude") $Sites[$iSite][3] = $oSite.getAttribute("longitude") $Sites[$iSite][4] = $oSite.getAttribute("elevation") $Sites[$iSite][5] = $oSite.getAttribute("region") $Sites[$iSite][6] = $oSite.getAttribute("unitaryAuthArea") $Sites[$iSite][7] = $oSite.getAttribute("nationalPark") If Int($iSite/100) = $iSite/100 Then GUICtrlSetData($lblStatus2,$iSite) EndIf if $iSitesMax = $iSitesMaxIdx Then ;if array is full ;add another 1000 rows $iSitesMaxIdx += 1000 ReDim $Sites[$iSitesMaxIdx][10] EndIf ;ncrement array index $iSite += 1 Next Next ;remove unused rows ReDim $Sites[$iSite][10] "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook Link to comment Share on other sites More sharing options...
czardas Posted February 22, 2014 Share Posted February 22, 2014 (edited) Here's the old _ATan2() code by Nutster, in case you don't have it. I don't know why it would have been removed. <REMOVED> ; Edited February 23, 2014 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Langy Posted February 23, 2014 Author Share Posted February 23, 2014 This should solve your first problem, the slow load. ReDim is a slow function so it's best to not use it every time you add a new record. Add new array space in big blocks and remove any unused rows when you have finished loading. Thanks that helped enormously, now the whole 6000 sites loads in a couple of seconds. I do start off now with an array at 6000 and if that fills up add 100 at a time, just in case it should ever increase. Then I finally just cut it back to size when the whole xml file is loaded. czardas, yes I could have copied the code from my machine at work, but I think that there is an issue with it as to why it was removed. I did have to modify my code a little as it could return a negative direction. I've based my code on some proper equations I found online which should cut out any errors, plus I've tested quite a few results as to that which I have in an Excel file. Func GeoDir($LatStart,$LongStart,$LatEnd,$LongEnd) $y = $LatStart - $LatEnd $x = $LongStart - $LongEnd $bear = ATan2($y,$x) $degB = 180 + _Degree($bear) If $degb < 0 Then $degb = 360 + $degb EndIf Return $degB EndFunc Link to comment Share on other sites More sharing options...
czardas Posted February 23, 2014 Share Posted February 23, 2014 (edited) Ah, I remember reading something about this now. Edited February 23, 2014 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now