예제 #1
0
        private void LoadSegment(int offset)
        {
            int currentBuffer = offsets[0] >= 0 ? 0 : 1;

            if (offset - offsets[currentBuffer] < 0 || offset - offsets[currentBuffer] >= 4096)
            {
                int segmentStart = offset / 4096 * 4096;
                if (wrotePages.Contains(segmentStart))
                {
                    if (lastSegment == segmentStart)
                    {
                        IOProxy.getInst().LoadSegment(level, segmentStart, buffer[1 - currentBuffer], dataLength - lastSegment);
                    }
                    else
                    {
                        IOProxy.getInst().LoadSegment(level, segmentStart, buffer[1 - currentBuffer], 4096);
                    }
                }
                else
                {
                    Array.Clear(buffer[1 - currentBuffer], 0, 4096);
                }
                offsets[1 - currentBuffer] = segmentStart;
                if (offsets[currentBuffer] >= 0)
                {
                    WriteSegment(currentBuffer);
                }
            }
        }
예제 #2
0
        public TaskDirectory(int level, int minRow, int maxRow, int minCol, int maxCol)
        {
            buffer     = new byte[2][];
            buffer[0]  = new byte[4096];
            buffer[1]  = new byte[4096];
            offsets    = new int[2];
            offsets[0] = 0;
            offsets[1] = -1;
            validCount = 0;
            startRow   = minRow;
            endRow     = maxRow;
            startCol   = minCol;
            endCol     = maxCol;
            this.level = level;
            rowCount   = maxRow - minRow + 1;
            colCount   = maxCol - minCol + 1;
            int totalCount  = rowCount * colCount;
            int tableLength = totalCount % 8 == 0 ? totalCount / 8 : totalCount / 8 + 1;

            dataLength   = tableLength + 28;
            lastSegment  = dataLength / 4096 * 4096;
            buffer[0][0] = 0xFF;
            buffer[0][1] = (byte)level;
            Array.Copy(IOProxy.getInst().l2b(dataLength, 4), 0, buffer[0], 2, 4);
            Array.Copy(IOProxy.getInst().l2b(minRow, 4), 0, buffer[0], 6, 4);
            Array.Copy(IOProxy.getInst().l2b(maxRow, 4), 0, buffer[0], 10, 4);
            Array.Copy(IOProxy.getInst().l2b(minCol, 4), 0, buffer[0], 14, 4);
            Array.Copy(IOProxy.getInst().l2b(maxCol, 4), 0, buffer[0], 18, 4);
            int fileOffset = IOProxy.getInst().recommendOffset();

            IOProxy.getInst().setLevelOffset(level, fileOffset, dataLength);
            wrotePages = new List <int>();
        }
예제 #3
0
        public void Finish()
        {
            LoadSegment(0);
            int currentBuffer = offsets[0] >= 0 ? 0 : 1;

            Array.Copy(IOProxy.getInst().l2b(validCount, 4), 0, buffer[currentBuffer], 22, 4);
            WriteSegment(currentBuffer);
        }
예제 #4
0
 public static IOProxy getInst()
 {
     if (_inst == null)
     {
         _inst = new IOProxy();
     }
     return(_inst);
 }
예제 #5
0
 private void WriteSegment(int currentBuffer)
 {
     if (lastSegment == offsets[currentBuffer])
     {
         buffer[currentBuffer][dataLength - lastSegment - 2] = 0xFF;
         buffer[currentBuffer][dataLength - lastSegment - 1] = 0xFE;
         IOProxy.getInst().WriteSegment(level, offsets[currentBuffer], buffer[currentBuffer], dataLength - lastSegment);
     }
     else
     {
         IOProxy.getInst().WriteSegment(level, offsets[currentBuffer], buffer[currentBuffer], 4096);
     }
     if (!wrotePages.Contains(offsets[currentBuffer]))
     {
         wrotePages.Add(offsets[currentBuffer]);
     }
     offsets[currentBuffer] = -1;
 }
예제 #6
0
        protected override void DoConvertToMBTiles(string outputPath, string name, string description, string attribution, int[] levels, Geometry geometry, bool doCompact)
        {
            Util.Envelope initial;
            Point         pLeftTop;
            Point         pRightBottom;

            if (geometry is Envelope)
            {
                initial      = geometry as Envelope;
                pLeftTop     = Utility.GeographicToWebMercator(new Util.Point(initial.XMin, initial.YMax));
                pRightBottom = Utility.GeographicToWebMercator(new Util.Point(initial.XMax, initial.YMin));
            }
            else
            {
                Polygon temp = geometry as Polygon;
                pLeftTop     = new Util.Point(temp.Extent.XMin, temp.Extent.YMax);
                pRightBottom = new Util.Point(temp.Extent.XMax, temp.Extent.YMin);
                Point GPS_pLeftTop     = Utility.WebMercatorToGeographic(pLeftTop);
                Point GPS_pRightBottom = Utility.WebMercatorToGeographic(pRightBottom);
                initial = new Envelope(GPS_pLeftTop.X, GPS_pRightBottom.Y, GPS_pRightBottom.X, GPS_pLeftTop.Y);
            }


            Envelope downloadExtentMercator = new Envelope(pLeftTop.X, pRightBottom.Y, pRightBottom.X, pLeftTop.Y);

            _outputFile       = outputPath;
            _downloadGeometry = geometry;
            _convertingStatus.IsInProgress = true;
            try
            {
                CreateMBTilesFileAndWriteMetaData(outputPath, name, description, attribution, initial);
                if (autoCorrectCoord)
                {
                    CreateCCMBTilesFile(outputPath, name, description, attribution, initial);
                }
                _outputconn = new SQLiteConnection("Data source = " + base._outputFile);
                _outputconn.Open();

                #region calculate startCol/Row and endCol/Row and tiles count of each level
                _convertingStatus.TotalCount = 0;
                string[] keyTileInfos      = new string[levels.Length];
                int[]    tilesCountOfLevel = new int[levels.Length];
                for (int i = 0; i < levels.Length; i++)
                {
                    LODInfo lod             = TilingScheme.LODs[levels[i]];
                    double  oneTileDistance = lod.Resolution * 256;
                    int     level           = TilingScheme.LODs[levels[i]].LevelID;
                    int     startTileRow    = (int)(Math.Abs(TilingScheme.TileOrigin.Y - geometry.Extent.YMax) / oneTileDistance);
                    int     startTileCol    = (int)(Math.Abs(TilingScheme.TileOrigin.X - geometry.Extent.XMin) / oneTileDistance);
                    int     endTileRow      = (int)(Math.Abs(TilingScheme.TileOrigin.Y - geometry.Extent.YMin) / oneTileDistance);
                    int     endTileCol      = (int)(Math.Abs(TilingScheme.TileOrigin.X - geometry.Extent.XMax) / oneTileDistance);
                    keyTileInfos[i]               = string.Format("{0},{1},{2},{3}", startTileRow, startTileCol, endTileRow, endTileCol);
                    tilesCountOfLevel[i]          = Math.Abs((endTileCol - startTileCol + 1) * (endTileRow - startTileRow + 1));
                    _convertingStatus.TotalCount += tilesCountOfLevel[i];
                }
                _totalCount    = _convertingStatus.TotalCount;
                _completeCount = _errorCount = 0;
                _wroteBytes    = _wroteCounts = 0;
                #endregion
                int arcgisTileCount = 0;
                for (int i = 0; i < levels.Length; i++)
                {
                    int level, startR, startC, endR, endC;//startTileRow,startTileCol,...
                    level  = TilingScheme.LODs[levels[i]].LevelID;
                    startR = int.Parse(keyTileInfos[i].Split(new char[] { ',' })[0]);
                    startC = int.Parse(keyTileInfos[i].Split(new char[] { ',' })[1]);
                    endR   = int.Parse(keyTileInfos[i].Split(new char[] { ',' })[2]);
                    endC   = int.Parse(keyTileInfos[i].Split(new char[] { ',' })[3]);
                    _convertingStatus.Level              = level;
                    _convertingStatus.LevelTotalCount    = tilesCountOfLevel[i];
                    _convertingStatus.LevelCompleteCount = _convertingStatus.LevelErrorCount = 0;
                    _levelTotalCount    = _convertingStatus.LevelTotalCount;
                    _levelCompleteCount = _levelErrorCount = 0;
                    SaveOneLevelTilesToMBTiles(level, startR, startC, endR, endC);
                    if (autoCorrectCoord)
                    {
                        RCRange range = BaiDuMapManager.inst.getArcgisRCRangeFromMercator(downloadExtentMercator, levels[i]);
                        startR = range.MinRow;
                        startC = range.MinCol;
                        endR   = range.MaxRow;
                        endC   = range.MaxCol;
                        recordScope(level, startR, startC, endR, endC);
                        arcgisTileCount += (endR - startR + 1) * (endC - startC + 1);
                    }
                    if (_convertingStatus.IsCancelled)
                    {
                        _convertingStatus.IsCompletedSuccessfully = false;
                        break;
                    }
                }
                IOProxy.getInst().Dispose();
                recordCount(arcgisTileCount);
                if (doCompact)
                {
                    _convertingStatus.IsDoingCompact    = true;
                    _convertingStatus.SizeBeforeCompact = new FileInfo(_outputFile).Length;
                    CompactMBTiles(_outputFile);
                    _convertingStatus.IsDoingCompact   = false;
                    _convertingStatus.SizeAfterCompact = new FileInfo(_outputFile).Length;
                }
                if (!_convertingStatus.IsCancelled)
                {
                    _convertingStatus.IsCompletedSuccessfully = true;
                }
            }
            finally
            {
                if (_correctOutputconn != null)
                {
                    _correctOutputconn.Dispose();
                }
                RecoverFailure();
                _convertingStatus.IsInProgress            = false;
                _convertingStatus.IsCommittingTransaction = false;
                _convertingStatus.IsDoingCompact          = false;
                _outputconn.Close();
                _outputconn.Dispose();
            }
        }