1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MaplibreGrid = {})); 5}(this, (function (exports) { 'use strict'; 6 7 function _classCallCheck(instance, Constructor) { 8 if (!(instance instanceof Constructor)) { 9 throw new TypeError("Cannot call a class as a function"); 10 } 11 } 12 13 function _defineProperties(target, props) { 14 for (var i = 0; i < props.length; i++) { 15 var descriptor = props[i]; 16 descriptor.enumerable = descriptor.enumerable || false; 17 descriptor.configurable = true; 18 if ("value" in descriptor) descriptor.writable = true; 19 Object.defineProperty(target, descriptor.key, descriptor); 20 } 21 } 22 23 function _createClass(Constructor, protoProps, staticProps) { 24 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 25 if (staticProps) _defineProperties(Constructor, staticProps); 26 return Constructor; 27 } 28 29 /** 30 * @module helpers 31 */ 32 33 /** 34 * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. 35 * 36 * @memberof helpers 37 * @type {number} 38 */ 39 var earthRadius = 6371008.8; 40 /** 41 * Unit of measurement factors using a spherical (non-ellipsoid) earth radius. 42 * 43 * @memberof helpers 44 * @type {Object} 45 */ 46 47 var factors = { 48 centimeters: earthRadius * 100, 49 centimetres: earthRadius * 100, 50 degrees: earthRadius / 111325, 51 feet: earthRadius * 3.28084, 52 inches: earthRadius * 39.37, 53 kilometers: earthRadius / 1000, 54 kilometres: earthRadius / 1000, 55 meters: earthRadius, 56 metres: earthRadius, 57 miles: earthRadius / 1609.344, 58 millimeters: earthRadius * 1000, 59 millimetres: earthRadius * 1000, 60 nauticalmiles: earthRadius / 1852, 61 radians: 1, 62 yards: earthRadius / 1.0936 63 }; 64 /** 65 * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}. 66 * 67 * @name feature 68 * @param {Geometry} geometry input geometry 69 * @param {Object} [properties={}] an Object of key-value pairs to add as properties 70 * @param {Object} [options={}] Optional Parameters 71 * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature 72 * @param {string|number} [options.id] Identifier associated with the Feature 73 * @returns {Feature} a GeoJSON Feature 74 * @example 75 * var geometry = { 76 * "type": "Point", 77 * "coordinates": [110, 50] 78 * }; 79 * 80 * var feature = turf.feature(geometry); 81 * 82 * //=feature 83 */ 84 85 function feature(geom, properties, options) { 86 if (options === void 0) { 87 options = {}; 88 } 89 90 var feat = { 91 type: "Feature" 92 }; 93 94 if (options.id === 0 || options.id) { 95 feat.id = options.id; 96 } 97 98 if (options.bbox) { 99 feat.bbox = options.bbox; 100 } 101 102 feat.properties = properties || {}; 103 feat.geometry = geom; 104 return feat; 105 } 106 /** 107 * Creates a {@link Point} {@link Feature} from a Position. 108 * 109 * @name point 110 * @param {Array<number>} coordinates longitude, latitude position (each in decimal degrees) 111 * @param {Object} [properties={}] an Object of key-value pairs to add as properties 112 * @param {Object} [options={}] Optional Parameters 113 * @param {Array<number>} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature 114 * @param {string|number} [options.id] Identifier associated with the Feature 115 * @returns {Feature<Point>} a Point feature 116 * @example 117 * var point = turf.point([-75.343, 39.984]); 118 * 119 * //=point 120 */ 121 122 function point(coordinates, properties, options) { 123 if (options === void 0) { 124 options = {}; 125 } 126 127 if (!coordinates) { 128 throw new Error("coordinates is required"); 129 } 130 131 if (!Array.isArray(coordinates)) { 132 throw new Error("coordinates must be an Array"); 133 } 134 135 if (coordinates.length < 2) { 136 throw new Error("coordinates must be at least 2 numbers long"); 137 } 138 139 if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) { 140 throw new Error("coordinates must contain numbers"); 141 } 142 143 var geom = { 144 type: "Point", 145 coordinates: coordinates 146 }; 147 return feature(geom, properties, options); 148 } 149 /** 150 * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. 151 * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet 152 * 153 * @name radiansToLength 154 * @param {number} radians in radians across the sphere 155 * @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres, 156 * meters, kilometres, kilometers. 157 * @returns {number} distance 158 */ 159 160 function radiansToLength(radians, units) { 161 if (units === void 0) { 162 units = "kilometers"; 163 } 164 165 var factor = factors[units]; 166 167 if (!factor) {
168 throw new Error(units + " units is invalid"); 169 } 170 171 return radians * factor; 172 } 173 /** 174 * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians 175 * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet 176 * 177 * @name lengthToRadians 178 * @param {number} distance in real units 179 * @param {string} [units="kilometers"] can be degrees, radians, miles, inches, yards, metres, 180 * meters, kilometres, kilometers. 181 * @returns {number} radians 182 */ 183 184 function lengthToRadians(distance, units) { 185 if (units === void 0) { 186 units = "kilometers"; 187 } 188 189 var factor = factors[units]; 190 191 if (!factor) { 192 throw new Error(units + " units is invalid"); 193 } 194 195 return distance / factor; 196 } 197 /** 198 * Converts an angle in radians to degrees 199 * 200 * @name radiansToDegrees 201 * @param {number} radians angle in radians 202 * @returns {number} degrees between 0 and 360 degrees 203 */ 204 205 function radiansToDegrees(radians) { 206 var degrees = radians % (2 * Math.PI); 207 return degrees * 180 / Math.PI; 208 } 209 /** 210 * Converts an angle in degrees to radians 211 * 212 * @name degreesToRadians 213 * @param {number} degrees angle between 0 and 360 degrees 214 * @returns {number} angle in radians 215 */ 216 217 function degreesToRadians(degrees) { 218 var radians = degrees % 360; 219 return radians * Math.PI / 180; 220 } 221 /** 222 * isNumber 223 * 224 * @param {*} num Number to validate 225 * @returns {boolean} true/false 226 * @example 227 * turf.isNumber(123) 228 * //=true 229 * turf.isNumber('foo') 230 * //=false 231 */ 232 233 function isNumber(num) { 234 return !isNaN(num) && num !== null && !Array.isArray(num); 235 } 236 237 /** 238 * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate. 239 * 240 * @name getCoord 241 * @param {Array<number>|Geometry<Point>|Feature<Point>} coord GeoJSON Point or an Array of numbers 242 * @returns {Array<number>} coordinates 243 * @example 244 * var pt = turf.point([10, 10]); 245 * 246 * var coord = turf.getCoord(pt); 247 * //= [10, 10] 248 */ 249 250 function getCoord(coord) { 251 if (!coord) {
252 throw new Error("coord is required"); 253 } 254 255 if (!Array.isArray(coord)) { 256 if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") { 257 return coord.geometry.coordinates; 258 } 259 260 if (coord.type === "Point") { 261 return coord.coordinates; 262 } 263 } 264 265 if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) { 266 return coord; 267 } 268 269 throw new Error("coord must be GeoJSON Point or an Array of numbers"); 270 } 271 272 //http://www.movable-type.co.uk/scripts/latlong.html 273 274 /** 275 * Calculates the distance between two {@link Point|points} in degrees, radians, miles, or kilometers. 276 * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. 277 * 278 * @name distance 279 * @param {Coord} from origin point 280 * @param {Coord} to destination point 281 * @param {Object} [options={}] Optional parameters 282 * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers 283 * @returns {number} distance between the two points 284 * @example 285 * var from = turf.point([-75.343, 39.984]); 286 * var to = turf.point([-75.534, 39.123]); 287 * var options = {units: 'miles'}; 288 * 289 * var distance = turf.distance(from, to, options); 290 * 291 * //addToMap 292 * var addToMap = [from, to]; 293 * from.properties.distance = distance; 294 * to.properties.distance = distance; 295 */ 296 297 function distance(from, to, options) { 298 if (options === void 0) { 299 options = {}; 300 } 301 302 var coordinates1 = getCoord(from); 303 var coordinates2 = getCoord(to); 304 var dLat = degreesToRadians(coordinates2[1] - coordinates1[1]); 305 var dLon = degreesToRadians(coordinates2[0] - coordinates1[0]); 306 var lat1 = degreesToRadians(coordinates1[1]); 307 var lat2 = degreesToRadians(coordinates2[1]); 308 var a = Math.pow(Math.sin(dLat / 2), 2) + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2); 309 return radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), options.units); 310 } 311 312 // http://en.wikipedia.org/wiki/Haversine_formula 313 /** 314 * Takes a {@link Point} and calculates the location of a destination point given a distance in 315 * degrees, radians, miles, or kilometers; and bearing in degrees. 316 * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. 317 * 318 * @name destination 319 * @param {Coord} origin starting point 320 * @param {number} distance distance from the origin point 321 * @param {number} bearing ranging from -180 to 180 322 * @param {Object} [options={}] Optional parameters 323 * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians 324 * @param {Object} [options.properties={}] Translate properties to Point 325 * @returns {Feature<Point>} destination point 326 * @example 327 * var point = turf.point([-75.343, 39.984]); 328 * var distance = 50; 329 * var bearing = 90; 330 * var options = {units: 'miles'}; 331 * 332 * var destination = turf.destination(point, distance, bearing, options); 333 * 334 * //addToMap 335 * var addToMap = [point, destination] 336 * destination.properties['marker-color'] = '#f00'; 337 * point.properties['marker-color'] = '#0f0'; 338 */ 339 340 function destination(origin, distance, bearing, options) { 341 if (options === void 0) { 342 options = {}; 343 } // Handle input 344 345 346 var coordinates1 = getCoord(origin); 347 var longitude1 = degreesToRadians(coordinates1[0]); 348 var latitude1 = degreesToRadians(coordinates1[1]); 349 var bearingRad = degreesToRadians(bearing); 350 var radians = lengthToRadians(distance, options.units); // Main 351 352 var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) + Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)); 353 var longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1), Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2)); 354 var lng = radiansToDegrees(longitude2); 355 var lat = radiansToDegrees(latitude2); 356 return point([lng, lat], options.properties); 357 } 358 359 /** @typedef {import('@turf/helpers').Units} Units */ 360 361 /** 362 * @param {GeoJSON.BBox} bbox 363 * @param {number} gridWidth 364 * @param {number} gridHeight 365 * @param {Units} units 366 * @returns {GeoJSON.Feature<GeoJSON.LineString>[]} 367 */ 368 369 function getGrid(bbox, gridWidth, gridHeight, units) { 370 // return rectangleGrid(bbox, gridWidth, gridHeight, { units });
371 var earthCircumference = Math.ceil(distance([0, 0], [180, 0], { 372 units: units 373 }) * 2); 374 var maxColumns = Math.floor(earthCircumference / gridWidth); 375 /** @type {(from: GeoJSON.Position, to: GeoJSON.Position, options: { units: Units }) => number} */ 376 377 var fullDistance = function fullDistance(from, to, options) { 378 var dist = distance(from, to, options); 379 380 if (Math.abs(to[0] - from[0]) >= 180) { 381 return earthCircumference - dist; 382 } 383 384 return dist; 385 }; 386 /** @type {GeoJSON.Feature<GeoJSON.LineString>[]} */ 387 388 389 var features = []; 390 var west = bbox[0]; 391 var south = bbox[1]; 392 var east = bbox[2]; 393 var north = bbox[3]; // calculate grid start point 394 395 var deltaX = (west < 0 ? -1 : 1) * fullDistance([0, 0], [west, 0], { 396 units: units 397 }); 398 var deltaY = (south < 0 ? -1 : 1) * fullDistance([0, 0], [0, south], { 399 units: units 400 }); 401 var startDeltaX = Math.ceil(deltaX / gridWidth) * gridWidth; 402 var startDeltaY = Math.ceil(deltaY / gridHeight) * gridHeight; 403 /** @type {GeoJSON.Position} */ 404 405 var startPoint = [destination([0, 0], startDeltaX, 90, { 406 units: units 407 }).geometry.coordinates[0], destination([0, 0], startDeltaY, 0, { 408 units: units 409 }).geometry.coordinates[1]]; // calculate grid columns and rows count 410 411 var width = fullDistance([west, 0], [east, 0], { 412 units: units 413 }); 414 var height = fullDistance([0, south], [0, north], { 415 units: units 416 }); 417 var columns = Math.min(Math.ceil(width / gridWidth), maxColumns); 418 var rows = Math.ceil(height / gridHeight); // console.log(startPoint, columns, rows); 419 420 /** @type {GeoJSON.Position} */ 421 422 var currentPoint; // meridians 423 424 currentPoint = startPoint; 425 426 for (var i = 0; i < columns; i++) { 427 /** @type {GeoJSON.Position[]} */ 428 var coordinates = [[currentPoint[0], south], [currentPoint[0], north]]; 429 /** @type {GeoJSON.Feature<GeoJSON.LineString>} */ 430 431 var feature = { 432 type: 'Feature', 433 geometry: { 434 type: 'LineString', 435 coordinates: coordinates 436 }, 437 properties: {} 438 }; 439 features.push(feature); 440 currentPoint = [destination([currentPoint[0], 0], gridWidth, 90, { 441 units: units 442 }).geometry.coordinates[0], currentPoint[1]]; 443 } // parallels 444 445 446 currentPoint = startPoint; 447 448 for (var _i = 0; _i < rows; _i++) { 449 /** @type {GeoJSON.Position[]} */ 450 var _coordinates = [[west, currentPoint[1]], [east, currentPoint[1]]]; 451 /** @type {GeoJSON.Feature<GeoJSON.LineString>} */ 452 453 var _feature = { 454 type: 'Feature', 455 geometry: { 456 type: 'LineString', 457 coordinates: _coordinates 458 }, 459 properties: {} 460 }; 461 features.push(_feature); 462 currentPoint = [currentPoint[0], destination([0, currentPoint[1]], gridHeight, 0, { 463 units: units 464 }).geometry.coordinates[1]]; 465 } 466 467 return features; 468 } 469 /** 470 * @param {GeoJSON.Position} point 471 * @param {number} gridWidth 472 * @param {number} gridHeight 473 * @param {Units} units 474 * @returns {GeoJSON.BBox} 475 */ 476 477 function getGridCell(point, gridWidth, gridHeight, units) { 478 var earthCircumference = Math.ceil(distance([0, 0], [180, 0], { 479 units: units 480 }) * 2); 481 /** @type {(from: GeoJSON.Position, to: GeoJSON.Position, options: { units: Units }) => number} */ 482 483 var fullDistance = function fullDistance(from, to, options) { 484 var dist = distance(from, to, options); 485 486 if (Math.abs(to[0] - from[0]) >= 180) { 487 return earthCircumference - dist; 488 } 489 490 return dist; 491 }; 492 493 var deltaX = (point[0] < 0 ? -1 : 1) * fullDistance([0, 0], [point[0], 0], { 494 units: units 495 }); 496 var deltaY = (point[1] < 0 ? -1 : 1) * fullDistance([0, 0], [0, point[1]], { 497 units: units 498 }); 499 var minDeltaX = Math.floor(deltaX / gridWidth) * gridWidth; 500 var minDeltaY = Math.floor(deltaY / gridHeight) * gridHeight; 501 var maxDeltaX = Math.ceil(deltaX / gridWidth) * gridWidth; 502 var maxDeltaY = Math.ceil(deltaY / gridHeight) * gridHeight; 503 var bbox = 504 /** @type {GeoJSON.BBox} */ 505 [destination([0, 0], minDeltaX, 90, { 506 units: units 507 }).geometry.coordinates[0], destination([0, 0], minDeltaY, 0, { 508 units: units 509 }).geometry.coordinates[1], destination([0, 0], maxDeltaX, 90, { 510 units: units 511 }).geometry.coordinates[0], destination([0, 0], maxDeltaY, 0, { 512 units: units 513 }).geometry.coordinates[1]]; 514 return bbox; 515 } 516 517 /** @typedef {import('maplibre-gl').Map} Map */ 518 519 /** @typedef {import('maplibre-gl').GeoJSONSource} GeoJSONSource */ 520 521 /** @typedef {import('maplibre-gl').LngLatBounds} LngLatBounds */ 522 523 /** @typedef {import('maplibre-gl').MapMouseEvent} MapMouseEvent */ 524 525 /** @typedef {import('@turf/helpers').Units} Units */ 526 527 /** @typedef {import('./grid').GridConfig} GridConfig */ 528 529 /** @typedef {import('./grid').GridClickEvent} GridClickEvent */ 530 531 var GRID_CLICK_EVENT = 'grid.click'; 532 function randomString() { 533 return Math.floor(Math.random() * 10e12).toString(36); 534 } 535 var Grid = /*#__PURE__*/function () { 536 /** 537 * @param {GridConfig} config 538 */ 539 function Grid(config) { 540 _classCallCheck(this, Grid); 541 542 this.id = "grid-".concat(randomString()); 543 this.config = config; 544 this.updateBound = this.update.bind(this); 545 this.onMapClickBound = this.onMapClick.bind(this); 546 } 547 /** 548 * @param {Map} map 549 * @returns {HTMLElement} 550 */ 551 552 553 _createClass(Grid, [{ 554 key: "onAdd",
555 value: function onAdd(map) { 556 this.map = map; 557 this.map.on('load', this.updateBound); 558 this.map.on('move', this.updateBound); 559 this.map.on('click', this.onMapClickBound); 560 561 if (this.map.loaded()) { 562 this.update(); 563 } 564 565 return document.createElement('div'); 566 } 567 /** 568 * @returns {void} 569 */ 570 571 }, { 572 key: "onRemove", 573 value: function onRemove() { 574 if (!this.map) { 575 return; 576 } 577 578 var source = this.map.getSource(this.id); 579 580 if (source) { 581 this.map.removeLayer(this.id); 582 this.map.removeSource(this.id); 583 } 584 585 this.map.off('load', this.updateBound); 586 this.map.off('move', this.updateBound); 587 this.map.off('click', this.onMapClickBound); 588 this.map = undefined; 589 } 590 /** 591 * @returns {void} 592 */ 593 594 }, { 595 key: "update", 596 value: function update() { 597 if (!this.map) { 598 return; 599 } 600 /** @type {GeoJSON.Feature<GeoJSON.LineString>[]} */ 601 602 603 var grid = []; 604 605 if (this.active) { 606 grid = getGrid(this.bbox, this.config.gridWidth, this.config.gridHeight, this.config.units); 607 } // console.log(grid); 608 609 610 var source = 611 /** @type {GeoJSONSource} */ 612 this.map.getSource(this.id); 613 614 if (!source) { 615 var _this$config$paint; 616 617 this.map.addSource(this.id, { 618 type: 'geojson', 619 data: { 620 type: 'FeatureCollection', 621 features: grid 622 } 623 }); 624 this.map.addLayer({ 625 id: this.id, 626 source: this.id, 627 type: 'line', 628 paint: (_this$config$paint = this.config.paint) !== null && _this$config$paint !== void 0 ? _this$config$paint : {} 629 }); 630 } else { 631 source.setData({ 632 type: 'FeatureCollection', 633 features: grid 634 }); 635 } 636 } 637 /** 638 * @returns {boolean} 639 */ 640 641 }, { 642 key: "active", 643 get: function get() { 644 var _this$config$minZoom, _this$config$maxZoom; 645 646 if (!this.map) { 647 return false; 648 } 649 650 var minZoom = (_this$config$minZoom = this.config.minZoom) !== null && _this$config$minZoom !== void 0 ? _this$config$minZoom : 0; 651 var maxZoom = (_this$config$maxZoom = this.config.maxZoom) !== null && _this$config$maxZoom !== void 0 ? _this$config$maxZoom : 22; 652 var zoom = this.map.getZoom(); // console.log(zoom); 653 654 return minZoom <= zoom && zoom < maxZoom; 655 } 656 /** 657 * @returns {GeoJSON.BBox} 658 */ 659 660 }, { 661 key: "bbox", 662 get: function get() { 663 if (!this.map) { 664 throw new Error('Invalid state'); 665 } 666 667 var bounds = this.map.getBounds(); 668 669 if (bounds.getEast() - bounds.getWest() >= 360) { 670 bounds.setNorthEast([bounds.getWest() + 360, bounds.getNorth()]); 671 } 672 673 var bbox = 674 /** @type {GeoJSON.BBox} */ 675 bounds.toArray().flat(); 676 return bbox; 677 } 678 /** 679 * @param {MapMouseEvent} event 680 * @returns {void} 681 */ 682 683 }, { 684 key: "onMapClick", 685 value: function onMapClick(event) { 686 if (!this.map || !this.active) { 687 return; 688 } 689 690 var point = event.lngLat.toArray(); 691 var bbox = getGridCell(point, this.config.gridWidth, this.config.gridWidth, this.config.units); 692 /** @type {GridClickEvent} */ 693 694 var event2 = { 695 bbox: bbox 696 }; 697 this.map.fire(GRID_CLICK_EVENT, event2); 698 } 699 }]); 700 701 return Grid; 702 }(); 703 704 exports.GRID_CLICK_EVENT = GRID_CLICK_EVENT; 705 exports.Grid = Grid; 706 exports.randomString = randomString; 707 708 Object.defineProperty(exports, '__esModule', { value: true }); 709 710}))); 711//# sourceMappingURL=maplibre-grid.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.