Updated the attachment to fix a few problems
Lately I became interested in learning about neural networking the basis for A.I. I found lots of tutorials on the subject in many computer languages but none using OORexx. So I found the simplest one written in C++ and translated it to OORexx, works great, its attached, I think OORexx should include a sample like this. It might encourage younger users to use OORexx.
Well it took awhile but finally I have the merge code that has passed all my testers. It follows the intersection points of the polygons to merge them . I had to add a new method and some routines: - method distance - it finds the distance between two sets of lat/lons. Used to sort the intersections. - routine ring_array - orders the sections of the merging polygon so they can be processed sequentially. - routines Create_WP and Create_Route which create gpx files of the intersection points and the...
Well it took awhile but finally I have the merge code that has passed all my testers. It follows the intersection points of the polygons to merge them . I had to add a new method and some routines: * method distance - it finds the distance between two sets of lat/lons. Used to sort the intersections. * routine ring_array - orders the sections of the merging polygon so they can be processed sequentially. * routines Create_WP and Create_Route which create gpx files of the intersection points and the...
JanErik, When I put the code into my program all mt testing of it worked. But when I asked my tester too test he found it failed. I am working on a fix, Paul
I found the code would not support two cases: * When the two intersection points were on the same section (see attachment "IP on Same Section") * When there were more than two intersection points (see attachment "More than two Intersections") I've attached the new Polyshape.cls it works great.
I made the following change and it seems to work: if add_section > fin_section then add_section = 0 I put that right before your new code see the attached new polyshape.cls I will do more testing . I think the code will fail if there are more than two intersection points.
I am slowly digesting your code. I have never been a fan of the trace. I prefer to simply put in say statements. Now that I corrected the data it makes more sense. Will let you know what I find.
You are right. The problem I get when I replace my logic with yours is on the fourth merge where it tries to merge the existing large polygon with the next one (see attachment "Two polygons to merge"). The resulting polygon (second attachment "Result Merged") does not follow the next one, probably because the polygons share a point. I put the two polygons into the test program: p1 = .WGS84~new('117.494063,8.487999,0 117.52863,8.566254,0 117.537862,8.599729,0 117.524659,8.624429,0 117.552887,8.658872,0...
You are right. The problem I get when I replace my logic with yours is on the fourth merge where it tries to merge the existing large polygon with the next one (see attachment "Two polygons to merge"). The resulting polygon (second attachment "Result Merged") does not follow the next one, probably because the polygons share a point. I put the two polygons into the test program: p1 = .WGS84~new('117.494063,8.487999,0 117.52863,8.566254,0 117.537862,8.599729,0 117.524659,8.624429,0 117.552887,8.658872,0...
Its better (see attachment) but that little jog to point 6 should not exist. Point 5 should connect to point 7.
Will give a try when I get a chance. Right now have other problems.
Are you asking me to figure out the new calculation?
JanErik, I tried two polygons and get a weird result: p1 = .WGS84~new('117.494063,8.487999,0 117.529286,8.567740,0 117.570462,8.549952,0 117.535230,8.470211,0 117.494063,8.487999,0') p2 = .WGS84~new('117.528199,8.564692,0 117.538691,8.602737,0 117.582045,8.591045,0 117.571549,8.553000,0 117.528199,8.564692,0') p1~merge( p2 ) say p1~toString result: 117.494063,8.487999,0 117.52863,8.566254,0 117.538691,8.602737,0 117.549874,8.558846,0 117.570462,8.549952,0 117.53523,8.470211,0 117.494063,8.487999,0...
JanErik, I tried two polygons and get a weird result: p1 = .WGS84~new('117.494063,8.487999,0 117.529286,8.567740,0 117.570462,8.549952,0 117.535230,8.470211,0 117.494063,8.487999,0') p2 = .WGS84~new('117.528199,8.564692,0 117.538691,8.602737,0 117.582045,8.591045,0 117.571549,8.553000,0 117.528199,8.564692,0') p1~merge( p2 ) say p1~toString result: 117.494063,8.487999,0 117.52863,8.566254,0 117.538691,8.602737,0 117.549874,8.558846,0 117.570462,8.549952,0 117.53523,8.470211,0 117.494063,8.487999,0...
Interesting. Will have a look at this and see if it can replace my existing code. Thanks
I already look at it and found it's too hard too follow. I have downloaded many others and some converted but they do not work. For now I am sticking with the original one I had that follows the intersection points. Thanks for looking.
Jan-Erik, Something is really confusing to me. Why do you reverse the x and y for a point. For example: pt = .point~new("117.501452,8.490863") say 'PT='pt~x pt~y the result is: PT=8.490863 117.501452
I found this link that explains the problem and the theory of how to combine the two polygons but no real code: https://stackoverflow.com/questions/2667748/how-do-i-combine-complex-polygons
Using Jan_Eriks Polyshape.cls I am able to am able to merge polygons (see the attachment) by following the intersections of the two polygons but it is quite complicated logic . But I am wondering if there is some algorithm that can be used to merge polygons. I did find a convex hull algorithm that I converted to rex but a convex hull is not what is needed. So my question is does anyone know of some logic to merge the points of two polygons?
Thanks for the update. But I still can not use WGS84.
I changed all formats in my previous post to: ~format(18,self~decimals)~strip to make it compatible with all decimal values. But to make that test above work I had to change the self~decimals = 6 for the Polyshape class and use .Polyshape for both lines because if I use WGS84 in my test for both the lines it always returns .Nil like this: BG_LN =.WGS84~new('-77.619237,20.631839 -77.619237,20.698505') say 'BG_LN='BG_LN LG_LN =.PolyShape~new('-77.617041,20.698442 -77.621432, 20.631902') say 'LG_LN='LG_LN...
OK I found the problem: at the end of the intersectionpoint method you do compares and some fail because they are are not formatted to the same number of decimal places. Fixed it by: Do j = 1 To shape~point~Items - 1 (shape~point[ j ]~x)~format(4,6)~strip (shape~point[ j +1 ]~x)~format(4,6)~strip (shape~point[ j ]~y)~format(3,6)~strip (shape~point[ j +1 ]~x)~format(3,6)~strip ... px = ( d2~x * d1~z - d1~x * d2~z ) / d12 py = ( d1~y * d2~z - d2~y * d1~z ) / d12 px = px~format(4,6)~strip py = py~format(3,6)~strip...
Jan-Erik, I seem to still have a problem finding the intersectionpoint of two lines when the angle between them is small. Here is what I found: BG_LN =.PolyShape~new('-77.619237,20.631839 -77.619237,20.698505') say 'BG_LN='BG_LN LG_LN =.PolyShape~new('-77.617041,20.698442 -77.621432, 20.631902') say 'LG_LN='LG_LN say 'intersect='LG_LN~intersect(BG_LN) -- say 'intersects='LG_LN~intersects(BG_LN) IP1 = LG_LN~intersectionPoint(BG_LN) if .Nil <> IP1 then say 'intersectionPoint='IP1~y IP1~x else say 'intersectionPoint...
Or I could do it like this: :~~~ :class myPolyShape public subclass polyShape ::method init Use Arg polyLine, nofixpoly, xyz, dbug points = .Array~new Do i = 1 To polyLine~Items Parse Value polyLine[ i ] With lat lon points~append(.Point~new(lon,lat)) end self~init:super( points, nofixpoly, xyz, dbug ) ~~~ It works. Maybe better than overriding the prepare method
OK thanks Ruurd
Been using Jan-Erik's shape cls with my program and they work great. But I often find I have arrays of lat/lons that I want to create a polygon from for example: my_points= .array~of("8.919400 118.009485","8.920184 118.008687","8.909866 118.040771","8.901590 118.038006") Currently I have to convert the array entries to a string to create the polygon. I want to create the polygon directly from the array. I modified the the polyshape.cls prepare method to do this as follows: ::method prepare Use Arg...
I don't use servers. It just runs on a Windows PC.
Jan, Yes that fixed it thanks. BTW I changed the self~decimals = 3 to 6 in PolyShape.Cls so the tostring gives the full 6 decimal places. Having 3 decimal places is not too useful for navigation . I think you should make it 6 as most users would not know how to change it. Will checkout your other files later.
Jan, if you have time look at this. I define two polygons: see the attachment, the first polygon is in blue the second in yellow. They have two intersection points. curr_poly =.PolyShape~new('117.519585,8.643308,0 117.522866,8.583716,0 117.590189,8.587334,0 117.586919,8.646926,0 117.519585,8.643308,0') big_poly = .PolyShape~new('117.526397,8.600475,0 117.47546,8.500079,0 117.535704,8.470178,0 117.586657,8.570574,0 117.526397,8.600475,0') say 'intersect='curr_poly~intersect(big_poly) IP0 = curr_poly~intersectionPoint(big_poly)...
Jan, Thank you. I have been using OORexx for nearly 40 years and I am getting better all the time but when I look at your code I am still an amateur. Keep up the great work. Cheers,
Yes, it works great. Thank you. Question on the : intersectionPoint( LS2, 2 ) what does the ",2" do? If I delete it it gives same result. Also, is there some documentation to explain what all the methods do?
Yes, it works great. Thank you. Question on the : intersectionPoint( LS2, 2 ) what does the ",2" do? If I delete it it gives same result.
Let me know if you want me to test anything new.
If I just use simple coordinates rather than lat/lon it still returns.Nil poly = .Polygon~new( '5,3,0 5,7,0 8,7,0 8,3,0 5,3,0' ) say 'poly='poly line = .PolyShape~new( '9,1 7,2 6,6',.false ) say 'line='line say poly~intersectionPoint( line) -- returns .Nil
Jan, any idea why I receive .Nil with that code?
Sorry here it is,,
Jan, The sun is over the yard arm here in the Philippines and a bottle of whiskey is calling so I am crashing, The attachment is what those points look like. Goodnight
I changed the .PolyShape to .WGS84 and the result was .Nil changed back .PolyShape to try your modified ne .PolyShape and also go .Nil. Here is the code with .PolyShape... LS1 = .PolyShape~new( '-82.351362,23.144393 -82.377884,23.158500 -82.400960,23.147176 -82.377254,23.146636') LS2 = .PolyShape~new( '-82.369393,23.165881 -82.382508,23.160703 -82.381667,23.149727',.false) say 'LS1='LS1 say 'LS2='LS2 pt = LS1~intersectionPoint(LS2,2) if .Nil=pt then say 'PT is .nil' else say 'pt='pt Here is the result:...
Thanks but I get the same error: with the new clss Again here is code: LS1 = .PolyShape~new( '-82.351362,23.144393 -82.377884,23.158500 -82.400960,23.147176 -82.377254,23.146636 -82.366451,23.157573') LS2 = .PolyShape~new( '-82.369393,23.165881 -82.382508,23.160703 -82.381667,23.149727',.false) say 'LS1='LS1 say 'LS2='LS2 pt = LS1~intersectionPoint(LS2,2) if .Nil=pt then say 'PT is .nil' else say 'pt='pt Result: 581 - Return .Point~new( self~point[ section + 1 ]~x - self~point[ section ]~x, self~point[...
Jan, This is really good stuff. I think will solve some difficult problems in my program.
Jan, I downloaded our classes and the example you posted. But when I run it I get: C:\SAT2CHART\SAT2CHART.Testing>Shape_test.rex 399 - ::method box 10 - ::REQUIRES 'Polygon.cls' Error 99 running C:\SAT2CHART\SAT2CHART.Testing\Polygon.cls line 399: Translation error. Error 99.902: Duplicate ::METHOD directive instruction. and indeed there are two box methods in the Polygon.cls ?? I commented the 2nd box method and the example worked.
Jan, I downloaded our classes and the example you posted. But when I run it I get: C:\SAT2CHART\SAT2CHART.Testing>Shape_test.rex 399 - ::method box 10 - ::REQUIRES 'Polygon.cls' Error 99 running C:\SAT2CHART\SAT2CHART.Testing\Polygon.cls line 399: Translation error. Error 99.902: Duplicate ::METHOD directive instruction. and indeed there are two box methods in the Polygon.cls ??
Jan, Just read this how do I get those classes?
Well I solved this by giving the listView a NOHEADER option then putting static fields above the listView with the column names and created a tooltip for each of static fields.
I should have been more specific. I want to add tooltips to the header columns listView not to the rows. Anybody figured out how to do that? See the attachment
OK thanks Jon
Has anyone got some code they could share with me on how handle tooltips for a listView? The examples manageControlTool.rex and customPositionToolTip.rex show how to set it up for a treeView but they don't work for a listView. Thanks
My program accesses other windows using the WindowObject Class. I can check and uncheck checkboxes by sending a SPACE to it but I am unable to tell if the checkbox is checked or not. The state method doesn't say is checked or not. Is there anyway to tell if its checked?
Most Virus programs think rexxhide.exe has a server virus. See attachment. This is in all the latest version of V5 beta. Its probably a false positive but all the users of my program are scared of it. Can anything be done?
I found this problem seems to be caused by a change in OORexx R11367 https://sourceforge.net/p/oorexx/feature-requests/712/ If I replace the rexxhide.exe in r12269 with the one from R11912 the problem goes away.
I found this problem seems to be caused by a change in R11367 https://sourceforge.net/p/oorexx/feature-requests/712/ If I replace the rexxhide.exe in r12269 with the one from R11912 the problem goes away.
Sorry Window 10 home
Window defender claims Rexxhide.exe has a virus.
Thank you Jon. I uploaded rexxhide.exe to the site you suggested and also got 6 AV saying its bad. I will open a bug report. I think its false but its scaring a lot of users of my program.
Rexx version is:REXX-ooRexx_5.0.0(MT)_32-bit 5.0.0 12:29:04.526000 Open Object Rexx Version 5.0.0 r12269 12:29:04.530000 Build date: Jun 10 2021 12:29:04.536000 Addressing mode: 32
See attachment
Faulting application name: rexx.exe, version: 5.0.0.12180, time stamp: 0x60368a02 Faulting module name: rexx.dll, version: 5.0.0.12180, time stamp: 0x603689fd Exception code: 0xc0000005 Fault offset: 0x00057b6c Faulting process id: 0x2928 Faulting application start time: 0x01d73979493c1123 Faulting application path: C:\Program Files (x86)\ooRexx\rexx.exe Faulting module path: C:\Program Files (x86)\ooRexx\rexx.dll Report Id: df156ca7-f287-4d98-a8a5-aca022737f41 Faulting package full name: Faulting...
OK thanks for your help. I'll have to rethink this whole thing.
Mine did eventually hang but everything seemed to lock up even my browser. Had to restart windows. Now that I am at the 64 bit OOrexx will the variable pool be larger? On 32 bit when the memory got around 1.5 Gig it usually ran out of resources.
OK now on 64 bit and the test program has been running OK for awhile. When you were testing was it with the 32 bit or 64 bit version?
Ok I'll try the 64 bit version to see if the test program works. For some reason I have to use the 32 bit for the main program but I forgot why.
Well I have your attention: what happens to those external queues when the program crashes? Are they deleted?
Just ran the test program again and it froze in less than a minute. I have another user also testing the real program and gets the same hangs.
Tried that but those queues get so big the program gets a "out of resources" crash. Using RexxQueue keeps the memory way down.
Forgot to mention this is on Windows 10 and I'm at the latest 32bit OOREXX.
Sorry here is the program
OK took awhile but I have created a test program to test REXXQueueue. The main thread dispatches a number of Calc_FS threads then loops monitoring the threads until everything is finished. The Calc_FS thread will randomly generate a number of messages and queue them on to a RexxQueue called output_q. After the output_q is created it is split into smaller Rexxqueues called lb_queue and then dispatches a thread called Loadblobs for each of the lb_queues. The Loadblobs thread pulls off the messages...
OK thanks. Now my final question(hopefully) . The sub threads are creating .RexxQueues and some are queuing data onto the queues and others are pulling the data off for processing. I make sure the .Rexxqueues never has the same name. It seems when I queue something I have to first acquire a Mutexsemaphore then release it after I do the queue. If I don't, all the threads lock up including the main thread. I don't do this when I pull data off the queues. So is it necessary to protect the .Rexxqueues...
Sort of same question: I also expose a MutexSemaphore to the sub threads. Do I have to put a Guard around ~acquire ~release the semaphore?
OK thanks Rick
I have a oorexx program that spawns many threads to do some work. I expose a variable to all the sub threads called "terminate". Periodically the sub threads check that variable to see if it has been set and if so they terminate. My question is do I have to put a guard on/off around checking that variable? Thanks again.
OK thanks guys
How small can the sleep value be? Is call SysSleep(.0001) valid?
How small can the sleep value be? Is call SysSleep(.0001) valid?
Thanks, jfaucher. I' ll try that.
If it helps the dll routine is attached
Rick, Actually the next statement passes the obj3 back by putting it into a directory: RexxStringObject obj3 = context->NewString((CSTRING)pImage_RGB, size); context->DirectoryPut(Png_Info, obj3, "DEST_BLOB_UPDATED"); So will it be freed when the function returns
H Again, I have a program that merges blob images and it works well but after a run it stops with the oorexx program still running and there is a lot memory still allocated, over a gigabyte. I examined the code to see where I may not have dropped or freed things and found one piece of code that I have a question about. To do the merge I pass blobs to a function in a rexx dll. To pass back the merged blob I use a RexxStringObject created from a NewString RexxStringObject obj3 = context->NewString((CSTRING)pImage_RGB,...
Ok thanks Erich that fixes it using the single quotes.
I am using the oosqlite to update a mbtiles metadata table and found that if the data is equal to the column name then it will destroy the data in all of the rows. Here is the Create table for the metadata: "CREATE TABLE metadata (name text, value text);" Note: the first column is "name" The first attachment "Metadata_Before": shows what all the metadata data looks like before I update it. Note: that seventh row the data is in the name column is "name" I execute this one sql statement to update the...
Ok thanks
I have been doing some programming on shapefiles and using the GDAL ogr2ogr interface to process points and polygons. Today I was browsing the OORexx directory and I noticed there is a ooShapes.cls. Is there any documentation on this cls? Can it process polygons and points? Thanks for a great product (oorexx), its fantastic. Paul
I have been doing some programming on shapefiles and using the GDAL ogr2ogr interface to process points and polygons. Today I was browsing the OORexx directory and I noticed there is a ooShapes.cls. Is there any documentation on this cls? Can it process polygons and points? Thanks for a great product (oorexx), its fantastic. Paul
You are right, thanks
Thank you Gil and Rick. I decided to use Gil's suggestion but changed it to if xp >= self~dimension(1) | yp >= self~dimension(2) then return .Nil so I know when it hits the the right side or the bottom.
Using the subclass Array technique for my two dimension array described at the start, I come up with: tiles = .Tiles~new(4,4)~fill('x') tiles[2,2] = .nil do yp = 1 to 4 do xp = 1 to 4 select when .Nil = tiles[xp-1,yp] then say 'xp/yp='xp yp' Value to left is .Nil' when .Nil = tiles[xp,yp-1] then say 'xp/yp='xp yp' Value above is .Nil' otherwise say 'xp/xp='xp yp' tiles[xp,yp]='tiles[xp,yp] end end end ::class Tiles subclass Array ::method "[]" use arg xp,yp if xp = 0 | yp = 0 then return .Nil forward...
I used Erich' s idea and it seems to work: tiles = .Tiles~new(4)~fill(1) tiles[3] = .nil do xp = 1 to 4 if .Nil = tiles[xp-1] then say 'xp='xp' Value to left is .Nil' else say 'xp='xp' tiles[xp]='tiles[xp] end ::class Tiles subclass Array ::method "[]" use arg xp if xp = 0 then return .Nil forward class .Array Result is: xp=1 Value to left is .Nil xp=2 tiles[xp]=1 xp=3 tiles[xp]=The NIL object xp=4 Value to left is .Nil
Yes, but it still doesn't work
Jeremy, the "It" was trying your suggestion: tiles = .array~of('1','2','3','4') xp = 1 say 'tiles[xp]='tiles[xp] if (xp = 1) | ( (xp > 1) & (.Nil = tiles[xp-1]) ) then say 'Value to left is .Nil' else say 'Value to left is NOT .Nil' and this is the result: tiles[xp]=1 - Compiled method "[]" with scope "Array". 5 - if (xp = 1) | ( (xp > 1) & (.Nil = tiles[xp-1]) ) Error 93 running C:\SAT2CHART\SAT2CHART.Testing\Test.comma.rex line 5: Incorrect call to method. Error 93.907: Method argument 1 must be...
Just tried it with xp=1 and actually it fails for the same reason as Rick mentioned.
Beacuse then it would fail when xp=1 and it tried to execute & (.Nil = tiles[xp-1]) because xp-1 would be outside array.
OK thanks Rick. Guess I'll just have to use two statements.
Decide to simplify this with a small test program: tiles = .array~of('1','2','3','4') xp = 3 say 'tiles[xp]='tiles[xp] if xp > 1, .Nil = tiles[xp-1] then say 'Value to left is .Nil' else say 'Value to left is NOT .Nil' -- if ( (xp = 1) | (xp > 1, .Nil = tiles[xp-1]) ) then say 'OK2' Result is: tiles[xp]=3 Value to left is NOT .Nil 7 - if ( (xp = 1) | (xp > 1, .Nil = tiles[xp-1]) ) Error 34 running C:\SAT2CHART\SAT2CHART.Testing\Test.comma.rex line 7: Logical value not 0 or 1. Error 34.901: Logical...
This also fails with Logical value not 0 or 1 : when ((xp = 1) | (xp > 1, .Nil = comm._Tiles_All[xp-1,yp]))
Then why does it not work in this statement following the OR while it does if there is no preceeding condition: when (xp = 1) | (xp > 1, .Nil = comm._Tiles_All[xp-1,yp]) then do
I have a two dimensional array where each entry is either .Nil or some value. My logic is trying to determine when at a certain position in the array there is no valid entry to the left of the current position, in other words the entry at xp-1 is .Nil or xp is 1 . So I use these two when statements in a select: ~~~ when xp > 1, .Nil = comm._Tiles_All[xp-1,yp] then do -- Entry to the left is .Nil ... end when xp = 1 then do -- at the left side ... end ~~~ Those two statements works fine. Notice I...
Thanks for the info Rony. My approach is now to break up the blob filesecs into into smaller lists and dispatch a thread for each list that creates a temporary sql db with the same table definition. Once all the threads have finished. I attach each of the temporary databases and then use the: INSERT INTO tiles SELECT * FROM source.tiles; to merge them all into the main database table. I found that insert to be very fast. This reduced the time to process 57,000 blobs from 13 minutes using one thread...
Just to let you know that doing the calls using C++ was a bit faster but still way to slow. I was still reading in the blobs one by one and inserting them. But this gives me an idea: I could beak up the list of blob filesepes into into smaller lists and the dispatch separate threads for each list. This brings up a question: can separate threads insert rows into the same table at the same time? Anyone know?