@a2f0/skyline 0.2.14 → 0.2.15

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.
@@ -1,11 +1,13 @@
1
+ import * as THREE from "../vendor/three-r186.js";
2
+ import { chainSkin, chainsOf } from "./facade-grid.js";
1
3
  import { createBuilder, inside, line, polygonOf } from "./building-kit.js";
2
4
  // Kemper Building at 1 East Wacker Drive: the geographic layout's detailed
3
5
  // model. The mapped ground outline and tower part keep their OpenStreetMap
4
6
  // outlines; the 159 m top is OSM's height tag (522 ft in the 1962 record).
5
7
  // The marble shell, window bays, raised mullions, dark crown band with light
6
8
  // fins, and projecting cap reuse the fitted model's vocabulary at meter scale.
7
- // Window-column and pane proportions follow a 2012 photograph; bay counts,
8
- // window-row and crown spacings remain estimates. See
9
+ // Window columns follow dated photographs: twelve north/south, fourteen
10
+ // east/west. Window-row and crown spacings remain estimates. See
9
11
  // docs/kemper-geographic-reference.md. Units are meters; +x is east, +z south.
10
12
  export const kemperGeographicLevels = Object.freeze({
11
13
  podium: 7.8, // OSM way 685494067: two floors at the tower's average floor height
@@ -63,24 +65,44 @@ export function createKemperGeographicBuilding(record, projectPlan, offset) {
63
65
  // FID-KEM-002: the 2012 north-face photograph gives openings about 48% of
64
66
  // each bay and glass about 52% of each floor pitch. Opaque panels continue
65
67
  // the narrow columns between windows; the marble piers stay uninterrupted.
66
- tower.forEach((run, side) => {
67
- const bays = Math.max(1, Math.round(run.length / 3.1));
68
- const width = run.length / bays;
68
+ // Keep one rhythm across the map's almost-collinear tracing vertices. The
69
+ // 15° tolerance includes the short east-wall jog, but not the four corners.
70
+ const faces = chainsOf(tower, Math.PI / 12);
71
+ if (faces.length !== 4)
72
+ throw new Error("Kemper's tower must have four facade chains.");
73
+ const white = new THREE.Color(0xffffff);
74
+ const faceStrip = (batch, face, from, to, y0, y1, back, front) => {
75
+ const clearance = Math.max(Math.abs(back), Math.abs(front)) + 0.025;
76
+ from = Math.max(from, clearance);
77
+ to = Math.min(to, face.length - clearance);
78
+ if (to - from < 0.03 || y1 <= y0)
79
+ return;
80
+ const first = face.starts.findLastIndex((s) => s <= from);
81
+ const last = face.starts.findLastIndex((s) => s < to);
82
+ // A single closed skin mitres internal joints; neither a new bay nor a
83
+ // visible gap is introduced where the OSM tracing splits a physical face.
84
+ chainSkin(kit, batch, tower, face, first, last, from, to, [], [y0, y1], back, front, () => white, white);
85
+ };
86
+ faces.forEach((face, side) => {
87
+ // Twelve north columns in 2012; fourteen west columns in 2016. Matching
88
+ // counts on the opposite faces are an explicit symmetry inference.
89
+ const normal = tower[face.runs[0]].normal(0);
90
+ const bays = Math.abs(normal[0]) > Math.abs(normal[1]) ? 14 : 12;
91
+ const width = face.length / bays;
69
92
  const inset = width * 0.26;
70
93
  for (let bay = 0; bay < bays; bay += 1) {
71
- strip(spandrels, run, bay * width + inset, (bay + 1) * width - inset, h.podium, crownBase, 0.01, 0.04);
94
+ faceStrip(spandrels, face, bay * width + inset, (bay + 1) * width - inset, h.podium, crownBase, 0.01, 0.04);
72
95
  }
73
96
  for (let floor = 3; floor <= 39; floor += 1) {
74
97
  const bottom = floorHeight(floor), top = floorHeight(floor + 1);
75
98
  for (let bay = 0; bay < bays; bay += 1) {
76
- strip(paneTone(floor, bay, side), run, bay * width + inset + 0.01, (bay + 1) * width - inset - 0.01, bottom + pitch * 0.24, top - pitch * 0.24, 0.02, 0.07);
99
+ faceStrip(paneTone(floor, bay, side), face, bay * width + inset + 0.01, (bay + 1) * width - inset - 0.01, bottom + pitch * 0.24, top - pitch * 0.24, 0.02, 0.07);
77
100
  }
78
101
  }
79
102
  for (let i = 0; i <= bays; i += 1) {
80
- const s = Math.max(0.18, Math.min(run.length - 0.18, i * width));
81
- strip(mullions, run, s - inset, s + inset, h.podium + 0.02, crownBase - 0.05, 0.05, 0.16);
103
+ faceStrip(mullions, face, i * width - inset, i * width + inset, h.podium + 0.02, crownBase - 0.05, 0.05, 0.16);
82
104
  }
83
- strip(mullions, run, 0.015, run.length - 0.015, h.podium - 0.05, h.podium + 0.35, 0.06, 0.18);
105
+ faceStrip(mullions, face, 0.015, face.length - 0.015, h.podium - 0.05, h.podium + 0.35, 0.06, 0.18);
84
106
  });
85
107
  // The crown: dark glazing between light fins over the top two floors, then
86
108
  // a projecting closed cap at the 159 m roof. The mapped outline carries
@@ -13,7 +13,7 @@
13
13
  // Coordinates are [longitude, latitude] in WGS84. See docs/skyline-geography.md.
14
14
  export const geographicBuildings = [
15
15
  { "id": "building-heritage-at-millennium-park", "name": "The Heritage at Millennium Park", "shortName": "Heritage", "height": 192.4, "tipHeight": 192.4, "heightSource": "https://www.skyscrapercenter.com/building/the-heritage-at-millennium-park/1897", "note": "Detailed Heritage: mapped footprint; 192.4 m published top and 176.8 m occupied floor. Podium 32.8 m and lower terrace 89.5 m from city design drawings; facade spacing and roof equipment estimated.", "footprint": { "way": 147397547, "version": 7, "coordinates": [[-87.6260719, 41.8843928], [-87.6257481, 41.8843917], [-87.6257191, 41.8843891], [-87.6256478, 41.8843865], [-87.6255526, 41.884377], [-87.6254712, 41.8843689], [-87.6254652, 41.8841954], [-87.6254621, 41.8841073], [-87.6254542, 41.883665], [-87.6254571, 41.8836595], [-87.6254538, 41.8836092], [-87.6260475, 41.8836083]] }, "parts": [{ "way": 686199648, "version": 4, "coordinates": [[-87.6256927, 41.8839116], [-87.6256884, 41.883961], [-87.6255146, 41.8839622], [-87.6254791, 41.8840238], [-87.6254621, 41.8841073], [-87.6254652, 41.8841954], [-87.6254854, 41.8842648], [-87.6255135, 41.8842688], [-87.6255389, 41.8843317], [-87.6255398, 41.8843608], [-87.6257484, 41.8843597], [-87.6257491, 41.8842951], [-87.6258081, 41.8842912], [-87.6258044, 41.8842312], [-87.6258273, 41.8842124], [-87.6258393, 41.8841657], [-87.6258472, 41.8841049], [-87.6258401, 41.8840613], [-87.6258255, 41.8840069], [-87.6257984, 41.8839707], [-87.6257899, 41.883913], [-87.6257556, 41.8839132]], "bottom": 0, "top": 192.4 }, { "way": 686199649, "version": 1, "coordinates": [[-87.6257591, 41.8837593], [-87.6257556, 41.8839132], [-87.6256927, 41.8839116], [-87.6256884, 41.883961], [-87.6255146, 41.8839622], [-87.6254791, 41.8840238], [-87.6254621, 41.8841073], [-87.6254542, 41.883665], [-87.6257265, 41.8836609], [-87.6257315, 41.8837592]], "bottom": 0, "top": 89.5096, "estimatedHeight": true }, { "way": 686199650, "version": 2, "coordinates": [[-87.6254542, 41.883665], [-87.6254571, 41.8836595], [-87.6254538, 41.8836092], [-87.6260475, 41.8836083], [-87.6260719, 41.8843928], [-87.6257481, 41.8843917], [-87.6257484, 41.8843597], [-87.6257491, 41.8842951], [-87.6258081, 41.8842912], [-87.6258044, 41.8842312], [-87.6258273, 41.8842124], [-87.6258393, 41.8841657], [-87.6258472, 41.8841049], [-87.6258401, 41.8840613], [-87.6258255, 41.8840069], [-87.6257984, 41.8839707], [-87.6257899, 41.883913], [-87.6257556, 41.8839132], [-87.6257591, 41.8837593], [-87.6257315, 41.8837592], [-87.6257265, 41.8836609]], "bottom": 0, "top": 32.8176, "estimatedHeight": true }] },
16
- { "id": "building-kemper", "name": "Kemper Building", "shortName": "Kemper", "height": 159, "tipHeight": 159, "heightSource": "https://www.openstreetmap.org/way/64389514", "note": "Detailed Kemper: mapped footprint, tower part, and 159 m OpenStreetMap height; 41 published floors. Window rows, bays, and the finned crown are estimated.", "footprint": { "way": 64389514, "version": 13, "coordinates": [[-87.6277499, 41.8863375], [-87.6273407, 41.8863436], [-87.6273396, 41.8863339], [-87.6271328, 41.8863379], [-87.6270968, 41.8863386], [-87.6270991, 41.8866309], [-87.6271288, 41.8866306], [-87.6272242, 41.8866295], [-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163]] }, "parts": [{ "way": 685494066, "version": 4, "coordinates": [[-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163], [-87.6277499, 41.8863375], [-87.6273407, 41.8863436]], "bottom": 0, "top": 159 }, { "way": 685494067, "version": 4, "coordinates": [[-87.6273407, 41.8863436], [-87.6273446, 41.8866282], [-87.6272242, 41.8866295], [-87.6271288, 41.8866306], [-87.6270991, 41.8866309], [-87.6270968, 41.8863386], [-87.6271328, 41.8863379], [-87.6273396, 41.8863339]], "bottom": 0, "top": 7.8, "estimatedHeight": true }] },
16
+ { "id": "building-kemper", "name": "Kemper Building", "shortName": "Kemper", "height": 159, "tipHeight": 159, "heightSource": "https://www.openstreetmap.org/way/64389514", "note": "Detailed Kemper: mapped footprint, tower part, and 159 m OpenStreetMap height; 41 published floors. Photographed 12/14-column facade rhythm; window rows and crown remain estimated.", "footprint": { "way": 64389514, "version": 13, "coordinates": [[-87.6277499, 41.8863375], [-87.6273407, 41.8863436], [-87.6273396, 41.8863339], [-87.6271328, 41.8863379], [-87.6270968, 41.8863386], [-87.6270991, 41.8866309], [-87.6271288, 41.8866306], [-87.6272242, 41.8866295], [-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163]] }, "parts": [{ "way": 685494066, "version": 4, "coordinates": [[-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163], [-87.6277499, 41.8863375], [-87.6273407, 41.8863436]], "bottom": 0, "top": 159 }, { "way": 685494067, "version": 4, "coordinates": [[-87.6273407, 41.8863436], [-87.6273446, 41.8866282], [-87.6272242, 41.8866295], [-87.6271288, 41.8866306], [-87.6270991, 41.8866309], [-87.6270968, 41.8863386], [-87.6271328, 41.8863379], [-87.6273396, 41.8863339]], "bottom": 0, "top": 7.8, "estimatedHeight": true }] },
17
17
  { "id": "building-crain-communications", "name": "Crain Communications Building", "shortName": "Crain", "height": 177.4, "tipHeight": 177.4, "heightSource": "https://www.skyscrapercenter.com/building/150-north-michigan-avenue/2441", "note": "Detailed Crain: mapped parts, split, notches and roof bearing; roof slope and both peaks at the published 177.4 m measured on the source photograph, with its 3.5 m band pitch. Lobby, window module and roof grid estimated.", "footprint": { "way": 210671717, "version": 14, "coordinates": [[-87.6251984, 41.8846185], [-87.6252086, 41.8849637], [-87.6251849, 41.884981], [-87.6251613, 41.8849983], [-87.6252038, 41.8850292], [-87.6247448, 41.8850344], [-87.624744, 41.8850059], [-87.6247427, 41.8849565], [-87.6247379, 41.8847857], [-87.6247375, 41.8847566], [-87.6248159, 41.8846976], [-87.6248301, 41.884687], [-87.6248227, 41.8846815], [-87.6247345, 41.8846233], [-87.624814, 41.8846217], [-87.624879, 41.8846221]] }, "parts": [{ "way": 284816227, "version": 2, "coordinates": [[-87.6250471, 41.8849145], [-87.625093, 41.8848805], [-87.6252086, 41.8849637], [-87.6251849, 41.884981], [-87.6251613, 41.8849983]], "bottom": 0, "top": 152.5 }, { "way": 284816228, "version": 2, "coordinates": [[-87.6247345, 41.8846233], [-87.6248227, 41.8846815], [-87.6248301, 41.884687], [-87.625093, 41.8848805], [-87.6252086, 41.8849637], [-87.6251984, 41.8846185], [-87.624879, 41.8846221], [-87.624814, 41.8846217]], "bottom": 0, "top": 172.4, "roofSlope": { "direction": 133.0, "height": 75.0 } }, { "way": 284816229, "version": 2, "coordinates": [[-87.6251613, 41.8849983], [-87.6250471, 41.8849145], [-87.625093, 41.8848805], [-87.6248301, 41.884687], [-87.6248159, 41.8846976], [-87.6247375, 41.8847566], [-87.6247379, 41.8847857], [-87.6247427, 41.8849565], [-87.624744, 41.8850059], [-87.6247448, 41.8850344], [-87.6252038, 41.8850292]], "bottom": 0, "top": 177.4, "roofSlope": { "direction": 133.0, "height": 73.0 } }] },
18
18
  { "id": "building-330-north-wabash", "name": "330 North Wabash", "shortName": "330 N Wabash", "height": 211.84, "tipHeight": 211.84, "heightSource": "https://en.wikipedia.org/wiki/330_North_Wabash", "note": "Detailed 330 North Wabash (AMA Plaza): the tower the drawing labels Michigan Plaza South, whose roof corners land on the drawn ones through the photograph's camera. Mapped outline and 211.84 m (695 ft) height; bronze I-beam mullions on the 5 ft module, bronze spandrels and glass on 12 ft 6 in floors, a lobby on the 25 ft plaza, and louvered mechanical floors. No drawn model; the original layout has no counterpart.", "footprint": { "way": 64596068, "version": 20, "coordinates": [[-87.6278354, 41.8890249], [-87.627387, 41.8890335], [-87.6273775, 41.888809], [-87.6273647, 41.8885094], [-87.6273551, 41.8882848], [-87.6278057, 41.8882763]] }, "parts": [{ "way": 64596068, "version": 20, "coordinates": [[-87.6278354, 41.8890249], [-87.627387, 41.8890335], [-87.6273775, 41.888809], [-87.6273647, 41.8885094], [-87.6273551, 41.8882848], [-87.6278057, 41.8882763]], "bottom": 0, "top": 211.84 }] },
19
19
  { "id": "building-michigan-plaza-south-tower", "name": "Michigan Plaza South", "shortName": "Michigan Plaza S", "height": 168.6, "tipHeight": 168.6, "heightSource": "https://www.skyscrapercenter.com/building/michigan-plaza-south/2825", "note": "Detailed Michigan Plaza South: mapped outline, published 168.6 m height, and a 44-story glazed grid; window rows and bays estimated.", "footprint": { "way": 127107024, "version": 12, "coordinates": [[-87.6231713, 41.8858935], [-87.6239484, 41.8858842], [-87.6239505, 41.8861715], [-87.6238471, 41.8861735], [-87.6238486, 41.886216], [-87.6238504, 41.8862675], [-87.6235019, 41.8862724], [-87.6235019, 41.8861725], [-87.6231743, 41.8861722]] }, "parts": [{ "way": 127107024, "version": 12, "coordinates": [[-87.6231713, 41.8858935], [-87.6239484, 41.8858842], [-87.6239505, 41.8861715], [-87.6238471, 41.8861735], [-87.6238486, 41.886216], [-87.6238504, 41.8862675], [-87.6235019, 41.8862724], [-87.6235019, 41.8861725], [-87.6231743, 41.8861722]], "bottom": 0, "top": 168.6 }] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a2f0/skyline",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "description": "Interactive Chicago skyline viewer and reusable Three.js building models",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,11 +1,13 @@
1
+ import * as THREE from "../vendor/three-r186.js";
2
+ import { chainSkin, chainsOf } from "./facade-grid.js";
1
3
  import { createBuilder, inside, line, polygonOf } from "./building-kit.js";
2
4
  // Kemper Building at 1 East Wacker Drive: the geographic layout's detailed
3
5
  // model. The mapped ground outline and tower part keep their OpenStreetMap
4
6
  // outlines; the 159 m top is OSM's height tag (522 ft in the 1962 record).
5
7
  // The marble shell, window bays, raised mullions, dark crown band with light
6
8
  // fins, and projecting cap reuse the fitted model's vocabulary at meter scale.
7
- // Window-column and pane proportions follow a 2012 photograph; bay counts,
8
- // window-row and crown spacings remain estimates. See
9
+ // Window columns follow dated photographs: twelve north/south, fourteen
10
+ // east/west. Window-row and crown spacings remain estimates. See
9
11
  // docs/kemper-geographic-reference.md. Units are meters; +x is east, +z south.
10
12
  export const kemperGeographicLevels = Object.freeze({
11
13
  podium: 7.8, // OSM way 685494067: two floors at the tower's average floor height
@@ -63,24 +65,44 @@ export function createKemperGeographicBuilding(record, projectPlan, offset) {
63
65
  // FID-KEM-002: the 2012 north-face photograph gives openings about 48% of
64
66
  // each bay and glass about 52% of each floor pitch. Opaque panels continue
65
67
  // the narrow columns between windows; the marble piers stay uninterrupted.
66
- tower.forEach((run, side) => {
67
- const bays = Math.max(1, Math.round(run.length / 3.1));
68
- const width = run.length / bays;
68
+ // Keep one rhythm across the map's almost-collinear tracing vertices. The
69
+ // 15° tolerance includes the short east-wall jog, but not the four corners.
70
+ const faces = chainsOf(tower, Math.PI / 12);
71
+ if (faces.length !== 4)
72
+ throw new Error("Kemper's tower must have four facade chains.");
73
+ const white = new THREE.Color(0xffffff);
74
+ const faceStrip = (batch, face, from, to, y0, y1, back, front) => {
75
+ const clearance = Math.max(Math.abs(back), Math.abs(front)) + 0.025;
76
+ from = Math.max(from, clearance);
77
+ to = Math.min(to, face.length - clearance);
78
+ if (to - from < 0.03 || y1 <= y0)
79
+ return;
80
+ const first = face.starts.findLastIndex((s) => s <= from);
81
+ const last = face.starts.findLastIndex((s) => s < to);
82
+ // A single closed skin mitres internal joints; neither a new bay nor a
83
+ // visible gap is introduced where the OSM tracing splits a physical face.
84
+ chainSkin(kit, batch, tower, face, first, last, from, to, [], [y0, y1], back, front, () => white, white);
85
+ };
86
+ faces.forEach((face, side) => {
87
+ // Twelve north columns in 2012; fourteen west columns in 2016. Matching
88
+ // counts on the opposite faces are an explicit symmetry inference.
89
+ const normal = tower[face.runs[0]].normal(0);
90
+ const bays = Math.abs(normal[0]) > Math.abs(normal[1]) ? 14 : 12;
91
+ const width = face.length / bays;
69
92
  const inset = width * 0.26;
70
93
  for (let bay = 0; bay < bays; bay += 1) {
71
- strip(spandrels, run, bay * width + inset, (bay + 1) * width - inset, h.podium, crownBase, 0.01, 0.04);
94
+ faceStrip(spandrels, face, bay * width + inset, (bay + 1) * width - inset, h.podium, crownBase, 0.01, 0.04);
72
95
  }
73
96
  for (let floor = 3; floor <= 39; floor += 1) {
74
97
  const bottom = floorHeight(floor), top = floorHeight(floor + 1);
75
98
  for (let bay = 0; bay < bays; bay += 1) {
76
- strip(paneTone(floor, bay, side), run, bay * width + inset + 0.01, (bay + 1) * width - inset - 0.01, bottom + pitch * 0.24, top - pitch * 0.24, 0.02, 0.07);
99
+ faceStrip(paneTone(floor, bay, side), face, bay * width + inset + 0.01, (bay + 1) * width - inset - 0.01, bottom + pitch * 0.24, top - pitch * 0.24, 0.02, 0.07);
77
100
  }
78
101
  }
79
102
  for (let i = 0; i <= bays; i += 1) {
80
- const s = Math.max(0.18, Math.min(run.length - 0.18, i * width));
81
- strip(mullions, run, s - inset, s + inset, h.podium + 0.02, crownBase - 0.05, 0.05, 0.16);
103
+ faceStrip(mullions, face, i * width - inset, i * width + inset, h.podium + 0.02, crownBase - 0.05, 0.05, 0.16);
82
104
  }
83
- strip(mullions, run, 0.015, run.length - 0.015, h.podium - 0.05, h.podium + 0.35, 0.06, 0.18);
105
+ faceStrip(mullions, face, 0.015, face.length - 0.015, h.podium - 0.05, h.podium + 0.35, 0.06, 0.18);
84
106
  });
85
107
  // The crown: dark glazing between light fins over the top two floors, then
86
108
  // a projecting closed cap at the 159 m roof. The mapped outline carries
@@ -13,7 +13,7 @@
13
13
  // Coordinates are [longitude, latitude] in WGS84. See docs/skyline-geography.md.
14
14
  export const geographicBuildings = [
15
15
  { "id": "building-heritage-at-millennium-park", "name": "The Heritage at Millennium Park", "shortName": "Heritage", "height": 192.4, "tipHeight": 192.4, "heightSource": "https://www.skyscrapercenter.com/building/the-heritage-at-millennium-park/1897", "note": "Detailed Heritage: mapped footprint; 192.4 m published top and 176.8 m occupied floor. Podium 32.8 m and lower terrace 89.5 m from city design drawings; facade spacing and roof equipment estimated.", "footprint": { "way": 147397547, "version": 7, "coordinates": [[-87.6260719, 41.8843928], [-87.6257481, 41.8843917], [-87.6257191, 41.8843891], [-87.6256478, 41.8843865], [-87.6255526, 41.884377], [-87.6254712, 41.8843689], [-87.6254652, 41.8841954], [-87.6254621, 41.8841073], [-87.6254542, 41.883665], [-87.6254571, 41.8836595], [-87.6254538, 41.8836092], [-87.6260475, 41.8836083]] }, "parts": [{ "way": 686199648, "version": 4, "coordinates": [[-87.6256927, 41.8839116], [-87.6256884, 41.883961], [-87.6255146, 41.8839622], [-87.6254791, 41.8840238], [-87.6254621, 41.8841073], [-87.6254652, 41.8841954], [-87.6254854, 41.8842648], [-87.6255135, 41.8842688], [-87.6255389, 41.8843317], [-87.6255398, 41.8843608], [-87.6257484, 41.8843597], [-87.6257491, 41.8842951], [-87.6258081, 41.8842912], [-87.6258044, 41.8842312], [-87.6258273, 41.8842124], [-87.6258393, 41.8841657], [-87.6258472, 41.8841049], [-87.6258401, 41.8840613], [-87.6258255, 41.8840069], [-87.6257984, 41.8839707], [-87.6257899, 41.883913], [-87.6257556, 41.8839132]], "bottom": 0, "top": 192.4 }, { "way": 686199649, "version": 1, "coordinates": [[-87.6257591, 41.8837593], [-87.6257556, 41.8839132], [-87.6256927, 41.8839116], [-87.6256884, 41.883961], [-87.6255146, 41.8839622], [-87.6254791, 41.8840238], [-87.6254621, 41.8841073], [-87.6254542, 41.883665], [-87.6257265, 41.8836609], [-87.6257315, 41.8837592]], "bottom": 0, "top": 89.5096, "estimatedHeight": true }, { "way": 686199650, "version": 2, "coordinates": [[-87.6254542, 41.883665], [-87.6254571, 41.8836595], [-87.6254538, 41.8836092], [-87.6260475, 41.8836083], [-87.6260719, 41.8843928], [-87.6257481, 41.8843917], [-87.6257484, 41.8843597], [-87.6257491, 41.8842951], [-87.6258081, 41.8842912], [-87.6258044, 41.8842312], [-87.6258273, 41.8842124], [-87.6258393, 41.8841657], [-87.6258472, 41.8841049], [-87.6258401, 41.8840613], [-87.6258255, 41.8840069], [-87.6257984, 41.8839707], [-87.6257899, 41.883913], [-87.6257556, 41.8839132], [-87.6257591, 41.8837593], [-87.6257315, 41.8837592], [-87.6257265, 41.8836609]], "bottom": 0, "top": 32.8176, "estimatedHeight": true }] },
16
- { "id": "building-kemper", "name": "Kemper Building", "shortName": "Kemper", "height": 159, "tipHeight": 159, "heightSource": "https://www.openstreetmap.org/way/64389514", "note": "Detailed Kemper: mapped footprint, tower part, and 159 m OpenStreetMap height; 41 published floors. Window rows, bays, and the finned crown are estimated.", "footprint": { "way": 64389514, "version": 13, "coordinates": [[-87.6277499, 41.8863375], [-87.6273407, 41.8863436], [-87.6273396, 41.8863339], [-87.6271328, 41.8863379], [-87.6270968, 41.8863386], [-87.6270991, 41.8866309], [-87.6271288, 41.8866306], [-87.6272242, 41.8866295], [-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163]] }, "parts": [{ "way": 685494066, "version": 4, "coordinates": [[-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163], [-87.6277499, 41.8863375], [-87.6273407, 41.8863436]], "bottom": 0, "top": 159 }, { "way": 685494067, "version": 4, "coordinates": [[-87.6273407, 41.8863436], [-87.6273446, 41.8866282], [-87.6272242, 41.8866295], [-87.6271288, 41.8866306], [-87.6270991, 41.8866309], [-87.6270968, 41.8863386], [-87.6271328, 41.8863379], [-87.6273396, 41.8863339]], "bottom": 0, "top": 7.8, "estimatedHeight": true }] },
16
+ { "id": "building-kemper", "name": "Kemper Building", "shortName": "Kemper", "height": 159, "tipHeight": 159, "heightSource": "https://www.openstreetmap.org/way/64389514", "note": "Detailed Kemper: mapped footprint, tower part, and 159 m OpenStreetMap height; 41 published floors. Photographed 12/14-column facade rhythm; window rows and crown remain estimated.", "footprint": { "way": 64389514, "version": 13, "coordinates": [[-87.6277499, 41.8863375], [-87.6273407, 41.8863436], [-87.6273396, 41.8863339], [-87.6271328, 41.8863379], [-87.6270968, 41.8863386], [-87.6270991, 41.8866309], [-87.6271288, 41.8866306], [-87.6272242, 41.8866295], [-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163]] }, "parts": [{ "way": 685494066, "version": 4, "coordinates": [[-87.6273446, 41.8866282], [-87.627346, 41.8866984], [-87.6273463, 41.8867111], [-87.6273478, 41.8867197], [-87.627381, 41.8867192], [-87.6275197, 41.8867167], [-87.6277622, 41.8867154], [-87.6277552, 41.8865163], [-87.6277499, 41.8863375], [-87.6273407, 41.8863436]], "bottom": 0, "top": 159 }, { "way": 685494067, "version": 4, "coordinates": [[-87.6273407, 41.8863436], [-87.6273446, 41.8866282], [-87.6272242, 41.8866295], [-87.6271288, 41.8866306], [-87.6270991, 41.8866309], [-87.6270968, 41.8863386], [-87.6271328, 41.8863379], [-87.6273396, 41.8863339]], "bottom": 0, "top": 7.8, "estimatedHeight": true }] },
17
17
  { "id": "building-crain-communications", "name": "Crain Communications Building", "shortName": "Crain", "height": 177.4, "tipHeight": 177.4, "heightSource": "https://www.skyscrapercenter.com/building/150-north-michigan-avenue/2441", "note": "Detailed Crain: mapped parts, split, notches and roof bearing; roof slope and both peaks at the published 177.4 m measured on the source photograph, with its 3.5 m band pitch. Lobby, window module and roof grid estimated.", "footprint": { "way": 210671717, "version": 14, "coordinates": [[-87.6251984, 41.8846185], [-87.6252086, 41.8849637], [-87.6251849, 41.884981], [-87.6251613, 41.8849983], [-87.6252038, 41.8850292], [-87.6247448, 41.8850344], [-87.624744, 41.8850059], [-87.6247427, 41.8849565], [-87.6247379, 41.8847857], [-87.6247375, 41.8847566], [-87.6248159, 41.8846976], [-87.6248301, 41.884687], [-87.6248227, 41.8846815], [-87.6247345, 41.8846233], [-87.624814, 41.8846217], [-87.624879, 41.8846221]] }, "parts": [{ "way": 284816227, "version": 2, "coordinates": [[-87.6250471, 41.8849145], [-87.625093, 41.8848805], [-87.6252086, 41.8849637], [-87.6251849, 41.884981], [-87.6251613, 41.8849983]], "bottom": 0, "top": 152.5 }, { "way": 284816228, "version": 2, "coordinates": [[-87.6247345, 41.8846233], [-87.6248227, 41.8846815], [-87.6248301, 41.884687], [-87.625093, 41.8848805], [-87.6252086, 41.8849637], [-87.6251984, 41.8846185], [-87.624879, 41.8846221], [-87.624814, 41.8846217]], "bottom": 0, "top": 172.4, "roofSlope": { "direction": 133.0, "height": 75.0 } }, { "way": 284816229, "version": 2, "coordinates": [[-87.6251613, 41.8849983], [-87.6250471, 41.8849145], [-87.625093, 41.8848805], [-87.6248301, 41.884687], [-87.6248159, 41.8846976], [-87.6247375, 41.8847566], [-87.6247379, 41.8847857], [-87.6247427, 41.8849565], [-87.624744, 41.8850059], [-87.6247448, 41.8850344], [-87.6252038, 41.8850292]], "bottom": 0, "top": 177.4, "roofSlope": { "direction": 133.0, "height": 73.0 } }] },
18
18
  { "id": "building-330-north-wabash", "name": "330 North Wabash", "shortName": "330 N Wabash", "height": 211.84, "tipHeight": 211.84, "heightSource": "https://en.wikipedia.org/wiki/330_North_Wabash", "note": "Detailed 330 North Wabash (AMA Plaza): the tower the drawing labels Michigan Plaza South, whose roof corners land on the drawn ones through the photograph's camera. Mapped outline and 211.84 m (695 ft) height; bronze I-beam mullions on the 5 ft module, bronze spandrels and glass on 12 ft 6 in floors, a lobby on the 25 ft plaza, and louvered mechanical floors. No drawn model; the original layout has no counterpart.", "footprint": { "way": 64596068, "version": 20, "coordinates": [[-87.6278354, 41.8890249], [-87.627387, 41.8890335], [-87.6273775, 41.888809], [-87.6273647, 41.8885094], [-87.6273551, 41.8882848], [-87.6278057, 41.8882763]] }, "parts": [{ "way": 64596068, "version": 20, "coordinates": [[-87.6278354, 41.8890249], [-87.627387, 41.8890335], [-87.6273775, 41.888809], [-87.6273647, 41.8885094], [-87.6273551, 41.8882848], [-87.6278057, 41.8882763]], "bottom": 0, "top": 211.84 }] },
19
19
  { "id": "building-michigan-plaza-south-tower", "name": "Michigan Plaza South", "shortName": "Michigan Plaza S", "height": 168.6, "tipHeight": 168.6, "heightSource": "https://www.skyscrapercenter.com/building/michigan-plaza-south/2825", "note": "Detailed Michigan Plaza South: mapped outline, published 168.6 m height, and a 44-story glazed grid; window rows and bays estimated.", "footprint": { "way": 127107024, "version": 12, "coordinates": [[-87.6231713, 41.8858935], [-87.6239484, 41.8858842], [-87.6239505, 41.8861715], [-87.6238471, 41.8861735], [-87.6238486, 41.886216], [-87.6238504, 41.8862675], [-87.6235019, 41.8862724], [-87.6235019, 41.8861725], [-87.6231743, 41.8861722]] }, "parts": [{ "way": 127107024, "version": 12, "coordinates": [[-87.6231713, 41.8858935], [-87.6239484, 41.8858842], [-87.6239505, 41.8861715], [-87.6238471, 41.8861735], [-87.6238486, 41.886216], [-87.6238504, 41.8862675], [-87.6235019, 41.8862724], [-87.6235019, 41.8861725], [-87.6231743, 41.8861722]], "bottom": 0, "top": 168.6 }] },