[Bio] / Sprout / SearchHelper.pm Repository:
ViewVC logotype

Diff of /Sprout/SearchHelper.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4, Mon Oct 2 03:15:37 2006 UTC revision 1.12, Mon Oct 16 22:58:37 2006 UTC
# Line 214  Line 214 
214                      }                      }
215                  }                  }
216              }              }
         }  
217          # Close the session file.          # Close the session file.
218          $self->CloseSession();          $self->CloseSession();
219            }
220          # Return the result count.          # Return the result count.
221          return $retVal;          return $retVal;
222      }      }
# Line 316  Line 316 
316      return $self->{query};      return $self->{query};
317  }  }
318    
319    
320    
321  =head3 DB  =head3 DB
322    
323  C<< my $sprout = $shelp->DB(); >>  C<< my $sprout = $shelp->DB(); >>
# Line 607  Line 609 
609    
610  =head3 PutFeature  =head3 PutFeature
611    
612  C<< $shelp->PutFeature($fquery); >>  C<< $shelp->PutFeature($fdata); >>
613    
614  Store a feature in the result cache. This is the workhorse method for most  Store a feature in the result cache. This is the workhorse method for most
615  searches, since the primary data item in the database is features.  searches, since the primary data item in the database is features.
# Line 618  Line 620 
620  the feature query object using the B<AddExtraColumns> method. For example, the following  the feature query object using the B<AddExtraColumns> method. For example, the following
621  code adds columns for essentiality and virulence.  code adds columns for essentiality and virulence.
622    
623      $fq->AddExtraColumns(essential => $essentialFlag, virulence => $vfactor);      $fd->AddExtraColumns(essential => $essentialFlag, virulence => $vfactor);
624      $shelp->PutFeature($fq);      $shelp->PutFeature($fd);
625    
626  For correct results, all values should be specified for all extra columns in all calls to  For correct results, all values should be specified for all extra columns in all calls to
627  B<PutFeature>. (In particular, the column header names are computed on the first  B<PutFeature>. (In particular, the column header names are computed on the first
# Line 629  Line 631 
631      if (! $essentialFlag) {      if (! $essentialFlag) {
632          $essentialFlag = undef;          $essentialFlag = undef;
633      }      }
634      $fq->AddExtraColumns(essential => $essentialFlag, virulence => $vfactor);      $fd->AddExtraColumns(essential => $essentialFlag, virulence => $vfactor);
635      $shelp->PutFeature($fq);      $shelp->PutFeature($fd);
636    
637  =over 4  =over 4
638    
639  =item fquery  =item fdata
640    
641  FeatureQuery object containing the current feature data.  B<FeatureData> object containing the current feature data.
642    
643  =back  =back
644    
# Line 644  Line 646 
646    
647  sub PutFeature {  sub PutFeature {
648      # Get the parameters.      # Get the parameters.
649      my ($self, $fq) = @_;      my ($self, $fd) = @_;
650      # Get the CGI query object.      # Get the CGI query object.
651      my $cgi = $self->Q();      my $cgi = $self->Q();
652      # Get the feature data.      # Get the feature data.
653      my $record = $fq->Feature();      my $record = $fd->Feature();
654      my $extraCols = $fq->ExtraCols();      my $extraCols = $fd->ExtraCols();
655      # Check for a first-call situation.      # Check for a first-call situation.
656      if (! defined $self->{cols}) {      if (! defined $self->{cols}) {
657          # Here we need to set up the column information. Start with the defaults.          # Here we need to set up the column information. Start with the defaults.
658          $self->{cols} = $self->DefaultFeatureColumns();          $self->{cols} = $self->DefaultFeatureColumns();
659          # Add the externals if they were requested.          # Add any additional columns requested by the feature filter.
660          if ($cgi->param('ShowAliases')) {          push @{$self->{cols}}, FeatureQuery::AdditionalColumns($self);
             push @{$self->{cols}}, 'alias';  
         }  
661          # Append the extras, sorted by column name.          # Append the extras, sorted by column name.
662          for my $col (sort keys %{$extraCols}) {          for my $col (sort keys %{$extraCols}) {
663              push @{$self->{cols}}, "X=$col";              push @{$self->{cols}}, "X=$col";
# Line 667  Line 667 
667          $self->WriteColumnHeaders(map { $self->FeatureColumnTitle($_) } @{$self->{cols}});          $self->WriteColumnHeaders(map { $self->FeatureColumnTitle($_) } @{$self->{cols}});
668      }      }
669      # Get the feature ID.      # Get the feature ID.
670      my ($fid) = $record->Value('Feature(id)');      my $fid = $fd->FID();
671      # Loop through the column headers, producing the desired data.      # Loop through the column headers, producing the desired data.
672      my @output = ();      my @output = ();
673      for my $colName (@{$self->{cols}}) {      for my $colName (@{$self->{cols}}) {
674          push @output, $self->FeatureColumnValue($colName, $record, $extraCols);          push @output, $self->FeatureColumnValue($colName, $record, $extraCols);
675      }      }
676      # Compute the sort key. The sort key floats NMPDR organism features to the      # Compute the sort key. The sort key usually floats NMPDR organism features to the
677      # top of the return list.      # top of the return list.
678      my $key = $self->SortKey($record);      my $key = $self->SortKey($fd);
679      # Write the feature data.      # Write the feature data.
680      $self->WriteColumnData($key, @output);      $self->WriteColumnData($key, @output);
681  }  }
# Line 756  Line 756 
756      # Check for an open session file.      # Check for an open session file.
757      if (defined $self->{fileHandle}) {      if (defined $self->{fileHandle}) {
758          # We found one, so close it.          # We found one, so close it.
759            Trace("Closing session file.") if T(2);
760          close $self->{fileHandle};          close $self->{fileHandle};
761      }      }
762  }  }
# Line 823  Line 824 
824                                                      ['Genome(genus)', 'Genome(species)',                                                      ['Genome(genus)', 'Genome(species)',
825                                                       'Genome(unique-characterization)',                                                       'Genome(unique-characterization)',
826                                                       'Genome(primary-group)']);                                                       'Genome(primary-group)']);
827          # Null out the supporting group.          # Format and cache the name and display group.
828          $group = "" if ($group eq $FIG_Config::otherGroup);          ($orgName, $group) = $self->SaveOrganismData($group, $genomeID, $genus, $species,
829          # If the organism does not exist, format an unknown name.                                                              $strain);
         if (! defined($genus)) {  
             $orgName = "Unknown Genome $genomeID";  
         } else {  
             # It does exist, so format the organism name.  
             $orgName = "$genus $species";  
             if ($strain) {  
                 $orgName .= " $strain";  
             }  
         }  
         # Save this organism in the cache.  
         $cache->{$genomeID} = [$orgName, $group];  
830      }      }
831      # Return the result.      # Return the result.
832      return ($orgName, $group);      return ($orgName, $group);
# Line 987  Line 977 
977      my ($self, $incomingType, $desiredType, $sequence) = @_;      my ($self, $incomingType, $desiredType, $sequence) = @_;
978      # Declare the return variable. If an error occurs, it will remain undefined.      # Declare the return variable. If an error occurs, it will remain undefined.
979      my $retVal;      my $retVal;
980        # This variable will be cleared if an error is detected.
981        my $okFlag = 1;
982      # Create variables to hold the FASTA label and data.      # Create variables to hold the FASTA label and data.
983      my ($fastaLabel, $fastaData);      my ($fastaLabel, $fastaData);
984        Trace("FASTA incoming type is $incomingType, desired type is $desiredType.") if T(4);
985      # Check for a feature specification.      # Check for a feature specification.
986      if ($sequence =~ /^\s*(\w+\|\S+)\s*$/) {      if ($sequence =~ /^\s*(\w+\|\S+)\s*$/) {
987          # Here we have a feature ID in $1. We'll need the Sprout object to process          # Here we have a feature ID in $1. We'll need the Sprout object to process
988          # it.          # it.
989          my $fid = $1;          my $fid = $1;
990            Trace("Feature ID for fasta is $fid.") if T(3);
991          my $sprout = $self->DB();          my $sprout = $self->DB();
992          # Get the FIG ID. Note that we only use the first feature found. We are not          # Get the FIG ID. Note that we only use the first feature found. We are not
993          # supposed to have redundant aliases, though we may have an ID that doesn't          # supposed to have redundant aliases, though we may have an ID that doesn't
# Line 1001  Line 995 
995          my ($figID) = $sprout->FeaturesByAlias($fid);          my ($figID) = $sprout->FeaturesByAlias($fid);
996          if (! $figID) {          if (! $figID) {
997              $self->SetMessage("No feature found with the ID \"$fid\".");              $self->SetMessage("No feature found with the ID \"$fid\".");
998                $okFlag = 0;
999          } else {          } else {
1000              # Set the FASTA label.              # Set the FASTA label.
1001              my $fastaLabel = $fid;              my $fastaLabel = $fid;
1002              # Now proceed according to the sequence type.              # Now proceed according to the sequence type.
1003              if ($desiredType =~ /prot/i) {              if ($desiredType eq 'prot') {
1004                  # We want protein, so get the translation.                  # We want protein, so get the translation.
1005                  $fastaData = $sprout->FeatureTranslation($figID);                  $fastaData = $sprout->FeatureTranslation($figID);
1006                    Trace(length $fastaData . " characters returned for translation of $fastaLabel.") if T(3);
1007              } else {              } else {
1008                  # We want DNA, so get the DNA sequence. This is a two-step process.                  # We want DNA, so get the DNA sequence. This is a two-step process.
1009                  my @locList = $sprout->FeatureLocation($figID);                  my @locList = $sprout->FeatureLocation($figID);
1010                  $fastaData = $sprout->DNASeq(\@locList);                  $fastaData = $sprout->DNASeq(\@locList);
1011                    Trace(length $fastaData . " characters returned for DNA of $fastaLabel.") if T(3);
1012              }              }
1013          }          }
1014      } elsif ($incomingType =~ /prot/ && $desiredType =~ /dna/) {      } elsif ($incomingType eq 'prot' && $desiredType eq 'dna') {
1015          # Here we're being asked to do an impossible conversion.          # Here we're being asked to do an impossible conversion.
1016          $self->SetMessage("Cannot convert a protein sequence to DNA.");          $self->SetMessage("Cannot convert a protein sequence to DNA.");
1017            $okFlag = 0;
1018      } else {      } else {
1019            Trace("Analyzing FASTA sequence.") if T(4);
1020          # Here we are expecting a FASTA. We need to see if there's a label.          # Here we are expecting a FASTA. We need to see if there's a label.
1021          if ($sequence =~ /^>\s*(\S.*)\s*\n(.+)$/) {          if ($sequence =~ /^>[\n\s]*(\S[^\n]*)\n(.+)$/s) {
1022                Trace("Label \"$1\" found in match to sequence:\n$sequence") if T(4);
1023              # Here we have a label, so we split it from the data.              # Here we have a label, so we split it from the data.
1024              $fastaLabel = $1;              $fastaLabel = $1;
1025              $fastaData = $2;              $fastaData = $2;
1026          } else {          } else {
1027                Trace("No label found in match to sequence:\n$sequence") if T(4);
1028              # Here we have no label, so we create one and use the entire sequence              # Here we have no label, so we create one and use the entire sequence
1029              # as data.              # as data.
1030              $fastaLabel = "User-specified $incomingType sequence";              $fastaLabel = "User-specified $incomingType sequence";
# Line 1036  Line 1037 
1037          # we've already prevented a conversion from protein to DNA.          # we've already prevented a conversion from protein to DNA.
1038          if ($incomingType ne $desiredType) {          if ($incomingType ne $desiredType) {
1039              $fastaData = Sprout::Protein($fastaData);              $fastaData = Sprout::Protein($fastaData);
1040                # Check for bad characters.
1041                if ($fastaData =~ /X/) {
1042                    $self->SetMessage("Invalid characters detected. Is the input really of type $incomingType?");
1043                    $okFlag = 0;
1044                }
1045            } elsif ($desiredType eq 'dna' && $fastaData =~ /[^agct]/i) {
1046                $self->SetMessage("Invaid characters detected. Is the input really a DNA sequence?");
1047                $okFlag = 0;
1048          }          }
1049      }      }
1050      # At this point, either "$fastaLabel" and "$fastaData" have values or an error is      Trace("FASTA data sequence: $fastaData") if T(4);
1051      # in progress.      # Only proceed if no error was detected.
1052      if (defined $fastaLabel) {      if ($okFlag) {
1053          # We need to format the sequence into 60-byte chunks. We use the infamous          # We need to format the sequence into 60-byte chunks. We use the infamous
1054          # grep-split trick. The split, because of the presence of the parentheses,          # grep-split trick. The split, because of the presence of the parentheses,
1055          # includes the matched delimiters in the output list. The grep strips out          # includes the matched delimiters in the output list. The grep strips out
1056          # the empty list items that appear between the so-called delimiters, since          # the empty list items that appear between the so-called delimiters, since
1057          # the delimiters are what we want.          # the delimiters are what we want.
1058          my @chunks = grep { $_ } split /(.{1,60})/, $fastaData;          my @chunks = grep { $_ } split /(.{1,60})/, $fastaData;
1059          my $retVal = join("\n", ">$fastaLabel", @chunks, "");          $retVal = join("\n", ">$fastaLabel", @chunks, "");
1060      }      }
1061      # Return the result.      # Return the result.
1062      return $retVal;      return $retVal;
# Line 1082  Line 1091 
1091  Number of rows to display. If omitted, the default is 1 for a single-select list  Number of rows to display. If omitted, the default is 1 for a single-select list
1092  and 10 for a multi-select list.  and 10 for a multi-select list.
1093    
1094    =item crossMenu (optional)
1095    
1096    If specified, is presumed to be the name of another genome menu whose contents
1097    are to be mutually exclusive with the contents of this menu. As a result, instead
1098    of the standard onChange event, the onChange event will deselect any entries in
1099    the other menu.
1100    
1101  =item RETURN  =item RETURN
1102    
1103  Returns the HTML text to generate a C<SELECT> menu inside a form.  Returns the HTML text to generate a C<SELECT> menu inside a form.
# Line 1092  Line 1108 
1108    
1109  sub NmpdrGenomeMenu {  sub NmpdrGenomeMenu {
1110      # Get the parameters.      # Get the parameters.
1111      my ($self, $menuName, $multiple, $selected, $rows) = @_;      my ($self, $menuName, $multiple, $selected, $rows, $cross) = @_;
1112      # Get the Sprout and CGI objects.      # Get the Sprout and CGI objects.
1113      my $sprout = $self->DB();      my $sprout = $self->DB();
1114      my $cgi = $self->Q();      my $cgi = $self->Q();
# Line 1126  Line 1142 
1142          for my $genome (@genomeList) {          for my $genome (@genomeList) {
1143              # Get the genome data.              # Get the genome data.
1144              my ($group, $genomeID, $genus, $species, $strain) = @{$genome};              my ($group, $genomeID, $genus, $species, $strain) = @{$genome};
1145              # Form the genome name.              # Compute and cache its name and display group.
1146              my $name = "$genus $species";              my ($name, $displayGroup) = $self->SaveOrganismData($group, $genomeID, $genus, $species,
1147              if ($strain) {                                                                  $strain);
1148                  $name .= " $strain";              # Push the genome into the group's list. Note that we use the real group
1149              }              # name here, not the display group name.
             # Push the genome into the group's list.  
1150              push @{$gHash{$group}}, [$genomeID, $name];              push @{$gHash{$group}}, [$genomeID, $name];
1151          }          }
1152          # Save the genome list for future use.          # Save the genome list for future use.
# Line 1157  Line 1172 
1172      my $showSelect = "showSelected($menuName, '$divID', 1000);";      my $showSelect = "showSelected($menuName, '$divID', 1000);";
1173      # If multiple selection is supported, create an onChange event.      # If multiple selection is supported, create an onChange event.
1174      my $onChange = "";      my $onChange = "";
1175      if ($multiple) {      if ($cross) {
1176            $onChange = " onChange=\"crossUnSelect($menuName, '$divID', $cross, '${formName}_${cross}_status', 1000)\"";
1177        } elsif ($multiple) {
1178          $onChange = " onChange=\"$showSelect\"";          $onChange = " onChange=\"$showSelect\"";
1179      }      }
1180      # Create the SELECT tag and stuff it into the output array.      # Create the SELECT tag and stuff it into the output array.
# Line 1338  Line 1355 
1355      # Create the row.      # Create the row.
1356      my $retVal = $cgi->Tr($cgi->td("Results/Page"),      my $retVal = $cgi->Tr($cgi->td("Results/Page"),
1357                            $cgi->td($cgi->popup_menu(-name => 'PageSize',                            $cgi->td($cgi->popup_menu(-name => 'PageSize',
1358                                                      -values => [10, 25, 45, 100, 1000],                                                      -values => [10, 25, 50, 100, 1000],
1359                                                      -default => $pageSize) . " " .                                                      -default => $pageSize) . " " .
1360                                     $cgi->checkbox(-name => 'ShowURL',                                     $cgi->checkbox(-name => 'ShowURL',
1361                                                    -value => 1,                                                    -value => 1,
# Line 1354  Line 1371 
1371    
1372  C<< my $htmlText = $shelp->FeatureFilterRows(); >>  C<< my $htmlText = $shelp->FeatureFilterRows(); >>
1373    
1374  This method creates table rows that can be used to filter features. There are  This method creates table rows that can be used to filter features. The form
1375  two rows returned, and the values can be used to select features by genome  values can be used to select features by genome using the B<FeatureQuery>
1376  using the B<FeatureQuery> object.  object.
1377    
1378  =cut  =cut
1379    
# Line 1406  Line 1423 
1423          # Get the feature location string.          # Get the feature location string.
1424          my $loc = $sprout->FeatureLocation($feat);          my $loc = $sprout->FeatureLocation($feat);
1425          # Compute the contig, start, and stop points.          # Compute the contig, start, and stop points.
1426          my($start, $stop, $contig) = BasicLocation::Parse($loc);          my($contig, $start, $stop) = BasicLocation::Parse($loc);
1427            Trace("Start and stop are ($start,$stop) on contig $contig.") if T(3);
1428          # Now we need to do some goofiness to insure that the location is not too          # Now we need to do some goofiness to insure that the location is not too
1429          # big and that we get some surrounding stuff.          # big and that we get some surrounding stuff.
1430          my $mid = int(($start + $stop) / 2);          my $mid = int(($start + $stop) / 2);
# Line 1436  Line 1454 
1454          }          }
1455          my $seg_id = $contig;          my $seg_id = $contig;
1456          $seg_id =~ s/:/--/g;          $seg_id =~ s/:/--/g;
1457            Trace("Show limits are ($show_start,$show_stop) in genome $genomeID with ref $seg_id.") if T(3);
1458          # Assemble all the pieces.          # Assemble all the pieces.
1459          $retVal = "gbrowse.cgi/GB_$genomeID?ref=$seg_id&start=$show_start&stop=$show_stop";          $retVal = "gbrowse.cgi/GB_$genomeID?ref=$seg_id&start=$show_start&stop=$show_stop";
1460      }      }
# Line 1571  Line 1590 
1590          # a singleton list, but that's okay.          # a singleton list, but that's okay.
1591          my @values = split (/\0/, $parms{$parmKey});          my @values = split (/\0/, $parms{$parmKey});
1592          # Check for special cases.          # Check for special cases.
1593          if ($parmKey eq 'featureTypes') {          if (grep { $_ eq $parmKey } qw(SessionID ResultCount Page PageSize Trace TF ShowURL)) {
             # Here we need to see if the user wants all the feature types. If he  
             # does, we erase all the values so that the parameter is not output.  
             my %valueCheck = map { $_ => 1 } @values;  
             my @list = FeatureQuery::AllFeatureTypes();  
             my $okFlag = 1;  
             for (my $i = 0; $okFlag && $i <= $#list; $i++) {  
                 if (! $valueCheck{$list[$i]}) {  
                     $okFlag = 0;  
                 }  
             }  
             if ($okFlag) {  
                 @values = ();  
             }  
         } elsif (grep { $_ eq $parmKey } qw(SessionID ResultCount Page PageSize Trace TF ShowURL)) {  
1594              # These are bookkeeping parameters we don't need to start a search.              # These are bookkeeping parameters we don't need to start a search.
1595              @values = ();              @values = ();
1596          } elsif ($parmKey =~ /_SearchThing$/) {          } elsif ($parmKey =~ /_SearchThing$/) {
# Line 1647  Line 1652 
1652      return $retVal;      return $retVal;
1653  }  }
1654    
1655    =head3 AdvancedClassList
1656    
1657    C<< my @classes = SearchHelper::AdvancedClassList(); >>
1658    
1659    Return a list of advanced class names. This list is used to generate the directory
1660    of available searches on the search page.
1661    
1662    The reason we have to convert the list from a string is that the B<NMPDRSetup.pl>
1663    script is only able to insert strings into the generated B<FIG_Config> file.
1664    
1665    =cut
1666    
1667    sub AdvancedClassList {
1668        return split /\s+/, $FIG_Config::advanced_classes;
1669    }
1670    
1671  =head2 Feature Column Methods  =head2 Feature Column Methods
1672    
1673  The methods in this column manage feature column data. If you want to provide the  The methods in this column manage feature column data. If you want to provide the
# Line 1874  Line 1895 
1895      return $retVal;      return $retVal;
1896  }  }
1897    
1898    =head3 SaveOrganismData
1899    
1900    C<< my ($name, $displayGroup) = $shelp->SaveOrganismData($group, $genomeID, $genus, $species, $strain); >>
1901    
1902    Format the name of an organism and the display version of its group name. The incoming
1903    data should be the relevant fields from the B<Genome> record in the database. The
1904    data will also be stored in the genome cache for later use in posting search results.
1905    
1906    =over 4
1907    
1908    =item group
1909    
1910    Name of the genome's group as it appears in the database.
1911    
1912    =item genomeID
1913    
1914    ID of the relevant genome.
1915    
1916    =item genus
1917    
1918    Genus of the genome's organism. If undefined or null, it will be assumed the genome is not
1919    in the database. In this case, the organism name is derived from the genomeID and the group
1920    is automatically the supporting-genomes group.
1921    
1922    =item species
1923    
1924    Species of the genome's organism.
1925    
1926    =item strain
1927    
1928    Strain of the species represented by the genome.
1929    
1930    =item RETURN
1931    
1932    Returns a two-element list. The first element is the formatted genome name. The second
1933    element is the display name of the genome's group.
1934    
1935    =back
1936    
1937    =cut
1938    
1939    sub SaveOrganismData {
1940        # Get the parameters.
1941        my ($self, $group, $genomeID, $genus, $species, $strain) = @_;
1942        # Declare the return values.
1943        my ($name, $displayGroup);
1944        # If the organism does not exist, format an unknown name and a blank group.
1945        if (! defined($genus)) {
1946            $name = "Unknown Genome $genomeID";
1947            $displayGroup = "";
1948        } else {
1949            # It does exist, so format the organism name.
1950            $name = "$genus $species";
1951            if ($strain) {
1952                $name .= " $strain";
1953            }
1954            # Compute the display group. This is currently the same as the incoming group
1955            # name unless it's the supporting group, which is nulled out.
1956            $displayGroup = ($group eq $FIG_Config::otherGroup ? "" : $group);
1957        }
1958        # Cache the group and organism data.
1959        my $cache = $self->{orgs};
1960        $cache->{$genomeID} = [$name, $displayGroup];
1961        # Return the result.
1962        return ($name, $displayGroup);
1963    }
1964    
1965  =head2 Virtual Methods  =head2 Virtual Methods
1966    
1967  =head3 Form  =head3 Form
# Line 1901  Line 1989 
1989    
1990  =head3 SortKey  =head3 SortKey
1991    
1992  C<< my $key = $shelp->SortKey($record); >>  C<< my $key = $shelp->SortKey($fdata); >>
1993    
1994  Return the sort key for the specified record. The default is to sort by feature name,  Return the sort key for the specified feature data. The default is to sort by feature name,
1995  floating NMPDR organisms to the top. This sort may be overridden by the search class  floating NMPDR organisms to the top. If a full-text search is used, then the default
1996  to provide fancier functionality. This method is called by B<PutFeature>, so it  sort is by relevance followed by feature name. This sort may be overridden by the
1997  is only used for feature searches. A non-feature search would presumably have its  search class to provide fancier functionality. This method is called by
1998  own sort logic.  B<PutFeature>, so it is only used for feature searches. A non-feature search
1999    would presumably have its own sort logic.
2000    
2001  =over 4  =over 4
2002    
2003  =item record  =item record
2004    
2005  The C<DBObject> from which the current row of data is derived.  The C<FeatureData> containing the current feature.
2006    
2007  =item RETURN  =item RETURN
2008    
# Line 1925  Line 2014 
2014    
2015  sub SortKey {  sub SortKey {
2016      # Get the parameters.      # Get the parameters.
2017      my ($self, $record) = @_;      my ($self, $fdata) = @_;
2018      # Get the feature ID from the record.      # Get the feature ID from the record.
2019      my ($fid) = $record->Value('Feature(id)');      my $fid = $fdata->FID();
2020      # Get the group from the feature ID.      # Get the group from the feature ID.
2021      my $group = $self->FeatureGroup($fid);      my $group = $self->FeatureGroup($fid);
2022      # Ask the feature query object to form the sort key.      # Ask the feature query object to form the sort key.
2023      my $retVal = FeatureQuery::SortKey($self, $group, $record);      my $retVal = $fdata->SortKey($self, $group);
2024      # Return the result.      # Return the result.
2025      return $retVal;      return $retVal;
2026  }  }
2027    
2028  1;  1;

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.12

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3