Пример #1
0
        // -----------------------------------------------------------------------------------------------
        // receives descriptor and ordinal at which file is being generated in the sequence (keeps files in order)
        private String generateSliceFilename( SliceDescriptor desc, int fileSequenceIndex, bool appendCoordinate )
        {
            String filename ="";

            // -- sequence index --
            // surely 1000 numbers will be enough...for now
            filename = _outputFilename + "_vs" + _sliceDirection.ToString() + "_" + fileSequenceIndex.ToString("D4");

            // -- coordinate --
            if ( appendCoordinate )
            {
                if ( _sliceDirection == SliceDirectionType.NS )
                {
                    filename += "_long_" + desc.Start.Longitude().ToString("F4");
                }
                else
                {
                    filename += "_lat_" + desc.Start.Latitude().ToString("F4");
                }
            }

            return filename;
        }
Пример #2
0
        // -----------------------------------------------------------------------------------------------
        private void generateSlice( SliceDescriptor sliceDesc )
        {
            Console.WriteLine( "generating file = " + sliceDesc.filename );
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Reset();
            stopwatch.Start();

            fillPixelBuffer( _backgroundColor );

            // -- inits --
            double currentLatitude = sliceDesc.Start.Latitude();
            double currentLongitude = sliceDesc.Start.Longitude();

            var startRowCol = CoordinateToRowCol( sliceDesc.Start );
            var endRowCol = CoordinateToRowCol( sliceDesc.End );

            // These are invariant over the slices, why aren't I doing them outside of this?
            // note this is elevation range in image, which includes buffers at top/bottom
            float elevationRange = (_maxElevationInRect - _minElevationInRect) + (BufferMeters * 2.0f);
            // scale elevation range to image width
            float pixelsPerMeter = _imageHeight / elevationRange;

            var yCoordinates = new int[ _imageWidth ];

            // -- loop over image x axis --
            for ( int currentImageX = 0; currentImageX < _imageWidth; ++currentImageX )
            {
                // what point in data is current image column looking 'down' on ?
                var currentRowCol = CoordinateToRowCol( currentLatitude, currentLongitude );
                var currentHeight = _data.ValueAt( currentRowCol.Item1, currentRowCol.Item2 );

                // the 'y' in the bitmap of the groundline is analogous to the height data at the current point in the topo data (converted to
                // pixels)
                int groundPixelHeight = Convert.ToInt32((currentHeight - _minElevationInRect + BufferMeters) * pixelsPerMeter);

                /*
                 * if this happens, it means my maths are broken again
                if ( _imageHeight - groundPixelHeight < 0 )
                {
                    int breakpoint = 10;
                    breakpoint++;
                }
                 * */

                // note : subtract from image height because bitmap y coordinates are 0 at the top ,increasing downward
                int currentImageY = Math.Max( _imageHeight - groundPixelHeight, 0 );

                yCoordinates[ currentImageX ] = currentImageY;

                _pixels[ (currentImageY * _imageWidth) + currentImageX ] = _contourLineColor;

                // check for vertical gaps between consecutive pixels (>1 pixel apart)
                // It might be better to break up the slice into a series of lines, and handle these gaps that way (by iterating
                // over a series of points, drawing actual lines between them), but for now we'll take advantage of the fact
                // that we're always only moving one pixel horizontally in screen space, and that these gaps don't appear very
                // often in most datasets (unless you're in an area with a lot of cliffs and bluffs e.g. the Grand Canyon)
                if ( currentImageX > 0 )
                {
                    if ( Math.Abs( currentImageY - yCoordinates[ currentImageX - 1 ] ) > 1 )    // found a gap
                    {
                        int midY = (yCoordinates[ currentImageX ] + yCoordinates[ currentImageX - 1 ]) / 2;

                        // fill FROM previous y TO current, but half on each coordinate
                        verticalLine( currentImageX - 1, yCoordinates[ currentImageX - 1 ], midY, _contourLineColor );
                        verticalLine( currentImageX, midY, yCoordinates[ currentImageX ], _contourLineColor );
                    }
                }

                currentLatitude += _coordinateStepPerImagePixel.Latitude();
                currentLongitude += _coordinateStepPerImagePixel.Longitude();
            }

            stopwatch.Stop();
            addTiming( "generate slice", stopwatch.ElapsedMilliseconds );

            SaveBitmap( sliceDesc.filename, _pixels );
        }
Пример #3
0
        // -----------------------------------------------------------------------------------------------
        // iterates over the line between the coordinates start->end, stepping by degreesBetweenSlices, and
        // generating a slice descriptor at each step that goes from current location to current location + sliceDelta
        private List<SliceDescriptor> generateSliceDescriptors( Tuple<double,double> start, Tuple<double,double> end, 
                                                                double degreesBetweenSlices,
                                                                Tuple<double,double> sliceDelta )
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Reset();
            stopwatch.Start();

            // determine how many slices will be generated
            var startEndDelta = Vector.Ops.Delta( start, end );

            // length of delta
            double startEndDeltaDegrees = Vector.Ops.Length( startEndDelta );

            // note : add 1 because the division determines the count of spaces -between- slices
            int numSlices = (int)(startEndDeltaDegrees / degreesBetweenSlices) + 1;

            var slices = new List<SliceDescriptor>( numSlices );

            // need normalized length start->end delta
            var normalizedStartEndDelta = Vector.Ops.Normalize( startEndDelta );

            // now need coincident vector, but sized to degrees step
            var deltaStep = Vector.Ops.Scale( normalizedStartEndDelta, degreesBetweenSlices );

            // starting point of current slice
            double currentStartLatitude = start.Item1;
            double currentStartLongitude = start.Item2;

            for ( int currentSliceIndex = 0; currentSliceIndex < numSlices; ++currentSliceIndex )
            {
                var slice = new SliceDescriptor();

                // -- generate coordinates --
                slice.Start = new Tuple<double, double>( currentStartLatitude, currentStartLongitude );
                slice.End = new Tuple<double,double>( currentStartLatitude + sliceDelta.Latitude(), currentStartLongitude + sliceDelta.Longitude());

                // -- generate filename --
                slice.filename = generateSliceFilename( slice, currentSliceIndex, _appendCoordinatesToFilenames );

                slices.Add( slice );

                currentStartLatitude += deltaStep.Latitude();
                currentStartLongitude += deltaStep.Longitude();
            }

            stopwatch.Stop();
            addTiming( "generate slice descriptors", stopwatch.ElapsedMilliseconds );

            return slices;
        }
Пример #4
0
        // -----------------------------------------------------------------------------------------------
        //  NOTE : has some dependencies
        private void DetermineImageDimensionsVSlice( SliceDescriptor sampleSlice )
        {
            // note : adding buffer distance below and above min and max elevations
            // (not needed in ALL slices, but ones that contain min and/or max should be buffered)
            double elevationRange = _maxElevationInRect - _minElevationInRect + (BufferMeters * 2.0f);

            if (        ( false == ImageDimensionSpecified( _imageHeight ) )
                    &&  ( false == ImageDimensionSpecified( _imageWidth ) ) )
            {
                // neither specified...
                // the image "width" is 1x1 with the output rect
                // this means each pixel's real world width is the same a single data point's  (important below)
                _imageWidth = ( SliceDirectionType.NS == _sliceDirection ) ? rectHeight : rectWidth;

                // the image "height" is the vertical range of readings the slices will cover, plus some buffer at top and bottom
                // pixels, being square, are as tall as they are wide, which is the horizontal distance between data point cells
                _imageHeight = Convert.ToInt32( elevationRange / _metersPerCell );
            }
            else if (       ( ImageDimensionSpecified( _imageHeight ) )
                        &&  ( false == ImageDimensionSpecified( _imageWidth ) ) )
            {
                // height specified, width was not, calculate width from height
                // distance each pixel represents in specified height
                double metersPerPixel = elevationRange / _imageHeight;

                double sliceWidthDegrees = Vector.Ops.Length( sampleSlice.Start, sampleSlice.End );
                double sliceWidthMeters = sliceWidthDegrees * MetersPerDegree;

                _imageWidth = Convert.ToInt32( sliceWidthMeters / metersPerPixel );
            }
            else if (       ( ImageDimensionSpecified( _imageWidth ) )
                        &&  ( false == ImageDimensionSpecified( _imageHeight ) ) )
            {
                // width was specified, calculate height
                // determine scale factor on width (i.e. what is the width of a pixel at this size)
                double sliceWidthDegrees = Vector.Ops.Length( sampleSlice.Start, sampleSlice.End );
                double pixelsPerDegree = _imageWidth / sliceWidthDegrees;
                double pixelsPerMeter = pixelsPerDegree * DegreesPerMeter;

                _imageHeight = Convert.ToInt32( elevationRange * pixelsPerMeter );
            }

            // whatever height was, scale it
            _imageHeight = (int)(_imageHeight * _imageHeightScale);
        }