Files
openlayers/src/ol/geom/flatgeom.js

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;
};