@hpcc-js/map 3.4.10 → 3.4.11
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/LICENSE +43 -43
- package/README.md +88 -88
- package/TopoJSON/BR.json +122 -122
- package/TopoJSON/GB_idx.json +1 -1
- package/TopoJSON/IE_idx.json +1 -1
- package/TopoJSON/ND_idx.json +1 -1
- package/TopoJSON/countries.json +257 -257
- package/TopoJSON/us-counties.json +16550 -16550
- package/TopoJSON/us-states.json +458 -458
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +1 -1
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +7 -7
- package/src/CanvasPinLayer.ts +99 -99
- package/src/CanvasPins.ts +397 -397
- package/src/Choropleth.css +27 -27
- package/src/Choropleth.ts +203 -203
- package/src/ChoroplethContinents.ts +13 -13
- package/src/ChoroplethCounties.ts +111 -111
- package/src/ChoroplethCountries.ts +100 -100
- package/src/ChoroplethStates.ts +103 -103
- package/src/ChoroplethStatesHeat.ts +8 -8
- package/src/GMap.css +16 -16
- package/src/GMap.ts +880 -880
- package/src/GMapCounties.ts +93 -93
- package/src/GMapGraph.ts +61 -61
- package/src/GMapHeat.ts +27 -27
- package/src/GMapLayered.ts +94 -94
- package/src/GMapPin.ts +115 -115
- package/src/GMapPinLine.ts +138 -138
- package/src/GeoHash.css +15 -15
- package/src/GeoHash.ts +139 -139
- package/src/Graph.css +10 -10
- package/src/Graph.ts +98 -98
- package/src/Graticule.css +13 -13
- package/src/Graticule.ts +97 -97
- package/src/Heat.css +2 -2
- package/src/Heat.ts +87 -87
- package/src/IChoropleth.ts +8 -8
- package/src/Layer.ts +99 -99
- package/src/Layered.css +19 -19
- package/src/Layered.ts +206 -206
- package/src/Lines.css +9 -9
- package/src/Lines.ts +78 -78
- package/src/OpenStreet.css +15 -15
- package/src/OpenStreet.ts +126 -126
- package/src/Pins.css +18 -18
- package/src/Pins.ts +350 -350
- package/src/Projection.ts +42 -42
- package/src/TestHeatMap.ts +8 -8
- package/src/TopoJSONChoropleth.ts +125 -125
- package/src/Utility.ts +484 -484
- package/src/__package__.ts +3 -3
- package/src/index.ts +33 -33
- package/src/leaflet/AlbersPR.ts +48 -48
- package/src/leaflet/Blank.ts +9 -9
- package/src/leaflet/Circles.ts +139 -139
- package/src/leaflet/ClusterCircles.css +26 -26
- package/src/leaflet/ClusterCircles.ts +88 -88
- package/src/leaflet/Countries.ts +43 -43
- package/src/leaflet/DrawLayer.ts +167 -167
- package/src/leaflet/FeatureLayer.ts +138 -138
- package/src/leaflet/GMap.ts +44 -44
- package/src/leaflet/HeatLayer.ts +77 -77
- package/src/leaflet/Icons.ts +60 -60
- package/src/leaflet/Leaflet.css +3 -3
- package/src/leaflet/Leaflet.ts +239 -239
- package/src/leaflet/MapBox.ts +35 -35
- package/src/leaflet/Markers.ts +109 -109
- package/src/leaflet/OpenStreet.ts +27 -27
- package/src/leaflet/Path.ts +138 -138
- package/src/leaflet/Pins.ts +73 -73
- package/src/leaflet/Polygons.ts +113 -113
- package/src/leaflet/Region.ts +138 -138
- package/src/leaflet/Text.ts +99 -99
- package/src/leaflet/TileLayer.ts +81 -81
- package/src/leaflet/TopoJSON.ts +146 -146
- package/src/leaflet/US.ts +15 -15
- package/src/leaflet/USCounties.ts +43 -43
- package/src/leaflet/USStates.ts +41 -41
- package/src/leaflet/World.css +3 -3
- package/src/leaflet/World.ts +172 -172
- package/src/leaflet/index.ts +18 -18
- package/src/leaflet/leaflet-shim.ts +18 -18
- package/src/leaflet/plugins/BeautifyIcon.css +44 -44
- package/src/leaflet/plugins/BeautifyIcon.ts +190 -190
- package/src/leaflet/plugins/BeutifyIcon.licence +20 -20
- package/src/leaflet/plugins/D3SvgOverlay.css +3 -3
- package/src/leaflet/plugins/D3SvgOverlay.licence +20 -20
- package/src/leaflet/plugins/D3SvgOverlay.ts +175 -175
- package/src/leaflet/plugins/HeatLayer.license +21 -21
- package/src/leaflet/plugins/HeatLayer.ts +224 -224
- package/src/leaflet/plugins/Leaflet.GoogleMutant.ts +424 -424
- package/src/leaflet/plugins/lru_map.ts +352 -352
- package/src/test.ts +114 -114
package/src/leaflet/Text.ts
CHANGED
|
@@ -1,99 +1,99 @@
|
|
|
1
|
-
import { BeautifyIcon, Map } from "./leaflet-shim.ts";
|
|
2
|
-
import { format as d3Format } from "d3-format";
|
|
3
|
-
import { Markers } from "./Markers.ts";
|
|
4
|
-
|
|
5
|
-
export class Text extends Markers {
|
|
6
|
-
|
|
7
|
-
constructor(cluster = false) {
|
|
8
|
-
super(cluster);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
layerUpdate(map: Map) {
|
|
12
|
-
const columns = this.columns();
|
|
13
|
-
const textIdx = columns.indexOf(this.textColumn());
|
|
14
|
-
const textColorIdx = columns.indexOf(this.textColorColumn());
|
|
15
|
-
const strokeColorIdx = columns.indexOf(this.strokeColorColumn());
|
|
16
|
-
const fillColorIdx = columns.indexOf(this.fillColorColumn());
|
|
17
|
-
super.layerUpdate(map, (row) => {
|
|
18
|
-
let text = this.propValue(textIdx, row, this.text());
|
|
19
|
-
const textSize = this.textSize(text, this.fontFamily(), this.fontSize());
|
|
20
|
-
if (this.textFormat_exists()) {
|
|
21
|
-
text = d3Format(this.textFormat())(text);
|
|
22
|
-
}
|
|
23
|
-
return {
|
|
24
|
-
icon: BeautifyIcon({
|
|
25
|
-
iconShape: "rectangle",
|
|
26
|
-
iconAnchor: [
|
|
27
|
-
(textSize.width / 2) + this.textOffsetX(),
|
|
28
|
-
(textSize.height / 2) + this.textOffsetY()
|
|
29
|
-
],
|
|
30
|
-
html: `<span style="
|
|
31
|
-
${this.fontFamily_exists() ? `font-family:${this.fontFamily()};` : ""}
|
|
32
|
-
font-size:${this.fontSize()}px;
|
|
33
|
-
pointer-events: none;
|
|
34
|
-
white-space:nowrap;
|
|
35
|
-
">${text}</span>`,
|
|
36
|
-
textColor: this.propValue(textColorIdx, row, this.textColor()),
|
|
37
|
-
borderColor: this.propValue(strokeColorIdx, row, this.strokeColor()),
|
|
38
|
-
backgroundColor: this.propValue(fillColorIdx, row, this.fillColor()),
|
|
39
|
-
props: {
|
|
40
|
-
owner: this,
|
|
41
|
-
row
|
|
42
|
-
}
|
|
43
|
-
}),
|
|
44
|
-
draggable: false
|
|
45
|
-
};
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
Text.prototype._class += " map_Text";
|
|
50
|
-
|
|
51
|
-
export interface Text {
|
|
52
|
-
text(): string;
|
|
53
|
-
text(_: string);
|
|
54
|
-
textColumn(): string;
|
|
55
|
-
textColumn(_: string);
|
|
56
|
-
textColumn_exists(): boolean;
|
|
57
|
-
textColor(): string;
|
|
58
|
-
textColor(_: string);
|
|
59
|
-
textColorColumn(): string;
|
|
60
|
-
textColorColumn(_: string);
|
|
61
|
-
textColorColumn_exists(): boolean;
|
|
62
|
-
strokeColor(): string;
|
|
63
|
-
strokeColor(_: string);
|
|
64
|
-
strokeColorColumn(): string;
|
|
65
|
-
strokeColorColumn(_: string);
|
|
66
|
-
strokColorColumn_exists(): boolean;
|
|
67
|
-
fillColor(): string;
|
|
68
|
-
fillColor(_: string);
|
|
69
|
-
fillColorColumn(): string;
|
|
70
|
-
fillColorColumn(_: string);
|
|
71
|
-
fillColorColumn_exists(): boolean;
|
|
72
|
-
fontFamily(): string;
|
|
73
|
-
fontFamily(_: string);
|
|
74
|
-
fontFamily_exists(): boolean;
|
|
75
|
-
fontSize(): number;
|
|
76
|
-
fontSize(_: number);
|
|
77
|
-
textOffsetX(): number;
|
|
78
|
-
textOffsetX(_: number): this;
|
|
79
|
-
textOffsetY(): number;
|
|
80
|
-
textOffsetY(_: number): this;
|
|
81
|
-
textFormat(): string;
|
|
82
|
-
textFormat(_: string): this;
|
|
83
|
-
textFormat_exists(): boolean;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
Text.prototype.publish("textOffsetX", 0, "number", "Horizontal offset of text");
|
|
87
|
-
Text.prototype.publish("textOffsetY", 0, "number", "Vertical offset of text");
|
|
88
|
-
Text.prototype.publish("text", "", "string", "Default text");
|
|
89
|
-
Text.prototype.publish("textColumn", null, "set", "Font awesome column", function () { return this.columns(); }, { optional: true });
|
|
90
|
-
Text.prototype.publish("textColor", "#ffffff", "html-color", "Default font awesome Color");
|
|
91
|
-
Text.prototype.publish("textColorColumn", null, "set", "Text color column", function () { return this.columns(); }, { optional: true });
|
|
92
|
-
Text.prototype.publish("textFontFamily", null, "set", "Text color column", function () { return this.columns(); }, { optional: true });
|
|
93
|
-
Text.prototype.publish("strokeColor", "transparent", "html-color", "Default stroke Color", null, { optional: true });
|
|
94
|
-
Text.prototype.publish("strokeColorColumn", null, "set", "Stroke color column", function () { return this.columns(); }, { optional: true });
|
|
95
|
-
Text.prototype.publish("fillColor", "#376cea", "html-color", "Default fill Color", null, { optional: true });
|
|
96
|
-
Text.prototype.publish("fillColorColumn", null, "set", "Fill color column", function () { return this.columns(); }, { optional: true });
|
|
97
|
-
Text.prototype.publish("fontFamily", null, "string", "Font family", null, { optional: true });
|
|
98
|
-
Text.prototype.publish("fontSize", 16, "number", "Font family", null, { optional: true });
|
|
99
|
-
Text.prototype.publish("textFormat", null, "string", "Format rules for text", null, { optional: true });
|
|
1
|
+
import { BeautifyIcon, Map } from "./leaflet-shim.ts";
|
|
2
|
+
import { format as d3Format } from "d3-format";
|
|
3
|
+
import { Markers } from "./Markers.ts";
|
|
4
|
+
|
|
5
|
+
export class Text extends Markers {
|
|
6
|
+
|
|
7
|
+
constructor(cluster = false) {
|
|
8
|
+
super(cluster);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
layerUpdate(map: Map) {
|
|
12
|
+
const columns = this.columns();
|
|
13
|
+
const textIdx = columns.indexOf(this.textColumn());
|
|
14
|
+
const textColorIdx = columns.indexOf(this.textColorColumn());
|
|
15
|
+
const strokeColorIdx = columns.indexOf(this.strokeColorColumn());
|
|
16
|
+
const fillColorIdx = columns.indexOf(this.fillColorColumn());
|
|
17
|
+
super.layerUpdate(map, (row) => {
|
|
18
|
+
let text = this.propValue(textIdx, row, this.text());
|
|
19
|
+
const textSize = this.textSize(text, this.fontFamily(), this.fontSize());
|
|
20
|
+
if (this.textFormat_exists()) {
|
|
21
|
+
text = d3Format(this.textFormat())(text);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
icon: BeautifyIcon({
|
|
25
|
+
iconShape: "rectangle",
|
|
26
|
+
iconAnchor: [
|
|
27
|
+
(textSize.width / 2) + this.textOffsetX(),
|
|
28
|
+
(textSize.height / 2) + this.textOffsetY()
|
|
29
|
+
],
|
|
30
|
+
html: `<span style="
|
|
31
|
+
${this.fontFamily_exists() ? `font-family:${this.fontFamily()};` : ""}
|
|
32
|
+
font-size:${this.fontSize()}px;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
white-space:nowrap;
|
|
35
|
+
">${text}</span>`,
|
|
36
|
+
textColor: this.propValue(textColorIdx, row, this.textColor()),
|
|
37
|
+
borderColor: this.propValue(strokeColorIdx, row, this.strokeColor()),
|
|
38
|
+
backgroundColor: this.propValue(fillColorIdx, row, this.fillColor()),
|
|
39
|
+
props: {
|
|
40
|
+
owner: this,
|
|
41
|
+
row
|
|
42
|
+
}
|
|
43
|
+
}),
|
|
44
|
+
draggable: false
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
Text.prototype._class += " map_Text";
|
|
50
|
+
|
|
51
|
+
export interface Text {
|
|
52
|
+
text(): string;
|
|
53
|
+
text(_: string);
|
|
54
|
+
textColumn(): string;
|
|
55
|
+
textColumn(_: string);
|
|
56
|
+
textColumn_exists(): boolean;
|
|
57
|
+
textColor(): string;
|
|
58
|
+
textColor(_: string);
|
|
59
|
+
textColorColumn(): string;
|
|
60
|
+
textColorColumn(_: string);
|
|
61
|
+
textColorColumn_exists(): boolean;
|
|
62
|
+
strokeColor(): string;
|
|
63
|
+
strokeColor(_: string);
|
|
64
|
+
strokeColorColumn(): string;
|
|
65
|
+
strokeColorColumn(_: string);
|
|
66
|
+
strokColorColumn_exists(): boolean;
|
|
67
|
+
fillColor(): string;
|
|
68
|
+
fillColor(_: string);
|
|
69
|
+
fillColorColumn(): string;
|
|
70
|
+
fillColorColumn(_: string);
|
|
71
|
+
fillColorColumn_exists(): boolean;
|
|
72
|
+
fontFamily(): string;
|
|
73
|
+
fontFamily(_: string);
|
|
74
|
+
fontFamily_exists(): boolean;
|
|
75
|
+
fontSize(): number;
|
|
76
|
+
fontSize(_: number);
|
|
77
|
+
textOffsetX(): number;
|
|
78
|
+
textOffsetX(_: number): this;
|
|
79
|
+
textOffsetY(): number;
|
|
80
|
+
textOffsetY(_: number): this;
|
|
81
|
+
textFormat(): string;
|
|
82
|
+
textFormat(_: string): this;
|
|
83
|
+
textFormat_exists(): boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
Text.prototype.publish("textOffsetX", 0, "number", "Horizontal offset of text");
|
|
87
|
+
Text.prototype.publish("textOffsetY", 0, "number", "Vertical offset of text");
|
|
88
|
+
Text.prototype.publish("text", "", "string", "Default text");
|
|
89
|
+
Text.prototype.publish("textColumn", null, "set", "Font awesome column", function () { return this.columns(); }, { optional: true });
|
|
90
|
+
Text.prototype.publish("textColor", "#ffffff", "html-color", "Default font awesome Color");
|
|
91
|
+
Text.prototype.publish("textColorColumn", null, "set", "Text color column", function () { return this.columns(); }, { optional: true });
|
|
92
|
+
Text.prototype.publish("textFontFamily", null, "set", "Text color column", function () { return this.columns(); }, { optional: true });
|
|
93
|
+
Text.prototype.publish("strokeColor", "transparent", "html-color", "Default stroke Color", null, { optional: true });
|
|
94
|
+
Text.prototype.publish("strokeColorColumn", null, "set", "Stroke color column", function () { return this.columns(); }, { optional: true });
|
|
95
|
+
Text.prototype.publish("fillColor", "#376cea", "html-color", "Default fill Color", null, { optional: true });
|
|
96
|
+
Text.prototype.publish("fillColorColumn", null, "set", "Fill color column", function () { return this.columns(); }, { optional: true });
|
|
97
|
+
Text.prototype.publish("fontFamily", null, "string", "Font family", null, { optional: true });
|
|
98
|
+
Text.prototype.publish("fontSize", 16, "number", "Font family", null, { optional: true });
|
|
99
|
+
Text.prototype.publish("textFormat", null, "string", "Format rules for text", null, { optional: true });
|
package/src/leaflet/TileLayer.ts
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import { Widget } from "@hpcc-js/common";
|
|
2
|
-
import { CRS, FeatureGroup, LatLngBounds, LeafletEvent, Map } from "./leaflet-shim.ts";
|
|
3
|
-
|
|
4
|
-
export interface ILayer {
|
|
5
|
-
|
|
6
|
-
init(): Promise<void>;
|
|
7
|
-
hasBounds(): boolean;
|
|
8
|
-
getBounds(): LatLngBounds;
|
|
9
|
-
|
|
10
|
-
layerEnter(map: Map);
|
|
11
|
-
layerUpdate(map: Map);
|
|
12
|
-
layerExit(map: Map);
|
|
13
|
-
|
|
14
|
-
zoomEnd(e);
|
|
15
|
-
moveEnd(e);
|
|
16
|
-
viewReset(e);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class TileLayer extends Widget implements ILayer {
|
|
20
|
-
private _layer = new FeatureGroup();
|
|
21
|
-
protected _crs: any = CRS.EPSG3857;
|
|
22
|
-
|
|
23
|
-
constructor(cluster = false) {
|
|
24
|
-
super();
|
|
25
|
-
(this._layer as any).__hpcc_layer = this;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
crs() {
|
|
29
|
-
return this._crs;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
attribution(): string {
|
|
33
|
-
return "";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
clear() {
|
|
37
|
-
this._layer.clearLayers();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
add(layer) {
|
|
41
|
-
this._layer.addLayer(layer);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ILayer ---
|
|
45
|
-
protected _initPromise;
|
|
46
|
-
init(): Promise<void> {
|
|
47
|
-
if (!this._initPromise) {
|
|
48
|
-
this._initPromise = Promise.resolve();
|
|
49
|
-
}
|
|
50
|
-
return this._initPromise;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
hasBounds(): boolean {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
getBounds(): LatLngBounds {
|
|
58
|
-
return this._layer.getBounds();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
layerEnter(map: Map) {
|
|
62
|
-
map.addLayer(this._layer);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
layerUpdate(map: Map) {
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
layerExit(map: Map) {
|
|
69
|
-
this._layer.clearLayers();
|
|
70
|
-
map.removeLayer(this._layer);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
zoomEnd(e: LeafletEvent) {
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
moveEnd(e: LeafletEvent) {
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
viewReset(e: LeafletEvent) {
|
|
80
|
-
}
|
|
81
|
-
}
|
|
1
|
+
import { Widget } from "@hpcc-js/common";
|
|
2
|
+
import { CRS, FeatureGroup, LatLngBounds, LeafletEvent, Map } from "./leaflet-shim.ts";
|
|
3
|
+
|
|
4
|
+
export interface ILayer {
|
|
5
|
+
|
|
6
|
+
init(): Promise<void>;
|
|
7
|
+
hasBounds(): boolean;
|
|
8
|
+
getBounds(): LatLngBounds;
|
|
9
|
+
|
|
10
|
+
layerEnter(map: Map);
|
|
11
|
+
layerUpdate(map: Map);
|
|
12
|
+
layerExit(map: Map);
|
|
13
|
+
|
|
14
|
+
zoomEnd(e);
|
|
15
|
+
moveEnd(e);
|
|
16
|
+
viewReset(e);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class TileLayer extends Widget implements ILayer {
|
|
20
|
+
private _layer = new FeatureGroup();
|
|
21
|
+
protected _crs: any = CRS.EPSG3857;
|
|
22
|
+
|
|
23
|
+
constructor(cluster = false) {
|
|
24
|
+
super();
|
|
25
|
+
(this._layer as any).__hpcc_layer = this;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
crs() {
|
|
29
|
+
return this._crs;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
attribution(): string {
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
clear() {
|
|
37
|
+
this._layer.clearLayers();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
add(layer) {
|
|
41
|
+
this._layer.addLayer(layer);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ILayer ---
|
|
45
|
+
protected _initPromise;
|
|
46
|
+
init(): Promise<void> {
|
|
47
|
+
if (!this._initPromise) {
|
|
48
|
+
this._initPromise = Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
return this._initPromise;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
hasBounds(): boolean {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getBounds(): LatLngBounds {
|
|
58
|
+
return this._layer.getBounds();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
layerEnter(map: Map) {
|
|
62
|
+
map.addLayer(this._layer);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
layerUpdate(map: Map) {
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
layerExit(map: Map) {
|
|
69
|
+
this._layer.clearLayers();
|
|
70
|
+
map.removeLayer(this._layer);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
zoomEnd(e: LeafletEvent) {
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
moveEnd(e: LeafletEvent) {
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
viewReset(e: LeafletEvent) {
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/leaflet/TopoJSON.ts
CHANGED
|
@@ -1,146 +1,146 @@
|
|
|
1
|
-
import { GeoJSON, Map } from "./leaflet-shim.ts";
|
|
2
|
-
import { json as d3Json } from "d3-request";
|
|
3
|
-
import * as topojson from "topojson-client";
|
|
4
|
-
import { topoJsonFolder } from "../Choropleth.ts";
|
|
5
|
-
import { FeatureLayer } from "./FeatureLayer.ts";
|
|
6
|
-
|
|
7
|
-
export function fixDateLine(feature, layer) {
|
|
8
|
-
const latlongs = layer.getLatLngs();
|
|
9
|
-
latlongs.forEach(function (shape) {
|
|
10
|
-
shape.forEach(function (cord) {
|
|
11
|
-
if (Array.isArray(cord)) {
|
|
12
|
-
const cutoff = 165;
|
|
13
|
-
let lhs = 0;
|
|
14
|
-
let rhs = 0;
|
|
15
|
-
let vlhs = 0;
|
|
16
|
-
let vrhs = 0;
|
|
17
|
-
cord.forEach(function (pnt) {
|
|
18
|
-
if (pnt.lat > -62) { // Ignore Antartica
|
|
19
|
-
if (pnt.lng > cutoff) {
|
|
20
|
-
++vrhs;
|
|
21
|
-
} else if (pnt.lng < -cutoff) {
|
|
22
|
-
++vlhs;
|
|
23
|
-
}
|
|
24
|
-
if (pnt.lng > 0) {
|
|
25
|
-
++rhs;
|
|
26
|
-
} else if (pnt.lng < 0) {
|
|
27
|
-
++lhs;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
if (vlhs > 0 && vrhs > 0) {
|
|
32
|
-
cord.forEach(function (pnt) {
|
|
33
|
-
if (pnt.lng > cutoff && lhs > rhs) {
|
|
34
|
-
pnt.lng -= 360;
|
|
35
|
-
} else if (pnt.lng < -cutoff && rhs > lhs) {
|
|
36
|
-
pnt.lng += 360;
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
layer.setLatLngs(latlongs);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export class TopoJSON extends GeoJSON {
|
|
47
|
-
|
|
48
|
-
constructor(data, options) {
|
|
49
|
-
super(data, {
|
|
50
|
-
...options,
|
|
51
|
-
onEachFeature: (feature, layer) => {
|
|
52
|
-
if (options.onEachFeature) {
|
|
53
|
-
options.onEachFeature(feature, layer);
|
|
54
|
-
}
|
|
55
|
-
fixDateLine(feature, layer);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
addData(data) {
|
|
61
|
-
let geojson;
|
|
62
|
-
let key;
|
|
63
|
-
if (data.type === "Topology") {
|
|
64
|
-
for (key in data.objects) {
|
|
65
|
-
if (data.objects.hasOwnProperty(key)) {
|
|
66
|
-
geojson = topojson.feature(data, data.objects[key]);
|
|
67
|
-
super.addData.call(this, geojson);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
super.addData.call(this, data);
|
|
73
|
-
return this;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
let usStates = null;
|
|
78
|
-
let usCounties = null;
|
|
79
|
-
let features = null;
|
|
80
|
-
let rFeatures = null;
|
|
81
|
-
export class TopoJSONLayer extends FeatureLayer {
|
|
82
|
-
|
|
83
|
-
initStates(): Promise<void> {
|
|
84
|
-
if (!this._initPromise) {
|
|
85
|
-
this._initPromise = new Promise<void>((resolve, reject) => {
|
|
86
|
-
if (usStates) {
|
|
87
|
-
resolve();
|
|
88
|
-
}
|
|
89
|
-
d3Json(`${topoJsonFolder()}/us-states.json`, function (_usStates) {
|
|
90
|
-
usStates = _usStates;
|
|
91
|
-
features = topojson.feature(usStates.topology, usStates.topology.objects.states).features;
|
|
92
|
-
rFeatures = {};
|
|
93
|
-
for (const key in features) {
|
|
94
|
-
if (features[key].id) {
|
|
95
|
-
rFeatures[usStates.stateNames[features[key].id].code] = features[key];
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
resolve();
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return this._initPromise;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
initCounties(): Promise<void> {
|
|
106
|
-
if (!this._initPromise) {
|
|
107
|
-
this._initPromise = new Promise<void>((resolve, reject) => {
|
|
108
|
-
if (usCounties) {
|
|
109
|
-
resolve();
|
|
110
|
-
}
|
|
111
|
-
d3Json(`${topoJsonFolder()}/us-counties.json`, function (_usCounties) {
|
|
112
|
-
usCounties = _usCounties;
|
|
113
|
-
features = topojson.feature(usCounties.topology, usCounties.topology.objects.counties).features;
|
|
114
|
-
rFeatures = {};
|
|
115
|
-
for (const key in features) {
|
|
116
|
-
if (features[key].id) {
|
|
117
|
-
rFeatures[features[key].id] = features[key];
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
resolve();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
return this._initPromise;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
init(): Promise<void> {
|
|
128
|
-
return this.initCounties();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
layerEnter(map: Map) {
|
|
132
|
-
super.layerEnter(map);
|
|
133
|
-
const topoJSON = new TopoJSON(features, {
|
|
134
|
-
style(feature) {
|
|
135
|
-
return {
|
|
136
|
-
color: "#000",
|
|
137
|
-
opacity: 1,
|
|
138
|
-
weight: 1,
|
|
139
|
-
fillColor: "#35495d",
|
|
140
|
-
fillOpacity: 0.2
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
this.add(topoJSON);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
1
|
+
import { GeoJSON, Map } from "./leaflet-shim.ts";
|
|
2
|
+
import { json as d3Json } from "d3-request";
|
|
3
|
+
import * as topojson from "topojson-client";
|
|
4
|
+
import { topoJsonFolder } from "../Choropleth.ts";
|
|
5
|
+
import { FeatureLayer } from "./FeatureLayer.ts";
|
|
6
|
+
|
|
7
|
+
export function fixDateLine(feature, layer) {
|
|
8
|
+
const latlongs = layer.getLatLngs();
|
|
9
|
+
latlongs.forEach(function (shape) {
|
|
10
|
+
shape.forEach(function (cord) {
|
|
11
|
+
if (Array.isArray(cord)) {
|
|
12
|
+
const cutoff = 165;
|
|
13
|
+
let lhs = 0;
|
|
14
|
+
let rhs = 0;
|
|
15
|
+
let vlhs = 0;
|
|
16
|
+
let vrhs = 0;
|
|
17
|
+
cord.forEach(function (pnt) {
|
|
18
|
+
if (pnt.lat > -62) { // Ignore Antartica
|
|
19
|
+
if (pnt.lng > cutoff) {
|
|
20
|
+
++vrhs;
|
|
21
|
+
} else if (pnt.lng < -cutoff) {
|
|
22
|
+
++vlhs;
|
|
23
|
+
}
|
|
24
|
+
if (pnt.lng > 0) {
|
|
25
|
+
++rhs;
|
|
26
|
+
} else if (pnt.lng < 0) {
|
|
27
|
+
++lhs;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
if (vlhs > 0 && vrhs > 0) {
|
|
32
|
+
cord.forEach(function (pnt) {
|
|
33
|
+
if (pnt.lng > cutoff && lhs > rhs) {
|
|
34
|
+
pnt.lng -= 360;
|
|
35
|
+
} else if (pnt.lng < -cutoff && rhs > lhs) {
|
|
36
|
+
pnt.lng += 360;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
layer.setLatLngs(latlongs);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class TopoJSON extends GeoJSON {
|
|
47
|
+
|
|
48
|
+
constructor(data, options) {
|
|
49
|
+
super(data, {
|
|
50
|
+
...options,
|
|
51
|
+
onEachFeature: (feature, layer) => {
|
|
52
|
+
if (options.onEachFeature) {
|
|
53
|
+
options.onEachFeature(feature, layer);
|
|
54
|
+
}
|
|
55
|
+
fixDateLine(feature, layer);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
addData(data) {
|
|
61
|
+
let geojson;
|
|
62
|
+
let key;
|
|
63
|
+
if (data.type === "Topology") {
|
|
64
|
+
for (key in data.objects) {
|
|
65
|
+
if (data.objects.hasOwnProperty(key)) {
|
|
66
|
+
geojson = topojson.feature(data, data.objects[key]);
|
|
67
|
+
super.addData.call(this, geojson);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
super.addData.call(this, data);
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let usStates = null;
|
|
78
|
+
let usCounties = null;
|
|
79
|
+
let features = null;
|
|
80
|
+
let rFeatures = null;
|
|
81
|
+
export class TopoJSONLayer extends FeatureLayer {
|
|
82
|
+
|
|
83
|
+
initStates(): Promise<void> {
|
|
84
|
+
if (!this._initPromise) {
|
|
85
|
+
this._initPromise = new Promise<void>((resolve, reject) => {
|
|
86
|
+
if (usStates) {
|
|
87
|
+
resolve();
|
|
88
|
+
}
|
|
89
|
+
d3Json(`${topoJsonFolder()}/us-states.json`, function (_usStates) {
|
|
90
|
+
usStates = _usStates;
|
|
91
|
+
features = topojson.feature(usStates.topology, usStates.topology.objects.states).features;
|
|
92
|
+
rFeatures = {};
|
|
93
|
+
for (const key in features) {
|
|
94
|
+
if (features[key].id) {
|
|
95
|
+
rFeatures[usStates.stateNames[features[key].id].code] = features[key];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
resolve();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return this._initPromise;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
initCounties(): Promise<void> {
|
|
106
|
+
if (!this._initPromise) {
|
|
107
|
+
this._initPromise = new Promise<void>((resolve, reject) => {
|
|
108
|
+
if (usCounties) {
|
|
109
|
+
resolve();
|
|
110
|
+
}
|
|
111
|
+
d3Json(`${topoJsonFolder()}/us-counties.json`, function (_usCounties) {
|
|
112
|
+
usCounties = _usCounties;
|
|
113
|
+
features = topojson.feature(usCounties.topology, usCounties.topology.objects.counties).features;
|
|
114
|
+
rFeatures = {};
|
|
115
|
+
for (const key in features) {
|
|
116
|
+
if (features[key].id) {
|
|
117
|
+
rFeatures[features[key].id] = features[key];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
resolve();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return this._initPromise;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
init(): Promise<void> {
|
|
128
|
+
return this.initCounties();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
layerEnter(map: Map) {
|
|
132
|
+
super.layerEnter(map);
|
|
133
|
+
const topoJSON = new TopoJSON(features, {
|
|
134
|
+
style(feature) {
|
|
135
|
+
return {
|
|
136
|
+
color: "#000",
|
|
137
|
+
opacity: 1,
|
|
138
|
+
weight: 1,
|
|
139
|
+
fillColor: "#35495d",
|
|
140
|
+
fillOpacity: 0.2
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
this.add(topoJSON);
|
|
145
|
+
}
|
|
146
|
+
}
|