0%

将ViewModel设置为View自身

1
2
3
4
5
//在构造函数中设置
public View(){
InitializeComponent();
DataContext = this;
}

Binding

Binding

在MVVM模型中,将View中的控件的依赖属性与ViewModel或其它实体的内容绑定。

Binding源与路径

控件作为Binding源

1
2
3
4
5
<!-- xaml里不能直接访问控件对象,应使用ElementName指定源 -->
<TextBox x:Name="textBox1" Text="{Binding Path=Value, ElementName=slider1}"/>
<!-- Binding类构造器本身可以接收Path参数可以简写为 -->
<TextBox x:Name="textBox1" Text="{Binding Value,ElementName=slider1}"/>
<Slider x:Name="slider1" Maximum="100" Minimum="0"/>
1
2
3
4
5
this.textBox1.SetBinding(TextBox.TextProperty,new Binding(){Path=new PropertyPath("Value"),ElementName="slider1"});
//C#代码可以直接访问控件对象也可以写为
this.textBox1.SetBinding(TextBox.TextProperty,new Binding(){Path=new PropertyPath("Value"),Source="slider1"});
//使用Binding的构造器写为
this.textBox1.SetBinding(TextBox.TextProperty,new Binding("Value"){Source="slider1"});

Binding的方向及数据更新

  1. 属性Mode控制Binding数据流向可选为 TwoWay,OneWay,OnTime,OnWayToSource,Default
  2. 属性UpdateSourceTrigger控制Binding目标的更新时机 可选为PropertyChanged,LostFocus,Explicit,Default
  3. 属性NotifyOnSourceUpdated和属性NotifyOnTargetUpdated设为True时,当源或目标更新时,会激发SourceUpdated和TargetUpdated事件。

Binding的路径Path

  1. 多级路径
1
2
3
<TextBox x:Name="textBox1" Text="{Binding Text.Length,ElementName=textBox2,Mode=OneWay}"/>
<!-- 集合类型的索引器(Indexer)又称为带参属性,既然是属性,也可以作为Path来使用。 点也可以省略-->
<TextBox x:Name="textBox1" Text="{Binding Text.[3],ElementName=textBox2,Mode=OneWay}"/>
  1. 当使用集合或DataView作为Binding源时,如果我们想把它的默认元素当做Path来使用,则需要使用这样的语法
1
2
3
4
List<string> stringList = new List<string>(){"Tim","Tom","Blog"};
this.textBox1.SetBinding(TextBox.TextProperty,new Binding("/"){Source=stringList});
this.textBox2.SetBinding(TextBox.TextProperty,new Binding("/Length"){Source=stringList,Mode=BindingMode.OneWay});
this.textBox3.SetBinding(TextBox.TextProperty,new Binding("/[2]"){Source=stringList,Mode=BindingMode.OneWay});
  1. 如果集合元素属性仍然是一个集合,使用多级斜线的语法。待完善。

没有Path的Binding

  1. Binding源本身就是数据,用"."表示,xaml可以省略,C#中不可以
1
2
3
4
5
6
7
8
9
10
<StackPanel>
<StackPanel.Resources>
<sys:String x:Key="string1">
本来无一物,何处惹尘埃
</sys:String>
</StackPanel.Resources>
<TextBox x:Name="textBox1" Text="{Binding Path=.,Source={StaticResource ResourceKey=string1}}">
<TextBox x:Name="textBox2" Text="{Binding .,Source={StaticResource ResourceKey=string1}}">
<TextBox x:Name="textBox3" Text="{Binding Source={StaticResource ResourceKey=string1}">
</StackPanel>
1
2
string string1 = "本来无一物,何处惹尘埃";
this.textBox1.SetBinding(TextBox.TextProperty,new Binding("."){Source=string1});

为Binding指定源的几种方法。

  • 普通CLR对象类型,只要类型实现INotifyPropertyChanged接口并在属性的set语句中激发PropertyChanged事件来通知Binding目标已经更新。
  • 普通CLR集合类型,包括数组 List,ObservableCollection 作为ItemsControl的ItemsSource属性的源。
  • ADO.NET数据对象,包括DataTable和DataView等对象。
  • 使用XmlDataProvider把XML数据指定为Source,可以用XML表示单个数据对象或集合,可以作为TreeView和Menu等级联式的控件关联的Binding的源。
  • 把依赖对象指定为Source,依赖对象不仅可以作为Binding的目标,同时也可以作为Binding的源。
  • 把容器的DataContext指定为Source(WPF Data Binding的默认行为)。
  • 通过ElementName指定Source
  • 通过Binding的RelativeSource属性相对的指定Source:当控件需要关注自己的,自己容器的或者自己内部元素的某个值就需要使用这个方法。
  • ObjectDataProvider对象指定Source:当数据源的数据不是通过属性而是通过方法暴露给外界的时候,我们可以使用者两种对象来包装数据源再把他们指定为Source。
  • 把使用LINQ检索得到的数据对象作为Binding的源。

没有Source的Binding----使用DataContext作为Binding的源

当一个Binding只知道Path而不知道Source时,会沿着UI元素树一直向树的根部去寻找
DataContext是一个依赖属性,依赖属性的重要特点是当你没有未控件的某个依赖属性显示赋值时,控件会把自己容器的属性值借过来当做自己的属性值,实际上是属性值沿着UI元素乡下传递了。
既没有Path也没有Source的情况

1
2
3
4
5
6
7
8
9
10
<StackPanel>
<StackPanel.DataContext>
<sys:String>Hello DataContext</sys:String>
</StackPanel.DataContext>
<Grid>
<StackPanel>
<TextBox Text="{Binding}"></TextBox>
</StackPanel>
</Grid>
</StackPanel>

DataContext的灵活用法。

  1. 当UI上的多个控件都使用Binding关注同一个对象时。
  2. 当作为Source的对象不能被直接访问的时候。比如B窗体内的控件想把A窗体的控件当做自己的Binding源时,但A窗体内的控件是private访问级别的,这时候就可以把这个控件(或者控件的值)作为窗体A的DataContext(这个属性是public访问级别的)从而暴露数据。????????

使用集合对象作为列表控件的ItemsSource

1
2
3
4
5
6
7
8
9
List<Student> students = new List<Student>(){
new Student(){Id=0,Name="Tim",Age=20,
···
}
}
this.listBoxStudents.ItemsSource= students;
this.listBoxStudents.DisplayMemberPath="Name";//此属性被赋值后会自动创建Path赋值创 Binding。
Binding binding = new Binding("SelectedItem.Id"){Source=listBoxStudents};
this.textBox1.SetBinding(TextBox.TextProperty,binding);
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 需要设置ItemsSource属性 -->
<ListBox x:Name="listBoxStudents">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Id}"/>
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text="{Binding Path=Age}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

使用ADO.NET对象作为Binding的源。

listbox

1
2
3
DataTable dt = this.Load();
this.listBoxStudents.DisplayMemberPath="Name";
this.listBoxStudents.ItemsSource=dt.DefaultView;

listView

1
2
3
4
5
6
7
8
9
<ListView x:Name="listViewStudents">
<ListView.View>
<GridView>
<GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}">
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}">
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}">
</GridView>
</ListView.View>
</ListView>
  • ListView 派生自 ListBox GridView派生自ViewBase ListView的View属性是一个ViewBase对象,是组合模式。

使用XML数据作为Binding的源

使用XmlDataProvider 和XPath

1
2
3
4
5
6
7
8
9
XmlDocument doc = new XmlDocument();
doc.Load(@"D:\RawData.xml");

XmlDataProvider xdp = new XmlDataProvider();
xdp.Document = doc; //使用Document属性
xdp.Source = new Uri(@"D:\RawData.xml"); //使用SOUr
xdp.XPath = @"/StudentList/Student";
this.listViewStudents.DataContext=xdp;
this.listViewStudents.SetBinding(ListView.ItemsSourceProperty,new Binding())

使用LINQ检索结果作为Binding的源

1
this.listViewStudents.ItemsSource = from stu in stuList where stu.Name.StartsWith("T") select stu;

使用ObjectDataProvider对象作为Binding的源

使用BInding的RelativeSource

  • 当一个Binding有明确的数据来源时我们可以通过为Source或ElementName赋值的办法让Binding与之关联。
1
2
3
4
5
6
//多层布局
RelativeSource rs = new RelativeSource(RelativeSourceMode.FindAncestor);
rs.AncestorLevel = 1;
rs.AncestorType=typeof(Grid);
Binding binding = new Binding("Name"){RelativeSource=rs};
this.textBox1.SetBinding(TextBox.TextProperty,binding);
1
<TextBox Text="{Binding Name,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}AncestorLevel=1}}"/>
1
2
3
4
5
//自身属性
RelativeSource rs = new RelativeSource();
rs.Mode = RelativeSourceMode.Self;
Binding binding new Binding("Name"){RelativeSource=rs};
this.textBox1.SetBinding(TextBox.TextProperty,binding)

RelativeSourceMode枚举值取值有PreviousData TemplatedParent Self FindAncestor
三个静态属性 PreviousData Self TemplatedParent 直接返回上述类型的三个实例。

Binding对数据的转换与校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//验证逻辑 
public class RangeValidationRule:ValidationRule{
public override ValidationResult Validate(object value,System.Globalization.CultureInfo cultureInfo){
double d = 0;
if(double.TryParse(value.ToString(),out d)){
if(d>=0&&d<=100){
return new ValidationResult(true,null);
}
}
return new ValidationResult(false,"Validation Failed");
}
}
//绑定
Binding binding = new Binding("Value"){Source = this.slider1};
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
RangeValidationRule rule = new RangeValitionRule();
binding.ValidationRules.Add(rule);
this.textBox1.SetBinding(TextBox.TextProperty,binding);

默认校验机制为Source更新Target(用户输入)更新时不校验,如果改变可以设置可已设置ValidatesOnTargetUpdated设置为true;

Binding的数据转换

实现继承IValueConverter的类

1
2
3
<local:MyValueConverter x:key="cts"/>
...
<TextBox Text="{Binding Name,Converter={StaticResource cts}}"/>

控件的继承关系

下图为WPF结果的继承关系图

images

  • DispatcherObject

    WPF 中的大多数对象是从 DispatcherObject 派生的,这提供了用于处理并发和线程的基本构造。WPF 基于调度程序实现的消息系统。

  • DependencyObject

    依赖对象

  • Visual

    为 WPF 中的呈现提供支持,其中包括命中测试、坐标转换和边界框计算

  • UIElement

    WPF 核心级实现的基类,该类建立在 Windows Presentation Foundation (WPF) 元素和基本表示特征基础上。

  • FrameworkElement

    为 Windows Presentation Foundation (WPF) 元素提供 WPF 框架级属性集、事件集和方法集。此类表示附带的 WPF 框架级实现,它是基于由UIElement定义的 WPF 核心级 API 构建的。

  • Control

    表示 用户界面 (UI) 元素的基类,这些元素使用 ControlTemplate 来定义其外观。

DispatcherObject类用于线程管理的类,此出不详解,从下一个DependencyObject开始说起

模拟部署Hadoop集群

  1. 创建三台虚拟机 master slave slave1

  2. 配置时钟同步

    1
    crontab -e

    会自动打开/tmp/crontab.HNLfTD文件

    1
    2
    * * * /user/sbin/ntpdate cn.pool.ntp.org
    * * * /user/sbin/ntpdate aliyun.com

    星号是cron时间表达式,也可以直接输入后面的命令进行手动同步时间

  3. 配置主机名

    1
    2
    3
    4
    5
    vim /etc/sysconfig/network
    #确认修改生效
    hostname master
    #验证
    hostname
  4. 配置网络环境

    1
    2
    3
    4
    5
    6
    7
    #配置ip
    setup
    Network configuration
    #重启网络服务
    service network restart
    #查看状态
    ifconfig
  5. 关闭防火墙

    1
    2
    setup
    Firewall configuration
  6. 配置hosts列表

    1
    2
    3
    4
    #修改host
    vim /etc/hosts
    #验证
    ping master
  7. 安装JDK

    1
    2
    3
    4
    mkdir /usr/java 
    cp /home/ydh/jdk-7u71-linux-x64.gz /usr/java
    cd /usr/java
    tar –zxvf jdk-7u71-linux-x64.gz
  8. 配置环境变量

    1
    2
    3
    4
    5
    6
    7
    #配置给普通用户
    vim /home/ydh/.bash_profile
    export JAVA_HOME=/usr/java/jdk1.7.0_71
    export PATH=$JAVA_HOME/bin:$PATH
    source /home/ydh/.bash_profile
    #验证是否安装成功
    javac
  9. 设置SSH免密登陆

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #master普通用户下生成密钥
    ssh-keygen –t rsa
    #生成的密钥在/home/ydh/.ssh/目录下,私钥为id_rsa,公钥为id_rsa.pub
    #复制公钥文件到authorized_keys文件中
    cat /home/ydh/.ssh/id_rsa.pub >> /home/ydh/.ssh/authorized_keys
    #修改authorized_keys文件的权限,只有当前用户ydh有权限操作authorized_keys文件
    chmod 600 /home/ydh/.ssh/authorized_keys
    #将 HadoopMaster 主节点生成的 authorized_keys 公钥文件复制到 HadoopSlave 和HadoopSlave1从节点
    scp /home/ydh/.ssh/authorized_keys ydh@slave:/home/ydh/.ssh/
    scp /home/ydh/.ssh/authorized_keys ydh@slave1:/home/ydh/.ssh/
    #在从节点修改文件权限为当前用户可读可写
    chmod 600 /home/ydh/.ssh/authorized_keys
    #主节点验证免密登陆
    ssh slave
  10. 上传hadoop安装文件并解压

    1
    2
    3
    tar –zxvf hadoop-2.5.2.tar.gz 
    cd hadoop-2.5.2
    ls –l
  11. 配置环境变量hadoop-env.sh

    1
    2
    vim /home/ydh/Hadoop-2.5.2/etc/hadoop/hadoop-env.sh
    export JAVA_HOME=/usr/java/jdk1.7.0_71
  12. 配置环境变量yarn-env.sh

    1
    2
    vim /home/ydh/Hadoop-2.5.2/etc/hadoop/yarn-env.sh
    export JAVA_HOME=/usr/java/jdk1.7.0_71
  13. 配置核心组件core-site.xml

    1
    vim /home/ydh/Hadoop-2.5.2/etc/hadoop/core-site.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version=“1.0” encoding=“UTF-8”?>
    <?xml-stylesheet type=“text/xsl” href=“configuration.xsl”?>
    <!— Put site-specific property overrides in this file. —> <configuration>
    <!—HDFS文件系统的入口地址信息—>
    <property>
    <name>fs.defaultFS</name>
    <value>hdfs://master:9000</value>
    </property>
    <!—HDFS 文件系统数据落地到本地磁盘的路径信息,/home/ zkpk/hadoopdata 该目录需要单独创建,后面将在启动hadoop集群时统一 创建 —>
    <property>
    <name>hadoop.tmp.dir</name>
    <value>/home/ zkpk/hadoopdata</value>
    </property>
    </configuration>
  14. 配置文件系统hdfs-site.xml

    1
    vim /home/ydh/hadoop-2.5.2/etc/hadoop/hdfs-site.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version=“1.0” encoding=“UTF-8”?> 
    <?xml-stylesheet type=“text/xsl” href=“configuration.xsl”?>
    <!— Put site-specific property overrides in this file. —> <configuration>
    <property>
    <!—配置数据块的副因子(即副本数)为2–>
    <name>dfs.replication</name>
    <value>2</value>
    </property>
    </configuration>
  15. 配置配置YARN资源系统yarn-site.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <?xml version=“1.0”?> 
    <configuration>
    <!— yarn.nodemanager.aux-services 是 NodeManager 上运行的附属服务,其值需要配置成mapreduce_shuffle,才可以运行MapReduce程序—>
    <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
    </property>
    <!— yarn.resourcemanager.address 是ResourceManager对客户端暴露的访问地址,客户端通过该地址向ResourceManager提交或结束MapReduce应用程序—>
    <property>
    <name>yarn.resourcemanager.address</name>
    <value>master:18040</value>
    </property>
    <!-yarn.resourcemanager.scheduler.address是ResourceManager对ApplicationMaster (客户端将MapReduce应用程序提交到集群中,ResourceManager接受客户端应用程序的提交后,将该应用程序分配给某一个NodeManager,对该MapReduce应用程序进行初始化,进而产生一个应用程序初始化Java对象,将这个Java对象称为ApplicationMaster)暴露的访问地址,ApplicationMaster通过该地址向ResourceManager申请MapReduce应用程序在运行过程中所需要的资源,以及程序运行结束后对使用资源的释放等—>
    <property>
    <name>yarn.resourcemanager.scheduler.address</name>
    <value>master:18030</value>
    </property>
    <!— yarn.resourcemanager.resource-tracker.address 是ResourceManager对NodeManager暴露的访问地址,NodeManager通过该地址向ResourceManager发送心跳数据,汇报资源使用情况以及领取ResourceManager将要分配给自己的任务等—>
    <property>
    <name>yarn.resourcemanager.resource-tracker.address</name>
    <value>master:18025</value>
    </property>
    <!— yarn.resourcemanager.admin.address 是ResourceManager对管理员admin暴露的访问地址,管理员可通过该地址向ResourceManager发送管理命令等—>
    <property>
    <name>yarn.resourcemanager.admin.address</name>
    <value>master:18141</value>
    </property>
    <!— yarn.resourcemanager.webapp.address 是 ResourceManager YARN 平台提供用户查看正在运行的MapReduce程序的进度和状态的WEB UI系统的访问地址,可通过该地址在浏览器中查看应用程序的运行状态信息 —>
    <property>
    <name>yarn.resourcemanager.webapp.address</name>
    <value>master:18088</value>
    </property>
    </configuration>
  16. 配置计算框架mapred-site.xml

    1
    vim /home/ydh/hadoop-2.5.2/etc/hadoop/mapred-site.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version=“1.0”?> 
    <?xml-stylesheet type=“text/xsl” href=“configuration.xsl”?>
    <configuration>
    <!—MapReduce计算框架的资源交给YARN来管理—>
    <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    </property>
    </configuration>
  17. 在HadoopMaster节点配置slaves

    1
    2
    3
    4
    vim /home/ydh/hadoop-2.5.2/etc/hadoop/slaves
    #写入以下内容
    slave
    slave1
  18. 复制到从节点

    1
    2
    scp –r /home/ydh/hadoop-2.5.2 ydh@slave:~/ 
    scp –r /home/ydh/hadoop-2.5.2 ydh@slave1:~/
  19. 配置Hadoop主节点和从节点启动的系统环境变量

    1
    2
    3
    4
    5
    6
    7
    vim /home/ydh/.bash_profile
    #追加以下内容
    #Hadoop Path configuration
    export HADOOP_HOME=/home/ydh/hadoop-2.5.2
    export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
    #生效配置
    source /home/ydh/.bash_profile
  20. 主从节点创建数据目录

    1
    mkdir /home/ydh/hadoopdata
  21. 格式化分布式文件系统

    1
    hdfs namenode –format
  22. 启动hadoop

    1
    2
    cd /home/ydh/hadoop-2.5.2 
    sbin/start-all.sh
  23. 查看是否启动成功

    1
    2
    3
    jps
    cd hadoop-2.5.2/share/hadoop/mapreduce/
    hadoop jar hadoop-mapreduce-examples-2.5.1.jar pi 10 10

    http://master:50070/
    http://master:18088/

什么是RequestDelegate

IApplicationBUilder接口中包含以下方法,用来配置中间件,对于这个中间件的定义实则是一个处理请求的委托输入输出均为这个类

1
IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);

再来看看另外一个扩展方法,这个同样使用了RequestDelegate,但是只传入了RequestDelegate,没有传出这个类,这是作为最后一个中间件的写法,用于实际处理业务需求,如摘要所写(Adds a terminal middleware delegate to the application’s request pipeline.)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Microsoft.AspNetCore.Builder
{
//
// 摘要:
// Extension methods for adding terminal middleware.
public static class RunExtensions
{
//
// 摘要:
// Adds a terminal middleware delegate to the application's request pipeline.
//
// 参数:
// app:
// The Microsoft.AspNetCore.Builder.IApplicationBuilder instance.
//
// handler:
// A delegate that handles the request.
public static void Run(this IApplicationBuilder app, RequestDelegate handler);
}
}

下面看看这个RequestDelegate实际是什么,下面是其定义,传入了一个请求上下文,返回了一个异步任务,用于响应请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace Microsoft.AspNetCore.Http
{
//
// 摘要:
// A function that can process an HTTP request.
//
// 参数:
// context:
// The Microsoft.AspNetCore.Http.HttpContext for the request.
//
// 返回结果:
// A task that represents the completion of request processing.
public delegate Task RequestDelegate(HttpContext context);
}

让我们来实现一个RequestDelegate,下面是一个静态方法,作为一个获取请求方法(Get还是Post)的处理器,这里只是一个处理器,并不是中间件,因为

1
2
3
4
5
6
7
8
public static Task GetRequestMethod(HttpContext httpContext)
{
return Task.Run(() =>
{
Console.WriteLine(httpContext.Request.Method);
});
}

在实际使用中一般简写为

1
2
3
4
app.Run(async context =>
{
await context.Response.WriteAsync("hello world");
});

中间件的简单用法

代码中对于中间件的定义,通过翻看IApplicationBUilder的元数据,发现下面的两处定义对于形参的描述均为middleware,可见对于这两中委托均属于中间件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface IApplicationBuilder
{
//
// 摘要:
// Adds a middleware delegate to the application's request pipeline.
//
// 参数:
// middleware:
// The middleware delegate.
//
// 返回结果:
// The Microsoft.AspNetCore.Builder.IApplicationBuilder.
IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
}

上面这种中间用来进行中间件间的转发,里面根据业务情况来决定处理请求发给哪个中间件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static class UseExtensions
{
//
// 摘要:
// Adds a middleware delegate defined in-line to the application's request pipeline.
//
// 参数:
// app:
// The Microsoft.AspNetCore.Builder.IApplicationBuilder instance.
//
// middleware:
// A function that handles the request or calls the given next function.
//
// 返回结果:
// The Microsoft.AspNetCore.Builder.IApplicationBuilder instance.
public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware);
}
  • 作为终端的中间件
1
2
3
4
5
6
7
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Run(async context =>
{
await context.Response.WriteAsync("This is a middleware");
});
}
  • 加入两个中间件
1
2
3
4
5
6
7
8
9
10
11
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await next.Invoke();
});
app.Run(async context =>
{
await context.Response.WriteAsync("This is a middleware");
});
}
  • 通过匹配路径使用分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Map("/tom", app =>
{
app.Run(async context =>
{
await context.Response.WriteAsync("hello tom");
});
});

app.Map("/cat", app =>
{
app.Run(async context =>
{
await context.Response.WriteAsync("hello cat");
});
});

app.Map("", app =>
{
app.Run(async context =>
{
await context.Response.WriteAsync("hello everyone");
});
});
}
  • 通过自定义条件使用分支,判断规则按代码顺序判定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.MapWhen(context =>
{
if (context.Request.Path.Value.Contains("dog"))
return true;
return false;
}, app =>
{
app.Run(async context =>
{
await context.Response.WriteAsync("hello dog");
});
}
);

app.Map("/tom", app =>
{
app.Run(async context =>
{
await context.Response.WriteAsync("hello tom");
});
});

app.Map("", app =>
{
app.Run(async context =>
{
await context.Response.WriteAsync("hello everyone");
});
});
}

  • 嵌套Map + 多段匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Map("/animal", builder =>
{
builder.Map("/dog", builder2 =>
{
builder2.Run(async context =>
{
await context.Response.WriteAsync("hello dog");
});
});
});

app.Map("/people/tom", builder =>
{
builder.Run(async context =>
{
await context.Response.WriteAsync("hello tom");
});
});
}
  • 中间件的短路
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(GetRequestSchemeMiddleware);
app.Use(GetRequestMethodMiddleware);
app.Use(async (httpContext, func) =>
{
await func.Invoke();
});
app.Use((httpContext, func) =>
{
if (httpContext.Request.Path.Value.Contains("snapped"))
return httpContext.Response.WriteAsync("be snapped\r\n");
return func.Invoke();
});
app.Run(async context =>
{
await context.Response.WriteAsync("Terminal\r\n");
});
}

public static Task GetRequestSchemeMiddleware(HttpContext context,Func<Task> next)
{
string line = $"Request Method:{context.Request.Scheme}";
next.Invoke();
return context.Response.WriteAsync(line + "\r\n");
}
public static async Task GetRequestMethodMiddleware(HttpContext context, Func<Task> next)
{
string line = $"Request Method:{context.Request.Method}";
await next.Invoke();
await context.Response.WriteAsync(line + "\r\n");
}

连接字符串

一、MySQL Connector/ODBC 2.50 (MyODBC 2.50)连接方式

1、本地数据库连接Driver={MySQL};Server=localhost;Option=16834;Database=myDataBase;

2、远程数据连接Driver={MySQL};Server=myServerAddress;Option=131072;Stmt=;Database=myDataBase; User=myUsername;Password=myPassword;

3、特殊的TCP/IP端口连接说明:此Driver的默认端口是3306。如果没有在连接字符串中特别指出就是连接MySQL的3306端口。Driver={MySQL};Server=myServerAddress;Port=3306;Option=131072;Stmt=;Database=myDataBase; User=myUsername;Password=myPassword;

二、MySQL Connector/ODBC 3.51 (MyODBC 3.51)连接方式

1、本地数据库连接Driver={MySQL ODBC 3.51 Driver};Server=localhost;Database=myDataBase; User=myUsername;Password=myPassword;Option=3;

2、远程数据连接Driver={MySQL ODBC 3.51 Driver};Server=data.domain.com;Database=myDataBase;User=myUsername; Password=myPassword;Option=3;

3、特殊的TCP/IP端口连接说明:此Driver的默认端口是3306。如果没有在连接字符串中特别指出就是连接MySQL的3306端口。Driver={MySQL ODBC 3.51 Driver};Server=data.domain.com;Port=3306;Database=myDataBase;User=myUsername; Password=myPassword;Option=3;

4、特殊字符集的连接Driver={MySQL ODBC 3.51 Driver};Server=data.domain.com;charset=UTF8;Database=myDataBase;User=myUsername; Password=myPassword;Option=3;

三、OLE DB, OleDbConnection (.NET)连接方式

1、标准连接Provider=MySQLProv;Data Source=mydb;User Id=myUsername;Password=myPassword;

四、MySQL Connector/Net (.NET)连接方式

1、标准连接(说明,默认端口是3306。)Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;

2、特殊的TCP/IP端口连接Server=myServerAddress;Port=1234;Database=myDataBase;Uid=myUsername;Pwd=myPassword;

3、命名管道说明:端口值为-1,说明用命名管道方式连接。此方式只在Windows下有效,在UNIX下用会被忽略。Server=myServerAddress;Port=-1;Database=myDataBase;Uid=myUsername;Pwd=myPassword;

4、多服务器连接用此种方式连接到数据库中,不必担心该使用哪个数据库。
Server=serverAddress1 & serverAddress2 & etc…;Database=myDataBase;Uid=myUsername;Pwd=myPassword;

5、加密选项这条活动的SSL连接加密所有客户端和服务器商的数据传输。而且服务器要有一个证书。这个选项从Connector/NET5.0.3版开始出现,以前的版本中则没有此功能。
Server=myServerAddress;Port=-1;Database=myDataBase;Uid=myUsername;Pwd=myPassword;

6、修改默认的命令超时时间使用这条修改连接的默认命令超时时间。注意:此条不会影响你在单独命令对象上设置的超时时间。此条只对Connector/NET 5.1.4 及以上的版本有效.
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;default command timeout=20;

7、修改连接偿试时间使用这条修改在终止重试和接收错误的等待时间(以秒为单位)
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Connection Timeout=5;

8、Inactivating prepared statementsUse this one to instruct the provider to ignore any command prepare statements and prevent corruption issues with server side prepared statements.此选项被加入到Connector/NET的5.0.3版和1.0.9版。
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Ignore Prepare=true;

9、特殊的TCP/IP端口连接这条语句修改连接的端口。默认端口是3306。此参数会被Unix忽略。
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Port=3306;

10、特殊网络协议这条语句修改用哪种协议进行连接。如果没有特别说明,"socket"是默认的值。"tcp"是与"socket"相同意义的。"pipe"是使用命名管道连接,"unix"是使用 unix socket连接,"memory"是使用MySQL的共享内存。
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Protocol=socket;

11、特殊字符集的连接这个语句指出以使种字符串编码发送到服务器上的查询语句。注意:查询结果仍然是以反回数据的格式传送。
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;CharSet=UTF8;

12、修改共享内存名此语句用来修改用来通信的共享内存名称。说明:此语句只有当连接协议设置为"memory"时才有效。
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Shared Memory Name=MySQL;

五、MySQLConnection (.NET)连接方式

1、eInfoDesigns.dbProvider
Data Source=myServerAddress;Database=myDataBase;User ID=myUsername;Password=myPassword;Command Logging=false;

六、SevenObjects MySQLClient (.NET)连接方式

1、标准连接
Host=myServerAddress;UserName=myUsername;Password=myPassword;Database=myDataBase;

七、Core Labs MySQLDirect (.NET)连接方式

1、标准连接
User ID=root;Password=myPassword;Host=localhost;Port=3306;Database=myDataBase; Direct=true;Protocol=TCP;Compress=false;Pooling=true;Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0;

连接出错的问题记录

程序使用Mysql.Data.dll连接原5.1版本数据库,后升级5.7后不可用,连接字符串加入sslmode后恢复,原因未知。

1
Database=database;Data Source=ip;User Id=user;Password=password;pooling=false;CharSet=utf8;port=3306;sslmode=none

删除重复记录并且只保留一条

1
2
3
4
5
6
7
8
9
10
11
12
DELETE
FROM tablename
WHERE tab_col NOT IN(
SELECT dt.minno
FROM(
SELECT MIN(tab_col) AS minno
FROM tablename
WHERE col1 = 1 AND col2 = 2
GROUP BY col3
) dt
)
AND col1 = 1 AND col2 = 2

种类

如下图所示,高分一、二、四均搭载了全色多光谱相机(PMS)

卫星 传感器/模式 数据 分辨率 波段数 描述
GF1 PMS1 MSS1 8m 4 多光谱
_ _ PAN1 2m 1 全色
_ PMS2 _ _ _ 二台相机组合幅宽共60公里
_ WFV1 _ 16m 4 多光谱相机
_ WFV2 _ 16m 4 _
_ WFV3 _ 16m 4 _
_ WFV4 _ 16m 4 四台相机组合幅宽共800公里
GF2 PMS1 MSS1 4m 4 多光谱
_ _ PAN1 1m 1 全色
_ PMS2 MSS2 4m 4 _
_ _ PAN2 1m 1 二台相机组合幅宽共45公里
GF4 PMS _ 50m 5 全色多光谱
_ IRS _ 400m 1 中波红外

辐射定标

利用以下公式可将
GF-1
卫星各载荷的通道观测值计数值
DN
转换为卫星载荷
入瞳处等效表观辐亮度数据。

Le(λe)=GainDN+BiasL_e(\lambda_e)=Gain\cdot DN+Bias

where

GainGain 定标斜率,单位 Wm2sr1μm1W\cdot m^{-2}\cdot sr^{-1} \cdot \mu m^{-1}
BiasBias 定标截距,单位 Wm2sr1μm1W\cdot m^{-2}\cdot sr^{-1} \cdot \mu m^{-1}
DN 卫星载荷观测值;

各卫星载荷的定标系数

卫星 载荷 波段 Gain Bias
GF1 PMS1 PAN 0.1886 -13.127
_ BAND1 0.2082 4.6186
_ BAND2 0.1672 4.8768
_ BAND3 0.1748 4.8924
_ BAND4 0.1883 -9.4771
_ PMS2 PAN 0.1878 -7.9731
_ BAND1 0.2072 7.5348
_ BAND2 0.1776 3.9395
_ BAND3 0.1770 -1.7445
_ BAND4 0.1909 -7.2053
GF2 PMS1 PAN 0.1630 -0.6077
_ BAND1 0.1585 -0.8765
_ BAND2 0.1883 -0.9742
_ BAND3 0.1740 -0.7652
_ BAND4 0.1897 -0.7233
_ PMS2 PAN 0.1823 0.1654
_ BAND1 0.1748 -0.5930
_ BAND2 0.1817 -0.2717
_ BAND3 0.1741 -0.2879
_ BAND4 0.1975 -0.2773

Why

大数据的学习即为Hadoop的学习,之所以叫做大数据,顾名思义,即为数据量之大,服务器也不止一台,但是在大数据的学习过程中,可以选择使用Docker来模拟这种环境,Let’s go!

环境搭建

  1. 拉取镜像,通过搜索Docker仓库中既有的hadoop镜像,有很多种,本着学习与尝试的态度,毅然地选择了第一个Star人数最多的镜像,sequenceiq/hadoop-docker,好,现在让我们来把他拉取下来,并跑起来。
1
docker pull sequenceiq/hadoop-docker
  1. 经过很长时间等待,可能是网络问题,一直无法拉取下来,等更换了国内镜像源后,才把镜像拉取下来。

MODIS产品分类

  • L1级产品
产品标识符 子产品 分辨率 数据级别 描述
MOD01 MOD01 L1A 原始辐射率
MOD02 MOD02KM 1KM L1B 定标辐射
_ MOD02HKM 500M L1B 定标辐射
_ MOD02QKM 250M L1B 定标辐射
MOD03 MOD03 1KM L1A 经纬度坐标数据
  • 大气与陆地标准产品
产品标识符 子产品 数据级别 分辨率 时间尺度 描述 数据级别
MOD04 MOD04 L2 气溶胶
MOD05 MOD05 L2 可降水汽检测结果
MOD06 MOD06 L2 云产品
MOD07 MOD07 L2 温度和水汽轮廓产品
MOD08 MOD08_D3 L3 1D 气溶胶、水汽和云
_ MOD08_E3 L3 8D 气溶胶、水汽和云
_ MOD08_M3 L3 1M 全球气溶胶、水汽和云月合成产品
MOD035 MOD035 L2 250M和1KM云覆盖和光谱检测结果
MOD09 MOD09GHK L2G 500M 全球地表反射率
_ MOD09GQK L2G 250M 全球地表反射率
_ MOD09GST L2G 1KM 全球地表反射率
_ MOD09A1 L3 8D 500M 全球地表反射率
_ MOD09Q1 L3 8D 250M 全球地表反射率
MOD11 MOD11 L2 地表温度、发射率
_ MOD11A1 L3 1D 1KM 全球地表温度、发射率
_ MOD11A2 L3 8D 1KM 全球地表温度、发射率
_ MOD11B1 L3 8D 5KM 全球地表温度、发射率
_ MOD11C1 L3 1D 5KM 全球地表温度、发射率
_ MOD11C3
MOD12 MOD12 地表覆盖变化
_ MOD12Q1 L3 96D 全球土地搜索类型96天组合
MOD13 MOD13A1 L3 16D 500M 全球植被指数
_ MOD13A2 L3 16D 1KM 全球植被指数
_ MOD13A3 1M 1KM 全球植被指数
_ MOD13Q1 L3 16D 250M 全球植被指数
MOD14 MOD14 L2 1KM 分辨率温度异常/火
_ MOD14A1 L2G 1D 1KM 全球温度异常/火
_ MOD14A2 L3 8D 1KM 全球温度异常/火
_ MOD14GD L2G 1D 1KM 日间全球温度异常/火
_ MOD14GN L2G 1D 1KM 黑夜全球温度异常/火
MOD15 MOD15A2 L4 8D 1KM 全球叶面积指数/FAR
MOD17 MOD17 NPP
_ MOD17A2 L4 8D 1KM 全球净光合作用
MOD43 MOD43 BRDF&反照率
_ MOD43B1 L4 16D 1KM 全球BRDF&反照率
_ MOD43B3 L4 16D 1KM 全球最小反照率
_ MOD43B4 L4 16D 1KM 全球调整至天顶角反射率的BRDF
MOD44 MOD44 植被覆盖变化
_ MOD44B L3 植被连续区域

产品分幅

MODIS标准产品数据采用TILE类型进行组织即以地球为参照系, 采用了SIN(ISIN,正弦曲线投影) 地球投影系统,将全球按照10°经度X10°纬度(1200KM X 1200KM) 的方式分片(如下图),全球陆地被分割为600多个Tile,并对每一个Tile赋予了水平编号和垂直编号。左上角的编号为(0,0)右下角的编号为(35,17)。
iamge
下图为对应的中国区域的分幅编号。
iamge

数据官方下载地址

https://e4ftl01.cr.usgs.gov/

产品介绍

SAR(合成孔径雷达)
高分三共有十二种成像模式见下表所示

成像模式 - 分辨率/m 宽幅/km 极化方式
滑块聚束(SL) _ 1 10 单极化
条带成像模式 超精细条带(UFS) 3 30 单极化
_ 精细条带1(FS I) 5 50 双极化
_ 精细条带2(FS II) 10 100 双极化
_ 标准条带(SS) 25 130 双极化
_ 全极化条带1(QPS I) 8 30 全极化
_ 全极化条带2(QPS II) 25 40 全极化
扫描成像模式 窄幅扫描(NSC) 50 300 双极化
_ 宽幅扫描(WSC) 100 500 双极化
_ 全球观测成像模式(GLO) 500 650 双极化
波成像模式(WAV) _ 10 5 全极化
扩展入射角(EXT) 低入射角 25 130 双极化
_ 高入射角 25 80 双极化

预处理流程

  1. 辐射定标
  2. 复数据转换
  3. 多视处理
  4. 滤波
  5. 几何校正

辐射定标

一、定标公式

辐射定标是将传感器记录的无量纲的亮度值转换成具有实际物理意义的量,在SAR图像处理时为后向散射系数。

σdb0=10lg[PI(QV65535)2]Kdb\sigma_{db}^0 = 10\lg[P^I \cdot (\frac{QV}{65535})^2] - K_{db^\prime}

Where:

σdb0\sigma_{db}^0 :雷达后向散射系数(单位:db)
PI=DN2P^I = DN^2 : DN为L1B产品的幅度
QVQV :该图像量化前的最大值 在元数据meta.xml中QualifyValue字段
KDBK_{DB} :定标常数 在元数据meta.xml中CalibrationConst字段

二、复数据转换