Skip to content

Commit 3d89db4

Browse files
committed
fixed centroid calculation for empty polygons, contours always in clockwise order
1 parent 3196d34 commit 3d89db4

7 files changed

+73
-26
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 0.8.2
2+
* fixed centroid calculation for polygons with area = 0
3+
* fixed order for polygons
4+
15
### 0.8.1
26

37
* simplified API: loadMap() --> load()

kartograph-0.8.1.min.js

-3
This file was deleted.

kartograph-0.8.1.js renamed to kartograph-0.8.2.js

+36-12
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
(function() {
22-
var $, Aitoff, Azimuthal, BBox, Balthasart, Behrmann, BlurFilter, Bubble, CEA, CantersModifiedSinusoidalI, Circle, CohenSutherland, Conic, Cylindrical, EckertIV, EquidistantAzimuthal, Equirectangular, Filter, GallPeters, GlowFilter, GoodeHomolosine, Hatano, HoboDyer, HtmlLabel, Icon, K, Kartograph, LAEA, LCC, LabeledBubble, LatLon, Line, LinearScale, LogScale, LonLat, Loximuthal, MapLayer, MapLayerPath, Mercator, Mollweide, NaturalEarth, Nicolosi, Orthographic, Path, PieChart, Proj, PseudoConic, PseudoCylindrical, QuantileScale, REbraces, REcomment_string, REfull, REmunged, Robinson, Satellite, Scale, Sinusoidal, SqrtScale, StackedBarChart, Stereographic, SvgLabel, Symbol, SymbolGroup, View, WagnerIV, WagnerV, Winkel3, drawPieChart, filter, hex2rgb, kartograph, log, map_layer_path_uid, munge, munged, parsedeclarations, resolve, restore, root, uid, warn, __point_in_polygon, __proj, __type, _base, _base1, _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref2, _ref20, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9,
22+
var $, Aitoff, Azimuthal, BBox, Balthasart, Behrmann, BlurFilter, Bubble, CEA, CantersModifiedSinusoidalI, Circle, CohenSutherland, Conic, Cylindrical, EckertIV, EquidistantAzimuthal, Equirectangular, Filter, GallPeters, GlowFilter, GoodeHomolosine, Hatano, HoboDyer, HtmlLabel, Icon, K, Kartograph, LAEA, LCC, LabeledBubble, LatLon, Line, LinearScale, LogScale, LonLat, Loximuthal, MapLayer, MapLayerPath, Mercator, Mollweide, NaturalEarth, Nicolosi, Orthographic, Path, PieChart, Proj, PseudoConic, PseudoCylindrical, QuantileScale, REbraces, REcomment_string, REfull, REmunged, Robinson, Satellite, Scale, Sinusoidal, SqrtScale, StackedBarChart, Stereographic, SvgLabel, Symbol, SymbolGroup, View, WagnerIV, WagnerV, Winkel3, drawPieChart, filter, hex2rgb, kartograph, log, map_layer_path_uid, munge, munged, parsedeclarations, resolve, restore, root, uid, warn, __area, __is_clockwise, __point_in_polygon, __proj, __type, _base, _base1, _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref2, _ref20, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9,
2323
__hasProp = {}.hasOwnProperty,
2424
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
2525
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
@@ -1597,14 +1597,21 @@
15971597
represents complex polygons (aka multi-polygons)
15981598
*/
15991599
function Path(type, contours, closed) {
1600-
var self;
1600+
var cnt, self, _i, _len;
16011601

16021602
if (closed == null) {
16031603
closed = true;
16041604
}
16051605
self = this;
16061606
self.type = type;
1607-
self.contours = contours;
1607+
self.contours = [];
1608+
for (_i = 0, _len = contours.length; _i < _len; _i++) {
1609+
cnt = contours[_i];
1610+
if (!__is_clockwise(cnt)) {
1611+
cnt.reverse();
1612+
}
1613+
self.contours.push(cnt);
1614+
}
16081615
self.closed = closed;
16091616
}
16101617

@@ -1649,7 +1656,7 @@
16491656
};
16501657

16511658
Path.prototype.area = function() {
1652-
var area, cnt, i, me, _i, _j, _len, _ref5, _ref6;
1659+
var area, cnt, me, _i, _len, _ref5;
16531660

16541661
me = this;
16551662
if (me.areas != null) {
@@ -1660,12 +1667,7 @@
16601667
_ref5 = me.contours;
16611668
for (_i = 0, _len = _ref5.length; _i < _len; _i++) {
16621669
cnt = _ref5[_i];
1663-
area = 0;
1664-
for (i = _j = 0, _ref6 = cnt.length - 2; 0 <= _ref6 ? _j <= _ref6 : _j >= _ref6; i = 0 <= _ref6 ? ++_j : --_j) {
1665-
area += cnt[i][0] * cnt[i + 1][1] - cnt[i + 1][0] * cnt[i][1];
1666-
}
1667-
area *= .5;
1668-
area = area;
1670+
area = __area(cnt);
16691671
me.areas.push(area);
16701672
me._area += area;
16711673
}
@@ -1685,6 +1687,11 @@
16851687
cnt_orig = me.contours[i];
16861688
cnt = [];
16871689
l = cnt_orig.length;
1690+
a = me.areas[i];
1691+
k = a / area;
1692+
if (k === 0) {
1693+
continue;
1694+
}
16881695
for (j = _j = 0, _ref6 = l - 1; 0 <= _ref6 ? _j <= _ref6 : _j >= _ref6; j = 0 <= _ref6 ? ++_j : --_j) {
16891696
p0 = cnt_orig[j];
16901697
p1 = cnt_orig[(j + 1) % l];
@@ -1704,7 +1711,6 @@
17041711
}
17051712
}
17061713
}
1707-
a = me.areas[i];
17081714
x = y = x_ = y_ = 0;
17091715
l = cnt.length;
17101716
_lengths = [];
@@ -1724,7 +1730,6 @@
17241730
x += w * p0[0];
17251731
y += w * p0[1];
17261732
}
1727-
k = a / area;
17281733
cx += x * k;
17291734
cy += y * k;
17301735
}
@@ -1929,6 +1934,25 @@
19291934
return Math.abs(angle) >= pi;
19301935
};
19311936

1937+
__is_clockwise = function(contour) {
1938+
return __area(contour) > 0;
1939+
};
1940+
1941+
__area = function(contour) {
1942+
var i, n, s, x1, x2, y1, y2, _i;
1943+
1944+
s = 0;
1945+
n = contour.length;
1946+
for (i = _i = 0; 0 <= n ? _i < n : _i > n; i = 0 <= n ? ++_i : --_i) {
1947+
x1 = contour[i][0];
1948+
y1 = contour[i][1];
1949+
x2 = contour[(i + 1) % n][0];
1950+
y2 = contour[(i + 1) % n][1];
1951+
s += x1 * y2 - x2 * y1;
1952+
}
1953+
return s *= 0.5;
1954+
};
1955+
19321956
/*
19331957
kartograph - a svg mapping library
19341958
Copyright (C) 2011 Gregor Aisch

kartograph-0.8.2.min.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kartograph.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
kartograph-0.8.1.js
1+
kartograph-0.8.2.js

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name" : "kartograph-js",
33
"description" : "JavaScript library for SVG mapping",
4-
"version" : "0.8.1",
4+
"version" : "0.8.2",
55
"author" : "Gregor Aisch",
66
"homepage" : "http://kartograph.org",
77
"keywords" : ["svg", "map", "raphael"],

src/core/path.coffee

+28-9
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ class Path
2525
constructor: (type, contours, closed=true) ->
2626
self = @
2727
self.type = type
28-
self.contours = contours
28+
self.contours = []
29+
for cnt in contours
30+
if not __is_clockwise cnt
31+
cnt.reverse()
32+
self.contours.push cnt
2933
self.closed = closed
3034

3135
clipToBBox: (bbox) ->
@@ -60,11 +64,7 @@ class Path
6064
me.areas = []
6165
me._area = 0
6266
for cnt in me.contours
63-
area = 0
64-
for i in [0..cnt.length-2]
65-
area += cnt[i][0]*cnt[i+1][1] - cnt[i+1][0]*cnt[i][1]
66-
area *= .5
67-
area = area
67+
area = __area cnt
6868
me.areas.push area
6969
me._area += area
7070
me._area
@@ -82,6 +82,11 @@ class Path
8282
cnt = []
8383
l = cnt_orig.length
8484

85+
a = me.areas[i]
86+
k = a/area
87+
if k == 0
88+
continue
89+
8590
for j in [0..l-1]
8691
p0 = cnt_orig[j]
8792
p1 = cnt_orig[(j+1)%l]
@@ -98,7 +103,6 @@ class Path
98103
cnt.push sp
99104
# insert new points in between
100105

101-
a = me.areas[i]
102106
x = y = x_ = y_ = 0
103107
l = cnt.length
104108
# at first compute total edge length
@@ -119,7 +123,6 @@ class Path
119123
x += w * p0[0]
120124
y += w * p0[1]
121125

122-
k = a/area
123126
cx += x * k
124127
cy += y * k
125128
me._centroid = [cx,cy]
@@ -272,5 +275,21 @@ __point_in_polygon = (polygon, p) ->
272275
while dtheta < -pi
273276
dtheta += twopi
274277
angle += dtheta
275-
return Math.abs(angle) >= pi
278+
Math.abs(angle) >= pi
279+
280+
281+
__is_clockwise = (contour) ->
282+
__area(contour) > 0
283+
284+
285+
__area = (contour) ->
286+
s = 0
287+
n = contour.length
288+
for i in [0...n]
289+
x1 = contour[i][0]
290+
y1 = contour[i][1]
291+
x2 = contour[(i+1)%n][0]
292+
y2 = contour[(i+1)%n][1]
293+
s += x1 * y2 - x2 * y1
294+
s *= 0.5
276295

0 commit comments

Comments
 (0)