江西住房和城乡建设信息网站,外贸网站seo,产品设计软件有哪些软件,lollipop Wordpress上一节我们讲了用泛型实现返回结果#xff0c;这一节我们来讲讲在函数签名里面使用泛型来对输入参数进行自适配。
先看UML设计图#xff1a; 好吧#xff0c;看起来有点复杂#xff0c;我们一个个来解释。
首先定义的是一个生成绘图元素需要的参数结构,并且定义个特性这一节我们来讲讲在函数签名里面使用泛型来对输入参数进行自适配。
先看UML设计图 好吧看起来有点复杂我们一个个来解释。
首先定义的是一个生成绘图元素需要的参数结构,并且定义个特性就叫做构造绘图元素build_trace。
pub struct traceParamG{pub geometrys:VecG,pub colors: VecinputColor,pub size: usize,
}pub trait BuildTrace{fn build_trace(self) - VecBoxScatterMapboxf64,f64;
}
绘图元素的参数定义了三个参数 第一个参数是输入一个几何要素集合因为我们最起码有点线面三种几何要素所以定义的是一个泛型变量G。 第二参数是一个颜色集合这里也可以用泛型不过我们不需要那么多种颜色定义这里给了一个枚举型的输入颜色枚举定义如下
#[derive(Debug,Clone)]
pub enum inputColor {NamedColor(NamedColor),Rgba(Rgba),
}
这里支持NameColor和Rgba两种颜色定义即可。 第三个参数是一个size用来控制点的大小、线的宽度和面要素的边框当然你也可以设定更多的参数我这里仅用来说明就不搞那么麻烦了 接下去就可以写具体的实现了。
点要素的实现
impl BuildTrace for traceParamPoint{fn build_trace(self) - VecBoxScatterMapboxf64,f64 {let mut traces:VecBoxScatterMapboxf64,f64 Vec::new();for (pnt,color) in zip(self.geometrys,self.colors) {let mut trace: BoxScatterMapboxf64, f64 ScatterMapbox::new(vec![pnt.y()], vec![pnt.x()]);trace match color {inputColor::NamedColor(color) {MyTrace{color:*color,size:self.size,trace:trace}.set_trace(geo_type::Point)},inputColor::Rgba(color) {MyTrace{color:*color,size:self.size,trace:trace}.set_trace(geo_type::Point)},_ panic!(),};traces.push(trace);}traces}
}
线要素的实现
impl BuildTrace for traceParamLineString{fn build_trace(self) - VecBoxScatterMapboxf64,f64 {let mut traces:VecBoxScatterMapboxf64,f64 Vec::new();for (line,color) in zip(self.geometrys,self.colors) {let mut lat:Vecf64 Vec::new();let mut lon:Vecf64 Vec::new();for coord in line.coords(){lat.push(coord.y);lon.push(coord.x);}let mut trace: BoxScatterMapboxf64, f64 ScatterMapbox::new(lat, lon);trace match color {inputColor::NamedColor(color) {MyTrace{color:*color,size:self.size,trace:trace}.set_trace(geo_type::Line)},inputColor::Rgba(color) {MyTrace{color:*color,size:self.size,trace:trace}.set_trace(geo_type::Line)},_ panic!(),};traces.push(trace);}traces}
}
面数据的实现
impl BuildTrace for traceParamPolygon{fn build_trace(self) - VecBoxScatterMapboxf64,f64 {let mut traces:VecBoxScatterMapboxf64,f64 Vec::new();for (poly,color) in zip(self.geometrys,self.colors) {let mut lat:Vecf64 Vec::new();let mut lon:Vecf64 Vec::new();for coord in poly.exterior(){lat.push(coord.y);lon.push(coord.x);}let mut trace: BoxScatterMapboxf64, f64 ScatterMapbox::new(lat, lon);trace match color {inputColor::NamedColor(color) {MyTrace{color:*color,size:self.size,trace:trace}.set_trace(geo_type::Polygon)},inputColor::Rgba(color) {MyTrace{color:*color,size:self.size,trace:trace}.set_trace(geo_type::Polygon)},_ panic!(),};traces.push(trace);for ipoly in poly.interiors(){let mut ilat:Vecf64 Vec::new();let mut ilon:Vecf64 Vec::new();for coord in poly.exterior(){ilat.push(coord.y);ilon.push(coord.x);}trace ScatterMapbox::new(ilat, ilon); trace MyTrace{color:NamedColor::White,size:self.size,trace:trace}.set_trace(geo_type::Polygon);traces.push(trace);}}traces}
}
里面三个方法都用了一个处理trace的方法实现如下
struct MyTraceT{color:T,size:usize,trace:BoxScatterMapboxf64,f64
}enum geo_type{Point,Line,Polygon,
}
trait SetTraceT {fn set_trace(self,geo_type:geo_type)-BoxScatterMapboxf64,f64;
}impl SetTraceNamedColor for MyTraceNamedColor{fn set_trace(self,geo_type:geo_type)-BoxScatterMapboxf64,f64 {match geo_type{geo_type::Point {let t *self.trace.to_owned().marker(Marker::new().color(self.color)).show_legend(false);Box::new(t)},geo_type::Line {let t *self.trace.to_owned().line(Line::new().width(self.size as f64).color(self.color)).show_legend(false);Box::new(t)},geo_type::Polygon {let t *self.trace.to_owned().fill(plotly::scatter_mapbox::Fill::ToSelf).fill_color(self.color).show_legend(false);Box::new(t)},_ panic!()}}
}impl SetTraceRgba for MyTraceRgba{fn set_trace(self,geo_type:geo_type)-BoxScatterMapboxf64,f64 {match geo_type{geo_type::Point {let t *self.trace.to_owned().marker(Marker::new().color(self.color)).show_legend(false);Box::new(t)},geo_type::Line {let t *self.trace.to_owned().line(Line::new().width(self.size as f64).color(self.color)).show_legend(false);Box::new(t)},geo_type::Polygon {let t *self.trace.to_owned().fill(plotly::scatter_mapbox::Fill::ToSelf).fill_color(self.color).show_legend(false);Box::new(t)},_ panic!()}}
}
这两个方法几乎99%是想同的只是输入的颜色类型不一样这样就是静态语言的麻烦之处了只要函数签名不一致就相当于两个方法看到这里大家可能想问上一节讲过的泛型在这里能用么答案当然可以不过就算用泛型最终编译出来的代码也会因为编译器的处理而实现函数单态化即编译器会针对具体情况编译出多个静态函数出来。所以这里如果继续抽象也不是不行但是算做过度设计了。
之后就可以写一个绘制函数然后进行调用了
pub fn plot_draw_trace(traces:VecBoxScatterMapboxf64,f64,outimg: Optionstr){let mut plot Plot::new();for t in traces{plot.add_trace(t);}let layout _get_layout(1024, 800, Center::new(39.9, 116.3),MapboxStyle::Dark);plot.set_layout(layout);match outimg {Some(out) plot.write_image(out, ImageFormat::PNG, 1200, 900, 1.0),None plot.show(),}
}//这个是一个内部函数用来初始化构造制图参数的。
fn _get_layout(width:usize, height:usize,cnt:Center,ms:MapboxStyle) - Layout{Layout::new().drag_mode(DragMode::Zoom).margin(Margin::new().top(10).left(10).bottom(10).right(10)).width(width).height(height).mapbox(Mapbox::new().style(ms).access_token(pk.eyJ1IjoiYWxsZW5sdTIwMDgiLCJhIjoiY2xxZjNsaGtmMDd0ZTJqcWM1MzRmemx1NCJ9.TbiPQB6j1w9ilBP4pFHRRw).center(cnt).zoom(10),)
}
最后我们写一个测试调用方法来绘制一下百度地图
// 因为在Html里面绘制比较慢所以我这里就仅画三个图层
#[test]
fn draw_bd_style(){let shp1 ./data/shp/北京行政区划.shp;let poly1:VecPolygon readShapefile::shp::read_shp(shp1);let colors:VecinputColor (0..poly1.len()).map(|x|inputColor::Rgba(Rgba::new(240,243,250,1.0))).collect();let mut t1 traceParam{geometrys:poly1,colors:colors,size:0}.build_trace();let shp2 ./data/shp/面状水系.shp;let poly2:VecPolygon readShapefile::shp::read_shp(shp2);let colors:VecinputColor (0..poly2.len()).map(|x|inputColor::Rgba(Rgba::new(108,213,250,1.0))).collect();let mut t2 traceParam{geometrys:poly2,colors:colors,size:0}.build_trace();let shp3 ./data/shp/高速.shp;let line1:VecLineString readShapefile::shp::read_shp(shp3);let colors:VecinputColor (0..line1.len()).map(|x|inputColor::Rgba(Rgba::new(255,182,118,1.0))).collect();let mut t3 traceParam{geometrys:line1,colors:colors,size:1}.build_trace();t1.append(mut t2);t1.append(mut t3);plot_draw_trace(t1,None);
}
绘制效果如下 注意plotly.rs的JS引用的是Mapbox所以网络访问上可能会有一些障碍有可能需要科学上网…… 打完收工。