构造数据嵌拼地图的装置和方法

文档序号:6409777阅读:402来源:国知局

专利名称::构造数据嵌拼地图的装置和方法
技术领域
:本发明涉及雷达图象的显示,尤其涉及将多个雷达图象组合到那些图象的嵌拼地图来产生这样的显示。本发明还涉及电子计算机和数据处理系统,尤其涉及这些系统应用于地球科学(如气象)。本发明还涉及信息处理系统组织,尤其涉及采用具有人工智能系统细节的人工智能的应用,如地球科学(如气象)。本发明还进一步涉及通信、定向无线电波系统和装置(例如雷达或无线电导航),尤其是气象雷达、多种雷达及用来产生这些系统和装置的图象或图象的扫描变换的显示电路,以及用来指示风暴位置(例如三角测量)的定位无线电波系统和装置。
背景技术
:实践中,人们需要将几幅雷达图象组所得覆盖某一地理范围的一幅嵌拼地象。本发明满足了该种需要。在美国,存在大量的气象雷达站。国家气象雷达网由新的NEXRADWSR-88D气象监视多普勒雷达和以前就存在的WSR-57和WSR-74非多普勒气象雷达。每一这样的雷达站基本上可以独立工作,但这些站的范围可以重叠。必须将来自这些雷达站的数据装配到显示特定区域或纵横美国的气象情况的单幅嵌拼地图中。本发明满足了这种需要。雷达数据的嵌拼地图可以提供一大地理范围内的降雨量和恶劣的气候的地点和程度,并且因此用于气象学家和负责监视和预告气象情况的其他人员。雷达数据的产生通常要求将数据点从本地地理坐标系统(其中的位置由相对于各个雷达站来定义)变换到嵌拼地图的地理坐标系统。数据点从一个坐标系统到另一个(再投影)在计算上是相当繁重的任务,而且还必须确保准确性。甚至来自一个雷达站的雷达数据也可以由100,000个数据值组成,每一个数据值都必须经过再投影。一嵌拼地图可以由来自几十个雷达站的数据组成。因此要求准确地将来自所要求的雷达站的所有数据足够快地组合起来,以提供当前的气象描述。本发明满足了这种需要。发明概述因此,本发明的目的是提供一种将来自多个雷达站的数据组所得覆盖所要求的地理范围的单个图象。本发明的另一个目的是提供一种装置和方法,这种装置和方法能够实时以数字格式将来自多个雷达站的雷达数据(例如气象雷达数据)组所得覆盖某一地理范围的嵌拼地图。本发明的又一个目的是提供一种装置和方法,这种装置和方法用来将来自多个源的数据组所得能够在普通用途的计算机(如个人计算机)上运行的单个图象。本发明的再一个目的是提供一种装置和方法,这种装置和方法能够产生雷达数据的嵌拼地图,这些雷达数据能够提供一大地理范围内的降雨量和其他气象现象的位置和程度。本发明的进一步的目的是提供一种这种和方法,这种装置和方法能够准确地将来自多个所要求的雷达站的大量数据足够快地组合起来,以提供气象或其他现象的当前描述。本发明的再进一步的目的是提供一种能够既准确又有效地建立雷达数据的嵌拼地图的装置和方法。简略地说,本发明的这些目的和其他目的是通过将多个雷达数据箱(bin)中的每一个转换成镶嵌图象中相应的网格位置或网格框。但是,当每一个雷达数据箱映射到嵌拼地图的网格框时,不是雷达覆盖区内的每一个这样的网格框都可以接收一个箱。这可以是因为网格框比雷达箱多的缘故,或者因为雷达数据箱没有完全覆盖的缘故。在从箱到框的映射完成以后,发明的装置和方法可以返回并以如下的方式填满那些孔。雷达数据的箱被映射成用于部分所得显示的预定网格。每次该网格的网格元件接收一箱时,临时阵列的相应元素处在“设置”。随后,检查临时阵列找出任一“未被设置”或空白的元素。如果发现任一阵列元素没有箱,则找到位置上最靠近的数据箱。最靠近的数据箱及其相应的网格位置可以用来填满嵌拼地图网格中的孔。本发明的其他目的、优点和新特征在结合附图对本发明作了详细描述以后将变得清楚起来。附图简述图1是用于单个站雷达产品的显示的二维阵列图示;图2是一例将各个气象雷达产品数据映射成一大嵌拼地图网格的图示;图3是按照本发明直接将各个雷达数据值映射成按照本发明的嵌拼地图网格的整个过程图示;图4是按照本发明的较佳实施例的直接将各个雷达数据值映射成嵌拼地图网格的整个过程图示;图5描述的是图4所示方法中可以使用的查询表的格式;图6给出的是一例由于源数据网格和目标数据网格不一致时出现的孔的雷达数据映射而产生的显示;图7A和7B一起给出填满按照本发明的图6所示孔中任何一个孔的方法实施例的图示;图8A、8B、8C、8D和8E一起给出一个建立图4和图5所示查询表的方法的流程图;图9A、9B、9C、9D和9E一起给出一个采用图4、5和8A至8E的查询表建立按照本发明的雷达数据嵌拼地图的方法的流程图。详细描述下面参照附图,图中,相同的标号文字指得是相同或相应的部件,图1中给出由多个元素或象素组成的阵列10,标号12表示其中的一个元素或象素。每一阵列元素(如元素12)包含雷达返回的单个值。每一个这样的元素代表基本上与地球表面相切的水平表面的有限区域。阵列10包含一例经译码的单基站雷达数据产物14。阵列10中,产物表述14由代表在该产物中气象雷达数据返回的范围的圆圈16为边界。产物14内,各个雷达数据箱位置(例如位置18)由阵列中的x、y坐标来标记,箱的经纬根据相对于雷达站的距离来计算。中央箱20代表雷达站位置。对于一固定的雷达站,雷达站的纬度和经度已知,从而参照相对于中央箱位置的各个箱将提供用于各个箱的准确的位置信息。单基站雷达数据以数字格式接收,该数字格式使得数据值能够以二维阵列10赋值给计算机程序存储器。每一阵列元素(例如元素12)是一数据“箱”,它代表相对较小的有限区域(例如1公里乘1公里)内大气参数(例如降雨量)。所以,任何一个箱(例如箱18)的坐标可以提供该箱到该雷达站的x,y距离。然而,通常有一个以上的雷达产物必须用于某一区域中气候的单个网格阵列或图示。这可以是因为两个雷达站的范围会重叠,或者因为想要在一次显示中给出包括多个雷达站的足够大的地理范围的雷达数据。这种情况下,嵌拼地图是通过从单个雷达站的雷达数据中取出各个数据箱,并将那些箱的值赋给一大比例(例如区域或全国)网格中的相应位置,而该大比例的网格最好也位于二维阵列22的计算机存储器中。这样一种嵌拼地图形成的一个例子如图2所示。图2给出一例将来自例如不同雷达站的阵列10、24和26的各个气象雷达产物数据映射到更大比例的嵌拼地图网格22内。每一阵列10、24和26这里分别代表来自单基站A、B或C的雷达产物。每一这样的阵列10、24和26与图1所示的阵列10相似。如图2所示,来自阵列10的数据与来自其他这样的阵列24和26的数据组合,构成覆盖地理范围(包括所有这些雷达站)的嵌拼地图网格22。因此,在图2所示的例子中,阵列10被映射到网格22的部分或子阵列28上,阵列24被映射到网格22的部分或子阵列30上,阵列26被映射到网格22的部分或子阵列32上。在图2所示的例子中,来自单个雷达站的雷达数据的坐标系统不必与嵌拼地图22的坐标系统一致。即,阵列10、24和26的箱和网格22的网格框不必具有相同的大小,各坐标系统不必取向相同。为此,来自阵列10、24或26的每一箱的坐标必须转换(即再投影)成网格22的坐标。按照本发明将各个数据点的坐标按照本发明再投影到(例如从阵列10转换成)网格22的方法如图3所示。图3给出按照本发明将各个雷达数据值(例如来自阵列10)间接映射成嵌拼地图网格(例如网格22)的整个过程。在单个站雷达产物阵列10中,数据值被赋给箱。在图3所示的方法中,每一箱被转换为纬度和经度,并且随后纬度和经度被转换为相应的网格位置。在步骤34,每一组箱坐标x,y被转换成在x轴和y轴上与雷达站的20的距离。在步骤36,这个以x和y值的形式的距离接着被转换成地理上的纬度和经度。在步骤38,这些纬度值和经度值接着用网格22的x轴和y轴,被转换成与网格22中心相距的x、y距离。在步骤40,这些x、y距离被转换成网格22的相应x坐标值和坐标值。通过这种方式,来自阵列10的数据值被映射成嵌拼地图网格22。可以采用相似的过程实现从其他阵列24、26到网格22的映射。尽管该方法准确,但不是最佳的,因为该方法计算强度大(见步骤34、36、38和40),所以不适于在通用计算机(如个人计算机)上进行实时运算。另一种更好的从单基站网格或产物阵列10映射到嵌拼地图网格22的方法如图4所示。图4所示的方法比图3所示的方法更有效,因为图4的方法采用预先建立的查询表直接将雷达数据箱映射成网格22。这些查询表是如图8和该图中相应的编码所示,用计算量很大的算法建立起来的,用来计算每一雷达数据箱的纬度和经度,并将这些纬度和经度转换成网格22的框位置。气象数据雷达站通常具有固定的位置,所以产物阵列10、24或26的位置和取向中每一个这样的站相对于网格22的位置和取向是已知的。这些查询表最好脱机建立起来,并且最好作为文件存储在计算机数据库46中。然后图9所示建立嵌拼地图的程序在处理来自每一站的数据的同时,从恰当的查询表文件中读取数据。每一查询表包含一个箱x、y值和相应网格x、y值的列表,列表前面有一个查询表各表项的编号。这样一种查询表的较佳格式如图5所示。随后对查询表的每一表项的处理就是将来自箱x、y的雷达数据值赋于相应的网格x、y位置。图4给出的是采用预先建立的查询表,直接将各个雷达数据值映射成嵌拼地图网格的较佳过程。图4中,在单基站雷达产物阵列10,数据值被赋予到阵列中的箱。在图4所示的方法中,例如箱42到框44的直接映射是以下述方式完成的。每一站的查询表存储在数据库46内。比方说,当发生阵列10到网格22的映射时,在步骤48,从数据库46读取用于阵列10的站的查询表。接着,在步骤50,通过将箱x和y坐标值直接转换成网格22的x、y坐标值,将阵列10的每一箱(例如箱42)映射成网格22的框(例如框44),方法是,在查询表中找到前者,并在步骤50,从该表中读取相应的网格框位置。网格22是将如来自阵列10的数据值映射成该网格的嵌拼地图网格。实际上,采用图4所示的方法,图3所示的步骤34、36、38和40是事先脱机进行的,以减少实时运算期间所需处理的工作量。图5给出一例图4所示查询表的文件格式。图5中,所有的表项值为整数。每一文件为各基站专用。同时,每一文件也是坐标系统和各个产物(例如产物14)的空间分辨率和嵌拼地图网格(例如网格22)的空间分辨率所专用的。一给定的箱x、y坐标可以与一个网格以上的x、y坐标配对。与此类似,一给定的网格x、y坐标可以与一个以上的箱x、y坐标配对。然而,对于每一箱x、y坐标,至少有一个表表项,对于每一网格x、y坐标,至少有一个表项。然而,表项的总数不会超过要映射的箱的数目的较大者,或框数目的较大者。正如上面讨论的那样,产物数据箱的阵列(例如阵列10、24或26)将不必完全与嵌拼地图网格22对齐。结果,同一网格框将接收一个以上的箱。由于类似的原因,雷达数据范围内的某些网格箱将不接收任何箱。在后者的情况下,“孔”会保留在完整的嵌拼地图内,如从图6可以看到的那样。图6给出一例具有一个或多个孔52的雷达数据映射,其中的源和目标网格(即雷达箱和嵌拼地图网格)不一致。下面的附加处理在本发明中用来填充网格22中这样的孔52。该处理是以下述方式完成的。在建立如图8所示的查询表的过程中,识别网格中每一这样的“孔”的位置,并将最靠近的箱赋予到具有该孔的网格框。这是采用图7所示的临时阵列在雷达覆盖区域内找到未填满的网格框来完成的。每次箱x、y坐标与网格x、y位置配对时,设置临时阵列54中的一个元素。接着,当某一基站所有的箱x、y位置的处理完成时,在为其构筑查询表的雷达范围内,为临时阵列54中未设置或未填满的网格框执行“反向计算”。在这样的反向计算中,网格框x、y位置被转换成纬度和经度,并且随后该纬度和经度被转换成相应的箱x、y坐标,以找到在位置上最靠近该孔的箱x、y坐标的箱。每一这样“反向计算的”箱x、y和框x、y对,作为一个表项而加入该雷达站的查询表中。这一过程确保了每一数据箱被赋值到嵌拼地图网格,并且随后要被考虑的雷达范围内的每一网格框被赋给一数据值。图7描述的是用临时阵列54来填充网格22中的孔。临时阵列54的每一元素可以含有三个值中的任何一个第一个值,初始“空白”值(例如-1);第二个值,“未设置”值(例如0),用于落入雷达范围内的每一相应的网格元素或框;第三个值“设置”值(例如+1),表示某一雷达箱已经被映射到相应的网格元素。在网格22的子阵列(例如子阵列32)中来自相应产物阵列(例如阵列26)的气象雷达数据的箱被映射成具有箱22的取向而不是要被映射的源阵列的取向的网格22。在该映射过程中,每次网格22元素接收到一箱,则“设置”临时阵列54中相应的元素以表示之。接着检查瞬时阵列中的任何“未设置”或未填充的元素。在临时阵列54中,圆圈56代表接着被映射的气象雷达产物中雷达数据的范围。圆圈56中所有的阵列54元素用来从正被映射成网格22的相应产物阵列接收一数据箱或数据值。如果阵列54的阵列元素被发现没有被这样“设置”,那么执行反向计算,以找到在位置上最靠近该阵列元素的填充的数据。该数据箱x、y及其相应网格位置x、y被加到查询表中,以填充会产生嵌拼地图网格22的孔。为了执行图4所示的过程,建立嵌拼地图的过程需要分成二部分。如图8A-8E所示的这两部分中的第一部分可以脱机执行,并负责产生在本地数据库46中建立并存储的查询表。设计用来实时运行并采用预先建立的查询表来准确建立一个(或多个)嵌拼地图的第二部分如图9A-9E所示。在图8A-8E中,建立雷达站专用查询表的过程可以小结如下。针对每个雷达站进行下面的过程,为每一雷达站构造独立的表。首先对临时阵列54中的每一元素初始化,以反应出“空白”值或清另值。对于临时阵列中的每一元素,元素x、y坐标被转换成与雷达站相隔的距离或范围;如果该范围处在由圆圈56定义的雷达数据覆盖区域以内,那么赋给伴随数据库中临时阵列元素的标记一个“未设置”指示。对于正被映射的雷达产品的每一雷达数据箱位置,将箱x、y坐标转换成纬度和经度;将所得的箱纬度和经度转换成网格x、y位置;将这样找到的箱x、y网格x、y对赋值到该站的查询表中恰当的位置上;为该对计算临时阵列元素x、y位置;并赋给这样找到的x、y位置处的临时阵列元素一个“设置”指示,给出在该位置处没有出现孔。随后,为临时阵列54中的每一元素执行下面的步骤。首先判断临时阵列元素是否未被设置,并且因此处在雷达数据覆盖区域内但没有被赋给雷达数据箱。如果是这样,则将临时阵列元素x、y坐标转换成网格x、y坐标;将所得的网格x、y坐标转换成纬度和经度;将所得的纬度值和经度值转换成雷达箱x、y坐标;并且将所得箱坐标和网格x、y坐标对赋值到用于该单基站雷达产物的查询表,以填充或部分填充嵌拼地图网格中的孔。最后,将所得的查询表指定成数据库46中的一个文件。用查询表建立雷达数据嵌拼地图的图9所示的过程可以小结如下。首先,对于大网格22中的每一个位置或元素,使网格元素初始化成合适的预定值。接着,对每一雷达站,执行下面的步骤。从数据库读取该雷达站的最新气象雷达数据产物。接着将该雷达产物译码,将由该产物的各个数据值赋值到二维阵列。随后从数据库46读取预先建立查询表。接着,对于该查询表中的每一表项,从查询表获取相应的箱x、y坐标及其相应的网格x、y坐标。随后从经译码的雷达产物获取该箱x、y位置处的产物数据值。该产物数据值接着赋值到从查询表获得的相应网格x、y位置处。对于该查询表中的每一表项,重复这最后三个步骤。最后,网格中所得的组合的雷达数据被编码,并存储到数据库46中文件内。图8A、8B、8C、8D和8E一起给出建立查询表的方法的结构图或流程图。这些查询表对于图4所示的方法以及在通用数字计算机上实时建立雷达数据的嵌拼地图的相应系统是基本的部分。图8A-8E所示的方法可以作为计算机软件来实施,而计算机软件最好是在时间不紧迫时脱机运行,从而可进行在查询表建立过程中所需的费时的计算并在需要那些计算结果之前好好计算。如图8A所示,程序采用了一个手工产生的配置文件101,该文件含有有关要建立查询表的一个或多个雷达站的信息。配置文件101含有雷达站的编号和每一站的纬度/经度以及识别号。在步骤102,程序从文件101读取雷达站的编号,并且在步骤103,从文件101读入站信息并将该信息存储到计算机的存储器,供日后使用。接着,在步骤104,程序进入循环,对该表上每一个这样的雷达站进行处理。执行这一循环,直到处理了所有的站(在步骤105处确定),这时,程序终止(步骤106)。对每一站按该循环进行的处理开始于步骤107,对临时阵列进行初始化,将-1值赋值到阵列所有的元素。接着,如图8B所示,临时阵列由程序设置,以指示该临时阵列的哪些元素位于雷达覆盖区域内。在步骤110,该程序对临时阵列中每一x坐标进行循环,直到处理了所有的x坐标(在步骤111处确定)。在这个第二个循环中,在步骤112处将正被处理的临时阵列x坐标转换成相应的网格阵列x坐标。在步骤113处,接着判断所得的网格x坐标是否处在网格边界的外面;如果是,则程序跳到下一个临时阵列x坐标(步骤110、111和112)。这可以出现在位于靠近网格(例如感兴趣的区域的)东面或西面边界处,在这里,瞬时阵列54延伸超过网格22的边界。否则,对于一有效网格x坐标,程序在步骤114处开始对临时阵列中每一y坐标进入另一个循环,直到处理了所有的y坐标(步骤115)。在步骤116,由第三循环考虑的临时阵列y坐标被转换成相应的网格阵列y坐标。如果在步骤117处发现所得的网格y坐标位于网格的边界外面,则程序跳到下一个临时阵列y坐标(步骤114、115和116)。这可以出现在位于所定站的靠近网格(或者感兴趣的地理区域)北部或南部边界处,这里,临时阵列延伸超过网格的边界。否则,对于一有效网格y坐标,在步骤118处,用定义正被使用的特定网格的投影方程,将由步骤112和116发现的网格x、y位置转换成纬度和经度。例如,Lambert保角投影方程(Lambertconformalprojectionequation)可以用作这一用途。由于网格被当作是平面的,但用来代表一曲面,所以某些投影将用来将网格变换成曲面或反之;完成这一投影在绘图法上是人们熟知的。在步骤119,纬度和经度接着被转换成用于雷达坐标系统(即用于单基站雷达产物的坐标系统)的x和y坐标。对于步骤119,需要从纬度和经度到雷达产物阵列的坐标系统的恰当绘图(或类似的)转换。相反的这样的变换是在步骤118处完成的,除了如上所讨论的那样,网格坐标不必对应于单个站雷达产物阵列的网格坐标。在步骤119处找到的x坐标和y坐标接着在步骤120处用来计算由x、y坐标定义的与雷达站相隔的距离(在雷达产物阵列中)。在步骤121处,判断在步骤120处发现的距离是否位于如图1中圆圈16所定义的雷达覆盖范围内;如果是,则在步骤122处将在步骤112和116处使用的x,y坐标、所定义的临时阵列元素的值设置为零,以表示相应的雷达箱值是由单个站雷达产物阵列所定义。不管是哪一种方法,程序都在步骤114处进行到下一个y坐标。一旦临时阵列由图8B所示的方法设置起来以标识落入雷达覆盖区域的元素,则按图8C所示,继续查询表的产生。如图8C所示,查询表的产生在步骤130处开始,这里,查询表表项的编号设置为零。从步骤131开始,程序接着执行用于雷达产物光栅(raster)阵列中每一y坐标的循环,直到处理了该阵列中的所有y坐标(步骤132)。对于在步骤131处开始的每一循环迭代,程序执行雷达产物光栅阵列中每一x坐标的在步骤133处开始的循环;当雷达产物光栅阵列中所有的x坐标都经步骤133处开始的循环处理以后,该循环在步骤134处退出并返回到步骤131。在步骤133处开始的循环中,用当前产物光栅阵列x、y坐标,在步骤135处判断该坐标(该阵列中的)与雷达站的距离。在步骤136,判断在步骤135处计算的距离是否位于雷达覆盖范围以外;如果是,则程序回到步骤133并跳到下一个x、y位置。否则,如图8C所示,位置在雷达覆盖区内,并进行进一步的处理。在该进一步的处理中,在步骤137处,正被处理的x、y坐标首先被转换成纬度/经度。正如所使用的那样,坐标或位置所引用的x值和y值一起(例如迪卡尔坐标)定义了系统、阵列、网格、表面等的位置。在步骤138,接着将所得的纬度/经度变换成相应的网格坐标系统x、y位置。在步骤139,检查所得的网格x、y坐标的有效性。如果在步骤139发现在步骤138处找到的网格x、y位置是无效的(不位于预置的网格边界内),那么那些坐标就不属于正被构造的查询表,并且通过回到步骤133,程序跳到正被处理的雷达产物阵列中下一个元素。否则,在步骤140处,在步骤138处找到的雷达产物光栅阵列x、y坐标和用于该雷达x、y坐标的相应的网格x、y坐标被赋值到计算机存储器中正形成的查询表阵列。在步骤141,该查询表的查询表表项总数递增一;在程序进入步骤131循环之前,请回想一下,该号码已经在步骤130处初始化为零。在步骤141以后,在步骤138处发现并且在步骤140处进入查询表的网格x、y坐标在步骤142处用来计算相应于网格x、y坐标的临时阵列x、y坐标。在步骤143,该位置处临时阵列元素的值被设置为该值加一,以表示相应方格框至少从雷达产物光栅阵列接收了一个数据值。程序随后回到步骤133。如果在步骤132处发现雷达产物阵列中所有的y坐标已经由步骤131处开始的循环处理,则程序进行到如图8D所示的过程。在雷达产物光栅阵列中所有的元素已经由图8C所示的方法处理以后,则如图8D所示,程序确定与雷达产物光栅阵列的坐标或位置不一致的雷达覆盖区内的所有网格框的位置。这时通过搜索临时阵列中由图8B所示的步骤122处给定为零值的所有未设置元素来完成的。在图8D中,对临时阵列中的每一x坐标执行在步骤150处开始的循环,直到没有x坐标要处理为止(步骤151)。在该循环内,对由步骤150正被考虑的x坐标的每一y坐标执行在步骤152处开始的另一循环,直到所有的这些y坐标均被处理(步骤153)为止。在这个另一循环中,在步骤153处判断了是否还有要这样处理的y坐标以后,在步骤154处估算临时阵列中当前x、y位置处的值。在步骤154,判断由图8D确定的x、位置处的临时阵列元素是否等于零。如果位置的值为非零,则它或者处在雷达覆盖区域之外,或者它已经与雷达数据箱位置一致。否则,当x、y位置的值仍然没有设置(本例中赋值为零值)时,嵌拼地图中存在一孔。对于每一这样的孔,需要与在位置上最靠近该孔的雷达数据箱坐标一致。如果存在这样的孔,则根据步骤154处考虑的临时阵列x、y坐标,在步骤155处判断网格x、y坐标。在步骤156,用定义网格投影的方程(如上面讨论的那样)将所得网格x、y坐标转换成纬度/经度。在步骤156中发现的纬度/经度接着在步骤157被转换成最靠近雷达产物阵列坐标系统中的x、y坐标。在步骤158,判断在步骤157处发现的雷达产物x、y坐标是否有效,如果不是,则过程回到步骤153。在步骤159,接着判断在步骤155判断的网格x、y坐标是否有效,如果不是,则过程回到步骤153。如果雷达产物x、y坐标有效,并且网格x、y坐标有效(它们落入感兴趣的区域内),则在步骤160,那些坐标被赋值到该阵列中下一个有效位置中查询表阵列。如果出现这样的坐标,则在步骤153过程跳到下一个临时阵列元素。在雷达产物x、y坐标和相应的网格x、y坐标被加到查询表阵列以后,在步骤161,查询表中表项的总数递增一。从步骤161,过程回到步骤153。如果再没有y坐标出现,则过程回到步骤150,从而以图8D所述的方式对下一个x坐标寻址。如果没有再要处理的x坐标,则程序从步骤151进入图8E所示的步骤170。一旦以如图8D所示的方法完成了查询表时,则程序以如图8E所示方式,将如此确定的表存储到一文件内(例如计算机的软盘上)。首先,在步骤170产生唯一的查询表文件名,将当前站识别号与该文件相关联。在步骤170,接着打开该文件用于输出。在步骤172,程序接着在存储器中建立一查询表表头,表头包含其他信息外还包含有在步骤130、141和161处确定的表中表项数。程序接着在步骤174和175写到新查询表文件173。首先,在步骤172处建立的表头在步骤174写到查询表文件173,在步骤175后跟完整的查询表。在步骤176,查询表文件173接着关闭。程序接着回到图8A所示的步骤104,继续处理,直到站表中所有站的查询表完成为止。只有当一个或多个站移动或加到嵌拼地图时才必须重运行图8A-8E所示的程序;图8A-8E所示程序的实时运行是不需要的。按照本发明的查询表的结构可以在软件上实施。以C语言微软版本写成的一例这样的软件在下面几页中给出。然而,其他的编程语言也可以用来实现这一目的。图8A-8E一起给出该软件的流程图。<prelisting-type="program-listing"><![CDATA[/****************************************************************************UNISYSWIS嵌拼地图处理系统**Unisys公司1994年版权****程序名称CR_LUT.EXE****说明读入配置文件,并建立用于每一站的lut。将合成的反射36和38映一4**×4公里的国家网格。****所需数据文件**CONFIG.DAT(要建立lut文件的站的二进制数据文件。由位于本地目录内的config.exe程序产生)**OUTPUTFILLSCREATEDCR_???.LUT(将NEXRAD合成参考产物映射成4×4Km网格,对每一个NEXRAD站必个。)???代表NEXRAD站识别号。*****************************************************************************/#include<math.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<limits.h>#include<memory.h>#include<dos.h>#include<fcntl.h>#include<io.h>#include<sys\types.h>#include<sys\stat.h>#defineMAXWRITE65534#defineNODATA0#defineMIN_NUM0#defineMIN_VALUE0#defineNO_VALUE0#defineMIN_X0#defineMIN_Y0#defineGRID_X_SIZE_4KM1280#defineGRID_Y_SIZE_4KM896#defineLUT_MAX190000#defineGRID_X_HALF_4KM640#defineGRID_Y_HALF_4KM448#definePR_BINS_CR4232#definePR_ROWS_CR4232#defineTMP_X_SIZE_CR4250#defineTMP_Y_SIZE_CR4250#defineTMP_HALF_CR4125#defineBIN_X_IDX0#defineBIN_Y_IDX1#defineGRID_X_IDX2#defineGRID_Y_IDX3#defineLUT_WIDTH4#defineM_PI3.14159265358979323846#defineM_PI_21.57079632679489661923#defineM_PI_40.78539816339744830962longlut_key={123456};typedefstruct{longkeyword;longnum_entries;shortheader_size;shortsite_id;shortversion;shortdate_built;unsignedlongtime_built;shortgrid_res;shortgrid_width;shortgrid_height;shortbin_res;shortbin_width;shortbin_height;shortprojection;doublegrid_center_phi;doublegrid_center_lamda;doubleradar_phi;doubleradar_lamda;}lut_header_format;lut_header_formatlut_header;typedefstruct{doubledx;doubledy;doublephi_org;doublelamda_org;doublephi_value;doublelamda_value;shortx;shorty;shortpr_id;shortgrid_id;}coords;#定义MAX_SITES200longsite_key={24680};shortnexrad_site={1};shortrrwds_site={2};shortyes={1};shortno={0};typedefstruct{longkeyword;shortnum_sites;}site_header_format;site_header_formatsite_file_header;typedefstruct{shortsite_id;shortsite_flag;shorrsite_build_lut;shortsite_use;doublesite_lat;doublesite_lon;charsite_char[8];}site_contents_format;site_contents_formatsite_file_contents[MAX_SITES];doublemax_range={464.0};doublephi_center_deg=38.0;doublelamda_center_deg=-98.0;/***模型*/shortrnd_oft(doublefl);int_l_c_km2latlon(coords*l_coords);int_l_c_latlon2km(coords*l_coords);int_l_c_latlon2grid(coords*l_coords);int_l_c_grid2latlon(coords*l_coords);int_nex_km2latlon(coords*l_coords);int_nex_latlon2km(coords*l_coords);int_nex_latlon2bin(coords*l_coords);intc_nex_bib2latlon(coords*l_coords);longhuge_fwrite(vojd_huge*buffer,longJength,size_count,intfhw);/***主程序*/intmain(){intstatus;unsignedintdos_status;longnread;size_tnwrite;longsize_write;shortbin_x;shortbin_y;shortnum_sites;shortj;longlut_size;charlut_name[100];staticshort_hugelut[LUT_MAX][LUT_WIDTH];longentry;shorttmp_init={-1};shorttmp_unset={0};shorttmp_set={1};shortgood_status={0};doublerange;shortgrid_x;shortgrid_y;doublephi_deg;/*"Object"latitude(degrees).*/doublelamda_deg;/*"Object"longitude(degrees).*/doublephi_radar_deg;/*Radarlatitude(degrees).*/doublelamda_radar_deg;/*Radarlongitude(degrees).*/staticshort_hugetmp[TMP_X_SIZE_CR4][TMP_Y_SIZE_CR4];shorttx,ty;doublenx,ny;shortgrid_radar_x,grid_radar_y;coordsdummy_coords;coords*local_coords;FILE*fpr;intfhw;/***使local_coords“pointer”初始化,从而它指向某处*/local_coords=&amp;dummy_coords;/***打开“readbinary”的配置文件。*/fpr=fopen("config-dat","rb");if(fpr=NULL){(void)printf("Erroropeningtheconfigurationfile.\n");return(1);}/***读入配置文件表头*/nread=fread(&amp;site_file_header,sizeof(site_header_format,1,fpr);if(nread==NODATA){(void)printf("Errorreadingtheconfigurationfileheader.\n");return(1);}/***检查配置文件表头的正确关键字,并且如果关键字不一致时退出程序。*/if(sitefile_header.keyword!=site_key){(void)printf("Invalidconfigurationfilekeyword\n");return(1);}/***从配置文件表头中获取站编号*/num_sites=site_file_header.num_sites;/***打印最大站编号。*/(void)printf("\nbuildingmosaiclookuptablesfor%dsites\n\n",num_sites);/***读入配置文件内容。要读入的量由站的编号以及每一站的结构大小决定。*/nread=fread(site_file_contents,num_sites*sizeof(site_contents_format),1,fpr);if(nread==NODATA){(void)printf("config.datfread(contents)error\n");return(1);}/***关闭配置文件*/status=fclose(fpr);if(status){(void)printf("Errorclosingtheconfigurationfile.\n");return(1);}/***循环所有的站,并为每一站建立一个lut*/for(j=MIN_NUM;j<num_sites;j++){if((site_file_contents[j].site_flag==nexrad_site)&amp;&amp;(site_file_contents[j].site_build_lut==yes)){/***用下述方法使临时阵列初始化。**通过设定每一阵列元素使阵列初始化。**该阵列用来确定孔出现在将NEXRAD数据箱初始映射成图象嵌拼地图中的何处。*/for(tx=MIN_X;tx<TMP_XSIZE_CR4;tx++){for(ty=MIN_Y;ty<TMP_Y_SIZE_CR4;ty++){tmp[tx][ty]=tnp_init;}}/***获取纬度和经度,并将赋值成简单变量,以及赋值成local_coords结构。*/phi_radar_deg=site_file_contents[j].site_lat;lamda_radar_deg=site_file_contents[j].site_lon;local_coords->phi_value=phi_radar_deg;local_coords->lamda_value=lamda_radar_deg;/***打印站识别号和雷达纬度/经度*/(void)printf("file#%3.3dNEXRADsite%3.3d",j,site_file_contents[j].site_id);(void)printf("radarlat/lon%f/%f(deg)\n",phi_radar_deg,lamda_radar_deg);/***用下述规则(采用Lambert保角投影)将当前站的雷达纬度/经度转换成国家网格**中的x,y坐标。以简单变量grid_radar_x,grid_radar_y存储x和y坐标*/status=l_c_latlon2grid(local_coords);if(status){(void)printf("Errorfroml_c_latlon2gridstatus=%d\n",status);return(1);}grid_radar_x=local_coords->x;grid_radar_y=local_coords->y;/***接着,不设置落在雷达范围内的阵列元素。这样做是因为这是必须检查通过将**NEXRAD箱映射成网格而剩下的“孔”的区域。首先,延x方向循环临时阵列。*/for(tx=MIN_X;tx<TMP_X_SIZE_CR4;tx++){/***将临时阵列x坐标转换成相应的网格框x坐标。*/grid_x=(grid_radar_x-TMP_HALF_CR4+tx);/***检查x网格坐标落在阵列内。**否则,跳过该位置。*/if((grid_x>=MINX)&amp;&amp;(grid_x<GRID_X_SIZE_4KM)){/***通过临时阵列中所有y箱的循环*/for(ty=MIN_Y;ty<TMP_Y_SIZE_CR4;ty++){/***将临时阵列y坐标转换成相应的网格框y坐标*/grid_y=(grid_radar_y-TMP_HALF_CR4+ty);/***检查y网格坐标是否落在阵列内。**否则,跳过该位置。*/if((grid_y>=MIN_Y)&amp;&amp;(grid_y<GRID_Y_SIZE_4KM)){/***将x,y网格框坐标转换成一纬度/经度值。*/local_coords->x=grid_x;local_coords->y=grid_y;status=l_c_grid2latlon(local_coords);phi_deg=local_coords->phi_value;lamda_deg=local_coords->lamda_value;/***接着,将纬度经度位置转换成以公里表示的与NEXRAD坐标系统中隔开的x,y位置。*/local_coords->phi_value=phi_deg;local_coords->lamda_value=lamda_deg;local_coords->phiorg=phi_radar_deg;local_coords->lamda_org=lamda_radar_deg;status=nex_latlon2km(local_coords);/***接着,用以公里表示的x,y坐标确定以公里表示的与雷达相隔的实际距离。**如果该距离落在产物的范围内,则不设置临时阵列值。*/nx=local_coords->dx;ny=local_coords->dy;range=sqrt((nx*nx)+(ny*ny));if(range<max_range){tmp[tx][ty]=tmp_unset;}}}}}/***在此建立查询表。第一步,将每一NEXRAD箱“映射成”网格x,y坐标。整个方法是**将箱位置转换成纬度/经度,并接着将该纬度/经度转换成一网格x,y坐标(用在Lambert**保角投影中)。查询表由表项表组成,每一个包含一NEXRAD箱和行坐标以及相应的**网格x和y坐标。随后,在第二步,找网格中的孔,并将最靠近的NEXRAD映射成孔**的网格x,y坐标/***一开始,查询表中没有表项。*/entry=NO_VALUE;/***将当前站的雷达纬度经度值赋值成local_coards结构。*/local_coords->phi_org=phi_radar_deg;local_coords->lamda_org=lamda_radar_deg;/***为产物中的每一NEXRAD箱进行循环。较外面的循环处理每一行数据。*/for(bin_y=MIN_Y;bin_y<PR_ROWS_CR4;bin_y++){/***较内的循环处理一行中的每一箱。*/for(bin_x=MIN_X;bin_x<PR_BINS_CR4;bin_x++){/***对于处在NEXRAD坐标系统中的当前箱,确定纬度和经度*/local_coords->x=bin_x;local_coords->y=bin_y;status=nex_bin2latlon(local_coords);phi_deg=local_coords->phi_value;lamda_deg=local_coords->lamda_value;if(status==good_status){/***对于一有效x和y箱,取纬度/经度,并比较相应的网格x.,y坐标。*/local_coords->phi_value=phi_deg;local_coords->lamda_value=lamda_deg;status=l_c_latlon2grid(local_coords);grid_x=local_coords->x;grid_y=local_coords->y;if(status==good_status){/***对于一有效纬度/经度,将相应箱x,y和方格x,y坐标赋值给查询表阵列,并使表项编号递增。*/lut[entry][BIN_X_IDX]=bin_x;lut[entry][BIN_Y_IDX]=bin_y;lut[entry][GRID_X_IDX]=grid_x;lut[entry][GRID_Y_IDX]=grid_y;entry++;/***接着,方格x,y坐标用来计算临时阵列x,y坐标。如果临时阵列x,y坐标对该阵列有效,**则设置该阵列元素。任何未设置的阵列元素代表将在以后处理的“孔”。*/tx=grid_x-grid_radar_x+TMP_HALF_CR4;ty=grid_y-grid_radar_y+TMP_HALF_CR4;if((tx>=MIN_X)&amp;&amp;(tx<TMP_X_SIZE_CR4)&amp;&amp;(ty>=MIN_Y)&amp;&amp;(ty<TMP_Y_SIZE_CR4)){tmp[tx]ty]=tmp_set;}}}}}/***下一步,走过全部临时阵列,并找到没有接收箱的产物覆盖区中代表网格框的任何未设置阵**列无素,对于第一网格坐标,找到最靠近的NEXRAD数据,并将其映射成网格。这是填充**孔的地方。对于每一组NEXRAD箱、行和相应的网格x,y坐标,制作查询表的附**加表项。*/for(tx=MIN_X;tx<TMP_X_SIZE_CR4;tx++){for(ty=MIN_Y;ty<TMP_Y_SIZE_CR4;ty++){/***用下述方法检查当前临时阵列元素,以确定是否有孔。(否则,循环至下一个元素。)*/if(tmp[tx][ty]==tmp_unset){/***将临时阵列x,y坐标转换成网络x,y坐标。*/grid_x=(grid_radar_x-TMP_HALF_CR4+tx);grid_y=(grid_radar_y-TMP_HALF_CR4+ty);/***将网络x,y坐标转换成相应的纬度/经度。*/local_coords->x=grid_x;local_coords->y=grid_y;status=l_c_grid2latlon(local_coords);phi_deg=local_coords->phi_value;lamda_deg=local_coords->lamda_value;if(status==good_status){/***对于一有效网格x,y坐标,纬度/经度转换成相应(最靠近)的NEXRAD数据箱**(存入bin_x,bin_y)。*/local_coords->phi_value=phi_deg;local_coords->lamda_value=lamda_deg;local_coords->phi_org=phi_radar_deg;local_coords->lamda_org=lamda_radar_deg;status=nex_latlon2bin(local_coords);bin_x=local_coords->x;bin_y=local_coords->y;if(status==good_status){if((bin_x>=MIN_X)&amp;&amp;(bin_x<PR_BINS_CR4)&amp;&amp;(bin_y>=MIN_Y)&amp;&amp;(bin_y<PR_ROWS_CR4)&amp;&amp;(grid_x>=MIN_X)&amp;&amp;(grid_x<GRID_X_SIZE_4KM)&amp;&amp;(grid_y>=MIN_Y)&amp;&amp;(grid_y<GRID_Y_SIZE_4KM)){/***当箱坐标和网格x,y坐标有效时,将那些坐标对赋值到查询表阵列,并使表项编号递增。*/lut[entry][BIN_X_IDX]=bin_x;lut[entry][BIN_Y_IDX]=bin_y;lut[entry][GRID_X_IDX]=grid_x;lut[entry][GRID_Y_IDX]=grid_y;entry++;/***检查表项编号,以判定是否出现了不可能的情况,即查询表已满。这时,打印一条**信息,并断开循环。*/if(entry==LUT_MAX){(void)printf("LUTisfullentry=%d\n",entry);gotolut_full;}}}}}lut_full;/*goto在此分支,与循环断开。停止工作。*/;/***产生查询表(lut)文件名,其中的识别号以下述方式给出。*/(void)sprintf(lut_name,"cr4%3.3d.lut\0",site_file_contents[j].site_id);/***打印lut文件名。*/(void)printf("lookuptablewrittento%s\n\n",lut_name);/***产生并打开用于“写”的lut文件。*/_fmode=O_BINARY;fhw=creat(lut_name,S_lWRITE);if(fhw==-1){(void)printf("Errorcreatinglutfile%s\n",lut_name);return(1);}lut_header.keyword=lutkey;lut_header.num_entries=entry;lut_header.header_size=sizeof(lut_header_format);lut_header.site_id=site_file_contents[j].site_id;lut_header.version=1;lut_header.date_built=0;lut_header.time_built=0;lut_header.grid_res=4;lut_header.grid_width=GRID_X_SIZE_4KM;lut_header.grid_height=GRID_Y_SIZE_4KM;lut_header.bin_res=4;lut_header.bin_width=PR_BINS_CR4;lut_header.bin_height=PR_ROWS_CR4;lut_header.projection=1;lut_header.gird_center_phi=phi_center_deg;lut_header.grid_center_lamda=lamda_center_deg;lut_header.radar_phi=phi_radar_deg;lut_header.radar_lamda=lamda_radar_deg;/***用下述方式将lut文件表头写到lut文件。*/dos_status=_dos_write(fhw,&amp;lut_header,(size_t)sizeof(lut_header_format),&amp;nwrite);if(dos_status){(void)printf("Errorwritinglutfileheader%s\n",lut_name);return(1);}if(nwrite==NODATA){(void)printf("Errorwritinglutfileheader.nwrite=%d\n",nwrite);return(1);}/***根据表项的编号和每一表项的比特数,计算lut文件内容的大小。*/lut_size=entry*LUT_WIDTH*sizeof(short);/***用下述方式将lut文件件内容写到lut文件上。*/size_write=huge_fwrite(lut,lut_size,1,fhw);if(size_write==NODATA){(void)printf("Errorwritinglutfilecontents.\n");return(1);}dos_status=close(fhw);if(dos_status){(void)printf("Errorclosinglutfile%s\n",lut_name);return(1);}}}/***打印表示处理已完成的信息。*/(void)printf("normalterrnination->lookuptablesarecomplete\n\n");return(0);}/******************************************************************函数rnd_off()*去掉实数的尾数,使之简短。****************************************************************/shortrnd_off(doublefl){shorti;i=(fl<0.0)?(short)ceil(fl-0.5)(short)floor(fl+0.5);return(i);}/****************************************************************/intnex_km2latlon/**名称nex_km21atlon**说明*该程序将NEXRAD平面内的一个“目标”的x和y距离转换成以度表示的相应纬度的*经度。*//*------------------------输入参数----------------------------*//**phi_radar_deg“雷达”纬度(度)*lamda_radar_deg“雷达”经度(度)*zx“目标”与雷达的X距离(以公里表示之)**这里x延向东方向增大。*zy“目标”与雷达隔开的y距离(以公里表示)*这时y延向北的方向增大*//*------------------------------------------------------------*//*------------------------------输入参数----------------------*//**phi_deg“目标”纬度(度)*lamda_deg“目标”经度(度)*//*------------------------------------------------------------*/{/*------------------------------内部变量----------------------*/doublephi;/*“目标”纬度(弧度)*/doublelamda;/*“目标”经度(弧度)*/doublephi_radar;/*“雷达”纬度(弧度)*/doublelamda_radar;/*“雷达”经度(弧度)*/doubleradius={6380.};/*平均地球半径(以公里表示)*/doubleconstant={135.};/*常数*/doubledeg2radians={M_PL/180.};/*将度转换成弧度*/doublezp;/*中间项*/doublezsin_theta;/*中间项*/doublezcos_theta;/*中间项*/doublezsin_s;/*中间项*/doublezcos_s;/*中间项*/doublezsin_phi;/*中间项*/doublezcos_phi;/*中间项*/doublelamda_delta;/*中间项*//*-------------------------------------------------------------------------*/doublezx;doublezy;doublephi_radar_deg;doublelamdar_adar_deg;doublephi_deg;doublelamda_deg;/***从l_coords结构获取雷达纬度/经度(以度表示)*/phi_radar_deg=l_coords->phi_org;lamda_radar_deg=l_coords->lamda_org;/***从l_coords结构获取目标位置(以公里表示)*/zx=l_coords->dx;zy=l_coords->dy;/*检查与雷达位置隔开的x和y距离*/if((zx>-0.1)&amp;&amp;(zx<0.1))&amp;&amp;((zy>-0.1)&amp;&amp;(zy<0.1))){/***这处理的x和y距离接近零的情况(目标基本上处在雷达处)将目标纬度和经度(以度表**示)设置成雷达纬度的经度(以度表示)*/phi_deg=phi_radar_deg;lamda_deg=lamda_radar_deg;}else{/***这里处理的是x和y距离不接近零时的情况(目标不处在雷达处),计算目标纬度和经度。**首先,将雷达纬度和经从度转换成弧度。*/phi_radar=phiradar_deg*deg2radians;lamda_radar=lamda_radar_deg*deg2radians;/*计算与目标的距离(以公里表示)*/zp=sqrt(zx*zx)+(zy*zy));/*计算与目标所成角的正弦和余弦*/zsin_theta=(zx/zp);zcos_theta=(zy/zp);/**计算从雷达位置到目标位置角度大圆距离的中间正弦和余弦项。*/zsin_s=((zp/radius)*(1.0-((constant*zp)/(radius*radius))));zcos_s=sqrt(1.0-(zsin_s*zsin_s));/**计算目标纬度的中间正弦和余弦项。*/zsin_phi=(sin(phi_radar)*zcos_s+cos(phi_radar)*zsin_s*zcos_theta);zcos_phi=sqrt(1.0-(zsin_phi*zsin_phi));/*计算目标与雷达经度之差*/lamda_delta=asin(zsin_s*zsin_theta/zcos_phi);/*计算目标纬度和经度(以弧度表示)*/phi=atan2(zsin_phi,zcos_phi);larnda=lamda_radar+lamda_delta;/*将纬度和经度从弧度转换成度。*/phi_deg=(phi/deg2radians);lamda_deg=(lamda/deg2radians);}/***将纬度/经度(以)度表示)赋值成l_coords结构。*/l_coords->phi_value=phi_deg;l_coords->lamda_value=lamda_deg;/***返回-零值*/return(0);}/*************************************************************/intnex_latlon2km(coords*l_coords)/**名称nex_latlon2km**说明*该程序将NEXRAD平面内的“目标”的纬度和经度转换成以公里表示的x距离分量和*y距离分量。*/{/*---------------------------------输入参数--------------------------*/doublephi_deg;/*“目标”纬度(度)*/doublelamda_deg;/*“目标”经度(度)*/doublephi_radar_deg;/*“雷达”纬度(度)*/doublelamda_radar_deg;/*“雷达”经度(度)*//*------------------------------------------------------------------*//*---------------------------------输出参数-------------------------*/doublezx;/*“目标”与雷达的x距离(以公里表示)*//*这里x延向东方向增大。*/doublezy;/*“目标”与雷达的y距离(以公里表示)*//*这里y延向北方向增大。*//*------------------------------------------------------------------*//*---------------------------------内部变量-------------------------*/doublephi;/*“目标”纬度(度)*/doublelamda;/*“目标”经度(度)*/doublephi_radar;/*“雷达”纬度(度)*/doublelamda_radar;/*“雷达”经度(度)*/doubleradius={6380.};/*平均地球半径(以公里表示)*/doubleconstant={135.};/*常数*/doubledeg2radians={M_PI/180.};/*将度转换成弧度*/doublezterma;/*中间项A*/doubleztermb;/*中间项B*/doublezsin_s;/*中间项角度大圆的正弦*/doublezcos_s;/*中间项角度大圆的余弦*/doublezd;/*中间项D。*//*-----------------------------------------------------------------*/phi_deg=l_coords->phi_value;lamda_deg=l_coords->lamda_value;phi_radar_deg=l_coords->phi_org;lamda_radar_deg=l_coords->lamda_org;/*将雷达纬度从度转换成弧度。*/phi_radar=deg2radians*phi_radar_deg;/*将雷达经度从度转换成弧度*/lamda_radar=deg2radians*lamda_radar_deg;/将目标纬度从度转换成弧度*/phi=deg2radians*phi_deg;/*将目标经度从度转换弧度*/lamda=deg2radians*lamda_deg;/*计算中间项a和b*/zterma=cos(phi)*sin(lamda-lamda_radar);ztermb=((cos(phiradar)*sin(phi))-(sin(phi_radar)*cos(phi)*cos(lamda-lamda_radar)));/*计算从雷达位置到目标位置的角度大圆距离的中间正弦和余弦。*/zsin_s=sqrt((zterma*zterma)+(ztermb*ztermb));zcos_s=sqrt(1-(zsin_s*zsin_s));/*计算中间项D*/zd=(constant*zsin_s)+radius;/*计算×距离(以公里表示)*/zx=zd*cos(phi)*sin(lamda-lamda_radar);/*计算y距离(以公里表示)*/zy=zd*(sin(phi)-(sin(phi_radar)*zcos_s))/cos(phi_radar);l_coords->dx=zx;l_coords->dy=zy;/***返回到零值*/return(0);}/*************************************************************************************/intnex_latlon2bin(coords*l_coords){shortbin_x,bin_y;intstatus;doublezx,zy;/***用下述方式将纬度/经度转换成NEXRAD坐标系统中的公里。*/status=nex_latlon2km(l_coords);if(status){return(1);}zy=l_coords->dx;2y=l_coords->dy;/***将x和y距离分量从公里转换成数据箱坐标。当浮点值赋值成整数变量时,去掉浮点值的**尾数。*/bin_x=rnd_off((zx+462.)/4.0);bin_y=rnd_off(462.-zy)/4.0);/***将x和y箱坐标赋值成l_coords结构。*/l_coords->x=bin_x;l_coords->y=bin_y;/***检查x,y箱坐标是否处理在确定返回值的有效范围内。一非零返回值表示纬度经度对应**于无效x,y箱坐标。*/if((bin_x>=MIN_X)&amp;&amp;(bin_x<PR_BINS_CR4)&amp;&amp;(bin_y>=MIN_Y)&amp;&amp;(bin_y<PR_ROWS_CR4)){/***这是处理有效x,y箱值。返回一零值。*/return(0);}return(2);}/*******************************************************************/int_l_c_latlon2grid(coords*l_coords){shortgrid_x,grid_y;intstatus;doublezx,zy;doubleboxsize={4.0};/***用Lambert保角投影将到来纬度经度转换成以(标称)公里表示的距离。*/status=l_c_latlon2km(l_coords);if(status){/***如果出现无效状态,则从具有非零状态的程序返回。*/return(1);}/***从l_coords结构获x,y距离分量*/zy=l_coords->dx;zy=l_coords->dy;/***将x,y距离分量转换成网格x,y坐标。**当从浮点转换成整数时,去掉这些值的尾数。*/grid_x=md_off(zx/boxsize)+GRID_X_HALF_4KM;grid_y=GRID_Y_HALF_4KM-rnd_off(zy/boxsize);/***用下述方法将网格x,y坐标赋值成l_coords结构。*/l_coords->x=grid_x;l_coords->y=grid_y;/***检查网格x,y坐标值是否代表了一有效阵列指数。非零值产生一非零返回。*/if((grid_x>=MIN_X)&amp;&amp;(grid_x<GRID_X_SIZE_4KM)&amp;&amp;(grid_y>=MIN_Y)&amp;&amp;(grid_y<GRID_Y_SIZE_4KM)){/***这里处理一有效网格x,y坐标值。返回一零值。*/return(0);}return(2);}/*******************************************************************/intnex_bin2latlon(coords*l_coords){shortbin_x,bin_y;intstatus;doublezx,zy;doublerange;/***从l_coords结构获取NEXRAD数据箱坐标。*/bin_x=l_coords->x;bin_y=l_coords->y;/***检查有效阵列指数值的网格x,y坐标对。一非有效坐标号致从程序的非零返回。*/if(bin_x>=MIN_X)&amp;&amp;(bin_x<PR_BINS_CR4)&amp;&amp;(bin_y>=MIN_Y)&amp;&amp;(bin_y<PR_ROWS_CR4)){/***将箱网格x,y坐标转换成网格x,y距离分量,结果是一对俘点值。*/zx=((bin_x*4.0)-462.0);zy=(-((bin_y*4.0)-462.0));/***用距离分量计算以公里表示的范围。*/range=sqrt(zx*zx)+(zy*zy));/***检查该范围,以确保其处在NEXRAD范围内。否则返回一非零值。*/if(range<max_range){/***这处理式EXRAD范围内的坐标。将x,y距离分量赋值成l_coords阵列。*/l_coords->dx=zx;l_coords->dy=zy;/***用下述程序计算点的纬度/经度,将NEXRAD平面内的x,y距离转换成纬度/经度(以度表示)*/status=nex__km2latlon(l_coords);if(status){/***这里处理表示经过非有效坐标面返回的非零状态。返回一非零状态值。*/return(3);}/***这表示计算了有效纬度/经度。返回零值。*/return(0);}return(1);}return(2);}/*******************************************************************/intl_c_grid2latlon(coords*l_coords){shortgrid_x,grid_y;intstatus;doublezx,zy;doubleboxsize={4.0};/***从l_coords结构获取网格x,y坐标。*/grid_x=l_coords->x;grid_y=l_coords->y;/***检查网格x,y坐标是有效阵列指数否则返回一非零状态。*/if((grid_x>=MIN_X)&amp;&amp;(grid_x<GRID_X_SIZE_4KM)&amp;&amp;(grid_y>=MIN_Y)&amp;&amp;(grid_y<GRID_Y_SIZE_4KM)){/***这处理的有效网格x,y坐标。将网格x,y坐标转换成以(标称)公里表示的x,y距离**分量。y坐标被反向。然后将距离分量赋值成l_coords结构。*/zx=(grid_x-GRIDX_HALF_4KM)*boxsize;zy=(GRID_Y_HALF_4KM-grid_y)*boxsize;l_coords->dx=zx;l_coords->dy=zy;/***用下述程序,用Lambert保留投影将(用公里表示的)x,y距离分量转换成**纬度/经度。*/status=l_c_km2latlon(l_coords);if(status){/***这里处理的是出现无效情况时的情况。返回一非零值。*/return(2);}/***这里处理有效情况,并返回一零值。*/return(0);}return(1);}/*****************************************************************函数l_c_latlon2km()*用lambert保留将纬度/经度转换成x/y****************************************************************//*将纬度/经反转换成x/y*/intl_c_latlon2km(coords*l_coords){staticdoubledeg2radians={M_PI/l80.};/*将反转换成弧度*/staticdoublephi_1_deg={33};/*标准纬度1(以度表示)*/staticdoublephi_2_deg={45};/*标准纬度2(以度表示)*/staticdoubleradius={6380.};/*平均地球半径(以公里表示)*/staticdoublephi_0_eg={38.0};/*网格原点纬度(以度表示)*/staticdoublelamda_0_deg={-98.0};/*网格原点经度(以度表示)*//***对上面定义的网格中心、地球半球半径和标准纬度,计算下面的常数。在没有重新**计算这些常数时,不要将该程度用于其它中心。*/staticdoublephi_1={0.575958653158129};/*标准纬度1(以弧度表示)*/staticdoublephi_2={0.785398163397448};/*标准纬度2(以弧度表示)*/staticdoublephi_0={0.663225115757845};/*网格原点纬度(以弧度表示)*/staticdoublelamda_0={-1.710422666954443};/*网格原点经度(以弧度表示)*/staticdoublerho_0={7931.823624772932817};staticdoublen={0.630477697315427};staticdoublef={1.955000201593793};staticdoublerf={12472.901286168398656};/*中间项=(radins*f)*/doublephi_deg;doublelamda_deg;doublezx;doublezy;doublerho;doubletheta;doublephi;/*当前纬度值(弧度)*/doublelamda;/*当前经度值(弧度)*//***从l_coords结构获取目标(以度表示)的纬度和经度*/phi_deg=l_coords->phi_value;lamda_deg=l_coords->lamda_value;/***将目标的纬度和经度从反转换成弧度。*/phi=phi_deg*deg2radians;lamda=lamda_deg*deg2radians;tho=(rf/(pow(tan(M_PI_4+(phi/2)),n)));theta=n*(lamda-lamda_0);/***计算x和y距离分量(以标称公里表示)*/zx=(rho*sin(theta));zy=(rho_0-rho*cos(theta));/***将x,y距离分量(以标称公里表示)赋值成l_coords结构。*/l_coords->dx=zx;l_coords->dy=zy;/***返回一零值*/return(0);}/*************************************************************/intl_c_km21atlon(coords*l_coords)/**名称l_c_km2latlon**说明*该程度将“目标”的x和y距离分量在Lanbert保角投影下转换成以反表示的*纬度和经度。**//*-----------------------输入参数------------------------------*//**zx目标与雷达的x距离(以公里表示)*//*这里x延向南方向增大*//*/**zy"“目标”与雷达的y距离(以公里表示)/*/*这里y延向北方向增大*//*--------------------------------------------------------------*//*------------------------输出参数------------------------------*//*phi_deg“目标”纬度(度)*//*lamda_deg“目标”经度(度)*//*------------------------------------------------------------------*/{staticdoublephi_l={0.575958653158129};/*标准纬度(以弧度表示)*/staticdoublephi_2={0.785398163397448};/*标准纬度(以弧度表示)*/staticdoublephi_0={0.663225115757845};/*网格原点纬度(以弧度表示)*/staticdoublelamda_0={-1.710422666954443};/*网格原点经度(以弧度表示)*/staticdoublerho_0={7931.823624772932817};staticdoublen={0.630477697315427};staticdoublef={1.955000201593793};staticdoublerf={12472.901286168398656};/*中间项=(radius*f)*/staticdoubleradius={6380.};/*平均地球半径(以公里表示)*/staticdoubledeg2radians={M_PI/180.};/*将反转换成弧度*/staticdoublephi_l_deg={33};/*标准纬度1(以度表示)*/staticdoublephi_2_deg={45};/*标准经度2(以度表示)*/staticdoublephi_0_deg={38.0};staticdoublelamda_0_deg={-98.0};/*----------------------------内部变量---------------------------*/doublephi;/*“目标”纬度(弧度)*/doublelamda;/*“目标”经度(弧度)*/doublerho;doubletheta;doublezx,zy;doublephi_deg;doublelamda_deg;/*---------------------------------------------------------*//***从l_coords结构获取目标距离(以公里表示)。*/zx=l_coords->dx;zy=l_coords->dy;rho=sqrt((zx*zx)+((rho_0-zy)*(rho_0-zy)));/***计算纬度,以弧度表示。*/phi=((2*atan(pow((rf/rho),(1/n))))-M_PI_2);theta=atan2(zx,(rho_0-zy));/***计算经度,以弧度表示。*/lamda=((theta/n)+lamda_0);/***将纬度/经度从弧度转换成度*/phi_deg=phi/deg2radians;lamda_deg=lamda/deg2radiaus;/***将纬度和经度(以度表示)赋值成l_coords结构。*/l_coords->phi_value=phi_deg;l_coords->lamda_value=lamda_deg;/***返回一零值。*/return(0);}/***将一大阵列的内容写成一文件的函数*//*************************************************************/longhuge_fwrite(void_huge*buffer,longlength,size_tcount,intfhw)/***说明将一大阵列的内容写成一文件的函数*/{char_huge*pnt_buffer;longremain;size_tamount;size_tnwrite;longtotal;unsignedintdos_status;pnt_buffer=buffer;remain=length;total=0;while(remain>0){if(remain>MAXWRITE){amount=MAXWRITE;remain-=(long)amount;dos_status=_dos_write(fhw,pnt_buffer,amount,&amp;nwrite);if(dos_status){(void)printf("dos_writebadstatus\n");return(0);}pnt_buffer+=amount;total+=nwrite;if(nwrite==0){return(total);}}else{amount=(size_t)remain;remain=0;dos_status=_dos_write(fhw,pnt_buffer,amount,&amp;nwrite);if(dos_status){(void)printf("dos_writebadstatus\n");return(0);}pnt_buffer+=amount;total+=(long)nwrite;if(nwrite==0){return(total);}}}return(total);}]]></pre>图9A、9B、9C和9E一起给出描述能够建立雷达数据的嵌拼地图的结构图或流程图。图9A-9E所示的程序设计用来按图8A-8E所示的脱机程序建立的查询表实时运行。启动时,图9A-9E所示的程序作为一连续过程进行运行。如图9A所示,含有要在嵌拼地图中使用的站表而手工产生的配置文件200用来使步骤201和202处的过程初始化。首先,该过程从配置文件200读取站号和随后要存储到存储器中供以后使用的站表(步骤202)。接着,进入循环(步骤203),连续运行(图9B中示为所谓的“永远运行”循环)。循环的每一次执行都导致产生新的嵌拼地图,该新的嵌拼地图是从站表中指定的各个站得到的最最当前的数据的汇集。在准备产生嵌拼地图时,计算机存储器中所有的二维网格元素都设置(步骤204)为同样的预定值,例如设置为零(即网格被清除了任何存在的数据)。接着,设置索引“至站表中的当前站”(步骤205),以指向该表上的第一站。接着,进入另一个循环,一次一个地处理该站表上的雷达站(步骤206),直到所有的站(步骤207)均被处理为止。。通过从站表获取站识别号(步骤220)接着使站索引号递增一(步骤221),如图9B所示,每一雷达站的处理开始。站识别号被程序用来确定计算机本地数据库46中当前站的数据位置(步骤222)。如果没有用于当前站的数据(步骤223),则程序跳到下一个站。否则,程序识别用于该站的最当前的数据。该数据(称为产物)停留在本地数据库46中的文件(雷达产物数据225)内。首先,文件被打开(步骤224),并将产物“表头”读入到程序的存储器中(步骤226)。表头包含诸如数据日期和时间以及产物数据长度之类的信息。通过检查产物数据和时间,如果数据被判定为太旧(步骤227)了,则程序跳过该站并进入到下一站。否则,采用该数据长度,将文件225留下的内容读入到计算机存储器中(步骤228),并且随后关闭产物文件225(步骤229)。接着,如图9C所示,产物数据被译码,并存储到二维“光栅”阵列中。如果在译码过程中检测到差错,则程序跳到下一个站(步骤242)。当产物被成功译码以后,程序采用当前雷达站识别号来确定计算机本地数据库46中恰当查询表文件的位置(步骤243)。首先,查询表文件245被打开,并将表头(包含表表项的编号)读入到程序存储器内。程序接着采用表表项的编号,从文件245读入完整的查询表,该表随后被存储到程序存储器中。该查询表文件245接着关闭(步骤248)。图9D给出的是一旦读入了查询表时,单基站雷达数据是如何赋值到二维网格中去的。进入一个循环,以处理查询表中的所有表项(步骤260)。当完成了所有的处理以后,程序进行到下一站(步骤261)。首先,从查询表获取进入二维产物光栅阵列中的x和y索引(步骤262),并检查有效性(步骤263)。(实践中应永不出现无效表项,但如果出现,则程序跳过该表项,并进入到下一个表项。)接着从产物数据阵列获取产物数据值(步骤264)。随后,从查询表获取进入到二维嵌拼地图网格内的x和y索引(步骤266)。(再次指出,实践中应永远不出现无效表项,但如果检测到无效表项,则程序跳到下一个表项。)接着,检查产物数据值的有效性(步骤267),并且任何的无效数据值都使程序跳到下一个查询表表项。随后,产物值与现存的网格值比较,并且如果产物值大,则赋值到x,y位置处的网格,而如果不大,则跳过。对于查询表中其余所有表项以同样的方式继续进行处理。在这样处理了所有存在的站以后,网格中的数据被变换成如图9E所示新的产物。首先,将网格中的值转换成输出产物格式(步骤280),并赋值到计算机存储器中的一个缓冲器。随后,同样也在含有当前日期和时间以及产物数据长度的计算机存储器中建立表头(步骤281)。产生(步骤283)唯一的输出文件名,并打开该名称的文件用以输出(步骤283)。接着,将数据实际上写到输出产物文件284。首先,写产物表头(步骤285),后跟产物数据本身(步骤286)。最后,关闭输出产物文件284,并且程序继续开始下一个嵌拼地图。用上述给出的软件而构造的一个或多个预先构成的查询表直接将各个雷达数据值映射到嵌拼地图网格可以用软件来实施。下面的几页中给出一例用C语言的ANSI版本写的这样一个软件,可用于SunMicrosystem工作站。但是,也可以采用其他的编程语言来实现。图9A-9E一起给出用于该软件的流程图。下面几页中给出的软件实施图4所示的步骤48和50。上述软件以及下述软件一起实施图3所示的步骤34、36、38和40。<prelisting-type="program-listing"><![CDATA[/**************************************************UNISYSWIS嵌拼地图处理系统**Unisys公司1994年版权****程序名称BUILD.EXE****说明读入各雷达产物和相应的查询表,并将产物数据映射至一网格。**然后获取产生的网格值并产生一新的产物****假设用于所要求站的产物在指定的手册(directory)内。**用于所要求的站的查询表在"lut"手册(directory)内。***************************************************/#include<math.h>#include<errno.h>#include<time.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<ctype.h>/***子程序原型*/intget_latest(short,short,char*);#defineBIN_X_IDX0#defineBIN_Y_IDX1#defineGRID_X_IDX2#defineGRID_Y_IDX3#defineLUT_WIDTH4#defineMAX_DATA_SIZE300000#defineNUM_DATA_LEVELS16#defineNODATA0#defineMIN_NUM0#defineMIN_VALUE0#defineNO_VALUE0#defineMIN_X0#defineMIN_Y0#defineGRID_X_SIZE1280#defineGRID_Y_SIZE896#defineLUT_MAX50000#definePR_BINS232#definePR_ROWS232longlut_key={123456};typedefstruct{longkeyword;longnum_entries;shortheader_size;shortsite_id;shortversion;shortdate_built;unsignedlongtime_built;shortgrid_res;shortgrid_width;shortgrid_height;shortbin_res;shortbin_width;shortbin_height;shortprojection;doublegrid_center_phi;doublegrid_center_lamda;doubleradar_phi;doubleradar_lamda;}lut_header_format;lut_header_formatlut_header;typedefstruct{doubledx;doubledy;doublephi_org;doublelamda_org;doublephi_value;doublelamda_value;shortx;shorty;shortpr_id;shortgrid_id;}coords;longsite_key={24680};shortnexrad_site={1};shortrrwds_site={2};shortyes={1};shortno={0};typedefstruct{longkeyword;shorthum_sites;}site_header_format;site_header_format_site_file_header;typedefstruct{shortsite_id;shortsite_flag;shortsite_build_lut;shortsite_use;doublesite_lat;doublesite_lon;}site_contents_format;#defineMAX_SITES200site_contents_formatsite_file_contents[MAX_SITES];FILE*fpw;FILE*fpr;FILE*fpr_prod;char*buf;longdata_size;longnwrite;longnread;staticinterrno=0;typedefstruct{shortsite_id;char*site_text;}site_path_format;#defineNUM_SITE_PATH30/***站通路信息例*/staticsite_path_formatsite_path[NUM_SITE_PATH]={354,"AL_maxwell_AFB/",395,"AR_littlerock/",524,"AZ_phoenix/",347,"CO_denver/",351,"DE_dover/",302,"FL_melbourne/",728,"FL_miami/",337,"IL_chicago/",381,"IN_indianapolis",350,"KS_dodgecity/",366,"KS_goodland/",554,"KS_topeka/",562,"KS_wichita/",349,"MI_detroit",308,"MO_stlouis/″,342,"MS_columbus/",382,"MS_jackson/",367,"NE_hastings/",372,"NY_griffis_AFB/",340,"OH_cleveland/",305,"OK_frederick/",301,"OK_norman/",557,"OK_tulsa/",525,"PA_pittsburgh/",313,"TX_amarillo/",332,"TX_central/",353,"TX_dyess_AFB/",378,"TX_houston/",303,"VA_sterling/",000,"UNDEFINED/",};typedefstruct{shortprod_id;char*prod_text;}prod_path_format;#defineNUM_PROD_PATH1staticprod_path_formatprod_path[NUM_PROD_PATH]={38,"COMP_REF/",};/***建立镶嵌的主程序*/main(){#defineinitial_x0#defineinitial_y0intstatus;unsignedshort*index;unsignedshort*st_index;unsignedcharbyte;shortn_bytes;shortrun,col;char*cp;unsignedshortlength1,length2;shortk,m;shortp;shortbin;unsignedinttime1,time2;time_ttot_sec;unsignedshortopcode;shortmsg_code;shortinput_source_id;shortoutput_source_id;shortop_mode;shortvcp;shortnrows;longlut_size;longage_minutes;staticlongmax_age_minutes={15};longage_seconds;shortgrid_x;shortgrid_y;shortnum_sites;shortsite_id;shortprod_id;shortj;shortheader_size={136};shortproduct[PR_BINS][PR_ROWS];unsignedshortgrid[GRID_X_SIZE][GRID_Y_SIZE];shortrow;shortbox,box_y;shortrow_index;shortbin_index;shortmax_col;shortnumber_rows;shortnumber_bins;shortstart_bin;shortstart_row;charlut_name[512];charprod_name[512];charprod_file[25];char*s;shortlut[LUT_MAX][LUT_WIDTH];longentry;longnum_entry;shortprev_col;shortnbytes;longlayer_length;longlayer2_ength;longblock_length;longmessage_length;longtotal_length;shortscale_x,scale_y;unsignedshort*nbytes_index;unsignedshort*msw_layer_len_index;unsignedshort*lsw_layer_len_index;unsignedshort*msw_layer2_len_index;unsignedshort*lsw_layer2_len_index;unsignedshort*msw_block_len_index;unsignedshort*lsw_block_len_index;unsignedshort*msw_msg_len_index;unsignedshort*lsw_msg_len_index;unsignedshortmsw_layer_len;unsignedshortlsw_layer_len;unsignedshortmsw_layer2_len;unsignedshortlsw_layer2_len;unsignedshortmsw_block_len;unsignedshortlsw_block_len;unsignedshortmsw_msg_len;unsignedshortlsw_msg_len;shortref;shortdl;/***赋值成输出产物表头的数据级编码*/staticunsignedshortdata_level_16[NUM_DATA_LEVELS]={0x8002,0x0005,0x000a,0x000f,0x0014,0x0019,0x001e,0x0023,0x0028,0x002d,0x0032,0x0037,0x003c,0x004l,0x0046,0x004b};shortpr_type;unsignedshortproduct_color;unsignedshortgrid_color;shortflag_off={0};shortflag_on={1};shortnum;shortprid;shortdestination_id;shortnum_blocks;shortdivider;longlatitude_origin;longlongitude_origin;doublephi_center_deg={38.0};doublelamda_center_deg={-98.0};doublelat_origin_deg;doublelon_origin_deg;unsignedshortmsw_latitude;unsignedshortlsw_latitude;unsignedshortmsw_longitude;unsignedshortlsw_longitude;shortheight_value;shortsequence_num;shortscan_num;shortelevation_num;shortsym_block_id;shortnum_layers;unsignedshortraster_opcode;unsignedshortraster_const1;unsignedshortraster_const2;unsignedshortraster_const3;char*out_str_home="/home/";char*out_sgr_site="NATIONAL/";shortnum_included;shortnum_excluded;shortn;shorttab_included[MAX_SITES];shorttab_excluded[MAX_SITES];shortyear,month,day;longtime_sec;longseconds;longcur_seconds;shorthour,minute;shorthh,mm;longss;structtmJan_01_1970_struct={0};/*Initializeallfieldsto0.*/time_tJan_01_1970_t;time_tgmt_t;time_total_time;structtmgmt_struct;shortj_date;shortcur_j_date;shortmsg_date;longmsg_time;unsignedshortmsw_msg_time;unsignedshortlsw_msg_time;shortscan_date;longscan_time;unsignedshortmsw_scan_time;unsignedshort_lsw_scan_time;shortgeneration_date;longgeneration_time;unsignedshortmsw_generation_time;unsignedshortlsw_generation_time;union{longl_value;shorts_value[2];}long2short;/***获得读入现有产物且建立新产物并从中存入的缓冲器.*/buf=(char*)malloc(MAX_DATA_SIZE);if(buf==NULL){(void)printf("errormallocfailedforbuf,errno=%d\n",errno);return(1);}/***打开配置文件,并读入表头。*/fpr=fopen("config.dat","rb");if(fpr==NULL){(void)printf("fopenerrorforconfigurationfileheader,errno=%d\n",errno);return(1);}nread=fread(&amp;site_file_header,sizeof(site_fileheader),1,fpr);if(nread==NODATA){(void)printf("freaderrorwithsitefileheader,errrno=%d\n",errno);return(1);}/***检查用于正确关键词的配置文件表头,并且如果关键字不一致时,退出程序。*/if(site_file_header.keyword!=site_key){(void)printf("Invalidconfigurationfilekeyword\n");return(1);}/***从配置文件标题获取站编号,并用该编号确定文件内容的大小。从结构文件读配置内**容,这提供了站表,并且表示哪些是NEXRAD哪些是活动的(将用在嵌拼地图中)。*/num_sites=ske_file_header.num_sites;nread=fread(site_file_contents,num_sites*sizeof(site_contents_format),1,fpr);if(nread==NODATA){(void)printf("errorreadingconfigurationfilecontents,errno=%d\n",errno);return(1);}status=fclose(fpr);if(status!=0){(void)printf("errorclosingconfigurationfile,errno=%d\n",errno);}while(1)/*DOFOREVER*/{/***获得自1970年1月1日以来以秒表示的当前时间,用来确定它们从数据库被读取时,**现有产物的年代。*/Jan_01_1970_struct.tm_year=70;Jan01_1970_struct.tm_mon=0;Jan_01_1970_struct.tm_mday=0;Jan_01_1970_t=mktime(&amp;Jan_01_1970_struct);if(Jan_01_1970_t==(time_t)-1){(void)printf("errormktime(1/1/70)error.\n");return(1);}total_time=time(NULL);gmt_struct=*gmtime(&amp;total_time);year=gmt_struct.tm_year;if(year>99){year-=100;}month=gmt_struct.tm_mon+1;day=gmt_struct.tm_mday;hour=gmt_struct.tm_hour;minute=gmt_struct.tm_min;(void)printf("Current(gmt)year=%dmonth=%dday=%dhour=%dmin=%d\n",year,month,day,hour,minute);gmt_t=mktime(&amp;gmt_struct);if(gmt_t==(time_t)-1){(void)printf("errormktime(gmt)error.\n");return(1);}else{time_sec=difftime(gmt_t,Jan_01_1970_t);cur_j_date=time_sec/86400;cur_seconds=time_sec%86400;}/***使计算器初始化,以跟踪嵌拼地图中包括和除去的站。*/num_included=0;num_excluded=0;/***清除其中要建嵌拼地图的网格*/for(grid_y=MIN_Y;grid_y<GRID_Y_SIZE;grid_y++){for(grid_x=MIN_X;grid_x<GRID_X_SIZE;grid_x++){grid[grid_x][grid_y]=NO_VALUE;}}/***下面是读入各个NEXRAD产物并将数据映射成大网格的主循环。通过这些站**的循环包含在该结构中。*/for(j=MIN_NUM;j<num_sites;j++){/***从配置文件数据获取请求的站标识。*/site_id=site_file_contents[j].site_id;/***这里处理NEXRSD数据,请求合成反射率。*/prod_id=38;/***用下述方法找到通往用于指定站的指定类型的最新产物的路径。一非零状态码表示**没有产物。因此跳到下一个*/status=get_latest(site_id,prod_id,prod_name);prod_name[strlen(prod_name)-1]=′\0′;if(status){(void)printf("productisunavailable.\n");num_excluded++;tab_excluded[num_excluded-1]=site_id;gotojump_here;}/***用通往最新者的路径打开产物文件*/fpr_prod=fopen(prod_name,"rb");if(fpr_prod==NULL){(void)printf("Unabletoopenproduct.site=%d\n",site_id);num_excluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***读入产物标题/*nread=ftead(buf,header_size,1,fpr_prod);if(nread==NODATA){(void)printf("productreaderror,errno=%d\n",errno);numexcluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***从产物表示获取数据。首先是在缓冲器开头处存在的开始指数的位置。*/st_index=(unsignedshort*)buf;index=st_ndex;msg_code=*index;/***从产物表头获取运算模式和体积覆盖方式。用该信息检查雷达是否处在一有效模式下。**如果雷达处在维护模式下,则跳过该产物,并跳到(进入)循环的结束处。*/index=st_index+16;op_mode=*index;index=st_index+17;vcp=*index;if((op_mode!=1)&amp;&amp;(op_mode!=2)){(void)printf("invalidop_mode=%dvcp=%d\n",op_mode,vcp);num_excluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***获取输入产物站标识率。与请求的站标识率比较。如果获取和请求的站标识号不一致,**则报告差错,并跳到(进入)下一个站的产物。*/index=st_index+6;input_source_id=*index;if(site_file_contents[j].site_id!=input_source_id){(void)printf("requested(%d)product(%d)sitemismatch\n",site_id,input_source_id);num_excluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***从产物表头获取日期(自1970年1月1日以来以天计)和时间(秒),用这一信息**确定自1970年1月1日以来以秒计算的总时间。这用来与正确的时间比较,以确定**产物的“年代”。*/index=st_index+20;j_date=*index;index=st_index+21;time1=*index;index=st_index+22;time2=*index;tot_sec=(j_date*86400)+(time1*65536)+time2;if(tot_sec>time_sec){age_minutes=0;}else{age_seconds=time_sec-tot_sec;age_minutes=age_seconds/60;}/***检查产物的年代。如果产物太老,则跳到下一个站。*/if(age_minutes>max_age_minutes){(void)printf("productistoooldage_minutes=%d\n",age_minutes);numexcluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***确定数据层的长度(以比特表示)*/index=st_index+66;length1=*index;index=st_index+67;length2=*index;data_size=(long)((length1*65536)+length2);if(data_size>MAX_DATA_SIZE){(void)printf("productdatasizetoolargetoread");num_excluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***用下述方法读入其余的产物。*/nread=fread(buf,data_size,1,fpr_prod);if(nread==NODATA){(void)printf("errorreadingproductfile,errno=%d\n",errno);num_excluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}status=fclose(fpr_prod);if(status!=0){(void)printf("errorclosinginputproductfile,errrno=%d\n",errno);return(1);}/***确定运行长度编码的光栅数据的位置,并获取opcode,并检查其有效性。*/st_index=(unsignedshort*)buf;index=st_index;opcode=*index;if(opcode!=0xba07){(void)printf("errorinvalidrasteropcodeininputproduct=%x\n",opcode);num_excluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}/***从产物数据层获取行数*/index+=9;nrows=*index;/***指向运行长度偏码的光栅数据的第一行。*/index+=2;/***检查有效行数*/if((nrows>MIN_Y)&amp;&amp;(nrows<=PR_ROWS)){/***通过光栅数据行的循环*/for(row=MIN_Y;row<nrows;row++){n_bytes=*index;index++;cp=(char*)index;bin=NO_VALUE;/***通过当前行中RLE数据的比特。*/for(m=1;m<=n_bytes;m++){/***获取当前比特,并确定运行和颜色*/byte=*(cp);cp++;run=((short)byte)/16;col=((short)byte)%16;if(run>0){for(k=MIN_Y;k<run;k++){if((bin<PR_BINS)&amp;&amp;(row<PR_ROWS)){product[bin][row]=col;}else{/***在箱或行数超过阵列极限的非寻常情况下,报告差错,并跳到下一站的产物。*/(void)printf("errorbin=%drow=%d\n",bin,row);numexcluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}bin++;}}}index=(unsignedshort*)cp;}}else{(void)printf("errorproductinvalidnumberofrows=%d",nrows);numexcluded++;tab_excluded[num_excluded-1]=site_id;pintf("path=%s\n",prod_name);gotojump_here;}/***接着,打开并读入查询表文件。首先,产生包含表(lut)文件名(根据站号)的串,**并打开用于“读二进制”的lut文件。*/(void)sprintf(lut_name,"lut/cr4_%3.3d.lut\O",site_file_contents[j].site_id);fpr=fopen(lut_name,"rb");if(fpr==NULL){(void)printf("errorerroropeninglutfile(%s)forread,errno=%d\n",lut_name,errno);num_excluded++;tab_excluded[num_excluded-1]=site_id;gotojump_here;}/***接着,读入查询表(lut)文件表头从中获聚表项偏号,用来计算lut内容的大小**(lut大小)同时,检查关键词和表头大小,以检查读入了一有效“lut”表头。*/nread=fread(&amp;lut_header,sizeof(lut_header_format),1,fpr);if(nread==0){(void)printf("errorreadinglutfile,errno=%d\n",errno);numexcluded++;tab_excluded[num_excluded-1]=site_id;printf("path=%s\n",prod_name);gotojump_here;}num_entry=lut_header.num_entries;if(hum_entry>LUT_MAX){num_entry=LUT_MAX;}if(lut_header.keyword!=lut_key){(void)printf("invalidlutkeyword=%d\n",lut_header.keyword);num_entry=0;}if(lut_header.header_size!=sizeof(lut_header_format){(void)printf("invalidlutheadersize=%d\n,lut_header.header_size);num_entry=0;}lut_size=num_entry*LUT_WIDTH*sizeof(short);/***进行读,以读入lut本身。*/nread=fread(lut,lut_size,1,fpr);/***因为已经读入了lut,因此关闭文件说明符。*/status=fclose(fpr);if(status!=0){(void)printf("errorerrorclosinglookuptablefile,errno=%d\n",errno);return(1);}/***通过查询表中所有表项的循环,并将雷达数据映射成网格框。/*for(entry=MIN_NUM;entry<num_entry;entry++){/***获取当前雷达产物的箱和行坐标*/bin=lut[entry][BIN_X_IDX];row=lut[entry][BIN_Y_IDX];/***检查箱和行在产物数据阵列中是有效指数(即,它们是有效的)*/if((bin>=MIN_X)&amp;&amp;(bin<PR_BINS)&amp;&amp;(row>=MIN_Y)&amp;&amp;(row<PR_ROWS)){/***从用于当前臬和行的产物阵列获取产物颜色(数据级)*/product_color=product[bin][row];/***获取相应的x和y网格坐标。*/grid_x=lut[entry][GRID_X_IDX];grid_y=lut[entry][GRID_Y_IDX];/***检查当前x和y网格坐标,以验证这些值是有效的阵列指数。 */ if((grid_x>=MIN_X)&amp;&amp;(grid_x<GRID_X_SIZE)&amp;&amp;(grid_y>=MIN_Y)&amp;&amp;(grid_y<GRID_Y_SIZE)){/***检查某一值的现有网格框*/if(grid[grid_x][grid_y]==NO_VALUE){grid[grid_x][grid_y]=product_color;}else{/***在现有网格中现有值的情况下,在现有网格值和当前产物颜色值之间需要进行比较。**当其大于现有网格颜色值时,映射该产物颜色。*/grid_color=grid[grid_x][grid_y];if(product_color>grid_color){grid[grid_x][grid_y]=product_color;}}}else{/***这里处理x,y网格坐标不是有效阵列指数的一种非寻常情况,现在,打印该值,**并进行到下一个lut表项。*/(void)printf("entry=%dgrid_x=%dgrid_y=%d\n",entry,grid_x,grid_y);}}else{/***这里处理产物箱行和列不是一有效阵列指数的非寻常情况。现在,打印该值,**并进入下一个lut表项。*/(void)printf("entry=%dbin=%drow=%d\n",entry,bin,row);}}printf("productintegratedid=%dopmode=%dvcp=%d\n",msg_code,op_mode,vcp);printf("path=%s\n",prod_name);num_included++;tab_included[num_included-1]=site_id;jump_ere;/*这里跳过一产物,并进行到下一站。*/}/***既然将各个站产生处理网格的循环已完成,所以打印包括和不包括的站。*/(void)printf("Sitesprocessingcomplete\n");(void)printf("numberincluded=%d\n",num_included);for(n=0;n<num_included;n++){(void)printf("included=%d\n",tab_included[n]);}(void)printf("numberexcluded=%d\n",num_excluded);for(n=0;n<num_excluded;n++){(void)printf("excluded=%d\n",tab_excluded[n]);}/***产物已被映射成网格。这里建立一嵌拼地图产物。*/prid=5;/***将指针定位在缓冲器的开头处,以便准备将数据赋值给缓冲器。 */st_index=(unsignedshort*)buf;index=st_index+0;/***建立包含输出文件名的串。*/(void)strcpy(prod_name,out_str_home);(void)strcat(prod_name,out_str_site);/***继续建立产物文件名。下面建立以年、月、日、时、分格式表示的实际文件名。**串接文件名,完成产物路径名。*/(void)sprintf(prod_file,"%.2d%.2d%.2d.%.2d%.2d\0",year,month,day,hour,minute);(void)strcat(prod_name,prod_file);/***用下述方式打开写入二进制的产物路径名。*/fpw=fopen(prod_name,"wb");if(fpw==NULL){(void)printf("fopenforwriteerror,errno=%d\n",errno);return(1);}/***定义指定如何建立产物的参数*/number_rows=896;number_bins=1280;scale_x=1;scale_y=1;start_row=0;start_bin=0;output_source_id=10000;lat_origin_deg=phi_center_deg;lon_origin_deg=lamda_center_deg;/***随后开始将数据赋值给产物标题(productheader)。每一字段必须得到一个值,以重写**缓冲器中任一已经存在的数据。*/msg_code=prid;/*Assignthemessagecode*/*index=msg_code;/*它是产物ID。*/index=st_index+1;msg_date=cur_j_ate;/*赋值自1970年1月1日以来以日表示的当前日期。*/*index=msg_date;msg_time=cur_seconds;/*将秒转换成2个半字(halfwords)。*/long2shon.l_value=msg_time;index=st_index+2;msw_msg_time=long2short.s_value;*index=msw_msg_time;/*赋值当前时间(msw)。*/index=st_index+3;lsw_msg_time=long2short.s_value[1];*index=lsw_msg_time;/*赋值当前时间(lsw)。*/msw_msg_len_index=st_index+4;/*存储信息长度*/lsw_msg_len_index=st_index+5;/*的位置。*/index=st_index+6;*index=output_source_id;/*赋值源id。*/index=st_index+7;destination_id=NO_VALUE;*index=destination_id;/*赋值目标id(不用的)。*/index=st_index+8;num_blocks=3;*index=num_blocks;/*赋值块(block)数。*/index=st_index+9;divider=-1;*index=divider;/*赋值块除数(blockdivider)。*/latitude_origin=(long)(lat_origin_deg*1000.);long2short.l_value=latitude_origin;index=st_index+10;msw_latitude=long2short.s_value;*index=mswlatitude;/*赋值原点纬度(msw).*/index=st_index+11;lsw_latitude=long2short.s_value[1];*index=lsw_latitude;/*赋值原点纬度(lsw).*/longitude_origin=(long)(lon_origin_deg*1000.);long2short.l_value=longitude_origin;index=st_index+12;mswlongitude=long2short.s_value;*index=msw_longitude;/*赋值原点经度(msw).*/index=st_index+13;lsw_longitude=long2short.s_value[1];*index=lsw_longitude;/*赋值原点经度(lsw).*/index=st_index+14;height_value=NO_VALUE;*index=height_value;/*赋值高度值(不用的)。*/index=st_index+15;*index=prid;/*赋值产物标记*/index=st_index+16;op_mode=2;*index=op_mode;/*赋值运算方式值*/index=st_index+17;vcp=NO_VALUE;*index=vcp;/*赋值体积覆盖方式*/index=st_index+18;sequence_num=NO_VALUE;*index=sequence_num;/*赋值顺序号(不用的)*/index=st_index+19;scan_num=NO_VALUE;*index=scan_num;/*赋值体积扫描号(不用的)*/index=st_index+20;scan_date=cur_j_date;*index=scan_date;/*赋值扫描日期*/scan_time=cur_seconds;long2short.l_value=scan_time;index=st_index+21;msw_scan_time=long2short.s_value;*index=msw_scan_time;/*赋值扫描时间(msw).*/index=st_index+22;lsw_scan_time=long2short.s_value[1];*index=lsw_scan_time;/*赋值扫描时间(lsw).*/index=st_index+23;generation_date=cur_j_date;*index=generation_date;/*赋值产生日期*/generation_time=cur_seconds;long2short.l_value=generation_time;index=st_index+24;msw_generation_time=long2short.s_value;*index=msw_generation_time;/*赋值产生日期*/*时间(msw).*/index=st_index+25;lsw_generation_time=long2short.s_value[1];*index=lsw_generation_time;/*赋值产生日期*/*时间(lsw).*/index=st_index+26;*index=NOVALUE;/*依赖于产物的(不用的)。*/index=st_index+27;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+28;elevation_num=NO_VALUE;*index=elevation_num;/*赋值上升号(不用的)*/index=st_index+29;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+30;/*存储数据的位置*//***赋值一组恰当的数据级值*/for(dl=MIN_VALUE;dl<NUM_DATA_LEVELS;dl++){*index=data_level_16[dl];index++;}index=st_index+46;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+47;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+48;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+49;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+50;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+51;*index=NO_VALUE;/*依赖于产物的(不用的)*/index=st_index+52;*index=number_bins;/*列(箱)数*/index=sr_index+53;*index=NO_VALUE;/*不用*/index=st_index+54;*index=NO_VALUE;/*偏离符号学(msw)。*/index=st_index+55;*index=60;/*偏离符号学(lsw)。*/index=st_index+56;*index=NO_VALUE;/*偏离图像c(msw)。*/index=st_index+57;*index=NO_VALUE;/*偏离图像(lsw)。*/index=st_index+58;*index=NO_VALUE;/*偏离表格(msw)。*/index=st_index+59;*index=NO_VALUE;/*偏离表格(lsw)。*/index=st_index+60;/*符号块的开头*/divider=-1;*index=divider;/*赋值块除数*/index=st_index+61;sym_block_id=1;*index=sym_block_id;/*赋值符号量块标号*/index=st_index+62;msw_block_len_index=index;/*存储块大小的位置*/index=st_index+63;lsw_block_len_index=index;index=st_index+64;num_layers=1;*index=num_layers;/*赋值层数*/index=st_index+65;*index=divider;/*赋值层除数*/index=st_index+66;msw_layer_len_index=index;/*存储层长度的位置*/index=st_index+67;lsw_layer_len_index=index;index=st_index+68;raster_opcode=0xba07;*index=raster_opcode;/*赋值光栅数据格式Opcode*/index=st_index+69;raster_constl=0x8000;*index=raster_constl;/*赋值光栅数据格式常数*/index=st_index+70;rasterconst2=0x00c0;*index=raster_const2;/*赋值光栅数据格式常数*/index=st_index+71;*index=NO_VALUE;/*赋值用于光栅x原点的位置保持器*/index=st_index+72;*index=NO_VALUE;/*赋值用于光栅y原点的占位符*/index=st_index+73;*index=1;/*赋值比例x(整数部分)*/index=st_index+74;*index=NO_VALUE;/*赋值比例x(小数部分)*/index=st_index+75;*index=1;/*赋值比例y(整数部分)*/index=st_index+76;*index=NO_VALUE;/*赋值比例y(小数部分)*/index=st_index+77;*index=number_rows;/*赋值行数*/index=st_index+78;raster_const3=2;*index=raster_const3;/*赋值分组说明符*/index++;nbytes_index=index;/*存储第一行的“该行的比特数”的位置*/layer_length=22;/***下面的运行长反对。**用下面方法形成通过网格中所有行的循环。*/for(row=MIN_Y;row<number_rows;row++){prev_col=-1;rnn=MIN_VALUE;nbytes=MIN_VALUE;index++;cp=(char*)index;/***Loopthroughallofthebinsinthecurrentrow。*/for(bin=MIN_X;bin<number_bins;bin++){/***在当前箱和行位置处的网格获得取颜色值。屏蔽上面的位,从而只留下4个位颜色值。*/col=grid[bin][row];/***既然已经确定了颜色,所以或者开始一新的“运行”,或者用下述程序更新一现有的“运行”。*/if((prev_col!=-1)&amp;&amp;(col!=prevcol))‖(run==15)){/***当颜色改变时以及当前运行是15(是最大运行值)时,在一行的开头启动新的“运行”**运行/颜色组合赋值到字符指针(CP)位置处的缓冲器。*/byte=(run*16)+prev_col;*(cp)=byte;cp++;nbytes++;run=1;prey_col=col;}else{/***否则,更新现有运行,并进入下一个网格框箱值*/run++;prey_col=col;}}/***字处理了当前中的所有箱时,检查某一值是否处在等存储状态*/if(run>1){/***用下面的方法在输出缓冲器中存储最后“运行颜色”组合。*/byte=(run*16)+prey_col;*(cp)=byte;cp++;nbytes++;}/***如果比特数为奇数,则用一零值填塞另一个比特。*/if(nbytes%2){byte=MIN_VALUE;*(cp)=byte;cp++;nbytes++;}/***将用于该行的比较数赋值到恰当位置处的缓冲器。*/*(nbytes_index)=nbytes;layer_length+=nbytes;/***更新lay_length,以包括用于n比特值的2比特。*/layer_length+=2;/***使指示指针向前,从而它向下一行的比特长度的位置。*/index=(unsignedshort*)cp;nbytes_index=index;}/***既然已经处理了网络中所有的行,所以将层长度值转换成2“半字”,并将这些赋值**到产物符号学层中的层大小位置一个表头。*/long2short.l_value=layer_length;msw_layer_len=long2short.s_value;lsw_layer_len=long2short.s_value[1];*msw_layer_len_index=msw_layer_len;*lsw_layer_len_index=lsw_layer_len;block_length=layer_length+16;/***将块长度值转换成2“半字”,并将这些赋值到产物符号学块表头中的块长度位置处。*/long2short.l_value=block_length;msw_block_len=long2short.s_value;lsw_block_len=long2short.s_value[1];kmsw_block_len_index=msw_block_len;*lsw_block_len_index=lsw_block_len;/***将信息长度值转换成2“半字”,并将这些赋值到产物信息表头块的信息长度位置处。*/total_length=block_length+18+102;message_length=total_ength;long2short.l_value=message_length;msw_msg_len=long2short.s_value;lsw_msg_len=long2short.s_value[1];*msw_msg_len_index=msw_msg_len;*lsw_msg_len_index=lsw_msg_len;/***将产物写到该文件,并关闭文件。nwrite=fwrite(buf,total_length,1,tpw);if(nwrite==NODATA){(void)printf("errorwritingproductfile,errno=%d\n",errno);return(1);}status=fflush(fpw);if(status!=0){(void)printf("errorerrorflushingproductfile,errrno=%d\n",errno);return(1);}status=fclose(fpw);if(status!=0){(void)printf("errorerrorclosingproductfile,errno=%d\n",errno);return(1);}printf("Productiscomplete.\n\n");(void)fflush(stdout);(void)fflush(stderr);}return(0);}/***获得用于请求站的最新版本的请求产物的程序*/intget_latest(shortsite_id,shortprod_id,char*s){/***这里将含有完整路径名称的串传送到该类型的数据库中最新产物,类型产物指定,**并用站标识指定的站。****状态码由程序返回。下面列出了返回值**return=0->productnamefound(OKtoproceed).**return=1->noproductfoundindirectory.**return=2->invalidproductidnumber.**return=3->invalidsiteidnumber.**return=4->popenfailed.*/char*test;charcommand[512];charstring[512];constchar*commandl="/usr/bin/ls-r";constchar*command2="??????.????2>/dev/null/usr/ucb/head-1";constchar*string_home="/home/Products/radar/";FILE*cfd;shortj;/***将第一部分的指定复制到指定串。*/(void)strcpy(command,command1);/***将主查询串串接到指令串。*/(void)strcat(command,string_home);/***用下面的环路搜寻指定的站标号。*/for(j=0;j<NUM_SITE_PATH;j++){if(site_path[j].site_id==site_id){/***找到站标号时,将站名路径串串接到指令串,并接着跳出循环。*/(void)strcat(command,site_path[j].site_text);gotojumpl_here;}}/***仅当找到站标识时执行下面的三个表述。使路径串变零(null)将其复制到输出串,**并用表示没有找到产物的非零值从程度返回。*/string=′\0′;(void)strcpy(s,string),return(2);jump1_here;/*jumptohereandcontinue.*//***下面搜寻用于指定标号的产物标识表。*/for(j=0;j<NUM_PROD_PATH;j++){if(prod_path[j].prod_id==prod_id){/***找到产物时,将产物名路径串串接到指令串,并接着跳出循环。*/(void)strcat(command,prod_path[j].prod_text);gotojump2_here;}}/***仅当找到产物时执行下面的程序,使输出串变零,将其复制到输出,并从表示无效路径**的非零值从程序返回。*/string=′\0′;(void)strcpy(s,string);return(3);jump2_here;/*跳到这里并继续*//***将最后一部分指令串接到指令串的末端。*/(void)strcat(command,command2);/***在“sh”壳下打开管子,并执行指令。结果是返回到由指针“cfd”指示的串。*/cfd=popen(command,"r");if(cfd==NULL){/***这里处理的是popen函数失败的非寻常情况。**用非零状态码打印信息,并返回。*/(void)printf("get_latesterror->cfdisNULLerrno=%d\n",errno);return(4);}/***用下述方式获得串。记值fgets使包括新线字符在结束处的串返回(必须用NUL字符来**替换才能去除)。*/string=′\0′;(void)strcpy(s,string);test=fgets(string,sizeof(string),cfd);pclose(cfd);/***检查串的第一字符是否含零。*/if(string==′\0′){/***这处理的是第一个字符是一个零的串。**其意义是请求的产物没有找到。**零串通过,并且程序以一非零值返回。*/(void)strcpy(s,string);return(1);}/***当该串有效时,用该零字符替换最后的字符(回车(acarriagereturn))。**这确保了只有路径名返回到调用程序(thecallingroutine)。string[strlen(string)-1]=′\0′;/***Copythestringtotheoutputstringwhichispassedtothecalling**routine.Thevalueofzeroisreturnedwithreturnindicating**thatavalidproductwasfound。*/(void)strcpy(s,string);return(0);}]]></pre>本发明的装置和方法在所得的嵌拼地图中将雷达数据箱(或类似的数据)变换成网格位置框,反之不然。如果反向进行,则会丢失一些雷达数据箱。本发明可以用在本质上为地理地或地域的(从最广泛的意义上说)或将多个表面合并成一个嵌拼地图点相关的任何数据,构筑一个嵌拼地图。但是,我们强烈地建议这样的数据是光栅格式。因此,来自不同站的数据可以被组合起来,产生一个单个的嵌拼地图。本发明可以用预先建立的查询表或通过实时执行再投影计算来实施。但是,为了实时光栅操作或更快的响应,最好采用查询表。本发明的许多优点中的一些优点现在应当很清楚了。例如,提供的装置和方法可以用来将来自多个源的数据组所得一个或多个嵌拼地图,使得适用于终端用户的使用。这种装置和方法能够准确和有效地构造这样的嵌拼地图。同时,可以识别这样一种嵌拼地图中任何孔的位置。本发明还提供用来填充这样的孔。因此,提供的装置和方法用来将来自多个站的数据组合到覆盖所要求的地理区域的单个图象内。这样的装置和方法能够实时将来自多个雷达站的以数字格式的雷达数据(如气象雷达数据)或其他数据组合到覆盖某一地理区域的嵌拼地图内。这样的装置和方法进一步能够将来自多个源的数据组合到在通用计算机(如个人计算机)上运行的单个图象内。这样的装置和方法能够产生气象雷达数据的嵌拼地图,它能够在大地理范围内提供降雨的地点和强度以及其他的地理现象。当采用查询表时,本发明能够准确地将来自多个想要的站的大量数据快速地组合起来,以提供气象或其他现象的当前描述。很明显,考虑到上述原理,本发明还可以有许多修改和变异。所以,应当理解,上述实施例仅是举例,它们均包括在权利要求的保护范围内,本发明的保护范围以权利要求书为准。权利要求1.一种将具有第一坐标系统的第一组数据插入到具有可能与第一坐标系统不同的第二坐标系统的数据嵌拼地图中去的方法,其特征在于,它包含将第一组数据的一个项的位置转换成第一坐标系统中与第一参考点相隔的第一距离;将所述第一距离转换成第三坐标系统中的位置,其中,在所述第三坐标系统中第一参考点的位置是已知的;将所述第三坐标系统中的位置转换成与第二坐标系统中的与第二参考点相隔的第二距离,其中,在所述第三坐标系统中第二参考点的位置是已知的;将所述第二距离转换成第二坐标系统中的位置。2.一种将具有第一坐标系统的第一组数据插入到具有可能与第一坐标系统不同的第二坐标系统的数据嵌拼地图中去的方法,其特征在于,它包含形成用于第一组数据的具有多个表项的表,每一这样的表项在具有任何一个第一组数据的第一坐标系统中具有一个位置,并且在第二坐标系统中的每一位置对应于第一坐标系统中的位置,所述形成步骤包含下述步骤将所述第一组数据中的一个项的位置转换成与所述第一坐标系统中的第一参考点相隔的第一距离;将所述第一距离转换成第三坐标系统中的位置,其中,在所述第三坐标系统中的第一参考点的位置是已知的;将所述第三坐标系统中的位置转换成与所述第二坐标系统中的第二参考点相隔的第二距离,其中,在所述第三坐标系统中第二参考点的位置是已知的;将所述第二距离转换成所述第二坐标系统中的位置;以及在所述形成步骤以后,用所述表,将具有至少某些第一组数据的第一坐标系统中的多个位置中的每一个转换成所述第二坐标系统中的一个或多个位置。3.一种将具有第一坐标系统的第一组数据插入到具有可能与第一坐标系统不同的第二坐标系统的数据嵌拼地图中去的方法,其特征在于,它包含将所述第一坐标系统中第一组数据的第一位置转换成所述第二坐标系统中第二相应位置;在所述第二坐标系统中定义第一值的数据阵列,所述阵列包括所有的第二位置;将所述数据阵列的每一个第一子阵列的值从所述第一值变换成一第二值,所述子阵列由所述第二坐标系统中的所有位置组成,所述第二坐标系统中的所有子阵列可以映射成所述第一坐标系统中的任何一个位置;将所述数据阵列中每一个第二位置的值从所述第二值变换成一第三值;对于具有所述第二值的阵列中的位置,判定在位置上最靠近所述对于位置中相应的一个位置;以及在与具有所述第二值的阵列中的位置相应的所述第二坐标系统的位置中,插入在位置上最靠近所述第一位置的相应的一个位置的值。4.一种将具有第一坐标系统的第一组数据插入到可能与所述第一坐标系统不同的第二坐标系统的数据嵌拼地图中去的装置,其特征在于,它包含将所述第一组数据的一个项的位置转换成与所述第一坐标系统中的第一参考点相隔的第一距离的装置;将所述第一距离转换成第三坐标系统中的位置,其中,在所述第三坐标系统中第一参考点的位置是已知的;将所述第三坐标系统中的位置转换成与所述第二坐标系统中的参考点相隔一第二距离的装置,其中,在所述第三坐标系统中的点所述第二参考点的位置是已知的;以及将所述第二距离转换成第二坐标系统中的位置的装置。5.一种将具有第一坐标系统的第一组数据插入到具有可能与第一坐标系统不同的第二坐标系统的数据嵌拼地图中去的装置,其特征在于,它包含形成用于第一组数据的具有多个表项的表的装置,每一这样的表项在具有任何一个第一组数据的第一坐标系统中具有一个位置,并且在第二坐标系统中的每一位置对应于第一坐标系统中的位置,所述用于形成的装置包含将所述第一组数据中的一个项的位置转换成与所述第一坐标系统中的第一参考点相隔的第一距离的装置;将所述第一距离转换成第三坐标系统中的位置的装置,其中,在所述第三坐标系统中的第一参考点的位置是已知的;将所述第三坐标系统中的位置转换成与所述第二坐标系统中的第二参考点相隔的第二距离的装置,其中,在所述第三坐标系统中第二参考点的位置是已知的;将所述第二距离转换成所述第二坐标系统中的位置的装置;以及在所述形成步骤以后,用所述表,将具有至少某些第一组数据的第一坐标系统中的多个位置中的每一个转换成所述第二坐标系统中的一个或多个位置的装置。6.一种将具有第一坐标系统的第一组数据插入到具有可能与第一坐标系统不同的第二坐标系统的数据嵌拼地图中去的装置,其特征在于,它包含将所述第一坐标系统中第一组数据的第一位置转换成所述第二坐标系统中第二相应位置的装置;在所述第二坐标系统中定义第一值的数据阵列的装置,所述阵列包括所有的第二位置;将所述数据阵列的每一个第一子阵列的值从所述第一值变换成一第二值的装置,所述子阵列由所述第二坐标系统中的所有位置组成,所述第二坐标系统中的所有子阵列可以映射成所述第一坐标系统中的任何一个位置;将所述数据阵列中每一个第二位置的值从所述第二值变换成一第三值的装置;对于具有所述第二值的阵列中的位置,判定在位置上最靠近所述对于位置中相应的一个位置的装置;以及在与具有所述第二值的阵列中的位置相应的所述第二坐标系统的位置中,插入在位置上最靠近所述第一位置的相应的一个位置的值的装置。全文摘要一种用来实时将数字格式的来自多个雷达站的气象雷达数据组所得覆盖某一地区或国家范围(例如美国本土)的嵌拼地图的装置和方法。这种装置和方法设计得可以用计算机软件来实施并可在一通用个人计算机上运行。这种装置和方法最好采用“查询表”的数据库,该查询表用来将各个雷达数据箱直接投影到嵌拼地图所要求的坐标系统的网格上。采用这些查询表,将多个雷达数据箱中的每一个转换成相应的网格位置或嵌拼地象中的框。在每一个雷达数据箱被映射成用于嵌拼地图的网格框时,并不是雷达覆盖区内的每一个这样的网格框都可以接收这样的数据箱。接着,用另一个网格来识别产生的嵌拼地图中造成的孔,该另一个网格的位置对应于嵌拼地图的网格的位置,但它提供了随后出现在该嵌拼地图的相应位置有关数据的信息。每一个这样的孔接着由在位置上最靠近数据箱的数据填充。文档编号G06T1/00GK1190480SQ95197234公开日1998年8月12日申请日期1995年11月3日优先权日1994年11月4日发明者马克·J·罗更申请人:洛克系德·马丁有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1