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); } } }
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>(); }
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); }
public static IOProxy getInst() { if (_inst == null) { _inst = new IOProxy(); } return(_inst); }
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; }
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(); } }