dotted-map 3.0.0 → 3.1.0
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 +38 -2
- package/dist/index.cjs +60 -9
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +60 -9
- package/dist/{types-ByIhMtjO.d.cts → types-F6gvGCSl.d.mts} +11 -1
- package/dist/{types-UL1f7mia.d.mts → types-vOcy-UuQ.d.cts} +11 -1
- package/dist/without-countries.cjs +28 -4
- package/dist/without-countries.d.cts +3 -2
- package/dist/without-countries.d.mts +3 -2
- package/dist/without-countries.mjs +28 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
<img src="https://raw.githubusercontent.com/NTag/dotted-map/master/images/world-diagonal-circle-dark.svg" width="100%" />
|
|
9
9
|
|
|
10
|
+
<img src="https://raw.githubusercontent.com/NTag/dotted-map/master/images/world-orthographic-circle-dark.svg" width="100%" />
|
|
11
|
+
|
|
10
12
|
<img src="https://raw.githubusercontent.com/NTag/dotted-map/master/images/france-diagonal-hexagon-light.svg" height="150px" />
|
|
11
13
|
<img src="https://raw.githubusercontent.com/NTag/dotted-map/master/images/italy-diagonal-hexagon-light.svg" height="150px" />
|
|
12
14
|
<img src="https://raw.githubusercontent.com/NTag/dotted-map/master/images/uk-diagonal-hexagon-light.svg" height="150px" />
|
|
@@ -124,9 +126,10 @@ import DottedMap from 'dotted-map';
|
|
|
124
126
|
const map = new DottedMap({
|
|
125
127
|
height,
|
|
126
128
|
width, // just specify either height or width, so the ratio of the map is correct
|
|
127
|
-
countries: [
|
|
129
|
+
countries: [‘FRA’] // look into `countries.geo.json` to see which keys to use. You can also omit this parameter and the whole world will be used
|
|
128
130
|
region: { lat: { min, max }, lng: { min, max } }, // if not present, it will fit the countries (and if no country is specified, the whole world)
|
|
129
|
-
grid:
|
|
131
|
+
grid: ‘vertical’ | ‘diagonal’, // how points should be aligned
|
|
132
|
+
projection: { name, center }, // optional, see below
|
|
130
133
|
avoidOuterPins: false | true, // if it’s true, prevent adding pins when they are outside of region/countries
|
|
131
134
|
});
|
|
132
135
|
|
|
@@ -152,6 +155,39 @@ map.getSVG({
|
|
|
152
155
|
// <svg><circle … /><circle …></svg>
|
|
153
156
|
```
|
|
154
157
|
|
|
158
|
+
### Projection
|
|
159
|
+
|
|
160
|
+
By default, the map uses the Mercator projection. You can optionally pass a `projection` parameter to use a different one:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
const map = new DottedMap({
|
|
164
|
+
height: 60,
|
|
165
|
+
grid: 'diagonal',
|
|
166
|
+
projection: { name: 'robinson' },
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Available projections: `mercator` (default), `equirectangular`, `robinson`, `equalEarth`, `mollweide`, `miller`, `sinusoidal`, `orthographic`, `gallPeters`, `vanDerGrinten`.
|
|
171
|
+
|
|
172
|
+
You can also pass a `center` to shift the map's center point. This is especially useful for `orthographic` (which shows a single hemisphere) but works with any projection:
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
// Orthographic projection centered on North America
|
|
176
|
+
const map = new DottedMap({
|
|
177
|
+
height: 60,
|
|
178
|
+
grid: 'diagonal',
|
|
179
|
+
projection: { name: 'orthographic', center: { lat: 40, lng: -100 } },
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Robinson projection centered on the Pacific
|
|
183
|
+
const map = new DottedMap({
|
|
184
|
+
height: 60,
|
|
185
|
+
projection: { name: 'robinson', center: { lat: 0, lng: 150 } },
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Note: for `orthographic`, pins on the back side of the globe (not visible) will be ignored.
|
|
190
|
+
|
|
155
191
|
## Acknowledgments
|
|
156
192
|
|
|
157
193
|
Countries are from https://github.com/johan/world.geo.json.
|
package/dist/index.cjs
CHANGED
|
@@ -12766,6 +12766,26 @@ var countries_geo_default = {
|
|
|
12766
12766
|
|
|
12767
12767
|
//#endregion
|
|
12768
12768
|
//#region src/with-countries.ts
|
|
12769
|
+
const PROJECTIONS = {
|
|
12770
|
+
mercator: "+proj=merc +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12771
|
+
equirectangular: "+proj=eqc +lon_0={lng} +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12772
|
+
robinson: "+proj=robin +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12773
|
+
equalEarth: "+proj=eqearth +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12774
|
+
mollweide: "+proj=moll +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12775
|
+
miller: "+proj=mill +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12776
|
+
sinusoidal: "+proj=sinu +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12777
|
+
orthographic: "+proj=ortho +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12778
|
+
gallPeters: "+proj=cea +lon_0={lng} +lat_ts=45 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12779
|
+
vanDerGrinten: "+proj=vandg +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m"
|
|
12780
|
+
};
|
|
12781
|
+
const DEFAULT_PROJECTION = { name: "mercator" };
|
|
12782
|
+
const getProj4String = (projection = DEFAULT_PROJECTION) => {
|
|
12783
|
+
const template = PROJECTIONS[projection.name];
|
|
12784
|
+
const lat = projection.center?.lat ?? 0;
|
|
12785
|
+
const lng = projection.center?.lng ?? 0;
|
|
12786
|
+
return template.replace("{lat}", String(lat)).replace("{lng}", String(lng));
|
|
12787
|
+
};
|
|
12788
|
+
const isFinitePoint = (point) => point.every((v) => Number.isFinite(v));
|
|
12769
12789
|
const typedWorld = countries_geo_default;
|
|
12770
12790
|
const geojsonByCountry = typedWorld.features.reduce((countries, feature) => {
|
|
12771
12791
|
countries[feature.id] = feature;
|
|
@@ -12788,8 +12808,8 @@ const DEFAULT_WORLD_REGION = {
|
|
|
12788
12808
|
max: 71
|
|
12789
12809
|
},
|
|
12790
12810
|
lng: {
|
|
12791
|
-
min: -
|
|
12792
|
-
max:
|
|
12811
|
+
min: -168,
|
|
12812
|
+
max: 168
|
|
12793
12813
|
}
|
|
12794
12814
|
};
|
|
12795
12815
|
const computeGeojsonBox = (geojson) => {
|
|
@@ -12826,8 +12846,9 @@ const computeGeojsonBox = (geojson) => {
|
|
|
12826
12846
|
};
|
|
12827
12847
|
} else throw new Error(`Unknown geojson type ${geojson.type}`);
|
|
12828
12848
|
};
|
|
12829
|
-
const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertical" }) => {
|
|
12849
|
+
const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertical", projection = DEFAULT_PROJECTION }) => {
|
|
12830
12850
|
if (height <= 0 && width <= 0) throw new Error("height or width is required");
|
|
12851
|
+
const proj4String = getProj4String(projection);
|
|
12831
12852
|
let geojson = typedWorld;
|
|
12832
12853
|
let resolvedRegion = region;
|
|
12833
12854
|
if (countries.length > 0) {
|
|
@@ -12838,8 +12859,34 @@ const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertica
|
|
|
12838
12859
|
if (!resolvedRegion) resolvedRegion = computeGeojsonBox(geojson);
|
|
12839
12860
|
} else if (!resolvedRegion) resolvedRegion = DEFAULT_WORLD_REGION;
|
|
12840
12861
|
const poly = geojsonToMultiPolygons(geojson);
|
|
12841
|
-
const
|
|
12842
|
-
const
|
|
12862
|
+
const SAMPLES = 100;
|
|
12863
|
+
const r = resolvedRegion;
|
|
12864
|
+
let X_MIN = Infinity;
|
|
12865
|
+
let Y_MIN = Infinity;
|
|
12866
|
+
let X_MAX = -Infinity;
|
|
12867
|
+
let Y_MAX = -Infinity;
|
|
12868
|
+
for (let i = 0; i <= SAMPLES; i++) {
|
|
12869
|
+
const frac = i / SAMPLES;
|
|
12870
|
+
const sampleLat = r.lat.min + frac * (r.lat.max - r.lat.min);
|
|
12871
|
+
const sampleLng = r.lng.min + frac * (r.lng.max - r.lng.min);
|
|
12872
|
+
const candidates = [
|
|
12873
|
+
[sampleLng, r.lat.min],
|
|
12874
|
+
[sampleLng, r.lat.max],
|
|
12875
|
+
[r.lng.min, sampleLat],
|
|
12876
|
+
[r.lng.max, sampleLat],
|
|
12877
|
+
[sampleLng, sampleLat]
|
|
12878
|
+
];
|
|
12879
|
+
for (const point of candidates) {
|
|
12880
|
+
const [px, py] = (0, proj4.default)(proj4String, point);
|
|
12881
|
+
if (Number.isFinite(px) && Number.isFinite(py)) {
|
|
12882
|
+
X_MIN = Math.min(X_MIN, px);
|
|
12883
|
+
Y_MIN = Math.min(Y_MIN, py);
|
|
12884
|
+
X_MAX = Math.max(X_MAX, px);
|
|
12885
|
+
Y_MAX = Math.max(Y_MAX, py);
|
|
12886
|
+
}
|
|
12887
|
+
}
|
|
12888
|
+
}
|
|
12889
|
+
if (!Number.isFinite(X_MIN)) throw new Error("No valid projected points found for the given region and projection");
|
|
12843
12890
|
const X_RANGE = X_MAX - X_MIN;
|
|
12844
12891
|
const Y_RANGE = Y_MAX - Y_MIN;
|
|
12845
12892
|
if (width <= 0) width = Math.round(height * X_RANGE / Y_RANGE);
|
|
@@ -12849,7 +12896,9 @@ const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertica
|
|
|
12849
12896
|
for (let y = 0; y * ystep < height; y += 1) for (let x = 0; x < width; x += 1) {
|
|
12850
12897
|
const localx = y % 2 === 0 && grid === "diagonal" ? x + .5 : x;
|
|
12851
12898
|
const localy = y * ystep;
|
|
12852
|
-
|
|
12899
|
+
const wgs84Point = (0, proj4.default)(proj4String, "WGS84", [localx / width * X_RANGE + X_MIN, Y_MAX - localy / height * Y_RANGE]);
|
|
12900
|
+
if (!isFinitePoint(wgs84Point) || !(0, _turf_boolean_point_in_polygon.default)(wgs84Point, poly)) continue;
|
|
12901
|
+
points[[x, y].join(";")] = {
|
|
12853
12902
|
x: localx,
|
|
12854
12903
|
y: localy
|
|
12855
12904
|
};
|
|
@@ -12866,17 +12915,19 @@ const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertica
|
|
|
12866
12915
|
grid,
|
|
12867
12916
|
height,
|
|
12868
12917
|
width,
|
|
12869
|
-
ystep
|
|
12918
|
+
ystep,
|
|
12919
|
+
projection
|
|
12870
12920
|
};
|
|
12871
12921
|
};
|
|
12872
12922
|
const getMapJSON = (props) => JSON.stringify(getMap(props));
|
|
12873
|
-
const getCacheKey = ({ height = 0, width = 0, countries = [], region, grid = "vertical" }) => {
|
|
12923
|
+
const getCacheKey = ({ height = 0, width = 0, countries = [], region, grid = "vertical", projection = DEFAULT_PROJECTION }) => {
|
|
12874
12924
|
return [
|
|
12875
12925
|
JSON.stringify(region),
|
|
12876
12926
|
grid,
|
|
12877
12927
|
height,
|
|
12878
12928
|
width,
|
|
12879
|
-
JSON.stringify(countries)
|
|
12929
|
+
JSON.stringify(countries),
|
|
12930
|
+
JSON.stringify(projection)
|
|
12880
12931
|
].join(" ");
|
|
12881
12932
|
};
|
|
12882
12933
|
var DottedMap = class extends require_without_countries {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as MapSettings, c as
|
|
1
|
+
import { a as MapSettings, c as Projection, l as ProjectionName, s as Point, t as DottedMapSettings, u as Region } from "./types-vOcy-UuQ.cjs";
|
|
2
2
|
import DottedMapWithoutCountries from "./without-countries.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/with-countries.d.ts
|
|
@@ -10,4 +10,4 @@ declare class DottedMap extends DottedMapWithoutCountries {
|
|
|
10
10
|
}: DottedMapSettings);
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
|
-
export { type DottedMapSettings, DottedMapWithoutCountries, type MapSettings, type Point, type Region, DottedMap as default, getMapJSON };
|
|
13
|
+
export { type DottedMapSettings, DottedMapWithoutCountries, type MapSettings, type Point, type Projection, type ProjectionName, type Region, DottedMap as default, getMapJSON };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as MapSettings, c as
|
|
1
|
+
import { a as MapSettings, c as Projection, l as ProjectionName, s as Point, t as DottedMapSettings, u as Region } from "./types-F6gvGCSl.mjs";
|
|
2
2
|
import DottedMapWithoutCountries from "./without-countries.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/with-countries.d.ts
|
|
@@ -10,4 +10,4 @@ declare class DottedMap extends DottedMapWithoutCountries {
|
|
|
10
10
|
}: DottedMapSettings);
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
|
-
export { type DottedMapSettings, DottedMapWithoutCountries, type MapSettings, type Point, type Region, DottedMap as default, getMapJSON };
|
|
13
|
+
export { type DottedMapSettings, DottedMapWithoutCountries, type MapSettings, type Point, type Projection, type ProjectionName, type Region, DottedMap as default, getMapJSON };
|
package/dist/index.mjs
CHANGED
|
@@ -12762,6 +12762,26 @@ var countries_geo_default = {
|
|
|
12762
12762
|
|
|
12763
12763
|
//#endregion
|
|
12764
12764
|
//#region src/with-countries.ts
|
|
12765
|
+
const PROJECTIONS = {
|
|
12766
|
+
mercator: "+proj=merc +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12767
|
+
equirectangular: "+proj=eqc +lon_0={lng} +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12768
|
+
robinson: "+proj=robin +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12769
|
+
equalEarth: "+proj=eqearth +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12770
|
+
mollweide: "+proj=moll +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12771
|
+
miller: "+proj=mill +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12772
|
+
sinusoidal: "+proj=sinu +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12773
|
+
orthographic: "+proj=ortho +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12774
|
+
gallPeters: "+proj=cea +lon_0={lng} +lat_ts=45 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12775
|
+
vanDerGrinten: "+proj=vandg +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m"
|
|
12776
|
+
};
|
|
12777
|
+
const DEFAULT_PROJECTION = { name: "mercator" };
|
|
12778
|
+
const getProj4String = (projection = DEFAULT_PROJECTION) => {
|
|
12779
|
+
const template = PROJECTIONS[projection.name];
|
|
12780
|
+
const lat = projection.center?.lat ?? 0;
|
|
12781
|
+
const lng = projection.center?.lng ?? 0;
|
|
12782
|
+
return template.replace("{lat}", String(lat)).replace("{lng}", String(lng));
|
|
12783
|
+
};
|
|
12784
|
+
const isFinitePoint = (point) => point.every((v) => Number.isFinite(v));
|
|
12765
12785
|
const typedWorld = countries_geo_default;
|
|
12766
12786
|
const geojsonByCountry = typedWorld.features.reduce((countries, feature) => {
|
|
12767
12787
|
countries[feature.id] = feature;
|
|
@@ -12784,8 +12804,8 @@ const DEFAULT_WORLD_REGION = {
|
|
|
12784
12804
|
max: 71
|
|
12785
12805
|
},
|
|
12786
12806
|
lng: {
|
|
12787
|
-
min: -
|
|
12788
|
-
max:
|
|
12807
|
+
min: -168,
|
|
12808
|
+
max: 168
|
|
12789
12809
|
}
|
|
12790
12810
|
};
|
|
12791
12811
|
const computeGeojsonBox = (geojson) => {
|
|
@@ -12822,8 +12842,9 @@ const computeGeojsonBox = (geojson) => {
|
|
|
12822
12842
|
};
|
|
12823
12843
|
} else throw new Error(`Unknown geojson type ${geojson.type}`);
|
|
12824
12844
|
};
|
|
12825
|
-
const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertical" }) => {
|
|
12845
|
+
const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertical", projection = DEFAULT_PROJECTION }) => {
|
|
12826
12846
|
if (height <= 0 && width <= 0) throw new Error("height or width is required");
|
|
12847
|
+
const proj4String = getProj4String(projection);
|
|
12827
12848
|
let geojson = typedWorld;
|
|
12828
12849
|
let resolvedRegion = region;
|
|
12829
12850
|
if (countries.length > 0) {
|
|
@@ -12834,8 +12855,34 @@ const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertica
|
|
|
12834
12855
|
if (!resolvedRegion) resolvedRegion = computeGeojsonBox(geojson);
|
|
12835
12856
|
} else if (!resolvedRegion) resolvedRegion = DEFAULT_WORLD_REGION;
|
|
12836
12857
|
const poly = geojsonToMultiPolygons(geojson);
|
|
12837
|
-
const
|
|
12838
|
-
const
|
|
12858
|
+
const SAMPLES = 100;
|
|
12859
|
+
const r = resolvedRegion;
|
|
12860
|
+
let X_MIN = Infinity;
|
|
12861
|
+
let Y_MIN = Infinity;
|
|
12862
|
+
let X_MAX = -Infinity;
|
|
12863
|
+
let Y_MAX = -Infinity;
|
|
12864
|
+
for (let i = 0; i <= SAMPLES; i++) {
|
|
12865
|
+
const frac = i / SAMPLES;
|
|
12866
|
+
const sampleLat = r.lat.min + frac * (r.lat.max - r.lat.min);
|
|
12867
|
+
const sampleLng = r.lng.min + frac * (r.lng.max - r.lng.min);
|
|
12868
|
+
const candidates = [
|
|
12869
|
+
[sampleLng, r.lat.min],
|
|
12870
|
+
[sampleLng, r.lat.max],
|
|
12871
|
+
[r.lng.min, sampleLat],
|
|
12872
|
+
[r.lng.max, sampleLat],
|
|
12873
|
+
[sampleLng, sampleLat]
|
|
12874
|
+
];
|
|
12875
|
+
for (const point of candidates) {
|
|
12876
|
+
const [px, py] = proj4(proj4String, point);
|
|
12877
|
+
if (Number.isFinite(px) && Number.isFinite(py)) {
|
|
12878
|
+
X_MIN = Math.min(X_MIN, px);
|
|
12879
|
+
Y_MIN = Math.min(Y_MIN, py);
|
|
12880
|
+
X_MAX = Math.max(X_MAX, px);
|
|
12881
|
+
Y_MAX = Math.max(Y_MAX, py);
|
|
12882
|
+
}
|
|
12883
|
+
}
|
|
12884
|
+
}
|
|
12885
|
+
if (!Number.isFinite(X_MIN)) throw new Error("No valid projected points found for the given region and projection");
|
|
12839
12886
|
const X_RANGE = X_MAX - X_MIN;
|
|
12840
12887
|
const Y_RANGE = Y_MAX - Y_MIN;
|
|
12841
12888
|
if (width <= 0) width = Math.round(height * X_RANGE / Y_RANGE);
|
|
@@ -12845,7 +12892,9 @@ const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertica
|
|
|
12845
12892
|
for (let y = 0; y * ystep < height; y += 1) for (let x = 0; x < width; x += 1) {
|
|
12846
12893
|
const localx = y % 2 === 0 && grid === "diagonal" ? x + .5 : x;
|
|
12847
12894
|
const localy = y * ystep;
|
|
12848
|
-
|
|
12895
|
+
const wgs84Point = proj4(proj4String, "WGS84", [localx / width * X_RANGE + X_MIN, Y_MAX - localy / height * Y_RANGE]);
|
|
12896
|
+
if (!isFinitePoint(wgs84Point) || !booleanPointInPolygon(wgs84Point, poly)) continue;
|
|
12897
|
+
points[[x, y].join(";")] = {
|
|
12849
12898
|
x: localx,
|
|
12850
12899
|
y: localy
|
|
12851
12900
|
};
|
|
@@ -12862,17 +12911,19 @@ const getMap = ({ height = 0, width = 0, countries = [], region, grid = "vertica
|
|
|
12862
12911
|
grid,
|
|
12863
12912
|
height,
|
|
12864
12913
|
width,
|
|
12865
|
-
ystep
|
|
12914
|
+
ystep,
|
|
12915
|
+
projection
|
|
12866
12916
|
};
|
|
12867
12917
|
};
|
|
12868
12918
|
const getMapJSON = (props) => JSON.stringify(getMap(props));
|
|
12869
|
-
const getCacheKey = ({ height = 0, width = 0, countries = [], region, grid = "vertical" }) => {
|
|
12919
|
+
const getCacheKey = ({ height = 0, width = 0, countries = [], region, grid = "vertical", projection = DEFAULT_PROJECTION }) => {
|
|
12870
12920
|
return [
|
|
12871
12921
|
JSON.stringify(region),
|
|
12872
12922
|
grid,
|
|
12873
12923
|
height,
|
|
12874
12924
|
width,
|
|
12875
|
-
JSON.stringify(countries)
|
|
12925
|
+
JSON.stringify(countries),
|
|
12926
|
+
JSON.stringify(projection)
|
|
12876
12927
|
].join(" ");
|
|
12877
12928
|
};
|
|
12878
12929
|
var DottedMap = class extends DottedMapWithoutCountries {
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
|
+
type ProjectionName = 'mercator' | 'equirectangular' | 'robinson' | 'equalEarth' | 'mollweide' | 'miller' | 'sinusoidal' | 'orthographic' | 'gallPeters' | 'vanDerGrinten';
|
|
3
|
+
interface Projection {
|
|
4
|
+
name: ProjectionName;
|
|
5
|
+
center?: {
|
|
6
|
+
lat: number;
|
|
7
|
+
lng: number;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
2
10
|
interface Region {
|
|
3
11
|
lat: {
|
|
4
12
|
min: number;
|
|
@@ -15,6 +23,7 @@ interface MapSettings {
|
|
|
15
23
|
countries?: string[];
|
|
16
24
|
region?: Region;
|
|
17
25
|
grid?: 'vertical' | 'diagonal';
|
|
26
|
+
projection?: Projection;
|
|
18
27
|
}
|
|
19
28
|
interface DottedMapSettings extends MapSettings {
|
|
20
29
|
avoidOuterPins?: boolean;
|
|
@@ -60,6 +69,7 @@ interface MapData {
|
|
|
60
69
|
height: number;
|
|
61
70
|
width: number;
|
|
62
71
|
ystep: number;
|
|
72
|
+
projection?: Projection;
|
|
63
73
|
}
|
|
64
74
|
interface ImageInfo {
|
|
65
75
|
region: Region;
|
|
@@ -67,4 +77,4 @@ interface ImageInfo {
|
|
|
67
77
|
height: number;
|
|
68
78
|
}
|
|
69
79
|
//#endregion
|
|
70
|
-
export { MapSettings as a,
|
|
80
|
+
export { MapSettings as a, Projection as c, SvgSettings as d, MapData as i, ProjectionName as l, DottedMapWithoutCountriesSettings as n, PinInput as o, ImageInfo as r, Point as s, DottedMapSettings as t, Region as u };
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
|
+
type ProjectionName = 'mercator' | 'equirectangular' | 'robinson' | 'equalEarth' | 'mollweide' | 'miller' | 'sinusoidal' | 'orthographic' | 'gallPeters' | 'vanDerGrinten';
|
|
3
|
+
interface Projection {
|
|
4
|
+
name: ProjectionName;
|
|
5
|
+
center?: {
|
|
6
|
+
lat: number;
|
|
7
|
+
lng: number;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
2
10
|
interface Region {
|
|
3
11
|
lat: {
|
|
4
12
|
min: number;
|
|
@@ -15,6 +23,7 @@ interface MapSettings {
|
|
|
15
23
|
countries?: string[];
|
|
16
24
|
region?: Region;
|
|
17
25
|
grid?: 'vertical' | 'diagonal';
|
|
26
|
+
projection?: Projection;
|
|
18
27
|
}
|
|
19
28
|
interface DottedMapSettings extends MapSettings {
|
|
20
29
|
avoidOuterPins?: boolean;
|
|
@@ -60,6 +69,7 @@ interface MapData {
|
|
|
60
69
|
height: number;
|
|
61
70
|
width: number;
|
|
62
71
|
ystep: number;
|
|
72
|
+
projection?: Projection;
|
|
63
73
|
}
|
|
64
74
|
interface ImageInfo {
|
|
65
75
|
region: Region;
|
|
@@ -67,4 +77,4 @@ interface ImageInfo {
|
|
|
67
77
|
height: number;
|
|
68
78
|
}
|
|
69
79
|
//#endregion
|
|
70
|
-
export { MapSettings as a,
|
|
80
|
+
export { MapSettings as a, Projection as c, SvgSettings as d, MapData as i, ProjectionName as l, DottedMapWithoutCountriesSettings as n, PinInput as o, ImageInfo as r, Point as s, DottedMapSettings as t, Region as u };
|
|
@@ -3,6 +3,25 @@ let proj4 = require("proj4");
|
|
|
3
3
|
proj4 = require_chunk.__toESM(proj4);
|
|
4
4
|
|
|
5
5
|
//#region src/without-countries.ts
|
|
6
|
+
const PROJECTIONS = {
|
|
7
|
+
mercator: "+proj=merc +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
8
|
+
equirectangular: "+proj=eqc +lon_0={lng} +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
9
|
+
robinson: "+proj=robin +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
10
|
+
equalEarth: "+proj=eqearth +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
11
|
+
mollweide: "+proj=moll +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12
|
+
miller: "+proj=mill +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
13
|
+
sinusoidal: "+proj=sinu +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
14
|
+
orthographic: "+proj=ortho +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
15
|
+
gallPeters: "+proj=cea +lon_0={lng} +lat_ts=45 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
16
|
+
vanDerGrinten: "+proj=vandg +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m"
|
|
17
|
+
};
|
|
18
|
+
const DEFAULT_PROJECTION = { name: "mercator" };
|
|
19
|
+
const getProj4String = (projection = DEFAULT_PROJECTION) => {
|
|
20
|
+
const template = PROJECTIONS[projection.name];
|
|
21
|
+
const lat = projection.center?.lat ?? 0;
|
|
22
|
+
const lng = projection.center?.lng ?? 0;
|
|
23
|
+
return template.replace("{lat}", String(lat)).replace("{lng}", String(lng));
|
|
24
|
+
};
|
|
6
25
|
var DottedMapWithoutCountries = class {
|
|
7
26
|
constructor({ map, avoidOuterPins = false }) {
|
|
8
27
|
this.points = map.points;
|
|
@@ -16,6 +35,7 @@ var DottedMapWithoutCountries = class {
|
|
|
16
35
|
this.height = map.height;
|
|
17
36
|
this.ystep = map.ystep;
|
|
18
37
|
this.avoidOuterPins = avoidOuterPins;
|
|
38
|
+
this.proj4String = getProj4String(map.projection ?? DEFAULT_PROJECTION);
|
|
19
39
|
this.image = {
|
|
20
40
|
region: map.region,
|
|
21
41
|
width: map.width,
|
|
@@ -37,16 +57,20 @@ var DottedMapWithoutCountries = class {
|
|
|
37
57
|
return point;
|
|
38
58
|
}
|
|
39
59
|
getPin({ lat, lng }) {
|
|
40
|
-
const
|
|
60
|
+
const projected = (0, proj4.default)(this.proj4String, [lng, lat]);
|
|
61
|
+
if (!projected.every((v) => Number.isFinite(v))) return;
|
|
62
|
+
const [projX, projY] = projected;
|
|
41
63
|
if (this.avoidOuterPins) return;
|
|
42
|
-
let rawX = this.width * (
|
|
43
|
-
const rawY = this.height * (this.Y_MAX -
|
|
64
|
+
let rawX = this.width * (projX - this.X_MIN) / this.X_RANGE;
|
|
65
|
+
const rawY = this.height * (this.Y_MAX - projY) / this.Y_RANGE;
|
|
44
66
|
const y = Math.round(rawY / this.ystep);
|
|
45
67
|
if (y % 2 === 0 && this.grid === "diagonal") rawX -= .5;
|
|
46
68
|
let localx = Math.round(rawX);
|
|
47
69
|
const localy = Math.round(y) * this.ystep;
|
|
48
70
|
if (y % 2 === 0 && this.grid === "diagonal") localx += .5;
|
|
49
|
-
const
|
|
71
|
+
const inverse = (0, proj4.default)(this.proj4String, "WGS84", [localx * this.X_RANGE / this.width + this.X_MIN, this.Y_MAX - localy * this.Y_RANGE / this.height]);
|
|
72
|
+
if (!inverse.every((v) => Number.isFinite(v))) return;
|
|
73
|
+
const [localLng, localLat] = inverse;
|
|
50
74
|
return {
|
|
51
75
|
x: localx,
|
|
52
76
|
y: localy,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as
|
|
1
|
+
import { c as Projection, d as SvgSettings, i as MapData, l as ProjectionName, n as DottedMapWithoutCountriesSettings, o as PinInput, r as ImageInfo, s as Point, u as Region } from "./types-vOcy-UuQ.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/without-countries.d.ts
|
|
4
4
|
declare class DottedMapWithoutCountries {
|
|
@@ -13,6 +13,7 @@ declare class DottedMapWithoutCountries {
|
|
|
13
13
|
private ystep;
|
|
14
14
|
private avoidOuterPins;
|
|
15
15
|
private pins;
|
|
16
|
+
private proj4String;
|
|
16
17
|
image: ImageInfo;
|
|
17
18
|
constructor({
|
|
18
19
|
map,
|
|
@@ -40,4 +41,4 @@ declare class DottedMapWithoutCountries {
|
|
|
40
41
|
}?: SvgSettings): string;
|
|
41
42
|
}
|
|
42
43
|
//#endregion
|
|
43
|
-
export { type DottedMapWithoutCountriesSettings, type ImageInfo, type MapData, type PinInput, type Point, type Region, type SvgSettings, DottedMapWithoutCountries as default };
|
|
44
|
+
export { type DottedMapWithoutCountriesSettings, type ImageInfo, type MapData, type PinInput, type Point, type Projection, type ProjectionName, type Region, type SvgSettings, DottedMapWithoutCountries as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as
|
|
1
|
+
import { c as Projection, d as SvgSettings, i as MapData, l as ProjectionName, n as DottedMapWithoutCountriesSettings, o as PinInput, r as ImageInfo, s as Point, u as Region } from "./types-F6gvGCSl.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/without-countries.d.ts
|
|
4
4
|
declare class DottedMapWithoutCountries {
|
|
@@ -13,6 +13,7 @@ declare class DottedMapWithoutCountries {
|
|
|
13
13
|
private ystep;
|
|
14
14
|
private avoidOuterPins;
|
|
15
15
|
private pins;
|
|
16
|
+
private proj4String;
|
|
16
17
|
image: ImageInfo;
|
|
17
18
|
constructor({
|
|
18
19
|
map,
|
|
@@ -40,4 +41,4 @@ declare class DottedMapWithoutCountries {
|
|
|
40
41
|
}?: SvgSettings): string;
|
|
41
42
|
}
|
|
42
43
|
//#endregion
|
|
43
|
-
export { type DottedMapWithoutCountriesSettings, type ImageInfo, type MapData, type PinInput, type Point, type Region, type SvgSettings, DottedMapWithoutCountries as default };
|
|
44
|
+
export { type DottedMapWithoutCountriesSettings, type ImageInfo, type MapData, type PinInput, type Point, type Projection, type ProjectionName, type Region, type SvgSettings, DottedMapWithoutCountries as default };
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import proj4 from "proj4";
|
|
2
2
|
|
|
3
3
|
//#region src/without-countries.ts
|
|
4
|
+
const PROJECTIONS = {
|
|
5
|
+
mercator: "+proj=merc +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
6
|
+
equirectangular: "+proj=eqc +lon_0={lng} +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
7
|
+
robinson: "+proj=robin +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
8
|
+
equalEarth: "+proj=eqearth +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
9
|
+
mollweide: "+proj=moll +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
10
|
+
miller: "+proj=mill +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
11
|
+
sinusoidal: "+proj=sinu +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
12
|
+
orthographic: "+proj=ortho +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
13
|
+
gallPeters: "+proj=cea +lon_0={lng} +lat_ts=45 +x_0=0 +y_0=0 +datum=WGS84 +units=m",
|
|
14
|
+
vanDerGrinten: "+proj=vandg +lon_0={lng} +x_0=0 +y_0=0 +datum=WGS84 +units=m"
|
|
15
|
+
};
|
|
16
|
+
const DEFAULT_PROJECTION = { name: "mercator" };
|
|
17
|
+
const getProj4String = (projection = DEFAULT_PROJECTION) => {
|
|
18
|
+
const template = PROJECTIONS[projection.name];
|
|
19
|
+
const lat = projection.center?.lat ?? 0;
|
|
20
|
+
const lng = projection.center?.lng ?? 0;
|
|
21
|
+
return template.replace("{lat}", String(lat)).replace("{lng}", String(lng));
|
|
22
|
+
};
|
|
4
23
|
var DottedMapWithoutCountries = class {
|
|
5
24
|
constructor({ map, avoidOuterPins = false }) {
|
|
6
25
|
this.points = map.points;
|
|
@@ -14,6 +33,7 @@ var DottedMapWithoutCountries = class {
|
|
|
14
33
|
this.height = map.height;
|
|
15
34
|
this.ystep = map.ystep;
|
|
16
35
|
this.avoidOuterPins = avoidOuterPins;
|
|
36
|
+
this.proj4String = getProj4String(map.projection ?? DEFAULT_PROJECTION);
|
|
17
37
|
this.image = {
|
|
18
38
|
region: map.region,
|
|
19
39
|
width: map.width,
|
|
@@ -35,16 +55,20 @@ var DottedMapWithoutCountries = class {
|
|
|
35
55
|
return point;
|
|
36
56
|
}
|
|
37
57
|
getPin({ lat, lng }) {
|
|
38
|
-
const
|
|
58
|
+
const projected = proj4(this.proj4String, [lng, lat]);
|
|
59
|
+
if (!projected.every((v) => Number.isFinite(v))) return;
|
|
60
|
+
const [projX, projY] = projected;
|
|
39
61
|
if (this.avoidOuterPins) return;
|
|
40
|
-
let rawX = this.width * (
|
|
41
|
-
const rawY = this.height * (this.Y_MAX -
|
|
62
|
+
let rawX = this.width * (projX - this.X_MIN) / this.X_RANGE;
|
|
63
|
+
const rawY = this.height * (this.Y_MAX - projY) / this.Y_RANGE;
|
|
42
64
|
const y = Math.round(rawY / this.ystep);
|
|
43
65
|
if (y % 2 === 0 && this.grid === "diagonal") rawX -= .5;
|
|
44
66
|
let localx = Math.round(rawX);
|
|
45
67
|
const localy = Math.round(y) * this.ystep;
|
|
46
68
|
if (y % 2 === 0 && this.grid === "diagonal") localx += .5;
|
|
47
|
-
const
|
|
69
|
+
const inverse = proj4(this.proj4String, "WGS84", [localx * this.X_RANGE / this.width + this.X_MIN, this.Y_MAX - localy * this.Y_RANGE / this.height]);
|
|
70
|
+
if (!inverse.every((v) => Number.isFinite(v))) return;
|
|
71
|
+
const [localLng, localLat] = inverse;
|
|
48
72
|
return {
|
|
49
73
|
x: localx,
|
|
50
74
|
y: localy,
|