Skip to content

Commit 01e25e7

Browse files
authored
Merge pull request #5801 from plotly/new-geo-projections
Add satellite and various projection types to geo subplots
2 parents c4d4e06 + 8e352e2 commit 01e25e7

15 files changed

+16713
-301
lines changed

Diff for: draftlogs/5801_add.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add satellite and various projection types to geo subplots [[#5801](https://github.com/plotly/plotly.js/pull/5801)]

Diff for: src/plots/geo/constants.js

+52-60
Original file line numberDiff line numberDiff line change
@@ -2,128 +2,120 @@
22

33
// projection names to d3 function name
44
exports.projNames = {
5-
'equirectangular': 'equirectangular',
6-
'mercator': 'mercator',
7-
'orthographic': 'orthographic',
8-
'natural earth': 'naturalEarth',
9-
'kavrayskiy7': 'kavrayskiy7',
10-
'miller': 'miller',
11-
'robinson': 'robinson',
12-
'eckert4': 'eckert4',
13-
'azimuthal equal area': 'azimuthalEqualArea',
14-
'azimuthal equidistant': 'azimuthalEquidistant',
15-
'conic equal area': 'conicEqualArea',
16-
'conic conformal': 'conicConformal',
17-
'conic equidistant': 'conicEquidistant',
18-
'gnomonic': 'gnomonic',
19-
'stereographic': 'stereographic',
20-
'mollweide': 'mollweide',
21-
'hammer': 'hammer',
22-
'transverse mercator': 'transverseMercator',
23-
'albers usa': 'albersUsa',
24-
'winkel tripel': 'winkel3',
25-
'aitoff': 'aitoff',
26-
'sinusoidal': 'sinusoidal',
27-
/*
28-
// potential projections that could be added to the API
29-
305
'airy': 'airy',
31-
// 'albers': 'albers',
32-
'armadillo': 'armadillo',
6+
'aitoff': 'aitoff',
7+
'albers usa': 'albersUsa',
8+
'albers': 'albers',
9+
// 'armadillo': 'armadillo',
3310
'august': 'august',
11+
'azimuthal equal area': 'azimuthalEqualArea',
12+
'azimuthal equidistant': 'azimuthalEquidistant',
3413
'baker': 'baker',
35-
'berghaus': 'berghaus',
14+
// 'berghaus': 'berghaus',
3615
'bertin1953': 'bertin1953',
3716
'boggs': 'boggs',
3817
'bonne': 'bonne',
3918
'bottomley': 'bottomley',
4019
'bromley': 'bromley',
20+
// 'chamberlin africa': 'chamberlinAfrica',
4121
// 'chamberlin': 'chamberlin',
42-
'chamberlin africa': 'chamberlinAfrica',
4322
'collignon': 'collignon',
23+
'conic conformal': 'conicConformal',
24+
'conic equal area': 'conicEqualArea',
25+
'conic equidistant': 'conicEquidistant',
4426
'craig': 'craig',
4527
'craster': 'craster',
4628
'cylindrical equal area': 'cylindricalEqualArea',
4729
'cylindrical stereographic': 'cylindricalStereographic',
4830
'eckert1': 'eckert1',
4931
'eckert2': 'eckert2',
5032
'eckert3': 'eckert3',
33+
'eckert4': 'eckert4',
5134
'eckert5': 'eckert5',
5235
'eckert6': 'eckert6',
5336
'eisenlohr': 'eisenlohr',
37+
'equirectangular': 'equirectangular',
5438
'fahey': 'fahey',
55-
'foucaut': 'foucaut',
5639
'foucaut sinusoidal': 'foucautSinusoidal',
57-
'gilbert': 'gilbert',
58-
'gingery': 'gingery',
40+
'foucaut': 'foucaut',
41+
// 'gilbert': 'gilbert',
42+
// 'gingery': 'gingery',
5943
'ginzburg4': 'ginzburg4',
6044
'ginzburg5': 'ginzburg5',
6145
'ginzburg6': 'ginzburg6',
6246
'ginzburg8': 'ginzburg8',
6347
'ginzburg9': 'ginzburg9',
48+
'gnomonic': 'gnomonic',
49+
'gringorten quincuncial': 'gringortenQuincuncial',
6450
'gringorten': 'gringorten',
6551
'guyou': 'guyou',
66-
'hammer retroazimuthal': 'hammerRetroazimuthal',
67-
'healpix': 'healpix',
52+
// 'hammer retroazimuthal': 'hammerRetroazimuthal',
53+
'hammer': 'hammer',
54+
// 'healpix': 'healpix',
6855
'hill': 'hill',
6956
'homolosine': 'homolosine',
7057
'hufnagel': 'hufnagel',
7158
'hyperelliptical': 'hyperelliptical',
59+
// 'interrupted boggs': 'interruptedBoggs',
60+
// 'interrupted homolosine': 'interruptedHomolosine',
61+
// 'interrupted mollweide hemispheres': 'interruptedMollweideHemispheres',
62+
// 'interrupted mollweide': 'interruptedMollweide',
63+
// 'interrupted quartic authalic': 'interruptedQuarticAuthalic',
64+
// 'interrupted sinu mollweide': 'interruptedSinuMollweide',
65+
// 'interrupted sinusoidal': 'interruptedSinusoidal',
66+
'kavrayskiy7': 'kavrayskiy7',
7267
'lagrange': 'lagrange',
7368
'larrivee': 'larrivee',
7469
'laskowski': 'laskowski',
75-
'littrow': 'littrow',
70+
// 'littrow': 'littrow',
7671
'loximuthal': 'loximuthal',
72+
'mercator': 'mercator',
73+
'miller': 'miller',
74+
// 'modified stereographic alaska': 'modifiedStereographicAlaska',
75+
// 'modified stereographic gs48': 'modifiedStereographicGs48',
76+
// 'modified stereographic gs50': 'modifiedStereographicGs50',
77+
// 'modified stereographic lee': 'modifiedStereographicLee',
78+
// 'modified stereographic miller': 'modifiedStereographicMiller',
7779
// 'modified stereographic': 'modifiedStereographic',
78-
'modified stereographic alaska': 'modifiedStereographicAlaska',
79-
'modified stereographic gs48': 'modifiedStereographicGs48',
80-
'modified stereographic gs50': 'modifiedStereographicGs50',
81-
'modified stereographic miller': 'modifiedStereographicMiller',
82-
'modified stereographic lee': 'modifiedStereographicLee',
80+
'mollweide': 'mollweide',
8381
'mt flat polar parabolic': 'mtFlatPolarParabolic',
8482
'mt flat polar quartic': 'mtFlatPolarQuartic',
8583
'mt flat polar sinusoidal': 'mtFlatPolarSinusoidal',
84+
'natural earth': 'naturalEarth',
8685
'natural earth1': 'naturalEarth1',
8786
'natural earth2': 'naturalEarth2',
8887
'nell hammer': 'nellHammer',
8988
'nicolosi': 'nicolosi',
89+
'orthographic': 'orthographic',
9090
'patterson': 'patterson',
91+
'peirce quincuncial': 'peirceQuincuncial',
9192
'polyconic': 'polyconic',
93+
// 'polyhedral butterfly': 'polyhedralButterfly',
94+
// 'polyhedral collignon': 'polyhedralCollignon',
95+
// 'polyhedral waterman': 'polyhedralWaterman',
9296
'rectangular polyconic': 'rectangularPolyconic',
97+
'robinson': 'robinson',
9398
'satellite': 'satellite',
9499
'sinu mollweide': 'sinuMollweide',
100+
'sinusoidal': 'sinusoidal',
101+
'stereographic': 'stereographic',
95102
'times': 'times',
96-
// 'two point azimuthal': 'twoPointAzimuthal',
103+
'transverse mercator': 'transverseMercator',
97104
// 'two point azimuthalUsa': 'twoPointAzimuthalUsa',
98-
// 'two point equidistant': 'twoPointEquidistant',
105+
// 'two point azimuthal': 'twoPointAzimuthal',
99106
// 'two point equidistantUsa': 'twoPointEquidistantUsa',
107+
// 'two point equidistant': 'twoPointEquidistant',
100108
'van der grinten': 'vanDerGrinten',
101109
'van der grinten2': 'vanDerGrinten2',
102110
'van der grinten3': 'vanDerGrinten3',
103111
'van der grinten4': 'vanDerGrinten4',
104-
// 'wagner': 'wagner',
105112
'wagner4': 'wagner4',
106113
'wagner6': 'wagner6',
107114
// 'wagner7': 'wagner7',
115+
// 'wagner': 'wagner',
108116
'wiechel': 'wiechel',
117+
'winkel tripel': 'winkel3',
109118
'winkel3': 'winkel3',
110-
111-
// 'interrupt': 'interrupt',
112-
'interrupted homolosine': 'interruptedHomolosine',
113-
'interrupted sinusoidal': 'interruptedSinusoidal',
114-
'interrupted boggs': 'interruptedBoggs',
115-
'interrupted sinu mollweide': 'interruptedSinuMollweide',
116-
'interrupted mollweide': 'interruptedMollweide',
117-
'interrupted mollweide hemispheres': 'interruptedMollweideHemispheres',
118-
'interrupted quartic authalic': 'interruptedQuarticAuthalic',
119-
120-
'polyhedral butterfly': 'polyhedralButterfly',
121-
'polyhedral collignon': 'polyhedralCollignon',
122-
'polyhedral waterman': 'polyhedralWaterman',
123-
124-
'gringorten quincuncial': 'gringortenQuincuncial',
125-
'peirce quincuncial': 'peirceQuincuncial',
126-
*/
127119
};
128120

129121
// name of the axes

Diff for: src/plots/geo/geo.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -647,9 +647,9 @@ function getProjection(geoLayout) {
647647
var projFn = geo[projName] || geoProjection[projName];
648648
var projection = projFn();
649649

650-
var clipAngle = geoLayout._isClipped ?
651-
constants.lonaxisSpan[projType] / 2 :
652-
null;
650+
var clipAngle =
651+
geoLayout._isSatellite ? Math.acos(1 / projLayout.distance) * 180 / Math.PI :
652+
geoLayout._isClipped ? constants.lonaxisSpan[projType] / 2 : null;
653653

654654
var methods = ['center', 'rotate', 'parallels', 'clipExtent'];
655655
var dummyFn = function(_) { return _ ? projection : []; };
@@ -686,6 +686,10 @@ function getProjection(geoLayout) {
686686

687687
projection.precision(constants.precision);
688688

689+
if(geoLayout._isSatellite) {
690+
projection.tilt(projLayout.tilt).distance(projLayout.distance);
691+
}
692+
689693
if(clipAngle) {
690694
projection.clipAngle(clipAngle - constants.clipPad);
691695
}

Diff for: src/plots/geo/layout_attributes.js

+18
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,24 @@ var attrs = module.exports = overrideAll({
134134
].join(' ')
135135
}
136136
},
137+
tilt: {
138+
valType: 'number',
139+
dflt: 0,
140+
description: [
141+
'For satellite projection type only.',
142+
'Sets the tilt angle of perspective projection.'
143+
].join(' ')
144+
},
145+
distance: {
146+
valType: 'number',
147+
min: 1.001,
148+
dflt: 2,
149+
description: [
150+
'For satellite projection type only.',
151+
'Sets the distance from the center of the sphere to the point of view',
152+
'as a proportion of the sphere’s radius.'
153+
].join(' ')
154+
},
137155
parallels: {
138156
valType: 'info_array',
139157
items: [

Diff for: src/plots/geo/layout_defaults.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce, opts) {
3434
if(isAlbersUsa) scope = geoLayoutOut.scope = 'usa';
3535

3636
var isScoped = geoLayoutOut._isScoped = (scope !== 'world');
37-
var isConic = geoLayoutOut._isConic = projType.indexOf('conic') !== -1;
37+
var isSatellite = geoLayoutOut._isSatellite = projType === 'satellite';
38+
var isConic = geoLayoutOut._isConic = projType.indexOf('conic') !== -1 || projType === 'albers';
3839
var isClipped = geoLayoutOut._isClipped = !!constants.lonaxisSpan[projType];
3940

4041
if(geoLayoutIn.visible === false) {
@@ -148,6 +149,11 @@ function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce, opts) {
148149
coerce('center.lon', centerLonDflt);
149150
coerce('center.lat', centerLatDflt);
150151

152+
if(isSatellite) {
153+
coerce('projection.tilt');
154+
coerce('projection.distance');
155+
}
156+
151157
if(isConic) {
152158
var dfltProjParallels = scopeParams.projParallels || [0, 60];
153159
coerce('projection.parallels', dfltProjParallels);

Diff for: test/image/baselines/canada_geo_projections.png

1.6 MB
Loading

Diff for: test/image/baselines/distance_satellite.png

169 KB
Loading

Diff for: test/image/baselines/geo_fitbounds-locations.png

702 KB
Loading

Diff for: test/image/baselines/various_geo_projections.png

2.19 MB
Loading

0 commit comments

Comments
 (0)