dotted-map 2.2.2 → 3.0.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 +6 -5
- package/dist/chunk-C0xms8kb.cjs +34 -0
- package/dist/index.cjs +12897 -0
- package/dist/index.d.cts +13 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +12891 -0
- package/dist/types-ByIhMtjO.d.cts +70 -0
- package/dist/types-UL1f7mia.d.mts +70 -0
- package/dist/without-countries.cjs +85 -0
- package/dist/without-countries.d.cts +43 -0
- package/dist/without-countries.d.mts +43 -0
- package/dist/without-countries.mjs +83 -0
- package/package.json +47 -11
- package/index.d.ts +0 -62
- package/index.js +0 -1
- package/src/countries.geo.json +0 -182
- package/src/with-countries.js +0 -180
- package/src/without-countries.js +0 -108
- package/webpack.config.js +0 -37
- package/without-countries.d.ts +0 -70
- package/without-countries.js +0 -1
package/src/with-countries.js
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import proj4 from 'proj4';
|
|
2
|
-
import inside from '@turf/boolean-point-in-polygon';
|
|
3
|
-
import geojsonWorld from './countries.geo.json';
|
|
4
|
-
import DottedMapWithoutCountries from './without-countries';
|
|
5
|
-
|
|
6
|
-
const geojsonByCountry = geojsonWorld.features.reduce((countries, feature) => {
|
|
7
|
-
countries[feature.id] = feature;
|
|
8
|
-
return countries;
|
|
9
|
-
}, {});
|
|
10
|
-
|
|
11
|
-
const geojsonToMultiPolygons = (geojson) => {
|
|
12
|
-
const coordinates = geojson.features.reduce(
|
|
13
|
-
(poly, feature) =>
|
|
14
|
-
poly.concat(
|
|
15
|
-
feature.geometry.type === 'Polygon'
|
|
16
|
-
? [feature.geometry.coordinates]
|
|
17
|
-
: feature.geometry.coordinates,
|
|
18
|
-
),
|
|
19
|
-
[],
|
|
20
|
-
);
|
|
21
|
-
return { type: 'Feature', geometry: { type: 'MultiPolygon', coordinates } };
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const CACHE = {};
|
|
25
|
-
|
|
26
|
-
const DEFAULT_WORLD_REGION = {
|
|
27
|
-
lat: { min: -56, max: 71 },
|
|
28
|
-
lng: { min: -179, max: 179 },
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const computeGeojsonBox = (geojson) => {
|
|
32
|
-
const { type, features, geometry, coordinates } = geojson;
|
|
33
|
-
if (type === 'FeatureCollection') {
|
|
34
|
-
const boxes = features.map(computeGeojsonBox);
|
|
35
|
-
return {
|
|
36
|
-
lat: {
|
|
37
|
-
min: Math.min(...boxes.map((box) => box.lat.min)),
|
|
38
|
-
max: Math.max(...boxes.map((box) => box.lat.max)),
|
|
39
|
-
},
|
|
40
|
-
lng: {
|
|
41
|
-
min: Math.min(...boxes.map((box) => box.lng.min)),
|
|
42
|
-
max: Math.max(...boxes.map((box) => box.lng.max)),
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
} else if (type == 'Feature') {
|
|
46
|
-
return computeGeojsonBox(geometry);
|
|
47
|
-
} else if (type === 'MultiPolygon') {
|
|
48
|
-
return computeGeojsonBox({
|
|
49
|
-
type: 'Polygon',
|
|
50
|
-
coordinates: coordinates.flat(),
|
|
51
|
-
});
|
|
52
|
-
} else if (type == 'Polygon') {
|
|
53
|
-
const coords = coordinates.flat();
|
|
54
|
-
const latitudes = coords.map(([_lng, lat]) => lat);
|
|
55
|
-
const longitudes = coords.map(([lng, _lat]) => lng);
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
lat: {
|
|
59
|
-
min: Math.min(...latitudes),
|
|
60
|
-
max: Math.max(...latitudes),
|
|
61
|
-
},
|
|
62
|
-
lng: {
|
|
63
|
-
min: Math.min(...longitudes),
|
|
64
|
-
max: Math.max(...longitudes),
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
} else {
|
|
68
|
-
throw new Error(`Unknown geojson type ${type}`);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const getMap = ({
|
|
73
|
-
height = 0,
|
|
74
|
-
width = 0,
|
|
75
|
-
countries = [],
|
|
76
|
-
region,
|
|
77
|
-
grid = 'vertical',
|
|
78
|
-
}) => {
|
|
79
|
-
if (height <= 0 && width <= 0) {
|
|
80
|
-
throw new Error('height or width is required');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let geojson = geojsonWorld;
|
|
84
|
-
if (countries.length > 0) {
|
|
85
|
-
geojson = {
|
|
86
|
-
type: 'FeatureCollection',
|
|
87
|
-
features: countries.map((country) => geojsonByCountry[country]),
|
|
88
|
-
};
|
|
89
|
-
if (!region) {
|
|
90
|
-
region = computeGeojsonBox(geojson);
|
|
91
|
-
}
|
|
92
|
-
} else if (!region) {
|
|
93
|
-
region = DEFAULT_WORLD_REGION;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const poly = geojsonToMultiPolygons(geojson);
|
|
97
|
-
|
|
98
|
-
const [X_MIN, Y_MIN] = proj4(proj4.defs('GOOGLE'), [
|
|
99
|
-
region.lng.min,
|
|
100
|
-
region.lat.min,
|
|
101
|
-
]);
|
|
102
|
-
const [X_MAX, Y_MAX] = proj4(proj4.defs('GOOGLE'), [
|
|
103
|
-
region.lng.max,
|
|
104
|
-
region.lat.max,
|
|
105
|
-
]);
|
|
106
|
-
const X_RANGE = X_MAX - X_MIN;
|
|
107
|
-
const Y_RANGE = Y_MAX - Y_MIN;
|
|
108
|
-
|
|
109
|
-
if (width <= 0) {
|
|
110
|
-
width = Math.round((height * X_RANGE) / Y_RANGE);
|
|
111
|
-
} else if (height <= 0) {
|
|
112
|
-
height = Math.round((width * Y_RANGE) / X_RANGE);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const points = {};
|
|
116
|
-
const ystep = grid === 'diagonal' ? Math.sqrt(3) / 2 : 1;
|
|
117
|
-
|
|
118
|
-
for (let y = 0; y * ystep < height; y += 1) {
|
|
119
|
-
for (let x = 0; x < width; x += 1) {
|
|
120
|
-
const localx = y % 2 === 0 && grid === 'diagonal' ? x + 0.5 : x;
|
|
121
|
-
const localy = y * ystep;
|
|
122
|
-
|
|
123
|
-
const pointGoogle = [
|
|
124
|
-
(localx / width) * X_RANGE + X_MIN,
|
|
125
|
-
Y_MAX - (localy / height) * Y_RANGE,
|
|
126
|
-
];
|
|
127
|
-
const wgs84Point = proj4(
|
|
128
|
-
proj4.defs('GOOGLE'),
|
|
129
|
-
proj4.defs('WGS84'),
|
|
130
|
-
pointGoogle,
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
if (inside(wgs84Point, poly)) {
|
|
134
|
-
points[[x, y].join(';')] = { x: localx, y: localy };
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
points,
|
|
141
|
-
X_MIN,
|
|
142
|
-
Y_MIN,
|
|
143
|
-
X_MAX,
|
|
144
|
-
Y_MAX,
|
|
145
|
-
X_RANGE,
|
|
146
|
-
Y_RANGE,
|
|
147
|
-
region,
|
|
148
|
-
grid,
|
|
149
|
-
height,
|
|
150
|
-
width,
|
|
151
|
-
ystep,
|
|
152
|
-
};
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
export const getMapJSON = (props) => JSON.stringify(getMap(props));
|
|
156
|
-
|
|
157
|
-
const getCacheKey = ({
|
|
158
|
-
height = 0,
|
|
159
|
-
width = 0,
|
|
160
|
-
countries = [],
|
|
161
|
-
region,
|
|
162
|
-
grid = 'vertical',
|
|
163
|
-
}) => {
|
|
164
|
-
return [
|
|
165
|
-
JSON.stringify(region),
|
|
166
|
-
grid,
|
|
167
|
-
height,
|
|
168
|
-
width,
|
|
169
|
-
JSON.stringify(countries),
|
|
170
|
-
].join(' ');
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
function DottedMap({ avoidOuterPins = false, ...args }) {
|
|
174
|
-
const cacheKey = getCacheKey(args);
|
|
175
|
-
const map = CACHE[cacheKey] || getMap(args);
|
|
176
|
-
|
|
177
|
-
return new DottedMapWithoutCountries({ avoidOuterPins, map });
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export default DottedMap;
|
package/src/without-countries.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import proj4 from 'proj4';
|
|
2
|
-
import inside from '@turf/boolean-point-in-polygon';
|
|
3
|
-
|
|
4
|
-
function DottedMapWithoutCountries({ map, avoidOuterPins = false }) {
|
|
5
|
-
const {
|
|
6
|
-
points,
|
|
7
|
-
X_MIN,
|
|
8
|
-
Y_MAX,
|
|
9
|
-
X_RANGE,
|
|
10
|
-
Y_RANGE,
|
|
11
|
-
region,
|
|
12
|
-
grid,
|
|
13
|
-
width,
|
|
14
|
-
height,
|
|
15
|
-
ystep,
|
|
16
|
-
} = map;
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
addPin({ lat, lng, data, svgOptions }) {
|
|
20
|
-
const pin = this.getPin({ lat, lng });
|
|
21
|
-
const point = { ...pin, data, svgOptions };
|
|
22
|
-
|
|
23
|
-
points[[point.x, point.y].join(';')] = point;
|
|
24
|
-
|
|
25
|
-
return point;
|
|
26
|
-
},
|
|
27
|
-
getPin({ lat, lng }) {
|
|
28
|
-
const [googleX, googleY] = proj4(proj4.defs('GOOGLE'), [lng, lat]);
|
|
29
|
-
if (avoidOuterPins) {
|
|
30
|
-
const wgs84Point = proj4(proj4.defs('GOOGLE'), proj4.defs('WGS84'), [
|
|
31
|
-
googleX,
|
|
32
|
-
googleY,
|
|
33
|
-
]);
|
|
34
|
-
if (!inside(wgs84Point, poly)) return;
|
|
35
|
-
}
|
|
36
|
-
let [rawX, rawY] = [
|
|
37
|
-
(width * (googleX - X_MIN)) / X_RANGE,
|
|
38
|
-
(height * (Y_MAX - googleY)) / Y_RANGE,
|
|
39
|
-
];
|
|
40
|
-
const y = Math.round(rawY / ystep);
|
|
41
|
-
if (y % 2 === 0 && grid === 'diagonal') {
|
|
42
|
-
rawX -= 0.5;
|
|
43
|
-
}
|
|
44
|
-
const x = Math.round(rawX);
|
|
45
|
-
let [localx, localy] = [x, Math.round(y) * ystep];
|
|
46
|
-
if (y % 2 === 0 && grid === 'diagonal') {
|
|
47
|
-
localx += 0.5;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const [localLng, localLat] = proj4(
|
|
51
|
-
proj4.defs('GOOGLE'),
|
|
52
|
-
proj4.defs('WGS84'),
|
|
53
|
-
[
|
|
54
|
-
(localx * X_RANGE) / width + X_MIN,
|
|
55
|
-
Y_MAX - (localy * Y_RANGE) / height,
|
|
56
|
-
],
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
const pin = { x: localx, y: localy, lat: localLat, lng: localLng };
|
|
60
|
-
|
|
61
|
-
return pin;
|
|
62
|
-
},
|
|
63
|
-
getPoints() {
|
|
64
|
-
return Object.values(points);
|
|
65
|
-
},
|
|
66
|
-
getSVG({
|
|
67
|
-
shape = 'circle',
|
|
68
|
-
color = 'current',
|
|
69
|
-
backgroundColor = 'transparent',
|
|
70
|
-
radius = 0.5,
|
|
71
|
-
}) {
|
|
72
|
-
const getPoint = ({ x, y, svgOptions = {} }) => {
|
|
73
|
-
const pointRadius = svgOptions.radius || radius;
|
|
74
|
-
if (shape === 'circle') {
|
|
75
|
-
return `<circle cx="${x}" cy="${y}" r="${pointRadius}" fill="${
|
|
76
|
-
svgOptions.color || color
|
|
77
|
-
}" />`;
|
|
78
|
-
} else if (shape === 'hexagon') {
|
|
79
|
-
const sqrt3radius = Math.sqrt(3) * pointRadius;
|
|
80
|
-
|
|
81
|
-
const polyPoints = [
|
|
82
|
-
[x + sqrt3radius, y - pointRadius],
|
|
83
|
-
[x + sqrt3radius, y + pointRadius],
|
|
84
|
-
[x, y + 2 * pointRadius],
|
|
85
|
-
[x - sqrt3radius, y + pointRadius],
|
|
86
|
-
[x - sqrt3radius, y - pointRadius],
|
|
87
|
-
[x, y - 2 * pointRadius],
|
|
88
|
-
];
|
|
89
|
-
|
|
90
|
-
return `<polyline points="${polyPoints
|
|
91
|
-
.map((point) => point.join(','))
|
|
92
|
-
.join(' ')}" fill="${svgOptions.color || color}" />`;
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
return `<svg viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg" style="background-color: ${backgroundColor}">
|
|
97
|
-
${Object.values(points).map(getPoint).join('\n')}
|
|
98
|
-
</svg>`;
|
|
99
|
-
},
|
|
100
|
-
image: {
|
|
101
|
-
region,
|
|
102
|
-
width,
|
|
103
|
-
height,
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default DottedMapWithoutCountries;
|
package/webpack.config.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
|
|
4
|
-
class CleanOutput {
|
|
5
|
-
apply(compiler) {
|
|
6
|
-
compiler.hooks.thisCompilation.tap('CleanOutput', () => {
|
|
7
|
-
if (fs.existsSync('./index.js')) {
|
|
8
|
-
fs.rmSync('./index.js');
|
|
9
|
-
}
|
|
10
|
-
if (fs.existsSync('./without-countries.js')) {
|
|
11
|
-
fs.rmSync('./without-countries.js');
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = {
|
|
18
|
-
entry: {
|
|
19
|
-
index: './src/with-countries.js',
|
|
20
|
-
'without-countries': './src/without-countries.js',
|
|
21
|
-
},
|
|
22
|
-
mode: 'production',
|
|
23
|
-
output: {
|
|
24
|
-
path: path.resolve(__dirname),
|
|
25
|
-
filename: '[name].js',
|
|
26
|
-
library: {
|
|
27
|
-
name: 'dotted-map',
|
|
28
|
-
type: 'umd',
|
|
29
|
-
},
|
|
30
|
-
globalObject: 'this',
|
|
31
|
-
},
|
|
32
|
-
externals: {
|
|
33
|
-
'@turf/boolean-point-in-polygon': '@turf/boolean-point-in-polygon',
|
|
34
|
-
proj4: 'proj4',
|
|
35
|
-
},
|
|
36
|
-
plugins: [new CleanOutput()],
|
|
37
|
-
};
|
package/without-countries.d.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
namespace DottedMapWithoutCountriesLib {
|
|
2
|
-
interface Region {
|
|
3
|
-
lat: { min: number; max: number };
|
|
4
|
-
lng: { min: number; max: number };
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
interface Map {
|
|
8
|
-
points: Point[];
|
|
9
|
-
X_MIN: number;
|
|
10
|
-
Y_MAX: number;
|
|
11
|
-
X_RANGE: number;
|
|
12
|
-
Y_RANGE: number;
|
|
13
|
-
region: Region;
|
|
14
|
-
grid: 'vertical' | 'diagonal';
|
|
15
|
-
width: number;
|
|
16
|
-
height: number;
|
|
17
|
-
ystep: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface Settings extends MapSettings {
|
|
21
|
-
map: Map;
|
|
22
|
-
avoidOuterPins?: false | true;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface SvgOptions {
|
|
26
|
-
color?: string;
|
|
27
|
-
radius?: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface Pin {
|
|
31
|
-
lat: number;
|
|
32
|
-
lng: number;
|
|
33
|
-
data?: any;
|
|
34
|
-
svgOptions?: SvgOptions;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface SvgSettings {
|
|
38
|
-
shape?: 'circle' | 'hexagon';
|
|
39
|
-
color?: string;
|
|
40
|
-
backgroundColor?: string;
|
|
41
|
-
radius?: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
type Point = {
|
|
45
|
-
x: number;
|
|
46
|
-
y: number;
|
|
47
|
-
lat: number;
|
|
48
|
-
lng: number;
|
|
49
|
-
data?: any;
|
|
50
|
-
svgOptions?: SvgOptions;
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export default class DottedMapWithoutCountries {
|
|
55
|
-
constructor(settings: DottedMapWithoutCountriesLib.Settings);
|
|
56
|
-
|
|
57
|
-
addPin(
|
|
58
|
-
pin: DottedMapWithoutCountriesLib.Pin,
|
|
59
|
-
): DottedMapWithoutCountriesLib.Point;
|
|
60
|
-
getPin(
|
|
61
|
-
pin: DottedMapWithoutCountriesLib.Pin,
|
|
62
|
-
): DottedMapWithoutCountriesLib.Point;
|
|
63
|
-
getPoints(): DottedMapWithoutCountriesLib.Point[];
|
|
64
|
-
getSVG(settings: DottedMapWithoutCountriesLib.SvgSettings): string;
|
|
65
|
-
image: {
|
|
66
|
-
region: DottedMap.Region;
|
|
67
|
-
width: number;
|
|
68
|
-
height: number;
|
|
69
|
-
};
|
|
70
|
-
}
|
package/without-countries.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(o,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("proj4"),require("@turf/boolean-point-in-polygon")):"function"==typeof define&&define.amd?define(["proj4","@turf/boolean-point-in-polygon"],e):"object"==typeof exports?exports["dotted-map"]=e(require("proj4"),require("@turf/boolean-point-in-polygon")):o["dotted-map"]=e(o.proj4,o["@turf/boolean-point-in-polygon"])}(this,(function(o,e){return(()=>{"use strict";var t={620:o=>{o.exports=e},25:e=>{e.exports=o}},n={};function r(o){var e=n[o];if(void 0!==e)return e.exports;var i=n[o]={exports:{}};return t[o](i,i.exports,r),i.exports}r.n=o=>{var e=o&&o.__esModule?()=>o.default:()=>o;return r.d(e,{a:e}),e},r.d=(o,e)=>{for(var t in e)r.o(e,t)&&!r.o(o,t)&&Object.defineProperty(o,t,{enumerable:!0,get:e[t]})},r.o=(o,e)=>Object.prototype.hasOwnProperty.call(o,e),r.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})};var i={};return(()=>{r.r(i),r.d(i,{default:()=>a});var o=r(25),e=r.n(o),t=r(620),n=r.n(t);const a=function({map:o,avoidOuterPins:t=!1}){const{points:r,X_MIN:i,Y_MAX:a,X_RANGE:s,Y_RANGE:l,region:p,grid:u,width:d,height:c,ystep:f}=o;return{addPin({lat:o,lng:e,data:t,svgOptions:n}){const i={...this.getPin({lat:o,lng:e}),data:t,svgOptions:n};return r[[i.x,i.y].join(";")]=i,i},getPin({lat:o,lng:r}){const[p,g]=e()(e().defs("GOOGLE"),[r,o]);if(t){const o=e()(e().defs("GOOGLE"),e().defs("WGS84"),[p,g]);if(!n()(o,poly))return}let[y,v]=[d*(p-i)/s,c*(a-g)/l];const b=Math.round(v/f);b%2==0&&"diagonal"===u&&(y-=.5);const j=Math.round(y);let[x,O]=[j,Math.round(b)*f];b%2==0&&"diagonal"===u&&(x+=.5);const[h,m]=e()(e().defs("GOOGLE"),e().defs("WGS84"),[x*s/d+i,a-O*l/c]);return{x,y:O,lat:m,lng:h}},getPoints:()=>Object.values(r),getSVG:({shape:o="circle",color:e="current",backgroundColor:t="transparent",radius:n=.5})=>`<svg viewBox="0 0 ${d} ${c}" xmlns="http://www.w3.org/2000/svg" style="background-color: ${t}">\n ${Object.values(r).map((({x:t,y:r,svgOptions:i={}})=>{const a=i.radius||n;if("circle"===o)return`<circle cx="${t}" cy="${r}" r="${a}" fill="${i.color||e}" />`;if("hexagon"===o){const o=Math.sqrt(3)*a;return`<polyline points="${[[t+o,r-a],[t+o,r+a],[t,r+2*a],[t-o,r+a],[t-o,r-a],[t,r-2*a]].map((o=>o.join(","))).join(" ")}" fill="${i.color||e}" />`}})).join("\n")}\n </svg>`,image:{region:p,width:d,height:c}}}})(),i})()}));
|