351 lines
10 KiB
JavaScript
351 lines
10 KiB
JavaScript
goog.provide('ol.geom.flat');
|
|
|
|
goog.require('goog.asserts');
|
|
goog.require('goog.vec.Mat4');
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<ol.Coordinate>} coordinates Coordinates.
|
|
* @param {number} stride Stride.
|
|
* @return {number} offset Offset.
|
|
*/
|
|
ol.geom.flat.deflateCoordinates =
|
|
function(flatCoordinates, offset, coordinates, stride) {
|
|
var i, ii;
|
|
for (i = 0, ii = coordinates.length; i < ii; ++i) {
|
|
var coordinate = coordinates[i];
|
|
goog.asserts.assert(coordinate.length == stride);
|
|
var j;
|
|
for (j = 0; j < stride; ++j) {
|
|
flatCoordinates[offset++] = coordinate[j];
|
|
}
|
|
}
|
|
return offset;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<Array.<ol.Coordinate>>} coordinatess Coordinatess.
|
|
* @param {number} stride Stride.
|
|
* @param {Array.<number>=} opt_ends Ends.
|
|
* @return {Array.<number>} Ends.
|
|
*/
|
|
ol.geom.flat.deflateCoordinatess =
|
|
function(flatCoordinates, offset, coordinatess, stride, opt_ends) {
|
|
var ends = goog.isDef(opt_ends) ? opt_ends : [];
|
|
var i = 0;
|
|
var j, jj;
|
|
for (j = 0, jj = coordinatess.length; j < jj; ++j) {
|
|
var end = ol.geom.flat.deflateCoordinates(
|
|
flatCoordinates, offset, coordinatess[j], stride);
|
|
ends[i++] = end;
|
|
offset = end;
|
|
}
|
|
ends.length = i;
|
|
return ends;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<Array.<Array.<ol.Coordinate>>>} coordinatesss Coordinatesss.
|
|
* @param {number} stride Stride.
|
|
* @param {Array.<Array.<number>>=} opt_endss Endss.
|
|
* @return {Array.<Array.<number>>} Endss.
|
|
*/
|
|
ol.geom.flat.deflateCoordinatesss =
|
|
function(flatCoordinates, offset, coordinatesss, stride, opt_endss) {
|
|
var endss = goog.isDef(opt_endss) ? opt_endss : [];
|
|
var i = 0;
|
|
var j, jj;
|
|
for (j = 0, jj = coordinatesss.length; j < jj; ++j) {
|
|
var ends = ol.geom.flat.deflateCoordinatess(
|
|
flatCoordinates, offset, coordinatesss[j], stride, endss[i]);
|
|
endss[i++] = ends;
|
|
offset = ends[ends.length - 1];
|
|
}
|
|
return endss;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {number} end End.
|
|
* @param {number} stride Stride.
|
|
* @param {Array.<ol.Coordinate>=} opt_coordinates Coordinates.
|
|
* @return {Array.<ol.Coordinate>} Coordinates.
|
|
*/
|
|
ol.geom.flat.inflateCoordinates =
|
|
function(flatCoordinates, offset, end, stride, opt_coordinates) {
|
|
var coordinates = goog.isDef(opt_coordinates) ? opt_coordinates : [];
|
|
var i = 0;
|
|
var j;
|
|
for (j = offset; j < end; j += stride) {
|
|
coordinates[i++] = flatCoordinates.slice(j, j + stride);
|
|
}
|
|
coordinates.length = i;
|
|
return coordinates;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<number>} ends Ends.
|
|
* @param {number} stride Stride.
|
|
* @param {Array.<Array.<ol.Coordinate>>=} opt_coordinatess Coordinatess.
|
|
* @return {Array.<Array.<ol.Coordinate>>} Coordinatess.
|
|
*/
|
|
ol.geom.flat.inflateCoordinatess =
|
|
function(flatCoordinates, offset, ends, stride, opt_coordinatess) {
|
|
var coordinatess = goog.isDef(opt_coordinatess) ? opt_coordinatess : [];
|
|
var i = 0;
|
|
var j, jj;
|
|
for (j = 0, jj = ends.length; j < jj; ++j) {
|
|
var end = ends[j];
|
|
coordinatess[i++] = ol.geom.flat.inflateCoordinates(
|
|
flatCoordinates, offset, end, stride, coordinatess[i]);
|
|
offset = end;
|
|
}
|
|
coordinatess.length = i;
|
|
return coordinatess;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<Array.<number>>} endss Endss.
|
|
* @param {number} stride Stride.
|
|
* @param {Array.<Array.<Array.<ol.Coordinate>>>=} opt_coordinatesss
|
|
* Coordinatesss.
|
|
* @return {Array.<Array.<Array.<ol.Coordinate>>>} Coordinatesss.
|
|
*/
|
|
ol.geom.flat.inflateCoordinatesss =
|
|
function(flatCoordinates, offset, endss, stride, opt_coordinatesss) {
|
|
var coordinatesss = goog.isDef(opt_coordinatesss) ? opt_coordinatesss : [];
|
|
var i = 0;
|
|
var j, jj;
|
|
for (j = 0, jj = endss.length; j < jj; ++j) {
|
|
var ends = endss[j];
|
|
coordinatesss[i++] = ol.geom.flat.inflateCoordinatess(
|
|
flatCoordinates, offset, ends, stride, coordinatesss[i]);
|
|
offset = ends[ends.length - 1];
|
|
}
|
|
coordinatesss.length = i;
|
|
return coordinatesss;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {number} end End.
|
|
* @param {number} stride Stride.
|
|
* @param {number} x X.
|
|
* @param {number} y Y.
|
|
* @return {boolean} Contains (x, y).
|
|
*/
|
|
ol.geom.flat.linearRingContainsXY =
|
|
function(flatCoordinates, offset, end, stride, x, y) {
|
|
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
|
var contains = false;
|
|
var xi = flatCoordinates[offset];
|
|
var yi = flatCoordinates[offset + 1];
|
|
for (offset += stride; offset < end; offset += stride) {
|
|
var xj = flatCoordinates[offset];
|
|
var yj = flatCoordinates[offset + 1];
|
|
var intersect = ((yi > y) != (yj > y)) &&
|
|
(x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
|
if (intersect) {
|
|
contains = !contains;
|
|
}
|
|
xi = xj;
|
|
yi = yj;
|
|
}
|
|
return contains;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {number} end End.
|
|
* @param {number} stride Stride.
|
|
* @return {boolean} Is clockwise.
|
|
*/
|
|
ol.geom.flat.linearRingIsClockwise =
|
|
function(flatCoordinates, offset, end, stride) {
|
|
// http://tinyurl.com/clockwise-method
|
|
// https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
|
|
var edge = 0;
|
|
var x1 = flatCoordinates[end - stride];
|
|
var y1 = flatCoordinates[end - stride + 1];
|
|
for (; offset < end; offset += stride) {
|
|
var x2 = flatCoordinates[offset];
|
|
var y2 = flatCoordinates[offset + 1];
|
|
edge += (x2 - x1) * (y2 + y1);
|
|
x1 = x2;
|
|
y1 = y2;
|
|
}
|
|
return edge > 0;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<number>} ends Ends.
|
|
* @param {number} stride Stride.
|
|
* @param {number} x X.
|
|
* @param {number} y Y.
|
|
* @return {boolean} Contains (x, y).
|
|
*/
|
|
ol.geom.flat.linearRingsContainsXY =
|
|
function(flatCoordinates, offset, ends, stride, x, y) {
|
|
goog.asserts.assert(ends.length > 0);
|
|
if (ends.length === 0) {
|
|
return false;
|
|
}
|
|
if (!ol.geom.flat.linearRingContainsXY(
|
|
flatCoordinates, offset, ends[0], stride, x, y)) {
|
|
return false;
|
|
}
|
|
var i, ii;
|
|
for (i = 1, ii = ends.length; i < ii; ++i) {
|
|
if (ol.geom.flat.linearRingContainsXY(
|
|
flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<Array.<number>>} endss Endss.
|
|
* @param {number} stride Stride.
|
|
* @param {number} x X.
|
|
* @param {number} y Y.
|
|
* @return {boolean} Contains (x, y).
|
|
*/
|
|
ol.geom.flat.linearRingssContainsXY =
|
|
function(flatCoordinates, offset, endss, stride, x, y) {
|
|
goog.asserts.assert(endss.length > 0);
|
|
if (endss.length === 0) {
|
|
return false;
|
|
}
|
|
var i, ii;
|
|
for (i = 0, ii = endss.length; i < ii; ++i) {
|
|
var ends = endss[i];
|
|
if (ol.geom.flat.linearRingsContainsXY(
|
|
flatCoordinates, offset, ends, stride, x, y)) {
|
|
return true;
|
|
}
|
|
offset = ends[ends.length - 1];
|
|
}
|
|
return false;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<number>} ends Ends.
|
|
* @param {number} stride Stride.
|
|
* @return {number} End.
|
|
*/
|
|
ol.geom.flat.orientLinearRings =
|
|
function(flatCoordinates, offset, ends, stride) {
|
|
var i, ii;
|
|
for (i = 0, ii = ends.length; i < ii; ++i) {
|
|
var end = ends[i];
|
|
var isClockwise = ol.geom.flat.linearRingIsClockwise(
|
|
flatCoordinates, offset, end, stride);
|
|
var reverse = i === 0 ? !isClockwise : isClockwise;
|
|
if (reverse) {
|
|
ol.geom.flat.reverseCoordinates(flatCoordinates, offset, end, stride);
|
|
}
|
|
offset = end;
|
|
}
|
|
return offset;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {Array.<Array.<number>>} endss Endss.
|
|
* @param {number} stride Stride.
|
|
* @return {number} End.
|
|
*/
|
|
ol.geom.flat.orientLinearRingss =
|
|
function(flatCoordinates, offset, endss, stride) {
|
|
var i, ii;
|
|
for (i = 0, ii = endss.length; i < ii; ++i) {
|
|
offset = ol.geom.flat.orientLinearRings(
|
|
flatCoordinates, offset, endss[i], stride);
|
|
}
|
|
return offset;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} offset Offset.
|
|
* @param {number} end End.
|
|
* @param {number} stride Stride.
|
|
*/
|
|
ol.geom.flat.reverseCoordinates =
|
|
function(flatCoordinates, offset, end, stride) {
|
|
while (offset < end - stride) {
|
|
var i;
|
|
for (i = 0; i < stride; ++i) {
|
|
var tmp = flatCoordinates[offset + i];
|
|
flatCoordinates[offset + i] = flatCoordinates[end - stride + i];
|
|
flatCoordinates[end - stride + i] = tmp;
|
|
}
|
|
offset += stride;
|
|
end -= stride;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
* @param {number} stride Stride.
|
|
* @param {goog.vec.Mat4.AnyType} transform Transform.
|
|
* @param {Array.<number>=} opt_dest Destination.
|
|
* @return {Array.<number>} Transformed coordinates.
|
|
*/
|
|
ol.geom.flat.transform2D =
|
|
function(flatCoordinates, stride, transform, opt_dest) {
|
|
var m00 = goog.vec.Mat4.getElement(transform, 0, 0);
|
|
var m10 = goog.vec.Mat4.getElement(transform, 1, 0);
|
|
var m01 = goog.vec.Mat4.getElement(transform, 0, 1);
|
|
var m11 = goog.vec.Mat4.getElement(transform, 1, 1);
|
|
var m03 = goog.vec.Mat4.getElement(transform, 0, 3);
|
|
var m13 = goog.vec.Mat4.getElement(transform, 1, 3);
|
|
var dest = goog.isDef(opt_dest) ? opt_dest : [];
|
|
var i = 0;
|
|
var j, jj;
|
|
for (j = 0, jj = flatCoordinates.length; j < jj; j += stride) {
|
|
var x = flatCoordinates[j];
|
|
var y = flatCoordinates[j + 1];
|
|
dest[i++] = m00 * x + m01 * y + m03;
|
|
dest[i++] = m10 * x + m11 * y + m13;
|
|
}
|
|
if (goog.isDef(opt_dest) && dest.length != i) {
|
|
dest.length = i;
|
|
}
|
|
return dest;
|
|
};
|