142 {
143 try
144 {
145
146 foreach (var item in tiles)
147 {
148 item.Extent = item.Extent.WorldToPixelInvertedY(resolution);
149 }
150
151 if (!initialized)
152 {
153 Initialize();
154 }
155
156
157 double maxX = tiles.Max(t => t.Extent.MaxX);
158 double maxY = tiles.Max(t => t.Extent.MaxY);
159 double minX = tiles.Min(t => t.Extent.MinX);
160 double minY = tiles.Min(t => t.Extent.MinY);
161
162
163 int canvasWidth = (int)(maxX - minX);
164 int canvasHeight = (int)(maxY - minY);
165
166
167 using (CudaDeviceVariable<byte> devCanvas = new CudaDeviceVariable<byte>(canvasWidth * canvasHeight * 3))
168 {
169
170 dim3 blockSize = new dim3(16, 16, 1);
171 dim3 gridSize = new dim3((uint)((canvasWidth + blockSize.x - 1) / blockSize.x), (uint)((canvasHeight + blockSize.y - 1) / blockSize.y), 1);
172
173
174 foreach (var tile in tiles)
175 {
176 Extent extent = tile.Extent;
177
178 CudaDeviceVariable<byte> devTile = null;
179 foreach (var t in gpuTiles)
180 {
181 if (t.Item1.Index == tile.Index)
182 {
183 devTile = t.Item2;
184 break;
185 }
186 }
187 if (devTile != null)
188 {
189
190 int startX = (int)Math.Ceiling(extent.MinX - minX);
191 int startY = (int)Math.Ceiling(extent.MinY - minY);
192
193 int tileWidth = (int)Math.Ceiling(extent.MaxX - extent.MinX);
194 int tileHeight = (int)Math.Ceiling(extent.MaxY - extent.MinY);
195
196
197 int canvasTileWidth = tileWidth;
198 int canvasTileHeight = tileHeight;
199
200
201 kernel.BlockDimensions = blockSize;
202 kernel.GridDimensions = gridSize;
203
204
205 kernel.Run(devCanvas.DevicePointer, canvasWidth, canvasHeight, devTile.DevicePointer, 256, 256, startX, startY, canvasTileWidth, canvasTileHeight);
206 }
207 }
208
209
210 byte[] stitchedImageData = new byte[canvasWidth * canvasHeight * 3];
211 devCanvas.CopyToHost(stitchedImageData);
212
213
214 int clippedX = Math.Max(0, (int)(x - minX));
215 int clippedY = Math.Max(0, (int)(y - minY));
216
217
218 int viewportWidth = pxwidth;
219 int viewportHeight = pxheight;
220
221
222 byte[] viewportImageData = new byte[viewportWidth * viewportHeight * 3];
223 System.Threading.Tasks.Parallel.For(0, viewportHeight, row =>
224 {
225 try
226 {
227 int srcOffset = (clippedY + row) * canvasWidth * 3 + clippedX * 3;
228 int dstOffset = row * viewportWidth * 3;
229 Array.Copy(stitchedImageData, srcOffset, viewportImageData, dstOffset, viewportWidth * 3);
230 }
231 catch (Exception ex)
232 {
233 Console.WriteLine("An error occurred while extracting the viewport: " + ex.Message);
234 }
235 });
236
237 return viewportImageData;
238 }
239 }
240 catch (Exception ex)
241 {
242 Console.WriteLine("An error occurred: " + ex.Message);
243 Initialize();
244 return null;
245 }
246 }