Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.35 KB | None | 0 0
  1. def hausdorffDistance(geom1,geom2):
  2. '''
  3. Hausdorff Distance calculator, somewhat based on https://github.com/anitagraser/QGIS-Processing-tools/blob/master/1.1/scripts/find_similar_line_feature.py
  4. Uses pure pyqgis instead of numpy
  5. Inputs geom1 and geom2 should be QgsGeometry of type 'QGis.Line'
  6. '''
  7. dist = lambda x1, y1, x2, y2: float((x2-x1)**2+(y2-y1)**2)**(0.5) #Euclidean distance between two coordinates
  8.  
  9. ##Get all possible combinations between coordinates on the first line and second line
  10. combins = [dist(a[0], a[1], b[0], b[1]) for a in geom1.asPolyline() for b in geom2.asPolyline()]
  11.  
  12. ##Find array dimensions
  13. combinSz = len(list(combins))
  14. xArrSize = len(geom1.asPolyline())
  15. yArrSize = combinSz/xArrSize
  16. #print "{0}x{1} array".format(xArrSize, yArrSize)
  17.  
  18. ##Turn 1-dimensional list of distances into 2-dimensional list/array
  19. distAryOne = [[0]*yArrSize for i in range(xArrSize)] #initialize empty 2-dimensional distance array first
  20. for x in range(xArrSize):
  21. for y in range(yArrSize):
  22. distAryOne[x][y]=combins[(x*yArrSize)+y]
  23. distAryTwo = [[0]*xArrSize for i in range(yArrSize)] #flipped order of distAryOne
  24. for y in range(yArrSize):
  25. for x in range(xArrSize):
  26. #print y, x, (y*xArrSize)+x
  27. distAryTwo[y][x]=combins[(y*xArrSize)+x]
  28.  
  29. ##Finally calculates Hausdorff Distance
  30. #Calculate distances between origin and target feature
  31. H1 = max([min([distAryOne[i][j] for i in range(xArrSize)]) for j in range(yArrSize)]) #get the highest minimum (supremum infimum) travelling along axis 1 (y-axis)
  32. H2 = max([min([distAryOne[i][j] for j in range(yArrSize)]) for i in range(xArrSize)]) #get the highest minimum (supremum infimum) travelling along axis 0 (x-axis)
  33. #print H1, H2
  34. #Repeat the calculation in reverse order
  35. H3 = max([min([distAryTwo[j][i] for i in range(xArrSize)]) for j in range(yArrSize)]) #get the highest minimum (supremum infimum) travelling along axis 1 (y-axis)
  36. H4 = max([min([distAryTwo[j][i] for j in range(yArrSize)]) for i in range(xArrSize)]) #get the highest minimum (supremum infimum) travelling along axis 0 (x-axis)
  37. #print H3, H4
  38.  
  39. hausdorff = max([H1, H2]+[H3, H4])
  40. #print hausdorff
  41.  
  42. return hausdorff
  43.  
  44. hDist = hausdorffDistance(featureOne.geometry(), featureTwo.geometry()) #gets Hausdorff Distance between two QgsGeometry
  45.  
  46. linesDict = {}
  47. linesDict[1] = QgsGeometry.fromWkt('LineString (19195738.63976059108972549 -5399938.71016304567456245, 19195567.28721107169985771 -5399646.2101767435669899)')
  48. linesDict[2] = QgsGeometry.fromWkt('LineString (19195731.71763794869184494 -5399947.30879085976630449, 19195560.82387629151344299 -5399647.8986875806003809)')
  49. linesDict[3] = QgsGeometry.fromWkt('LineString (19194766.44169946759939194 -5400376.5755823515355587, 19195214.49306683242321014 -5400105.78012083098292351, 19195258.48439108207821846 -5400084.0807413337752223, 19195306.40671262890100479 -5400070.40886308066546917, 19195384.15196022763848305 -5400066.94008383341133595, 19195487.77627336978912354 -5400067.64584534615278244, 19195521.69570336490869522 -5400061.87798151094466448, 19195547.68196233361959457 -5400050.05497545935213566, 19195731.71763794869184494 -5399947.30879085976630449)')
  50. linesDict[4] = QgsGeometry.fromWkt('LineString (19194770.19089671224355698 -5400382.93258125334978104, 19195210.47202705591917038 -5400113.57951446622610092, 19195239.35679624602198601 -5400096.63180513121187687, 19195254.45391828566789627 -5400088.23555850423872471, 19195264.69389183074235916 -5400085.22728221211582422, 19195293.6455497182905674 -5400079.71067976579070091, 19195308.1098017729818821 -5400078.48953226301819086, 19195374.02861313149333 -5400069.41496563982218504, 19195383.67602141946554184 -5400068.01544827781617641, 19195487.77627336978912354 -5400067.64584534615278244, 19195514.07467959076166153 -5400068.170664357021451, 19195524.17230026796460152 -5400065.01574745960533619, 19195536.3263196162879467 -5400059.96993853803724051, 19195573.85859682410955429 -5400037.65741264726966619, 19195676.50016063824295998 -5399974.75716814957559109, 19195711.39376448467373848 -5399954.18374839331954718, 19195738.63976059108972549 -5399938.71016304567456245)')
  51. linesDict[5] = QgsGeometry.fromWkt('LineString (19195731.71763794869184494 -5399947.30879085976630449, 19196343.75779527798295021 -5399613.46129895187914371, 19196395.72945566475391388 -5399589.81357175391167402, 19196570.48818347230553627 -5399533.5258752852678299)')
  52. sixthLineStr = QgsGeometry.fromWkt('LineString (19195738.63976059108972549 -5399938.71016304567456245, 19196027.92994695901870728 -5399769.77589720394462347, 19196106.32950322702527046 -5399741.08493372611701488, 19196326.46363679319620132 -5399622.75882790051400661, 19196505.00672129169106483 -5399554.61725367326289415, 19196570.48818347230553627 -5399533.5258752852678299)') #The sixth linestring we want to compare to the other five
  53.  
  54. for lineNo in linesDict.keys():
  55. print lineNo, hausdorffDistance(linesDict[lineNo], sixthLineStr)
  56.  
  57. closestLineNo = sorted([(hausdorffDistance(linesDict[lineNo], sixthLineStr), lineNo) for lineNo in linesDict.keys()])[0][1]
  58. print "Line number {0} is the closest to the sixth Linestring".format(closestLineNo)
  59.  
  60. Result:
  61. 1 942.18211796
  62. 2 1066.25287595
  63. 3 1066.25287595
  64. 4 1065.47020549
  65. 5 352.393932128
  66. Line number 5 is the closest to the sixth Linestring
  67.  
  68. // Create list of LineStrings
  69. ArrayList<LineString> lineList = new ArrayList();
  70. lineList.add(new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(10, 10), new Coordinate(20, 20)}));
  71. lineList.add(new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(0, 1), new Coordinate(5, 5)}));
  72. // Create a new LineString
  73. LineString newLine = new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(5, 5), new Coordinate(0, 1)});
  74. // Compare your LineStrings
  75. double minDist = 99999;
  76. LineString closestLine = null;
  77. for(LineString ls : lineList){
  78. // you might want to save the resulting LineStrings in another list if there are multiple lines with 0 distance
  79. if(ls.distance(newLine) < minDist){
  80. minDist = ls.distance(newLine);
  81. closestLine = ls;
  82. System.out.println("Found new closest line: " + closestLine.toText());
  83. }
  84. }
  85. if(newLine.equalsExact(closestLine)){
  86. System.out.println("Lines have the same start- & endpoints!");
  87. }
  88. // you might also want to compare the reverse order...
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement