gis演算法基礎——左轉演算法拓撲生成
gis演算法基礎——向量資料壓縮道格拉斯普克壓縮演算法(非遞迴實現)
本人應用js中的canvas對演算法結果進行視覺化驗證,在演算法說明及實現中繪製驗證部分省略
拓撲相關基本概念:拓撲空間關係是一種對空間結構進行明確定義的數學方法。
•具有拓撲關係的向量資料結構就是拓撲資料結構。
•拓撲資料結構描述了基本空間目標點、線、面之間的關聯、鄰接和包含關係
•拓撲空間關係資訊是空間分析的基礎之一
資料預處理–弧段處理,使整幅圖形中的所有弧段,除在端點處相交外,沒有其他交點,即沒有相交或自相交的弧段–結點匹配,建立結點、弧段關係拓撲構建–建立多邊形,以左轉演算法或右轉演算法跟蹤,生成多邊形,建立多邊形與弧段的拓撲關係–建立多邊形與多邊形的拓撲關係
拓撲關係自動建立的第一步就是處理弧段,使得弧段不存在自相交和相交現象,其過程分為三步:
–直線段相交的判斷方法
–自相交弧段處理
–弧段相交打斷處理
從組成多邊形邊界的某一條弧段開始;如果該弧段與x軸正向夾角為最大,則從該弧段的同一結點出發的其他弧段中,方向角最小的弧段是該多邊形的後續弧段;如果該弧段的方向角最小或介於同一結點的其他弧段方向角之間,則最小夾角偏差所對應的弧段為多邊形的後續弧段
(1)順序取乙個結點作為起始結點,取完為止;取過該結點的方位角最小的未使用過的或僅使用過一次,且使用過的方向與本次相反的弧段作為起始弧段。(2)取這條弧段的另乙個結點,找這個結點關聯的弧段集合中的本條弧段的下一條弧段,如果本條弧段是最後一條弧段,則取弧段集合的第一條弧段,作為下一條弧段。
(3)判斷是否回到起點,如果是則形成了乙個多邊形,記錄下它,並且根據弧段的方向,設定組成該多邊形的左右多邊形資訊。否則轉(2)。
(4)取起始點上開始的,剛才所形成多邊形的最後一條邊作為新的起始弧段,轉(2);若這條弧段已經使用過兩次,即形成了兩個多邊形,轉(1)。
// 結點類
class
nodep
extends
point
sortarc()
this
.linkarc.
sort
(utils.
compareprop
('azimuth'))
;}getneararc
(aarc)
getuseablearc()
}return0;
}}
//弧段類
class
arcgetspep()
reverse()
getazimuth
(anode)
else
}getdirection
(anode)
else
if(anode ==
this
.points[
this
.points.length-1]
)else console.
log(
"點匹配失敗獲取方向出現問題");
}getanothernode
(node)
}
//多邊形類
class
polygon
getcp()
}let centerp =
newpoint
(sumx/sump,sumy/sump)
;return centerp;
}judgepart()
}getpoints()
}else
if(arc.ifergodic==2)
}else console.
log(
"賦予多邊形點資訊出錯");
}this
.points.
push
(this
.points[0]
);}arcside()
}area()
return asum/2;
}polygonbbox()
this
.bbox =
newbbox
(new
array
(ltp,rbp));
}}
//左轉演算法
static
subturnleft
(stnode,starc)
else
if(curarc.ifergodic==
1) curnode = curarc.sp;
//確定了方向的邊則一定是選取起始點
else console.
log(
"左轉選取下一條邊出現問題"
);
curarc.ifergodic++
; polyarcs.
push
(curarc)
; curarc = curnode.
getneararc
(curarc);}
let apolygon =
newpolygon
(polyid,polyarcs)
;++polyid;
apolygon.
arcside()
;//左右多邊形
apolygon.
getpoints()
;//按順序連線點
this
.judgehole
(apolygon,polygons,holes)
;//通過面積判斷將多邊形分別放入多邊形以及島列表中
starc = apolygon.arcs[apolygon.arcs.length-1]
;//多邊形最後一條邊作為起始進行遞迴
//todo:似乎有更好的邏輯???嘗試過之後會有bug
if(starc.ifergodic!=2)
this
.subturnleft
(stnode,starc)
;else
return;}
static
turnleft
(nodelist)
else
if(arc.ifergodic==1)
}else
if(arc.ifergodic==2)
continue
;//遍歷過兩次的邊跳過 }}
}
static
pairholes
(polygons,holes)
flag =1;
}if(flag)}}
}
利用canvas將生成的多邊形隨機填充為不同的顏色,多邊形島統一不填充(但是他們並非為空而也是多邊形)
左轉演算法邏輯清晰,多讀幾遍演算法過程描述就能理解其邏輯,但是將此邏輯轉化為程式語言並不容易,特別是在需要從基礎的類開始構建的情況下。
在我進行的過程中,按照自己的思路寫了一遍發現總是會有bug,在debug改**進行了很長時間依然沒有效果的情況下,我果斷選擇全部重寫,事實證明是有效的。對於js這門語言,在很多書中以及博主的教學中,都提及其動態性等導致自己的程式很難debug成功,而花費的時間精力不如從頭來過,並且這樣能解決大多數的問題。我是真實體驗過了。
GIS演算法 向量(陣列基礎 程式設計基礎)
在程式設計中的應用 有向線段 有一條線段的端點是有先後次序之分的,這條線段即有向線段 directed segment 向量 有限線段p1p2的起點p1在座標原點,把它稱為向量p2 二維向量p x1,y1 q x2,y2 向量加法 p q x1 x2,y1 y2 向量減法 p q x1 x2,y1 ...
GIS 演算法,計算箭頭
根據兩個點,計算箭頭。var x2 points length 1 x var y2 points length 1 y var x1 points length 2 x var y1 points length 2 y var distance math.sqrt math.pow x2 x1 2...
拓撲排序演算法
對許多資料結構教材實在不滿意,至少我是看不懂 至於拓撲排序演算法,教材上那些偽 真真教人頭暈。只寫了幾個struct結構,我根本看不出這是鄰接表。如果給出乙個清晰明了的圖,一切不就簡單了?總之,關鍵就是建立乙個鄰接表。然後利用這個表進行拓撲排序。邊表結點宣告 typedef struct edgen...