import Kernel from './Kernel' ; import MathUtils from './math/Utils' ; export enum TileGridPosition { LEFT_TOP , RIGHT_TOP , LEFT_BOTTOM , RIGHT_BOTTOM , LEFT , RIGHT , TOP , BOTTOM } const maxLatitudeOfWebMercator = MathUtils . webMercatorYToDegreeLat ( Kernel . MAX_PROJECTED_COORD ) ; class TileGrid { private Egeo : any = null ; constructor ( public level , public row , public column ) { } equals ( other ) { return other && this . level === other . level && this . row === other . row && this . column === other . column ; } getEgeo ( ) { if ( ! this . Egeo ) { this . Egeo = MathUtils . getTileGeographicEnvelopByGrid ( this . level , this . row , this . column ) ; } return this . Egeo ; } getLeftTopTag ( ) { return `${ this . level }_${ this . row }_${ this . column }` ; } getRightTopTag ( ) { return `${ this . level }_${ this . row }_${ this . column + 1 }` ; } getLeftBottomTag ( ) { return `${ this . level }_${ this . row + 1 }_${ this . column }` ; } getRightBottomTag ( ) { return `${ this . level }_${ this . row + 1 }_${ this . column + 1 }` ; } getLeft ( ) { return TileGrid . getTileGridByBrother ( this . level , this . row , this . column , TileGridPosition . LEFT ) ; } getRight ( ) { return TileGrid . getTileGridByBrother ( this . level , this . row , this . column , TileGridPosition . RIGHT ) ; } getTop ( ) { return TileGrid . getTileGridByBrother ( this . level , this . row , this . column , TileGridPosition . TOP ) ; } getBottom ( ) { return TileGrid . getTileGridByBrother ( this . level , this . row , this . column , TileGridPosition . BOTTOM ) ; } getParent ( ) { return TileGrid . getTileGridAncestor ( this . level - 1 , this . level , this . row , this . column ) ; } getAncestor ( ancestorLevel ) { return TileGrid . getTileGridAncestor ( ancestorLevel , this . level , this . row , this . column ) ; } param parentLevel param parentRow param parentColumn param position return { Object } static getTileGridByParent ( parentLevel , parentRow , parentColumn , position ) { var level = parentLevel + 1 ; var row = - 1 ; var column = - 1 ; if ( position === TileGridPosition . LEFT_TOP ) { row = 2 * parentRow ; column = 2 * parentColumn ; } else if ( position === TileGridPosition . RIGHT_TOP ) { row = 2 * parentRow ; column = 2 * parentColumn + 1 ; } else if ( position === TileGridPosition . LEFT_BOTTOM ) { row = 2 * parentRow + 1 ; column = 2 * parentColumn ; } else if ( position === TileGridPosition . RIGHT_BOTTOM ) { row = 2 * parentRow + 1 ; column = 2 * parentColumn + 1 ; } else { throw "invalid position" ; } return new TileGrid ( level , row , column ) ; } static getTilePositionOfParent ( level , row , column , parent ? ) { var position = null ; parent = parent || this . getTileGridAncestor ( level - 1 , level , row , column ) ; var ltTileGrid = this . getTileGridByParent ( parent . level , parent . row , parent . column , TileGridPosition . LEFT_TOP ) ; if ( ltTileGrid . row === row ) { if ( ltTileGrid . column === column ) { position = TileGridPosition . LEFT_TOP ; } else if ( ltTileGrid . column + 1 === column ) { position = TileGridPosition . RIGHT_TOP ; } } else if ( ltTileGrid . row + 1 === row ) { if ( ltTileGrid . column === column ) { position = TileGridPosition . LEFT_BOTTOM ; } else if ( ltTileGrid . column + 1 === column ) { position = TileGridPosition . RIGHT_BOTTOM ; } } return position ; } static getTileGridByBrother ( brotherLevel , brotherRow , brotherColumn , position , options ? ) { options = options || { } ; var result = new TileGrid ( brotherLevel , brotherRow , brotherColumn ) ; if ( position === TileGridPosition . LEFT ) { if ( brotherColumn === 0 ) { var maxSize = options . maxSize || Math . pow ( 2 , brotherLevel ) ; result . column = maxSize - 1 ; } else { result . column = brotherColumn - 1 ; } } else if ( position === TileGridPosition . RIGHT ) { var maxSize = options . maxSize || Math . pow ( 2 , brotherLevel ) ; if ( brotherColumn === maxSize - 1 ) { result . column = 0 ; } else { result . column = brotherColumn + 1 ; } } else if ( position === TileGridPosition . TOP ) { if ( brotherRow === 0 ) { var maxSize = options . maxSize || Math . pow ( 2 , brotherLevel ) ; result . row = maxSize - 1 ; } else { result . row = brotherRow - 1 ; } } else if ( position === TileGridPosition . BOTTOM ) { var maxSize = options . maxSize || Math . pow ( 2 , brotherLevel ) ; if ( brotherRow === maxSize - 1 ) { result . row = 0 ; } else { result . row = brotherRow + 1 ; } } else { throw "invalid position" ; } return result ; } param ancestorLevel param level param row param column returns { null } static getTileGridAncestor ( ancestorLevel , level , row , column ) { var result = null ; if ( ancestorLevel < level ) { var deltaLevel = level - ancestorLevel ; var a = Math . pow ( 2 , deltaLevel ) ; var ancestorRow = Math . floor ( row / a ) ; var ancestorColumn = Math . floor ( column / a ) ; result = new TileGrid ( ancestorLevel , ancestorRow , ancestorColumn ) ; } else if ( ancestorLevel === level ) { result = new TileGrid ( level , row , column ) ; } return result ; } static isValidLatitude ( lat ) { return lat >= - maxLatitudeOfWebMercator && lat <= maxLatitudeOfWebMercator ; } static getTileGridByGeo ( lon , lat , level ) { if ( ! ( lon >= - 180 && lon <= 180 ) ) { throw `invalid lon: ${ lon }` ; } var coordWebMercator = MathUtils . degreeGeographicToWebMercator ( lon , lat ) ; var x = coordWebMercator [ 0 ] ; var y = coordWebMercator [ 1 ] ; var horX = x + Kernel . MAX_PROJECTED_COORD ; var verY = Kernel . MAX_PROJECTED_COORD - y ; var size = Kernel . MAX_PROJECTED_COORD / Math . pow ( 2 , level - 1 ) ; var row = Math . floor ( verY / size ) ; var column = Math . floor ( horX / size ) ; return new TileGrid ( level , row , column ) ; } } export default TileGrid ;