bes  Updated for version 3.20.6
DilateArrayFunction.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2015 OPeNDAP, Inc.
7 // Authors:
8 // James Gallagher <jgallagher@opendap.org>
9 // Dan Holloway <dholloway@opendap.org>
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26 
27 #include "config.h"
28 
29 #include <cassert>
30 
31 #include <sstream>
32 #include <vector>
33 
34 #include <Type.h>
35 #include <BaseType.h>
36 #include <Byte.h>
37 #include <Int16.h>
38 #include <UInt16.h>
39 #include <Int32.h>
40 #include <UInt32.h>
41 #include <Float32.h>
42 #include <Float64.h>
43 #include <Str.h>
44 #include <Url.h>
45 #include <Array.h>
46 #include <Error.h>
47 #include <DDS.h>
48 
49 #include <DMR.h>
50 #include <D4Group.h>
51 #include <D4RValue.h>
52 
53 #include <debug.h>
54 #include <util.h>
55 
56 #include <BaseTypeFactory.h>
57 
58 #include <BESDebug.h>
59 
60 #include "DilateArrayFunction.h"
61 #include "functions_util.h"
62 
63 using namespace libdap;
64 
65 namespace functions {
66 
67 string dilate_array_info =
68  string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
69  + "<function name=\"dilate_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#dilate_array\">\n"
70  + "</function>";
71 
83 void function_dilate_dap2_array(int argc, BaseType * argv[], DDS &/*dds*/, BaseType **btpp)
84 {
85  if (argc == 0) {
86  Str *response = new Str("info");
87  response->set_value(dilate_array_info);
88  *btpp = response;
89  return;
90  }
91 
92  BESDEBUG("functions", "function_dilate_dap2_array() - argc: " << argc << endl);
93 
94  BaseType *btp = argv[0];
95 
96  if (btp->type() != dods_array_c)
97  throw Error(malformed_expr, "dilate_array(): first argument must point to a Array variable.");
98 
99  Array *mask = static_cast<Array*>(btp);
100  if (mask->var()->type() != dods_byte_c && mask->dimensions() == 2)
101  throw Error(malformed_expr, "dilate_array(): first argument must point to a Two dimensional Byte Array variable.");
102 
103  // OK, we've got a valid 2D mask, now get the bytes into a vector.
104  vector<dods_byte> mask_values(mask->length());
105  mask->value(&mask_values[0]);
106 
107  // Now make a vector<> for the result; I'm not sure if we really need this... jhrg 5/26/15
108  vector<dods_byte> dest_values(mask->length());
109 
110  // read argv[1], the number of dilation operations (size of the 'hot-dog') to perform.
111  if (!is_integer_type(argv[1]->type()))
112  throw Error(malformed_expr, "dilate_array(): Expected an integer for the second argument.");
113 
114  unsigned int dSize = extract_uint_value(argv[1]);
115 
116  Array::Dim_iter itr = mask->dim_begin();
117  int maxI = mask->dimension_size(itr++);
118  int maxJ = mask->dimension_size(itr);
119 
120  // Dilate each mask location 'dSize' elements around it.
121  // NB: currently not handling mask edge.
122  for (unsigned int i=dSize; i<maxI-dSize; i++) {
123  for (unsigned int j=dSize; j<maxJ-dSize; j++ ) {
124  int mask_offset = j + i * maxI;
125  if ( mask_values.at(mask_offset) /*mask[i][j]*/ == 1 ) {
126  // I think this could be modified to handle the edge case by expanding the
127  // ranges above to be the whole image and then using max() and min() in the
128  // initialization and loop tests below. Not sure though. jhrg 5/16/15
129  for (unsigned int x=i-dSize; x<=i+dSize; x++) {
130  for (unsigned int y=j-dSize; y<=j+dSize; y++) {
131  int dest_offset = y + x * maxI;
132  dest_values.at(dest_offset) = 1; //dest.value[x][y] = 1;
133  }
134  }
135  }
136  }
137  }
138 
139  // Create the 'dilated' array using the shape of the input 'mask' array variable.
140  Array *dest = new Array("dilated_mask", 0); // The ctor for Array copies the prototype pointer...
141 
142  BaseTypeFactory btf;
143  dest->add_var_nocopy(btf.NewVariable(dods_byte_c)); // ... so use add_var_nocopy() to add it instead
144 
145  dest->append_dim(maxI);
146  dest->append_dim(maxJ);
147 
148  dest->set_value(dest_values, mask->length());
149  dest->set_send_p(true);
150  dest->set_read_p(true);
151 
152  // return the array
153  *btpp = dest;
154 
155  return;
156 }
157 
158 
159 } // namesspace functions
libdap
Definition: BESDapFunctionResponseCache.h:35
Error