goog.provide('ol.Coordinate'); goog.provide('ol.CoordinateArray'); goog.provide('ol.CoordinateFormatType'); goog.provide('ol.coordinate'); goog.require('goog.math'); /** * A function that takes a {@link ol.Coordinate} and transforms it into a * `{string}`. * * @typedef {function((ol.Coordinate|undefined)): string} * @todo api */ ol.CoordinateFormatType; /** * An array of numbers representing a coordinate. Example: `[16, 48]`. * @typedef {Array.} ol.Coordinate * @todo api */ ol.Coordinate; /** * An array of coordinate arrays. * @typedef {Array.} * @todo api */ ol.CoordinateArray; /** * @param {ol.Coordinate} coordinate Coordinate. * @param {ol.Coordinate} delta Delta. * @return {ol.Coordinate} Coordinate. * @todo api */ ol.coordinate.add = function(coordinate, delta) { coordinate[0] += delta[0]; coordinate[1] += delta[1]; return coordinate; }; /** * Calculates the point closest to the passed coordinate on the passed segment. * This is the foot of the perpendicular of the coordinate to the segment when * the foot is on the segment, or the closest segment coordinate when the foot * is outside the segment. * * @param {ol.Coordinate} coordinate The coordinate. * @param {Array.} segment The two coordinates of the segment. * @return {ol.Coordinate} The foot of the perpendicular of the coordinate to * the segment. */ ol.coordinate.closestOnSegment = function(coordinate, segment) { var x0 = coordinate[0]; var y0 = coordinate[1]; var start = segment[0]; var end = segment[1]; var x1 = start[0]; var y1 = start[1]; var x2 = end[0]; var y2 = end[1]; var dx = x2 - x1; var dy = y2 - y1; var along = (dx === 0 && dy === 0) ? 0 : ((dx * (x0 - x1)) + (dy * (y0 - y1))) / ((dx * dx + dy * dy) || 0); var x, y; if (along <= 0) { x = x1; y = y1; } else if (along >= 1) { x = x2; y = y2; } else { x = x1 + along * dx; y = y1 + along * dy; } return [x, y]; }; /** * @param {number=} opt_fractionDigits The number of digits to include * after the decimal point. Default is `0`. * @return {ol.CoordinateFormatType} Coordinate format. * @todo api */ ol.coordinate.createStringXY = function(opt_fractionDigits) { return ( /** * @param {ol.Coordinate|undefined} coordinate Coordinate. * @return {string} String XY. */ function(coordinate) { return ol.coordinate.toStringXY(coordinate, opt_fractionDigits); }); }; /** * @private * @param {number} degrees Degrees. * @param {string} hemispheres Hemispheres. * @return {string} String. */ ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres) { var normalizedDegrees = goog.math.modulo(degrees + 180, 360) - 180; var x = Math.abs(Math.round(3600 * normalizedDegrees)); return Math.floor(x / 3600) + '\u00b0 ' + Math.floor((x / 60) % 60) + '\u2032 ' + Math.floor(x % 60) + '\u2033 ' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0); }; /** * @param {ol.Coordinate|undefined} coordinate Coordinate. * @param {string} template A template string with `{x}` and `{y}` placeholders * that will be replaced by first and second coordinate values. * @param {number=} opt_fractionDigits The number of digits to include * after the decimal point. Default is `0`. * @return {string} Formated coordinate. * @todo api */ ol.coordinate.format = function(coordinate, template, opt_fractionDigits) { if (goog.isDef(coordinate)) { return template .replace('{x}', coordinate[0].toFixed(opt_fractionDigits)) .replace('{y}', coordinate[1].toFixed(opt_fractionDigits)); } else { return ''; } }; /** * @param {ol.Coordinate} coordinate1 First coordinate. * @param {ol.Coordinate} coordinate2 Second coordinate. * @return {boolean} Whether the passed coordinates are equal. */ ol.coordinate.equals = function(coordinate1, coordinate2) { var equals = true; for (var i = coordinate1.length - 1; i >= 0; --i) { if (coordinate1[i] != coordinate2[i]) { equals = false; break; } } return equals; }; /** * @param {ol.Coordinate} coordinate Coordinate. * @param {number} angle Angle. * @return {ol.Coordinate} Coordinate. * @todo api */ ol.coordinate.rotate = function(coordinate, angle) { var cosAngle = Math.cos(angle); var sinAngle = Math.sin(angle); var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle; var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle; coordinate[0] = x; coordinate[1] = y; return coordinate; }; /** * @param {ol.Coordinate} coordinate Coordinate. * @param {number} s Scale. * @return {ol.Coordinate} Coordinate. */ ol.coordinate.scale = function(coordinate, s) { coordinate[0] *= s; coordinate[1] *= s; return coordinate; }; /** * @param {ol.Coordinate} coordinate Coordinate. * @param {ol.Coordinate} delta Delta. * @return {ol.Coordinate} Coordinate. */ ol.coordinate.sub = function(coordinate, delta) { coordinate[0] -= delta[0]; coordinate[1] -= delta[1]; return coordinate; }; /** * @param {ol.Coordinate} coord1 First coordinate. * @param {ol.Coordinate} coord2 Second coordinate. * @return {number} Squared distance between coord1 and coord2. */ ol.coordinate.squaredDistance = function(coord1, coord2) { var dx = coord1[0] - coord2[0]; var dy = coord1[1] - coord2[1]; return dx * dx + dy * dy; }; /** * Calculate the squared distance from a coordinate to a line segment. * * @param {ol.Coordinate} coordinate Coordinate of the point. * @param {Array.} segment Line segment (2 coordinates). * @return {number} Squared distance from the point to the line segment. */ ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) { return ol.coordinate.squaredDistance(coordinate, ol.coordinate.closestOnSegment(coordinate, segment)); }; /** * @param {ol.Coordinate|undefined} coordinate Coordinate. * @return {string} Hemisphere, degrees, minutes and seconds. * @todo api */ ol.coordinate.toStringHDMS = function(coordinate) { if (goog.isDef(coordinate)) { return ol.coordinate.degreesToStringHDMS_(coordinate[1], 'NS') + ' ' + ol.coordinate.degreesToStringHDMS_(coordinate[0], 'EW'); } else { return ''; } }; /** * @param {ol.Coordinate|undefined} coordinate Coordinate. * @param {number=} opt_fractionDigits The number of digits to include * after the decimal point. Default is `0`. * @return {string} XY. * @todo api */ ol.coordinate.toStringXY = function(coordinate, opt_fractionDigits) { return ol.coordinate.format(coordinate, '{x}, {y}', opt_fractionDigits); }; /** * Create an ol.Coordinate from an Array and take into account axis order. * @param {Array} array The array with coordinates. * @param {string} axis the axis info. * @return {ol.Coordinate} The coordinate created. * @todo api */ ol.coordinate.fromProjectedArray = function(array, axis) { var firstAxis = axis.charAt(0); if (firstAxis === 'n' || firstAxis === 's') { return [array[1], array[0]]; } else { return array; } };