選在周一發(fā),因?yàn)榇蠹曳凑膊豢?/span> 從第一天學(xué)習(xí)編程,可能大家就聽(tīng)說(shuō)這樣的組成公式:程序=算法+數(shù)據(jù)結(jié)構(gòu) ——該公式出自著名計(jì)算機(jī)科學(xué)家沃思(Nikiklaus Wirth)實(shí)際上,程序除了以上兩個(gè)主要要素之外,還應(yīng)當(dāng)采用結(jié)構(gòu)化程序設(shè)計(jì)方法進(jìn)行程序設(shè)計(jì),并且用某一種計(jì)算機(jī)語(yǔ)言表示。因此,算法、數(shù)據(jù)結(jié)構(gòu)、程序設(shè)計(jì)方法和語(yǔ)言工具4個(gè)方面是一個(gè)程序設(shè)計(jì)人員所應(yīng)具備的知識(shí)。所以,要學(xué)習(xí)組成程序的最重要的具現(xiàn)化方式,就是計(jì)算機(jī)語(yǔ)言。計(jì)算機(jī)語(yǔ)言則以是語(yǔ)句 + 表達(dá)式 為原子所組成邏輯集合體;最基礎(chǔ)的邏輯集合體,就是函數(shù)。計(jì)算機(jī)是一個(gè)固定的一個(gè)程序段,或稱其為一個(gè)子程序,它在可以實(shí)現(xiàn)固定運(yùn)算功能的同時(shí),還帶有一個(gè)入口和一個(gè)出口,所謂的入口,就是函數(shù)所帶的各個(gè)參數(shù),我們可以通過(guò)這個(gè)入口,把函數(shù)的參數(shù)值代入子程序,供計(jì)算機(jī)處理;所謂出口,就是指函數(shù)的函數(shù)值,在計(jì)算機(jī)求得之后,由此口帶回給調(diào)用它的程序。 所以,我們?cè)趯W(xué)習(xí)Rust的時(shí)候,不要被哪些天花亂墜的特性、泛型、生命周期給弄傻,要學(xué)習(xí),先去翻函數(shù),學(xué)習(xí)怎么寫函數(shù),一個(gè)函數(shù)解決一個(gè)問(wèn)題。同樣,去讀大神代碼的時(shí)候,也別一爬起來(lái)就去讀整體架構(gòu)設(shè)計(jì),安心去讀他最底層的實(shí)現(xiàn),如果讀不懂,可以借助GPT一類的工具,讓它給你講講,如下所示:效果那是極好的。 下面針對(duì)我們上篇文章那個(gè)可視化的需求,我們來(lái)寫個(gè)簡(jiǎn)單函數(shù)來(lái)實(shí)現(xiàn)一下:需求:讀取一個(gè)shapefile文件,把這個(gè)shapefile文件中的幾何信息繪制到地圖上。//Cargo.toml //后面的features特性,暫時(shí)不用去管,這是一種Rust特有的編譯特性 plotly = { version = "0.8.4", features = ["kaleido"] } shapefile = {version = "0.5.0", features = ["geo-types"]} geo-types = "0.7.12" 讀取一個(gè)shapefile,并且把幾何信息給獲取出來(lái)。在Rust中,可以通過(guò)shapefile包來(lái)讀取shapefile,實(shí)現(xiàn)如下: let shp = shapefile::read_as::<_, shapefile::Polygon, shapefile::dbase::Record>( "./data/shp/北京行政區(qū)劃.shp", ).expect(&format!("Could not open polygon-shapefile: './data/shp/北京行政區(qū)劃.shp'")); 接下去,需要把里面的geometry信息給取出來(lái): //定義一個(gè)集合,通過(guò)文件迭代器,把geometry部分轉(zhuǎn)換成polygon,然后加入到這個(gè)幾何里面去。 let mut polygons:Vec<Polygon> = Vec::new(); for (polygon, polygon_record) in shp { let geo_mpolygon: geo_types::MultiPolygon<f64> = polygon.into(); for poly in geo_mpolygon.iter(){ polygons.push(poly.to_owned()); } } 把這個(gè)polygon集合,繪制到plotly上去首先plotly繪制幾何圖形,是按照坐標(biāo)來(lái)的,一系列坐標(biāo)組成一個(gè)繪圖元素,代碼如下: let mut trace_vec = Vec::new(); for ps in polygons{ let mut lon:Vec<f64> = Vec::new(); let mut lat:Vec<f64> = Vec::new(); for p in ps.exterior(){ lon.push(p.x); lat.push(p.y); } let trace = ScatterMapbox::new(lat, lon).mode(Mode::None) .fill(plotly::scatter_mapbox::Fill::ToSelf) .fill_color(Rgba::new(0,0,255,0.5)); trace_vec.push(trace); } 獲得基本地圖的配置let layout = Layout::new() .drag_mode(DragMode::Zoom) .margin(Margin::new().top(10).left(10).bottom(10).right(10)) .width(1024) .height(700) .mapbox( Mapbox::new() .style(MapboxStyle::WhiteBg) .center(Center::new(39.9, 116.3)) .zoom(9), ) 最后繪制顯示地圖let mut plot = Plot::new(); plot.set_layout(layout); for t in trace_vec.iter(){ plot.add_trace(t.to_owned()); } plot.show(); 全部代碼,放到一個(gè)function里面,如下所示: 然后寫個(gè)測(cè)試方法運(yùn)行一下: 運(yùn)行結(jié)果: 現(xiàn)在看起來(lái),是不是很簡(jiǎn)單了,對(duì)比Python實(shí)際上也沒(méi)有多出幾行代碼,直接閱讀過(guò)去,除了一些定義類型和轉(zhuǎn)換類型的時(shí)候,比Python更加嚴(yán)格以外,會(huì)Python的同學(xué),幾乎可以完全能夠看懂。——所以說(shuō),你完全可以把Rust當(dāng)成一個(gè)類型嚴(yán)格版本的Python就闊以了……不過(guò),對(duì)于寫過(guò)工程性質(zhì)代碼的同學(xué)看完,肯定會(huì)覺(jué)得這個(gè)代碼寫的太粗糙了,所有步驟都混在一起,內(nèi)容全部寫死,而且無(wú)法復(fù)用……沒(méi)錯(cuò),初學(xué)者該有的毛病,這里都有,雖然功能實(shí)現(xiàn)了,但是根本只是一個(gè)demo,無(wú)法達(dá)到工程級(jí)的應(yīng)用,所以從下一節(jié)開(kāi)始,我們就會(huì)針對(duì)這個(gè)功能,按Rust的編碼風(fēng)格,去抽象和重構(gòu),最后完成一個(gè)工程級(jí)的可視化應(yīng)用模塊。
|