ol/extent.js
主要功能
参数
方法
import Corner from './extent/Corner.js' ;
import Relationship from './extent/Relationship.js' ;
import { assert} from './asserts.js' ;
export function boundingExtent ( coordinates ) {
const extent = createEmpty ( ) ;
for ( let i = 0 , ii = coordinates. length; i < ii; ++ i) {
extendCoordinate ( extent, coordinates[ i] ) ;
}
return extent;
}
function _boundingExtentXYs ( xs, ys, opt_extent ) {
const minX = Math. min . apply ( null , xs) ;
const minY = Math. min . apply ( null , ys) ;
const maxX = Math. max . apply ( null , xs) ;
const maxY = Math. max . apply ( null , ys) ;
return createOrUpdate ( minX, minY, maxX, maxY, opt_extent) ;
}
export function buffer ( extent, value, opt_extent ) {
if ( opt_extent) {
opt_extent[ 0 ] = extent[ 0 ] - value;
opt_extent[ 1 ] = extent[ 1 ] - value;
opt_extent[ 2 ] = extent[ 2 ] + value;
opt_extent[ 3 ] = extent[ 3 ] + value;
return opt_extent;
} else {
return [
extent[ 0 ] - value,
extent[ 1 ] - value,
extent[ 2 ] + value,
extent[ 3 ] + value,
] ;
}
}
export function clone ( extent, opt_extent ) {
if ( opt_extent) {
opt_extent[ 0 ] = extent[ 0 ] ;
opt_extent[ 1 ] = extent[ 1 ] ;
opt_extent[ 2 ] = extent[ 2 ] ;
opt_extent[ 3 ] = extent[ 3 ] ;
return opt_extent;
} else {
return extent. slice ( ) ;
}
}
export function closestSquaredDistanceXY ( extent, x, y ) {
let dx, dy;
if ( x < extent[ 0 ] ) {
dx = extent[ 0 ] - x;
} else if ( extent[ 2 ] < x) {
dx = x - extent[ 2 ] ;
} else {
dx = 0 ;
}
if ( y < extent[ 1 ] ) {
dy = extent[ 1 ] - y;
} else if ( extent[ 3 ] < y) {
dy = y - extent[ 3 ] ;
} else {
dy = 0 ;
}
return dx * dx + dy * dy;
}
export function containsCoordinate ( extent, coordinate ) {
return containsXY ( extent, coordinate[ 0 ] , coordinate[ 1 ] ) ;
}
export function containsExtent ( extent1, extent2 ) {
return (
extent1[ 0 ] <= extent2[ 0 ] &&
extent2[ 2 ] <= extent1[ 2 ] &&
extent1[ 1 ] <= extent2[ 1 ] &&
extent2[ 3 ] <= extent1[ 3 ]
) ;
}
export function containsXY ( extent, x, y ) {
return extent[ 0 ] <= x && x <= extent[ 2 ] && extent[ 1 ] <= y && y <= extent[ 3 ] ;
}
export function coordinateRelationship ( extent, coordinate ) {
const minX = extent[ 0 ] ;
const minY = extent[ 1 ] ;
const maxX = extent[ 2 ] ;
const maxY = extent[ 3 ] ;
const x = coordinate[ 0 ] ;
const y = coordinate[ 1 ] ;
let relationship = Relationship. UNKNOWN ;
if ( x < minX) {
relationship = relationship | Relationship. LEFT ;
} else if ( x > maxX) {
relationship = relationship | Relationship. RIGHT ;
}
if ( y < minY) {
relationship = relationship | Relationship. BELOW ;
} else if ( y > maxY) {
relationship = relationship | Relationship. ABOVE ;
}
if ( relationship === Relationship. UNKNOWN ) {
relationship = Relationship. INTERSECTING ;
}
return relationship;
}
export function createEmpty ( ) {
return [ Infinity , Infinity , - Infinity , - Infinity ] ;
}
export function createOrUpdate ( minX, minY, maxX, maxY, opt_extent ) {
if ( opt_extent) {
opt_extent[ 0 ] = minX;
opt_extent[ 1 ] = minY;
opt_extent[ 2 ] = maxX;
opt_extent[ 3 ] = maxY;
return opt_extent;
} else {
return [ minX, minY, maxX, maxY] ;
}
}
export function createOrUpdateEmpty ( opt_extent ) {
return createOrUpdate ( Infinity , Infinity , - Infinity , - Infinity , opt_extent) ;
}
export function createOrUpdateFromCoordinate ( coordinate, opt_extent ) {
const x = coordinate[ 0 ] ;
const y = coordinate[ 1 ] ;
return createOrUpdate ( x, y, x, y, opt_extent) ;
}
export function createOrUpdateFromCoordinates ( coordinates, opt_extent ) {
const extent = createOrUpdateEmpty ( opt_extent) ;
return extendCoordinates ( extent, coordinates) ;
}
export function createOrUpdateFromFlatCoordinates (
flatCoordinates,
offset,
end,
stride,
opt_extent
) {
const extent = createOrUpdateEmpty ( opt_extent) ;
return extendFlatCoordinates ( extent, flatCoordinates, offset, end, stride) ;
}
export function createOrUpdateFromRings ( rings, opt_extent ) {
const extent = createOrUpdateEmpty ( opt_extent) ;
return extendRings ( extent, rings) ;
}
export function equals ( extent1, extent2 ) {
return (
extent1[ 0 ] == extent2[ 0 ] &&
extent1[ 2 ] == extent2[ 2 ] &&
extent1[ 1 ] == extent2[ 1 ] &&
extent1[ 3 ] == extent2[ 3 ]
) ;
}
export function approximatelyEquals ( extent1, extent2, tolerance ) {
return (
Math. abs ( extent1[ 0 ] - extent2[ 0 ] ) < tolerance &&
Math. abs ( extent1[ 2 ] - extent2[ 2 ] ) < tolerance &&
Math. abs ( extent1[ 1 ] - extent2[ 1 ] ) < tolerance &&
Math. abs ( extent1[ 3 ] - extent2[ 3 ] ) < tolerance
) ;
}
export function extend ( extent1, extent2 ) {
if ( extent2[ 0 ] < extent1[ 0 ] ) {
extent1[ 0 ] = extent2[ 0 ] ;
}
if ( extent2[ 2 ] > extent1[ 2 ] ) {
extent1[ 2 ] = extent2[ 2 ] ;
}
if ( extent2[ 1 ] < extent1[ 1 ] ) {
extent1[ 1 ] = extent2[ 1 ] ;
}
if ( extent2[ 3 ] > extent1[ 3 ] ) {
extent1[ 3 ] = extent2[ 3 ] ;
}
return extent1;
}
export function extendCoordinate ( extent, coordinate ) {
if ( coordinate[ 0 ] < extent[ 0 ] ) {
extent[ 0 ] = coordinate[ 0 ] ;
}
if ( coordinate[ 0 ] > extent[ 2 ] ) {
extent[ 2 ] = coordinate[ 0 ] ;
}
if ( coordinate[ 1 ] < extent[ 1 ] ) {
extent[ 1 ] = coordinate[ 1 ] ;
}
if ( coordinate[ 1 ] > extent[ 3 ] ) {
extent[ 3 ] = coordinate[ 1 ] ;
}
}
export function extendCoordinates ( extent, coordinates ) {
for ( let i = 0 , ii = coordinates. length; i < ii; ++ i) {
extendCoordinate ( extent, coordinates[ i] ) ;
}
return extent;
}
export function extendFlatCoordinates (
extent,
flatCoordinates,
offset,
end,
stride
) {
for ( ; offset < end; offset += stride) {
extendXY ( extent, flatCoordinates[ offset] , flatCoordinates[ offset + 1 ] ) ;
}
return extent;
}
export function extendRings ( extent, rings ) {
for ( let i = 0 , ii = rings. length; i < ii; ++ i) {
extendCoordinates ( extent, rings[ i] ) ;
}
return extent;
}
export function extendXY ( extent, x, y ) {
extent[ 0 ] = Math. min ( extent[ 0 ] , x) ;
extent[ 1 ] = Math. min ( extent[ 1 ] , y) ;
extent[ 2 ] = Math. max ( extent[ 2 ] , x) ;
extent[ 3 ] = Math. max ( extent[ 3 ] , y) ;
}
export function forEachCorner ( extent, callback ) {
let val;
val = callback ( getBottomLeft ( extent) ) ;
if ( val) {
return val;
}
val = callback ( getBottomRight ( extent) ) ;
if ( val) {
return val;
}
val = callback ( getTopRight ( extent) ) ;
if ( val) {
return val;
}
val = callback ( getTopLeft ( extent) ) ;
if ( val) {
return val;
}
return false ;
}
export function getArea ( extent ) {
let area = 0 ;
if ( ! isEmpty ( extent) ) {
area = getWidth ( extent) * getHeight ( extent) ;
}
return area;
}
export function getBottomLeft ( extent ) {
return [ extent[ 0 ] , extent[ 1 ] ] ;
}
export function getBottomRight ( extent ) {
return [ extent[ 2 ] , extent[ 1 ] ] ;
}
export function getCenter ( extent ) {
return [ ( extent[ 0 ] + extent[ 2 ] ) / 2 , ( extent[ 1 ] + extent[ 3 ] ) / 2 ] ;
}
export function getCorner ( extent, corner ) {
let coordinate;
if ( corner === Corner. BOTTOM_LEFT ) {
coordinate = getBottomLeft ( extent) ;
} else if ( corner === Corner. BOTTOM_RIGHT ) {
coordinate = getBottomRight ( extent) ;
} else if ( corner === Corner. TOP_LEFT ) {
coordinate = getTopLeft ( extent) ;
} else if ( corner === Corner. TOP_RIGHT ) {
coordinate = getTopRight ( extent) ;
} else {
assert ( false , 13 ) ;
}
return coordinate;
}
export function getEnlargedArea ( extent1, extent2 ) {
const minX = Math. min ( extent1[ 0 ] , extent2[ 0 ] ) ;
const minY = Math. min ( extent1[ 1 ] , extent2[ 1 ] ) ;
const maxX = Math. max ( extent1[ 2 ] , extent2[ 2 ] ) ;
const maxY = Math. max ( extent1[ 3 ] , extent2[ 3 ] ) ;
return ( maxX - minX) * ( maxY - minY) ;
}
export function getForViewAndSize (
center,
resolution,
rotation,
size,
opt_extent
) {
const dx = ( resolution * size[ 0 ] ) / 2 ;
const dy = ( resolution * size[ 1 ] ) / 2 ;
const cosRotation = Math. cos ( rotation) ;
const sinRotation = Math. sin ( rotation) ;
const xCos = dx * cosRotation;
const xSin = dx * sinRotation;
const yCos = dy * cosRotation;
const ySin = dy * sinRotation;
const x = center[ 0 ] ;
const y = center[ 1 ] ;
const x0 = x - xCos + ySin;
const x1 = x - xCos - ySin;
const x2 = x + xCos - ySin;
const x3 = x + xCos + ySin;
const y0 = y - xSin - yCos;
const y1 = y - xSin + yCos;
const y2 = y + xSin + yCos;
const y3 = y + xSin - yCos;
return createOrUpdate (
Math. min ( x0, x1, x2, x3) ,
Math. min ( y0, y1, y2, y3) ,
Math. max ( x0, x1, x2, x3) ,
Math. max ( y0, y1, y2, y3) ,
opt_extent
) ;
}
export function getHeight ( extent ) {
return extent[ 3 ] - extent[ 1 ] ;
}
export function getIntersectionArea ( extent1, extent2 ) {
const intersection = getIntersection ( extent1, extent2) ;
return getArea ( intersection) ;
}
export function getIntersection ( extent1, extent2, opt_extent ) {
const intersection = opt_extent ? opt_extent : createEmpty ( ) ;
if ( intersects ( extent1, extent2) ) {
if ( extent1[ 0 ] > extent2[ 0 ] ) {
intersection[ 0 ] = extent1[ 0 ] ;
} else {
intersection[ 0 ] = extent2[ 0 ] ;
}
if ( extent1[ 1 ] > extent2[ 1 ] ) {
intersection[ 1 ] = extent1[ 1 ] ;
} else {
intersection[ 1 ] = extent2[ 1 ] ;
}
if ( extent1[ 2 ] < extent2[ 2 ] ) {
intersection[ 2 ] = extent1[ 2 ] ;
} else {
intersection[ 2 ] = extent2[ 2 ] ;
}
if ( extent1[ 3 ] < extent2[ 3 ] ) {
intersection[ 3 ] = extent1[ 3 ] ;
} else {
intersection[ 3 ] = extent2[ 3 ] ;
}
} else {
createOrUpdateEmpty ( intersection) ;
}
return intersection;
}
export function getMargin ( extent ) {
return getWidth ( extent) + getHeight ( extent) ;
}
export function getSize ( extent ) {
return [ extent[ 2 ] - extent[ 0 ] , extent[ 3 ] - extent[ 1 ] ] ;
}
export function getTopLeft ( extent ) {
return [ extent[ 0 ] , extent[ 3 ] ] ;
}
export function getTopRight ( extent ) {
return [ extent[ 2 ] , extent[ 3 ] ] ;
}
export function getWidth ( extent ) {
return extent[ 2 ] - extent[ 0 ] ;
}
export function intersects ( extent1, extent2 ) {
return (
extent1[ 0 ] <= extent2[ 2 ] &&
extent1[ 2 ] >= extent2[ 0 ] &&
extent1[ 1 ] <= extent2[ 3 ] &&
extent1[ 3 ] >= extent2[ 1 ]
) ;
}
export function isEmpty ( extent ) {
return extent[ 2 ] < extent[ 0 ] || extent[ 3 ] < extent[ 1 ] ;
}
export function returnOrUpdate ( extent, opt_extent ) {
if ( opt_extent) {
opt_extent[ 0 ] = extent[ 0 ] ;
opt_extent[ 1 ] = extent[ 1 ] ;
opt_extent[ 2 ] = extent[ 2 ] ;
opt_extent[ 3 ] = extent[ 3 ] ;
return opt_extent;
} else {
return extent;
}
}
export function scaleFromCenter ( extent, value ) {
const deltaX = ( ( extent[ 2 ] - extent[ 0 ] ) / 2 ) * ( value - 1 ) ;
const deltaY = ( ( extent[ 3 ] - extent[ 1 ] ) / 2 ) * ( value - 1 ) ;
extent[ 0 ] -= deltaX;
extent[ 2 ] += deltaX;
extent[ 1 ] -= deltaY;
extent[ 3 ] += deltaY;
}
export function intersectsSegment ( extent, start, end ) {
let intersects = false ;
const startRel = coordinateRelationship ( extent, start) ;
const endRel = coordinateRelationship ( extent, end) ;
if (
startRel === Relationship. INTERSECTING ||
endRel === Relationship. INTERSECTING
) {
intersects = true ;
} else {
const minX = extent[ 0 ] ;
const minY = extent[ 1 ] ;
const maxX = extent[ 2 ] ;
const maxY = extent[ 3 ] ;
const startX = start[ 0 ] ;
const startY = start[ 1 ] ;
const endX = end[ 0 ] ;
const endY = end[ 1 ] ;
const slope = ( endY - startY) / ( endX - startX) ;
let x, y;
if ( ! ! ( endRel & Relationship. ABOVE ) && ! ( startRel & Relationship. ABOVE ) ) {
x = endX - ( endY - maxY) / slope;
intersects = x >= minX && x <= maxX;
}
if (
! intersects &&
! ! ( endRel & Relationship. RIGHT ) &&
! ( startRel & Relationship. RIGHT )
) {
y = endY - ( endX - maxX) * slope;
intersects = y >= minY && y <= maxY;
}
if (
! intersects &&
! ! ( endRel & Relationship. BELOW ) &&
! ( startRel & Relationship. BELOW )
) {
x = endX - ( endY - minY) / slope;
intersects = x >= minX && x <= maxX;
}
if (
! intersects &&
! ! ( endRel & Relationship. LEFT ) &&
! ( startRel & Relationship. LEFT )
) {
y = endY - ( endX - minX) * slope;
intersects = y >= minY && y <= maxY;
}
}
return intersects;
}
export function applyTransform ( extent, transformFn, opt_extent, opt_stops ) {
let coordinates = [ ] ;
if ( opt_stops > 1 ) {
const width = extent[ 2 ] - extent[ 0 ] ;
const height = extent[ 3 ] - extent[ 1 ] ;
for ( let i = 0 ; i < opt_stops; ++ i) {
coordinates. push (
extent[ 0 ] + ( width * i) / opt_stops,
extent[ 1 ] ,
extent[ 2 ] ,
extent[ 1 ] + ( height * i) / opt_stops,
extent[ 2 ] - ( width * i) / opt_stops,
extent[ 3 ] ,
extent[ 0 ] ,
extent[ 3 ] - ( height * i) / opt_stops
) ;
}
} else {
coordinates = [
extent[ 0 ] ,
extent[ 1 ] ,
extent[ 2 ] ,
extent[ 1 ] ,
extent[ 2 ] ,
extent[ 3 ] ,
extent[ 0 ] ,
extent[ 3 ] ,
] ;
}
transformFn ( coordinates, coordinates, 2 ) ;
const xs = [ ] ;
const ys = [ ] ;
for ( let i = 0 , l = coordinates. length; i < l; i += 2 ) {
xs. push ( coordinates[ i] ) ;
ys. push ( coordinates[ i + 1 ] ) ;
}
return _boundingExtentXYs ( xs, ys, opt_extent) ;
}
export function wrapX ( extent, projection ) {
const projectionExtent = projection. getExtent ( ) ;
const center = getCenter ( extent) ;
if (
projection. canWrapX ( ) &&
( center[ 0 ] < projectionExtent[ 0 ] || center[ 0 ] >= projectionExtent[ 2 ] )
) {
const worldWidth = getWidth ( projectionExtent) ;
const worldsAway = Math. floor (
( center[ 0 ] - projectionExtent[ 0 ] ) / worldWidth
) ;
const offset = worldsAway * worldWidth;
extent[ 0 ] -= offset;
extent[ 2 ] -= offset;
}
return extent;
}