The ShapeFileReadInfo class stores information about a shapefile that can be used by external clients during a shapefile read.
Example #1
0
        /// <summary>
        /// Begin creating and displaying WPF shapes on the canvas.
        /// </summary>
        private void DisplayShapes(ShapeFileReadInfo info)
        {
            // Create shape brushes.
            if (this.shapeBrushes == null)
                this.CreateShapeBrushes(0.40, 45);

            // Set up the transformation for WPF shapes.            
            if (this.shapeTransform == null)
                this.shapeTransform = this.CreateShapeTransform(info);

            // Schedule display of the first block of shapefile records
            // using the dispatcher.
            this.dispatcher.BeginInvoke(DispatcherPriority.Normal, new DisplayNextPrototype(this.DisplayNextShapeRecord), info);
        }
Example #2
0
        /// <summary>
        /// Display a block of shape records as WPF shapes, and schedule
        /// the next display with the dispatcher if needed.
        /// </summary>
        /// <param name="info">Shapefile read information.</param>
        private void DisplayNextShapeRecord(ShapeFileReadInfo info)
        {
            if (this.cancelReadShapeFile)
                return;

            // Create a block of WPF shapes and add them to the shape list. 
            this.shapeList.Clear();
            int index = info.RecordIndex;
            for (; index < (info.RecordIndex + ShapeDisplay.displayShapesBlockingFactor); index++)
            {
                if (index >= info.ShapeFile.Records.Count)
                    break;

                ShapeFileRecord record = info.ShapeFile.Records[index];

                // Set the name of the WPF shape.
                ++this.wpfShapeCount;
                string shapeName = String.Format(System.Globalization.CultureInfo.InvariantCulture, "Shape{0}", this.wpfShapeCount);

                // Create the WPF shape.
                Shape shape;
                if (record.NumberOfParts == 0)
                    shape = this.CreateWPFPoint(shapeName, record);
                else
                    shape = this.CreateWPFShape(shapeName, record);

                // Set a tooltip for the shape that displays up to 5 attribute values.
                shape.ToolTip = shape.Name;
                if (record.Attributes != null)
                {
                    string attr = String.Empty;
                    for (int i = 0; i < Math.Min(5, record.Attributes.ItemArray.GetLength(0)); i++)
                    {
                        attr += (", " + record.Attributes[i].ToString());
                    }
                    shape.ToolTip += attr;
                }

                // Add the shape to the shape list.                
                //this.shapeList.Add(shape);

                // If the record just processed is very large, then don't process
                // any further records.
                if (record.Points.Count > 5000)
                {
                    ++index;
                    break;
                }
            }

            // Set the record index to read next (as part of the
            // next dispatched task).
            info.RecordIndex = index;

            // Add the newly created WPF shapes to the canvas.
            foreach (Shape shape in this.shapeList)
            {
                this.canvas.Children.Add(shape);
            }
            this.shapeList.Clear();

            // Display the current progress.
            double progressValue = (index * 100.0) / info.ShapeFile.Records.Count;
            progressValue = Math.Min(100, progressValue);
            this.ShowProgress("Creating WPF shapes...", progressValue);

            // See if we need to dispatch another display operation.
            if (index < info.ShapeFile.Records.Count)
            {
                // Schedule the next display at Background priority.
                this.dispatcher.BeginInvoke(DispatcherPriority.Background, new DisplayNextPrototype(this.DisplayNextShapeRecord), info);
            }
            else
            {
                // End the progress.
                this.ShowProgress("Creating WPF shapes...", 100);
                this.EndReadShapeFile(info);
            }
        }
Example #3
0
        /// <summary>
        /// Read dBASE file attributes.
        /// </summary>
        /// <param name="info">Shapefile read information.</param>
        private void ReadDbaseAttributes(ShapeFileReadInfo info)
        {
            // Read attributes from the associated dBASE file.
            try
            {
                string dbaseFile = info.FileName.Replace(".shp", ".dbf");
                dbaseFile = dbaseFile.Replace(".SHP", ".DBF");
                info.ShapeFile.ReadAttributes(dbaseFile);
            }
            catch (OleDbException ex)
            {
                // Note: An exception will occur if the filename of the dBASE
                // file does not follow 8.3 naming conventions. In this case,
                // you must use its short (MS-DOS) filename.
                MessageBox.Show(ex.Message);

                // Activate the window.
                this.owner.Activate();
            }
        }
Example #4
0
        /// <summary>
        /// Perform some cleanup at the end of reading a shapefile.
        /// </summary>
        /// <param name="info">Shapefile read information.</param>
        private void EndReadShapeFile(ShapeFileReadInfo info)
        {
            if (info != null && info.Stream != null)
            {
                info.Stream.Close();
                info.Stream.Dispose();
                info.Stream = null;
            }

            this.EndReadShapeFile();
        }
Example #5
0
        /// <summary>
        /// Read a block of shape file records and possibly schedule
        /// the next read with the dispatcher.
        /// </summary>
        /// <param name="info">Shapefile read information.</param>
        private void ReadNextShapeRecord(ShapeFileReadInfo info)
        {
            if (this.cancelReadShapeFile)
                return;

            try
            {
                // Read a block of shape records.
                for (int i = 0; i < ShapeDisplay.readShapesBlockingFactor; i++)
                {
                    ShapeFileRecord record = info.ShapeFile.ReadShapeFileRecord(info.Stream);
                    info.NumberOfBytesRead += (4 + record.ContentLength) * 2;
                }
            }
            catch (FileFormatException ex)
            {
                this.EndReadShapeFile(info);
                MessageBox.Show(ex.Message);

                return;
            }
            catch (IOException)
            {
                // Display the end progress (100 percent).
                this.ShowProgress("Reading shapefile...", 100);

                // Read attributes from the associated dBASE file.
                this.ReadDbaseAttributes(info);

                // Display shapes on the canvas.
                if (info.ShapeFile.Records.Count > 0)
                    this.DisplayShapes(info);
                else
                    this.EndReadShapeFile(info);

                return;
            }

            // Display the current progress.
            double progressValue = info.NumberOfBytesRead * 100.0 / (info.ShapeFile.FileHeader.FileLength * 2);
            progressValue = Math.Min(100, progressValue);
            this.ShowProgress("Reading shapefile...", progressValue);

            // Schedule the next read at Background priority.
            this.dispatcher.BeginInvoke(DispatcherPriority.Background, new ReadNextPrototype(this.ReadNextShapeRecord), info);
        }
Example #6
0
        /// <summary>
        /// Computes a transformation so that the shapefile geometry
        /// will maximize the available space on the canvas and be
        /// perfectly centered as well.
        /// </summary>
        /// <param name="info">Shapefile information.</param>
        /// <returns>A transformation object.</returns>
        private TransformGroup CreateShapeTransform(ShapeFileReadInfo info)
        {
            // Bounding box for the shapefile.
            double xmin = info.ShapeFile.FileHeader.XMin;
            double xmax = info.ShapeFile.FileHeader.XMax;
            double ymin = info.ShapeFile.FileHeader.YMin;
            double ymax = info.ShapeFile.FileHeader.YMax;

            // Width and height of the bounding box.
            double width = Math.Abs(xmax - xmin);
            double height = Math.Abs(ymax - ymin);

            // Aspect ratio of the bounding box.
            double aspectRatio = width / height;

            // Aspect ratio of the canvas.
            double canvasRatio = this.canvas.ActualWidth / this.canvas.ActualHeight;

            // Compute a scale factor so that the shapefile geometry
            // will maximize the space used on the canvas while still
            // maintaining its aspect ratio.
            double scaleFactor = 1.0;
            if (aspectRatio < canvasRatio)
                scaleFactor = this.canvas.ActualHeight / height;
            else
                scaleFactor = this.canvas.ActualWidth / width;

            // Compute the scale transformation. Note that we flip
            // the Y-values because the lon/lat grid is like a cartesian
            // coordinate system where Y-values increase upwards.
            ScaleTransform xformScale = new ScaleTransform(scaleFactor, -scaleFactor);

            // Compute the translate transformation so that the shapefile
            // geometry will be centered on the canvas.
            TranslateTransform xformTrans = new TranslateTransform();
            xformTrans.X = (this.canvas.ActualWidth - (xmin + xmax) * scaleFactor) / 2;
            xformTrans.Y = (this.canvas.ActualHeight + (ymin + ymax) * scaleFactor) / 2;

            // Add the two transforms to a transform group.
            TransformGroup xformGroup = new TransformGroup();
            xformGroup.Children.Add(xformScale);
            xformGroup.Children.Add(xformTrans);

            return xformGroup;
        }
Example #7
0
        /// <summary>
        /// Read shapes and attributes from the given shapefile.
        /// </summary>
        /// <param name="fileName">Full pathname of a shapefile.</param>
        public void ReadShapeFile(string fileName)
        {
            this.isReadingShapeFile = true;
            this.cancelReadShapeFile = false;

            // Create an object to store shapefile info during the read.
            ShapeFileReadInfo info = new ShapeFileReadInfo();
            info.FileName = fileName;
            info.ShapeFile = new ShapeFile();
            info.Stream = null;
            info.NumberOfBytesRead = 0;
            info.RecordIndex = 0;

            try
            {
                // Read the File Header first.
                info.Stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                info.ShapeFile.ReadShapeFileHeader(info.Stream);
                info.NumberOfBytesRead = ShapeFileHeader.Length;

                // Schedule the first read of shape file records using the dispatcher.
                this.dispatcher.BeginInvoke(DispatcherPriority.Normal, new ReadNextPrototype(this.ReadNextShapeRecord), info);
            }
            catch (IOException ex)
            {
                this.EndReadShapeFile(info);
                MessageBox.Show(ex.Message);
            }
        }