コード例 #1
0
        private string GetGdalInputFileParameter(string downloadedFilePath, TemporaryWorkFolder workFolder)
        {
            try
            {
                using (var zip = ZipFile.OpenRead(downloadedFilePath))
                {
                    if (zip.Entries.Count == 1)
                    {
                        // extract the source if has single entry
                        var singleEntry = zip.Entries.First();
                        using (var entryStream = zip.Entries.First().Open())
                        {
                            var extractedPath = Path.Combine(workFolder.CreateSubFolder("extracted"), singleEntry.Name);
                            using (var extractedStream = File.OpenWrite(extractedPath))
                            {
                                entryStream.CopyTo(extractedStream);
                                return(extractedPath);
                            }
                        }
                    }

                    // use zip file if has multiple entries
                    return($@"/vsizip/{downloadedFilePath}");
                }
            }
            catch
            {
                // directly use downloaded file if not a zip file
                return(downloadedFilePath);
            }
        }
コード例 #2
0
        protected override async Task Process()
        {
            // For the enlightenment of other, later, readers:
            // ogr2ogr will be used to process not only obvious conversion sources (eg shape files) but also
            // geojson files. Why, you might ask, because tippecanoe can import GeoJSON directly? It's because
            // passing the GeoJSON through ogr2ogr will ensure that the final GeoJSON is in the correct projection
            // and that it should be valid GeoJSON as well.
            QueuedConversionJob queued = null;

            try
            {
                queued = await _gdConversionQueue.GetJob();
            }
            catch (Exception ex)
            {
                _logger.LogError($"GdalConversion failed to retrieve queued job", ex);
            }

            if (queued != null) // if no job queued, don't try
            {
                using (var workFolder = new TemporaryWorkFolder())
                {
                    try
                    {
                        var job = queued.Content;
                        if (job?.DataLocation != null && job.LayerId != null && job.WorkspaceId != null)
                        // if the job has missing values, don't process it, just delete it from queue.
                        {
                            var timer = new Stopwatch();
                            timer.Start();
                            _logger.LogDebug($"Processing GDAL Conversion for Layer {queued.Content.LayerId} within Queue Message {queued.Id}");

                            // Keep source and dest separate in case of file name collision.
                            var sourcePath = workFolder.CreateSubFolder("source");
                            var destPath   = workFolder.CreateSubFolder("dest");

                            var downloadedFilePath = await new Uri(job.DataLocation).DownloadToLocal(sourcePath);
                            var inputFilePath      = GetGdalInputFileParameter(downloadedFilePath, workFolder);
                            var geoJsonFile        = Path.Combine(destPath, $"{job.LayerId}.geojson");

                            var processArgument = GetProcessArgument(job.LayerName, geoJsonFile, inputFilePath);
                            _logger.LogDebug($"executing ogr2ogr process with argument {processArgument}");
                            var executionResult =
                                ProcessExecutionService.ExecuteProcess(ConverterFileName, processArgument);
                            if (executionResult.success)
                            {
                                _logger.LogDebug($"ogr2ogr process successfully executed");
                            }
                            else
                            {
                                _logger.LogError($"ogr2ogr process failed: {executionResult.error}");
                                throw new Exception($"ogr2ogr process failed: {executionResult.error}");
                            }

                            // now we need to put the converted geojson file into storage
                            var location = await _geoJsonStorage.Store($"{job.WorkspaceId}/{job.LayerId}.geojson", geoJsonFile);

                            _logger.LogDebug("Upload of geojson file to storage complete.");

                            timer.Stop();
                            _logger.LogDebug($"GDAL Conversion finished for Layer {job.LayerId} in {timer.ElapsedMilliseconds} ms.");

                            // we created geoJson so we can put a request in for geojson to mvt conversion.
                            await _mbConversionQueue.Queue(new ConversionJobData
                            {
                                LayerId      = job.LayerId,
                                WorkspaceId  = job.WorkspaceId,
                                LayerName    = job.LayerName,
                                Description  = job.Description,
                                DataLocation = location
                            });
                        }
                        // we completed GDAL conversion and creation of MVT conversion request, so remove the GDAL request from the queue
                        await _gdConversionQueue.DeleteJob(queued);

                        _logger.LogDebug("GDAL Conversion message deleted ");
                    }
                    catch (Exception ex)
                    {
                        if (queued.DequeueCount >= RetryLimit)
                        {
                            try
                            {
                                await _gdConversionQueue.DeleteJob(queued);

                                if (queued.Content?.LayerId != null && queued.Content?.WorkspaceId != null)
                                {
                                    await _statusTable.UpdateStatus(queued.Content.WorkspaceId, queued.Content.LayerId,
                                                                    LayerStatus.Failed);
                                }

                                _logger.LogError($"GDAL Conversion failed for layer {queued.Content?.LayerId} after reaching retry limit", ex);
                            }
                            catch (Exception e)
                            {
                                _logger.LogError($"GDAL Conversion failed to clear bad conversion for layer {queued.Content?.LayerId}", e);
                            }
                        }
                        else
                        {
                            _logger.LogWarning($"GDAL Conversion failed for layer {queued.Content?.LayerId} will retry later", ex);
                        }
                    }
                }
            }
            else
            {
                await Task.Delay(_serviceOptions.ConvertPolling);
            }
        }