Skip to content

Commit

Permalink
Merge pull request #555 from OpenGeoscience/switch-to-earcut
Browse files Browse the repository at this point in the history
Switch to earcut for triangulating polygons
  • Loading branch information
jbeezley committed Apr 12, 2016
2 parents 7241ef2 + 1ca5558 commit 1ff57c7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 130 deletions.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
src/vgl/**
src/version.js
src/util/wigglemaps.js
src/util/pnltri.js
src/util/distanceGrid.js
geo.js
**/*.min.js
4 changes: 2 additions & 2 deletions docs/users.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ list of libraries used by GeoJS.
+---------------------------+------------+---------------------------+
| `GL matrix`_ | 2.1 | Core, GL renderer |
+---------------------------+------------+---------------------------+
| `pnltri`_ | 2.1 | GL polygon feature |
| `earcut`_ | 2.1 | GL polygon feature |
+---------------------------+------------+---------------------------+

.. table:: External GeoJS dependencies
Expand All @@ -52,7 +52,7 @@ list of libraries used by GeoJS.
.. _jQuery: http://jquery.com/
.. _proj4: http://proj4js.org/
.. _GL matrix: http://glmatrix.net/
.. _pnltri: https://github.com/jahting/pnltri.js/
.. _earcut: https://github.com/mapbox/earcut/
.. _d3: http://d3js.org/


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"bootswatch": "^3.3.6",
"codecov.io": "^0.1.6",
"codemirror": "^4.7.0",
"earcut": "^2.1.1",
"eslint": "^1.10.3",
"eslint-config-semistandard": "^5.0.1",
"eslint-config-standard": "^4.4.0",
Expand Down Expand Up @@ -56,7 +57,6 @@
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"phantomjs-prebuilt": "^2.1.5",
"pnltri": "^2.1.1",
"proj4": "^2.3.14",
"raw-body": "^2.1.6",
"sinon": "^1.17.3",
Expand Down
184 changes: 61 additions & 123 deletions src/gl/polygonFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var gl_polygonFeature = function (arg) {
polygonFeature.call(this, arg);

var vgl = require('vgl');
var Triangulator = require('pnltri').Triangulator;
var earcut = require('earcut');
var transform = require('../transform');

////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -80,19 +80,8 @@ var gl_polygonFeature = function (arg) {
}

function createGLPolygons() {
var i = null,
numPts = null,
start = null,
itemIndex = 0,
polygonItemCoordIndex = 0,
position = [],
fillColor = [],
fillOpacity = [],
fillColorNew = [],
fillOpacityNew = [],
posFunc = null,
var posFunc = null,
fillColorFunc = null,
polygonItem = null,
fillOpacityFunc = null,
buffers = vgl.DataBuffers(1024),
sourcePositions = vgl.sourceDataP3fv(),
Expand All @@ -102,128 +91,78 @@ var gl_polygonFeature = function (arg) {
vgl.sourceDataAnyfv(1, vgl.vertexAttributeKeysIndexed.Three),
trianglePrimitive = vgl.triangles(),
geom = vgl.geometryData(),
polygon = null,
holes = null,
extRing = null,
extIndex = 0,
extLength = null,
intIndex = 0,
posInstance = null,
triangulator = new Triangulator(),
triangList = null,
newTriangList = null,
fillColorInstance = null;
triangles = [],
target_gcs = m_this.gcs(),
map_gcs = m_this.layer().map().gcs(),
color;

posFunc = m_this.position();
fillColorFunc = m_this.style.get('fillColor');
fillOpacityFunc = m_this.style.get('fillOpacity');

m_this.data().forEach(function (item) {
polygon = m_this.polygon()(item, itemIndex);
polygonItem = polygon.outer || [];
holes = polygon.inner || [];
polygonItemCoordIndex = 0;
extRing = [];
extIndex = 0;
extLength = polygonItem.length - 1;
extRing[0] = [];
intIndex = 0;

polygonItem.forEach(function (extRingCoords) {
if (extIndex !== extLength) {
//extRing = extRing.concat(extRingCoords);
posInstance = posFunc(extRingCoords,
polygonItemCoordIndex,
item, itemIndex);
extRing[0].push({
x: posInstance.x, y: posInstance.y, i: fillColor.length
});

fillColorInstance = fillColorFunc(extRingCoords,
polygonItemCoordIndex,
item, itemIndex);
fillColor.push([fillColorInstance.r,
fillColorInstance.g,
fillColorInstance.b]);
fillOpacity.push(fillOpacityFunc(extRingCoords,
polygonItemCoordIndex,
item,
itemIndex));
polygonItemCoordIndex += 1;
}
extIndex += 1;
});

polygonItemCoordIndex = 0;
holes.forEach(function (hole) {
extRing[intIndex + 1] = [];
hole.forEach(function (intRingCoords) {
posInstance = posFunc(intRingCoords, polygonItemCoordIndex,
item, itemIndex);
extRing[intIndex + 1].push({
x: posInstance.x, y: posInstance.y, i: fillColor.length
});
fillColorInstance = fillColorFunc(intRingCoords,
polygonItemCoordIndex,
item, itemIndex);
fillColor.push([fillColorInstance.r,
fillColorInstance.g,
fillColorInstance.b]);
fillOpacity.push(fillOpacityFunc(intRingCoords,
polygonItemCoordIndex,
item, itemIndex));
polygonItemCoordIndex += 1;
});
intIndex += 1;
});

//console.log("extRing ", extRing);
//console.log("result", PolyK.Triangulate(extRing));
triangList = triangulator.triangulate_polygon(extRing);
newTriangList = [];

triangList.forEach(function (newIndices) {
Array.prototype.push.apply(newTriangList, newIndices);
});

for (i = 1; i < extRing.length; i += 1) {
extRing[0] = extRing[0].concat(extRing[i]);
}

newTriangList.forEach(function (polygonIndex) {
var polygonItemCoords = extRing[0][polygonIndex];
position.push([polygonItemCoords.x,
polygonItemCoords.y,
polygonItemCoords.z || 0.0]);
fillColorNew.push(fillColor[polygonItemCoords.i]);
fillOpacityNew.push(fillOpacity[polygonItemCoords.i]);
});

itemIndex += 1;
});

position = transform.transformCoordinates(
m_this.gcs(), m_this.layer().map().gcs(),
position, 3);

buffers.create('pos', 3);
buffers.create('indices', 1);
buffers.create('fillColor', 3);
buffers.create('fillOpacity', 1);

numPts = position.length;
m_this.data().forEach(function (item, itemIndex) {
var polygon, geometry, numPts, start, i, vertex, j;

start = buffers.alloc(numPts);
function position(d, i) {
var c = posFunc(d, i, item, itemIndex);
return [c.x, c.y, c.z || 0];
}

//console.log("numPts ", numPts);
for (i = 0; i < numPts; i += 1) {
buffers.write('pos', position[i], start + i, 1);
buffers.write('indices', [i], start + i, 1);
buffers.write('fillColor', fillColorNew[i], start + i, 1);
buffers.write('fillOpacity', [fillOpacityNew[i]], start + i, 1);
}
polygon = m_this.polygon()(item, itemIndex);
polygon.outer = polygon.outer || [];
polygon.inner = polygon.inner || [];

// expand to a geojson polygon geometry
geometry = [(polygon.outer || []).map(position)];
(polygon.inner || []).forEach(function (hole) {
geometry.push(hole.map(position));
});

// convert to an earcut geometry
geometry = earcut.flatten(geometry);

// tranform to map gcs
geometry.vertices = transform.transformCoordinates(
target_gcs,
map_gcs,
geometry.vertices,
geometry.dimensions
);

// triangulate
triangles = earcut(geometry.vertices, geometry.holes, geometry.dimensions);

// append to buffers
numPts = triangles.length;
start = buffers.alloc(triangles.length);

for (i = 0; i < numPts; i += 1) {
j = triangles[i] * 3;
vertex = geometry.vertices.slice(triangles[i] * 3, j + 3);
buffers.write('pos', vertex, start + i, 1);
buffers.write('indices', [i], start + i, 1);
color = fillColorFunc(vertex, i, item, itemIndex);

buffers.write(
'fillColor',
[color.r, color.g, color.b],
start + i,
1
);
buffers.write(
'fillOpacity',
[fillOpacityFunc(vertex, i, item, itemIndex)],
start + i,
1
);
}
});

//console.log(buffers.get('fillColor'));
sourcePositions.pushBack(buffers.get('pos'));
geom.addSource(sourcePositions);

Expand All @@ -233,7 +172,6 @@ var gl_polygonFeature = function (arg) {
sourceFillOpacity.pushBack(buffers.get('fillOpacity'));
geom.addSource(sourceFillOpacity);

//console.log(buffers.get('indices'));
trianglePrimitive.setIndices(buffers.get('indices'));
geom.addPrimitive(trianglePrimitive);

Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
* @copyright 2015, Brandon Jones, Colin MacKenzie IV
* @license MIT
*
* pnltri
* @copyright 2014, Jurgen Ahting
* @license MIT
* earcut
* @copyright 2016, Mapbox
* @license ISC
*/

var $ = require('jquery');
Expand Down

0 comments on commit 1ff57c7

Please sign in to comment.