spacemap 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # spacemap
2
2
 
3
3
  The map of the Solar System from [spacemap.co](https://spacemap.co), on your
4
- website! There are flat maps too, and 360 panoramas from the surface.
4
+ website! There are flat maps too, 360 panoramas from the surface, and a
5
+ diagram of the whole system to pick a body from.
5
6
 
6
7
  Distances are kilometres and angles are degrees throughout. Objects are named
7
8
  by their export id — `naif-399` for Earth, `spkid-20000004` for Vesta,
@@ -43,7 +44,7 @@ your page:
43
44
  ```html
44
45
  <div id="map" style="height: 500px"></div>
45
46
  <script type="module">
46
- import { createMap } from 'https://cdn.jsdelivr.net/npm/spacemap@0.1.3/dist/spacemap.js';
47
+ import { createMap } from 'https://cdn.jsdelivr.net/npm/spacemap@0.1.4/dist/spacemap.js';
47
48
  const map = await createMap({ container: '#map' });
48
49
  </script>
49
50
  ```
@@ -140,6 +141,31 @@ map.clock.setDate(new Date('2035-06-01'));
140
141
  map.clock.now();
141
142
  ```
142
143
 
144
+ ### Measuring
145
+
146
+ Some things can be read off the scene instead of drawn on it. All take the
147
+ bodies where the last frame put them, so after `setDate` wait for a `frame`
148
+ before asking.
149
+
150
+ ```js
151
+ // Kilometres between two anchors: centres, places on a surface, or one of each.
152
+ map.distanceKm({ body: 'naif-499' }, { body: 'naif-401' });
153
+ map.distanceKm({ body: 'naif-499', latitude: 18.4, longitude: 77.5 }, { body: 'naif-401' });
154
+
155
+ // The same with its direction kept, on ecliptic axes: [x, y, z] kilometres.
156
+ map.offsetKm({ body: 'naif-499' }, { body: 'naif-401' });
157
+
158
+ // Where the Sun is overhead: the middle of the lit half.
159
+ map.getSubsolarPoint('naif-499'); // { lon, lat }
160
+ ```
161
+
162
+ Any of them is null while a body it names is not loaded, or is nowhere at the
163
+ map's date: a moon before its discovery, a craft outside its mission. The
164
+ sub-solar point is given in the frame a surface anchor is placed in, so an
165
+ anchor there is on the lit side even on a body whose spin is not measured. It
166
+ is null as well until the map has read how the body spins, which it does once
167
+ the camera is on the body or its system.
168
+
143
169
  ### Drawing on it
144
170
 
145
171
  Everything you draw is put somewhere by an **anchor**, and the anchor is what
@@ -471,14 +497,29 @@ view exists — what a page picking one for the reader needs, since `createPanor
471
497
  opens the body's first unless told which:
472
498
 
473
499
  ```js
474
- import { fetchPanoramaIndex, fetchPanoramas } from 'spacemap';
500
+ import { fetchPanoramaIndex, fetchPanoramas, isViewable } from 'spacemap';
475
501
 
476
502
  await fetchPanoramaIndex(); // every body with coverage, and the missions on it
477
- const entries = await fetchPanoramas('naif-499'); // every panorama on Mars
503
+ const entries = (await fetchPanoramas('naif-499')).filter(isViewable); // every one that opens
478
504
  const pick = entries[(Math.random() * entries.length) | 0];
479
505
  const view = await createPanorama({ container: '#panorama', body: 'naif-499', at: pick.id });
480
506
  ```
481
507
 
508
+ The list is every stop on every traverse, and not every stop has a sphere this
509
+ page may open: some are places the archive withheld the imagery of, and some
510
+ are under a licence the page has not accepted (`includeNonCommercial`).
511
+ `isViewable` says which open; the view skips the rest itself.
512
+
513
+ Both read the page's own settings, which a `create…` call applies. A page that
514
+ reads the list before it has made anything applies them itself first, or the
515
+ list comes from the published export and under the default licence:
516
+
517
+ ```js
518
+ import { configureHost } from 'spacemap';
519
+
520
+ configureHost({ textures: 'non-commercial' }); // what `includeNonCommercial` sets
521
+ ```
522
+
482
523
  ```js
483
524
  const view = await createPanorama({
484
525
  container: '#panorama',
@@ -512,6 +553,113 @@ view.setLimits({ heading: [300, 60], fov: [60, 60] }); // ±60° of north, no zo
512
553
  view.setLimits({}); // free again
513
554
  ```
514
555
 
556
+ ## The system map
557
+
558
+ The Solar System as a diagram to pick from: the Sun at the left edge, every
559
+ body along a log distance axis at its true relative size, moons stacked over
560
+ their planet, the belts as bands. It is what spacemap.co opens its Solar System
561
+ and planetary system pages with.
562
+
563
+ ```js
564
+ import { createSystemMap } from 'spacemap';
565
+
566
+ const picker = await createSystemMap({ container: '#picker' });
567
+ picker.on('select', (target) => console.log(target.kind, target.name));
568
+ ```
569
+
570
+ It is as wide as its container and three times as wide as it is tall, and it
571
+ reads at any width from a corner panel up. It draws from the export's own
572
+ figures and no imagery, so it is the one map with no credit line.
573
+
574
+ There are three views:
575
+
576
+ ```js
577
+ await picker.setView({ kind: 'solar-system' });
578
+ await picker.setView({ kind: 'system', id: 'naif-699' }); // Saturn and its moons
579
+ await picker.setView({ kind: 'zone', zone: 'inner' }); // small bodies inside Jupiter's orbit
580
+ await picker.setView({ kind: 'zone', zone: 'outer' }); // and from it outward, the trojans included
581
+ ```
582
+
583
+ A `system` is named by its primary and measured in the primary's radii. A body
584
+ with no moons has no system map, and asking for one rejects, leaving the map as
585
+ it was.
586
+
587
+ **A click reports what was picked and goes nowhere.** Walking down into a
588
+ system and back up is the page's own doing, which is what lets it keep a back
589
+ button, a breadcrumb or a URL of its own:
590
+
591
+ ```js
592
+ picker.on('select', (target) => {
593
+ if (target.kind === 'system') picker.setView({ kind: 'system', id: target.id });
594
+ else if (target.kind === 'zone') picker.setView({ kind: 'zone', zone: target.zone });
595
+ else choose(target.id); // a body
596
+ });
597
+ ```
598
+
599
+ `getView()` says which view is up and `getTargets()` lists everything a click
600
+ on it can pick, for a page that wants a list beside the picture. `viewchange`
601
+ fires once a new view is drawn, and `error` when one could not be.
602
+
603
+ Two options decide what a click on the Solar System means:
604
+
605
+ ```js
606
+ createSystemMap({ container: '#picker', grouping: 'systems', zones: 'inner-outer' });
607
+ ```
608
+
609
+ - `grouping: 'systems'` makes a primary and the moons stacked on it one target,
610
+ a `system` — one click for "somewhere round Saturn". A primary with no moons
611
+ drawn stays a `body`. The default, `'bodies'`, leaves the dot and its stack a
612
+ target each.
613
+ - `zones: 'inner-outer'` turns the two belts into the doors of the two zones of
614
+ small bodies, labelled as such. The default, `'belts'`, leaves them the
615
+ scenery they are.
616
+
617
+ A map that offers part of the catalogue names it, and everything else goes
618
+ undrawn in every view:
619
+
620
+ ```js
621
+ const picker = await createSystemMap({
622
+ container: '#picker',
623
+ bodies: ['naif-499', 'naif-401', 'naif-602', 'spkid-20101955'],
624
+ names: { 'naif-602': 'Encelade' }
625
+ });
626
+ await picker.setBodies(null); // everything again, once redrawn
627
+ ```
628
+
629
+ A primary left out is still drawn while a moon of it is in, as the thing the
630
+ moon is found by; it is then not a target itself. `names` goes over the
631
+ export's own names, and is worth filling in for a small moon: the export names
632
+ a system's twenty most notable in a system view and the rest by id.
633
+
634
+ A zone shows the dwarf planets and large asteroids the Solar System view has,
635
+ and every other small body `bodies` names — a comet, a near-Earth asteroid, a
636
+ moon of one, which rides over its parent. The map has to learn where each of
637
+ those is, and reading that from the export costs a few hundred kilobytes a
638
+ body. A page that already knows says so instead, and nothing is read:
639
+
640
+ ```js
641
+ createSystemMap({
642
+ container: '#picker',
643
+ view: { kind: 'zone', zone: 'inner' },
644
+ bodies: ['spkid-20101955', 'spkid-20065803', 'spkid-120065803'],
645
+ places: [
646
+ { id: 'spkid-20101955', name: 'Bennu', aAu: 1.126, tiltDeg: 6.03, radiusKm: 0.245 },
647
+ { id: 'spkid-20065803', name: 'Didymos', aAu: 1.643, tiltDeg: 3.41, radiusKm: 0.39 },
648
+ { id: 'spkid-120065803', name: 'Dimorphos', moon: true, parent: 'spkid-20065803' }
649
+ ]
650
+ });
651
+ ```
652
+
653
+ The colours are custom properties, set on the container or anything above it:
654
+ `--sm-system-map-background`, `--sm-system-map-ink` for the axis and the muted
655
+ band, `--sm-system-map-sky` and `--sm-system-map-amber` for the other two bands
656
+ with a `-label` of each, `--sm-system-map-tip-background` and
657
+ `--sm-system-map-tip-ink` for the hover readout, and `--sm-system-map-radius`
658
+ for the corners. The words it writes itself are in `messages`, under
659
+ `system_map_*`, `planetary_system_*`, `tab_rings` and
660
+ `unit_symbol_astronomical_unit`. Kilometres are written by the browser, in the
661
+ `locale`'s own form.
662
+
515
663
  ## Restricting the map
516
664
 
517
665
  Both maps take restrictions on what the reader may do. Each gesture is a
@@ -619,7 +767,7 @@ this document describes: `flyTo` and `jumpTo`, `getLayers` and
619
767
 
620
768
  ## Where the data comes from
621
769
 
622
- Both maps read the published export. `dataUrl` and `imagesUrl` point them
770
+ Every map reads the published export. `dataUrl` and `imagesUrl` point them
623
771
  somewhere else — your own mirror, or a local copy while you develop. They are
624
772
  page-wide: the last map created sets them, and data already fetched keeps the
625
773
  origin it came from.