Ejemplo n.º 1
0
        }                                // Unused but supported as part of the TML file

        #endregion


        #region  Private Methods

        /// <summary>
        /// Tries to load the metadata resource at Path as a text string
        /// </summary>
        /// <remarks>
        /// This method will not throw an exception.
        /// Side effects:
        /// It will set ErrorMessage to an error message (if any are encountered)
        /// It may change the Type and Format if they are wrong.
        /// </remarks>
        /// <returns>a text string of the metadata if available or null</returns>
        private async Task <string> GetContentAsTextAsync()
        {
            string contents = null;

            ErrorMessage = null;

            if (string.IsNullOrEmpty(Path))
            {
                ErrorMessage = "Metadata has no Path to the content.";
                return(null);
            }

            // using System.Diagnostics.Eventing.Reader;
            // Trace.TraceInformation("{0}: Start of Metadata.LoadASText({1})", DateTime.Now, Path); Stopwatch time = Stopwatch.StartNew();

            // Try to guess an Undefined MetadataType
            if (Type == MetadataType.Undefined)
            {
                if (Path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                {
                    Type = MetadataType.Url;
                }
                else if (await MyFile.ExistsAsync(Path))
                {
                    Type = MetadataType.FilePath;
                }
                else if (Path.Contains(".gdb\\", StringComparison.OrdinalIgnoreCase) ||
                         Path.Contains(".sde\\", StringComparison.OrdinalIgnoreCase) ||
                         Path.Contains(".mdb\\", StringComparison.OrdinalIgnoreCase))
                {
                    Type = MetadataType.EsriDataPath;
                }
                else
                {
                    ErrorMessage = "The Type of the metadata Path is Undefined and not obvious.";
                    return(null);
                }
            }

            // Correct a URL with the file:// scheme
            if (Type == MetadataType.Url && new Uri(Path).IsFile)
            {
                Path = new Uri(Path).LocalPath;
                Type = MetadataType.FilePath;
            }

            // Try and load the content
            try
            {
                if (Type == MetadataType.FilePath)
                {
                    contents = await MyFile.ReadAllTextAsync(Path);
                }
                if (Type == MetadataType.EsriDataPath)
                {
                    contents = await GisInterface.GetMetadataAsXmlAsync(Path);

                    Format = MetadataFormat.Xml;
                }
                if (Type == MetadataType.Url)
                {
                    // If the format is Undefined, I need to download the contents to check the Format
                    // If the Format is Xml, I will download the contents for getting attributes
                    // For Html and Text Formats, I can't do anything with the contents, so skip this step
                    // The Display method will use the URL to get the contents
                    if (Format == MetadataFormat.Xml || Format == MetadataFormat.Undefined)
                    {
                        var uri = new Uri(Path);
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
                        HttpClient client   = new HttpClient();
                        var        response = await client.GetAsync(uri);

                        if (response.IsSuccessStatusCode)
                        {
                            contents = await response.Content.ReadAsStringAsync();
                        }
                        else
                        {
                            ErrorMessage =
                                $"Could not get {Path} from server.  Status code: {response.StatusCode}({response.ReasonPhrase})";
                            return(null);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
                Debug.Print("Exception thrown trying to load Metadata.\n" + ex);
                return(null);
            }

            // If the file, service, or geo-database returned nothing, we are done for.
            if (string.IsNullOrEmpty(contents) && (Type != MetadataType.Url || Format == MetadataFormat.Xml || Format == MetadataFormat.Undefined))
            {
                ErrorMessage = "The content of the resource at Path is empty.";
                Format       = MetadataFormat.Undefined;
                return(null);
            }

            // Test the format
            if (Format == MetadataFormat.Undefined)
            {
                // ReSharper disable once PossibleNullReferenceException
                if (contents.StartsWith("<?xml version=", StringComparison.OrdinalIgnoreCase) ||
                    contents.StartsWith("<metadata", StringComparison.OrdinalIgnoreCase))
                {
                    Format = MetadataFormat.Xml;
                }
                if (Regex.IsMatch(contents, "<html>|<html .+>"))
                {
                    Format = MetadataFormat.Html;
                }
                if (!Regex.IsMatch(contents, "<.+>|</.+>"))
                {
                    Format = MetadataFormat.Text;
                }
            }

            // time.Stop(); Trace.TraceInformation("{0}: End of Metadata.LoadASText() - Elapsed Time: {1}", DateTime.Now, time.Elapsed);

            return(contents);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a Metadata reference appropriate for the data source.
        /// </summary>
        /// <remarks>
        /// This method will guess the metadata Path, Type and Format based on Esri conventions
        /// and file existence. It is Async, because Iit will check the file system for a file
        /// and/or directory existance which will block, and could take significant time in unusual
        /// circumstances: missing drive, network connection problems, drive asleep, etc. This may
        /// need to check several different paths to ensure we do not miss existing metadata for a datasource.
        /// This method is only called by ThemeBuilder.cs when the user adds a new data source.
        /// </remarks>
        /// <param name="data">The theme's data source</param>
        /// <returns>a new Metadata object for a theme</returns>
        internal static async Task <Metadata> FromDataSourceAsync(ThemeData data)
        {
            Metadata newMetadata = new Metadata();

            if (data == null)
            {
                return(newMetadata);
            }

            //Caution: Setting Path will clear the Type and Format, so set Path first.

            // General file based metadata
            //   Includes layer files.  if *.lyr.xml exists, it trumps the datasource metadata (for single datasource layers)
            if (data.Path != null && await MyFile.ExistsAsync(data.Path + ".xml"))
            {
                newMetadata.Path   = data.Path + ".xml";
                newMetadata.Type   = MetadataType.FilePath;
                newMetadata.Format = MetadataFormat.Xml;
                return(newMetadata);
            }

            // General file based metadata
            //   Includes file based raster data, LAS datasets, and others.
            if (data.DataSource != null && await MyFile.ExistsAsync(data.DataSource + ".xml"))
            {
                newMetadata.Path   = data.DataSource + ".xml";
                newMetadata.Type   = MetadataType.FilePath;
                newMetadata.Format = MetadataFormat.Xml;
                return(newMetadata);
            }

            // Grids, TINs, and other directory based feature classes
            if (data.IsRasterBand && data.DataSource != null && await MyDirectory.ExistsAsync(data.DataSource))
            {
                string metadataPath = System.IO.Path.Combine(data.DataSource, "metadata.xml");
                if (await MyFile.ExistsAsync(metadataPath))
                {
                    newMetadata.Path   = metadataPath;
                    newMetadata.Type   = MetadataType.FilePath;
                    newMetadata.Format = MetadataFormat.Xml;
                }
                return(newMetadata);
            }

            // Shapefile
            if (data.IsShapefile)
            {
                string metadataPath = data.DataSource + ".shp.xml";
                if (await MyFile.ExistsAsync(metadataPath))
                {
                    newMetadata.Path   = metadataPath;
                    newMetadata.Type   = MetadataType.FilePath;
                    newMetadata.Format = MetadataFormat.Xml;
                }
                return(newMetadata);
            }

            // ArcInfo Coverages
            if (data.IsCoverage && data.WorkspacePath != null && data.Container != null)
            {
                string coverageDir = System.IO.Path.Combine(data.WorkspacePath, data.Container);
                if (await MyDirectory.ExistsAsync(coverageDir))
                {
                    string metadataPath = System.IO.Path.Combine(coverageDir, "metadata.xml");
                    if (await MyFile.ExistsAsync(metadataPath))
                    {
                        newMetadata.Path   = metadataPath;
                        newMetadata.Type   = MetadataType.FilePath;
                        newMetadata.Format = MetadataFormat.Xml;
                    }
                    return(newMetadata);
                }
            }

            // CAD
            if (data.IsCad && data.WorkspacePath != null && data.Container != null)
            {
                string cadFile = System.IO.Path.Combine(data.WorkspacePath, data.Container);
                if (await MyFile.ExistsAsync(cadFile))
                {
                    string metadataPath = cadFile + ".xml";
                    if (await MyFile.ExistsAsync(metadataPath))
                    {
                        newMetadata.Path   = metadataPath;
                        newMetadata.Type   = MetadataType.FilePath;
                        newMetadata.Format = MetadataFormat.Xml;
                    }
                    return(newMetadata);
                }
            }

            // SDC - Smart Data Compression for ESRI Street Map and Sample datasets.
            if (data.IsSdc && data.WorkspacePath != null && data.Container != null)
            {
                string sdcFile = System.IO.Path.Combine(data.WorkspacePath, data.Container);
                if (await MyFile.ExistsAsync(sdcFile))
                {
                    string metadataPath = sdcFile + ".xml";
                    if (await MyFile.ExistsAsync(metadataPath))
                    {
                        newMetadata.Path   = metadataPath;
                        newMetadata.Type   = MetadataType.FilePath;
                        newMetadata.Format = MetadataFormat.Xml;
                    }
                    return(newMetadata);
                }
            }

            // GeoDatabases - Metadata is not a separate XML file, it is internal to the database
            //   For SDE datasets to work, the original connection file (*.sde) must be available
            //     to all theme manager users, i.e. not in a local profile (the typical default location)
            if (data.IsInGeodatabase)
            {
                newMetadata.Path = data.DataSource;
                if (data.IsRasterBand)
                {
                    newMetadata.Path = data.DataSource?.Replace("\\" + data.DataSourceName, "");
                }
                newMetadata.Type   = MetadataType.EsriDataPath;
                newMetadata.Format = MetadataFormat.Xml;
                return(newMetadata);
            }

            // File based Raster band metadata
            //   DataSource will contain the Band Name, while metadata will not
            //   Needs to be done after geodatabase, else we miss rasterbands in geodatabases
            if (data.IsRasterBand && data.WorkspacePath != null && data.Container != null)
            {
                string rasterName   = System.IO.Path.Combine(data.WorkspacePath, data.Container);
                string metadataPath = rasterName + ".xml";
                if (await MyFile.ExistsAsync(metadataPath))
                {
                    newMetadata.Path   = metadataPath;
                    newMetadata.Type   = MetadataType.FilePath;
                    newMetadata.Format = MetadataFormat.Xml;
                }
                return(newMetadata);
            }

            // Esri Web services
            if ((data.IsEsriMapService || data.IsEsriImageService) && data.DataSource != null)
            {
                newMetadata.Path   = Regex.Replace(data.DataSource, "/arcgis/services/", "/arcgis/rest/services/", RegexOptions.IgnoreCase);
                newMetadata.Path  += "/info/metadata";
                newMetadata.Type   = MetadataType.Url;
                newMetadata.Format = MetadataFormat.Xml;
                return(newMetadata);
            }
            if (data.IsEsriFeatureService && data.WorkspacePath != null)
            {
                newMetadata.Path   = Regex.Replace(data.WorkspacePath, "/arcgis/services/", "/arcgis/rest/services/", RegexOptions.IgnoreCase);
                newMetadata.Path  += "/info/metadata";
                newMetadata.Type   = MetadataType.Url;
                newMetadata.Format = MetadataFormat.Xml;
                return(newMetadata);
            }

            // Other web services may have metadata, but we are not ready to support them
            // LiDAR data tiles (.las) are not data sources that ArcGIS manages directly (*.lasD files are handled above)
            // Raster functions have no permanent disk representation except a layer file

            // Do not provide a default, it was usually wrong, and it will be better to return nothing

            Debug.Print($"Metadata not found for Data.Path:{data.Path}, Data.DataSource:{data.DataSource}, Data.DataSetType:{data.DataSetType}");

            return(newMetadata);
        }