Define a new "Sphere" GeoJSON type.

This allows us to generate the clip outline for whole-earth projections
with arbitrary rotations.

Internally, this is interpreted as a polygon with null coordinates.
This commit is contained in:
Jason Davies 2012-12-05 18:39:57 +00:00
Родитель 36702f197f
Коммит 050b1c319e
5 изменённых файлов: 71 добавлений и 49 удалений

48
d3.js поставляемый
Просмотреть файл

@ -5366,6 +5366,9 @@
Polygon: function(polygon) {
this.polygon(polygon.coordinates);
},
Sphere: function() {
this.polygon(null);
},
object: function(object) {
return d3_geo_typeObjects.hasOwnProperty(object.type) ? this[object.type](object) : this.geometry(object);
},
@ -5388,7 +5391,8 @@
MultiPoint: 1,
MultiPolygon: 1,
Point: 1,
Polygon: 1
Polygon: 1,
Sphere: 1
};
var d3_geo_typeObjects = {
Feature: 1,
@ -5618,25 +5622,29 @@
}
function d3_geo_circleClipPolygon(coordinates, context, clipLine, interpolate) {
var subject = [], clip = [], segments = [], buffer = d3_geo_circleBufferSegments(clipLine), draw = [], visibleArea = 0, invisibleArea = 0, invisible = false;
coordinates.forEach(function(ring) {
var x = buffer(ring, context), ringSegments = x[1], segment, n = ringSegments.length;
if (!n) {
invisible = true;
invisibleArea += x[0][0];
return;
}
if (x[0][0] !== false) {
visibleArea += x[0][0];
draw.push(segment = ringSegments[0]);
var point = segment[0], n = segment.length - 1, i = 0;
context.moveTo(point[0], point[1]);
while (++i < n) context.lineTo((point = segment[i])[0], point[1]);
context.closePath();
return;
}
if (n > 1 && x[0][1]) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
segments = segments.concat(ringSegments.filter(d3_geo_circleSegmentLength1));
});
if (coordinates) {
coordinates.forEach(function(ring) {
var x = buffer(ring, context), ringSegments = x[1], segment, n = ringSegments.length;
if (!n) {
invisible = true;
invisibleArea += x[0][0];
return;
}
if (x[0][0] !== false) {
visibleArea += x[0][0];
draw.push(segment = ringSegments[0]);
var point = segment[0], n = segment.length - 1, i = 0;
context.moveTo(point[0], point[1]);
while (++i < n) context.lineTo((point = segment[i])[0], point[1]);
context.closePath();
return;
}
if (n > 1 && x[0][1]) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
segments = segments.concat(ringSegments.filter(d3_geo_circleSegmentLength1));
});
} else {
visibleArea = -4 * π;
}
if (!segments.length) {
if (visibleArea < 0 || invisible && invisibleArea < 0) {
var moved = false;

4
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -197,36 +197,41 @@ function d3_geo_circleClipPolygon(coordinates, context, clipLine, interpolate) {
visibleArea = 0,
invisibleArea = 0,
invisible = false;
coordinates.forEach(function(ring) {
var x = buffer(ring, context),
ringSegments = x[1],
segment,
n = ringSegments.length;
if (!n) {
invisible = true;
invisibleArea += x[0][0];
return;
}
if (coordinates) {
coordinates.forEach(function(ring) {
var x = buffer(ring, context),
ringSegments = x[1],
segment,
n = ringSegments.length;
// No intersections.
if (x[0][0] !== false) {
visibleArea += x[0][0];
draw.push(segment = ringSegments[0]);
var point = segment[0],
n = segment.length - 1,
i = 0;
context.moveTo(point[0], point[1]);
while (++i < n) context.lineTo((point = segment[i])[0], point[1]);
context.closePath();
return;
}
if (!n) {
invisible = true;
invisibleArea += x[0][0];
return;
}
// Rejoin connected segments.
if (n > 1 && x[0][1]) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
// No intersections.
if (x[0][0] !== false) {
visibleArea += x[0][0];
draw.push(segment = ringSegments[0]);
var point = segment[0],
n = segment.length - 1,
i = 0;
context.moveTo(point[0], point[1]);
while (++i < n) context.lineTo((point = segment[i])[0], point[1]);
context.closePath();
return;
}
segments = segments.concat(ringSegments.filter(d3_geo_circleSegmentLength1));
});
// Rejoin connected segments.
if (n > 1 && x[0][1]) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
segments = segments.concat(ringSegments.filter(d3_geo_circleSegmentLength1));
});
} else {
visibleArea = -4 * π; // whole sphere
}
if (!segments.length) {
if (visibleArea < 0 || invisible && invisibleArea < 0) {

Просмотреть файл

@ -50,6 +50,10 @@ var d3_geo_typeDefaults = {
this.polygon(polygon.coordinates);
},
Sphere: function() {
this.polygon(null);
},
// dispatch for any GeoJSON object type
object: function(object) {
return d3_geo_typeObjects.hasOwnProperty(object.type)
@ -86,7 +90,8 @@ var d3_geo_typeGeometries = {
MultiPoint: 1,
MultiPolygon: 1,
Point: 1,
Polygon: 1
Polygon: 1,
Sphere: 1
};
var d3_geo_typeObjects = {

Просмотреть файл

@ -418,6 +418,10 @@ suite.addBatch({
}
}
},
"Sphere": function(path) {
path({type: "Sphere"});
assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 87, y: 700}]);
}
},
"clipAngle(170)": {
topic: function() {