New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

leaflet-grid-distance

Package Overview
Dependencies
Maintainers
0
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

leaflet-grid-distance - npm Package Compare versions

Comparing version 1.0.0 to 2.0.1

20

dist/AxesGridLayer.d.ts
import * as L from 'leaflet';
interface AxesLayerOptions extends L.GridLayerOptions {
cells: number;
color: string;
axesColor: string;
axesWidth: number;
zoom: number;
showLabel: boolean;
defaultLabel: {
color: string;
size: number;
};
center: L.LatLngLiteral;
primaryColor: string;
secondaryColor: string;
textColor: string;
fontSize: number;
kmThreshold: number;
}
declare function AxesLayer(opts: Partial<AxesLayerOptions>): L.GridLayer;
export { AxesLayer, AxesLayerOptions };
declare function AxesLayerWithDistance(opts: Partial<AxesLayerOptions>): L.GridLayer;
export { AxesLayerWithDistance, AxesLayerOptions };

@@ -26,143 +26,155 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.AxesLayer = AxesLayer;
exports.AxesLayerWithDistance = AxesLayerWithDistance;
const L = __importStar(require("leaflet"));
const AxesLayerWithDistance = L.GridLayer.extend({
const AxesLayerWithDistanceClass = L.GridLayer.extend({
options: {
cells: 5,
color: '#40404044',
axesColor: '#ff6754',
axesWidth: 0.8,
zoom: 10,
showLabel: false,
defaultLabel: {
color: '#404040',
size: 13,
},
center: { lat: 0, lng: 0 },
tileSize: 256,
primaryColor: '#ff0000',
secondaryColor: '#999999',
textColor: '#000000',
fontSize: 12,
kmThreshold: 13,
},
initialize: function (options) {
L.setOptions(this, options);
L.GridLayer.prototype.initialize.call(this, options);
this._center = null;
},
onAdd: function (map) {
L.GridLayer.prototype.onAdd.call(this, map);
this.setCenter(this.options.center);
this._center = map.getCenter();
map.on('move', this._onMove, this);
},
setCenter: function (center) {
this.options.center = L.latLng(center);
onRemove: function (map) {
map.off('move', this._onMove, this);
L.GridLayer.prototype.onRemove.call(this, map);
},
// eslint-disable-next-line unused-imports/no-unused-vars
_onMove: function (e) {
this._center = this._map.getCenter();
this.redraw();
},
createTile: function (coords) {
const svg = this.createParentTile();
const n = this.options.cells;
createTile: function (coords, done) {
const tile = L.DomUtil.create('canvas', 'leaflet-tile');
const size = this.getTileSize();
tile.width = size.x;
tile.height = size.y;
const ctx = tile.getContext('2d');
// Ensure _center is defined before drawing
if (!this._center && this._map) {
this._center = this._map.getCenter();
}
if (this._center) {
this._drawGrid(ctx, coords, size);
}
setTimeout(() => {
done(null, tile);
}, 0);
return tile;
},
_drawGrid: function (ctx, coords, size) {
const zoom = this._map.getZoom();
const centerPoint = this._map.project(this._center, zoom);
const tilePoint = coords.scaleBy(size);
// Draw grid lines
ctx.strokeStyle = this.options.secondaryColor;
ctx.lineWidth = 1;
const gridSize = size.x / 4; // Since we're drawing 4x4 grid
for (let i = 0; i <= size.x; i += gridSize) {
ctx.beginPath();
ctx.moveTo(i, 0);
ctx.lineTo(i, size.y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, i);
ctx.lineTo(size.x, i);
ctx.stroke();
}
// Calculate axis positions
let xAxisY = centerPoint.y - tilePoint.y;
let yAxisX = centerPoint.x - tilePoint.x;
// Snap axes to nearest grid line
xAxisY = Math.round(xAxisY / gridSize) * gridSize;
yAxisX = Math.round(yAxisX / gridSize) * gridSize;
// Draw main axes
ctx.strokeStyle = this.options.primaryColor;
ctx.lineWidth = 2;
// Draw X-axis (horizontal line)
if (xAxisY >= 0 && xAxisY <= size.y) {
ctx.beginPath();
ctx.moveTo(0, xAxisY);
ctx.lineTo(size.x, xAxisY);
ctx.stroke();
}
// Draw Y-axis (vertical line)
if (yAxisX >= 0 && yAxisX <= size.x) {
ctx.beginPath();
ctx.moveTo(yAxisX, 0);
ctx.lineTo(yAxisX, size.y);
ctx.stroke();
}
// Draw distance labels
this._drawDistanceLabels(ctx, coords, size, centerPoint, zoom);
},
_drawDistanceLabels: function (ctx, coords, size, centerPoint, zoom) {
const tileSize = this.getTileSize();
const nwPoint = coords.scaleBy(tileSize);
const sePoint = nwPoint.add(tileSize);
const nw = this._map.unproject(nwPoint, coords.z);
const se = this._map.unproject(sePoint, coords.z);
const tileDiagonalDistance = this._map.distance(nw, se);
const tileEdgeDistance = tileDiagonalDistance / Math.sqrt(2);
const centerPoint = this._map.project(this.options.center, coords.z);
ctx.fillStyle = this.options.textColor;
ctx.font = `${this.options.fontSize}px Arial`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const tilePoint = coords.scaleBy(tileSize);
const relativePoint = tilePoint.subtract(centerPoint);
const size = 256 / n;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
const tile = this.Rect(i * size, j * size, size, size);
svg.appendChild(tile);
}
const xAxisY = centerPoint.y - tilePoint.y;
const yAxisX = centerPoint.x - tilePoint.x;
// Calculate the distance represented by one tile
const tileCenterPoint = tilePoint.add([tileSize.x / 2, tileSize.y / 2]);
let metersPerPixel;
try {
const tileCenterLatLng = this._map.unproject(tileCenterPoint, coords.z);
const tileEdgeLatLng = this._map.unproject(tileCenterPoint.add([tileSize.x / 2, 0]), coords.z);
const tileWidthMeters = tileCenterLatLng.distanceTo(tileEdgeLatLng) * 2;
metersPerPixel = tileWidthMeters / tileSize.x;
}
svg.setAttributeNS(null, 'id', coords.x.toString());
if (Math.abs(relativePoint.x) < 128) {
const weight = this.options.axesWidth;
const x = 128 - relativePoint.x;
const line = this.Line(x - weight / 2, 0, x - weight / 2, 256, weight);
svg.appendChild(line);
catch (error) {
console.warn('Error calculating distance:', error);
return; // Exit the function if we can't calculate the distance
}
if (Math.abs(relativePoint.y) < 128) {
const weight = this.options.axesWidth;
const y = 128 + relativePoint.y;
const line = this.Line(0, y - weight / 2, 256, y - weight / 2, weight);
svg.appendChild(line);
// Determine unit based on the zoom level
const useKilometers = zoom <= this.options.kmThreshold;
const unit = useKilometers ? 'km' : 'm';
const unitMultiplier = useKilometers ? 0.001 : 1;
// Function to format distance
const formatDistance = (distanceMeters) => {
const distance = distanceMeters * unitMultiplier;
return useKilometers ? distance.toFixed(2) : Math.round(distance);
};
// X-axis labels
if (xAxisY >= 0 && xAxisY <= size.y) {
for (let i = 0; i <= size.x; i += size.x / 4) {
const pixelDistance = Math.abs(i - yAxisX);
const distanceMeters = pixelDistance * metersPerPixel;
const formattedDistance = formatDistance(distanceMeters);
ctx.fillText(`${formattedDistance}${unit}`, i, xAxisY + 20);
}
}
if (this.options.showLabel) {
const size = this.options.defaultLabel.size;
const color = this.options.defaultLabel.color;
const tileNW = this._map.unproject(coords.scaleBy(tileSize), coords.z);
const baseDistance = this._map.distance(this.options.center, tileNW);
if (Math.abs(relativePoint.y) < 128) {
for (let i = 0; i < n; i++) {
const offsetX = (i - n / 2) * tileEdgeDistance / n;
const distance = baseDistance + offsetX;
const text = this.Text(this.normalize(distance), (i * 256) / n, 128 + relativePoint.y, color, size - 2);
svg.appendChild(text);
}
// Y-axis labels
if (yAxisX >= 0 && yAxisX <= size.x) {
for (let i = 0; i <= size.y; i += size.y / 4) {
const pixelDistance = Math.abs(i - xAxisY);
const distanceMeters = pixelDistance * metersPerPixel;
const formattedDistance = formatDistance(distanceMeters);
ctx.fillText(`${formattedDistance}${unit}`, yAxisX + 20, i);
}
if (Math.abs(relativePoint.x) < 128) {
for (let i = 0; i < n; i++) {
const offsetY = (n / 2 - i) * tileEdgeDistance / n;
const distance = baseDistance + offsetY;
const text = this.Text(this.normalize(distance), 128 - relativePoint.x, (i * 256) / n, color, size - 2);
svg.appendChild(text);
}
}
if (Math.abs(relativePoint.x) < 128 && Math.abs(relativePoint.y) < 128) {
const text = this.Text('0,0', 128 - relativePoint.x, 128 + relativePoint.y, color, size);
svg.appendChild(text);
}
}
return svg;
},
normalize(distanceInMeters) {
let val;
let unit;
if (Math.abs(distanceInMeters) >= 1000) {
val = distanceInMeters / 1000;
unit = 'km';
}
else {
val = distanceInMeters;
unit = 'm';
}
val = Math.round(val * 100) / 100;
return `${val}${unit}`;
_getScale: function (zoom) {
const centerLatLng = this._center || this._map.getCenter();
const pointC = this._map.project(centerLatLng, zoom);
const pointX = L.point(pointC.x + this.options.tileSize / 2, pointC.y);
const latLngC = this._map.unproject(pointC, zoom);
const latLngX = this._map.unproject(pointX, zoom);
return latLngC.distanceTo(latLngX) / (this.options.tileSize / 2);
},
createParentTile() {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttributeNS('http://www.w3.org/2000/svg', 'xlink', 'http://www.w3.org/1999/xlink');
svg.setAttributeNS('http://www.w3.org/2000/svg', 'height', '256');
svg.setAttributeNS('http://www.w3.org/2000/svg', 'width', '256');
const rect = this.Rect(0, 0, 256, 256, 2);
svg.appendChild(rect);
return svg;
},
Rect(x, y, width, height, weight = 0.5) {
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttributeNS(null, 'height', height.toString());
rect.setAttributeNS(null, 'width', width.toString());
rect.setAttributeNS(null, 'x', x.toString());
rect.setAttributeNS(null, 'y', y.toString());
rect.setAttributeNS(null, 'fill', 'none');
rect.setAttributeNS(null, 'stroke', this.options.color);
rect.setAttributeNS(null, 'stroke-width', weight.toString());
return rect;
},
Line(x1, y1, x2, y2, weight = 1) {
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttributeNS(null, 'x1', x1.toString());
line.setAttributeNS(null, 'y1', y1.toString());
line.setAttributeNS(null, 'x2', x2.toString());
line.setAttributeNS(null, 'y2', y2.toString());
line.setAttributeNS(null, 'stroke', this.options.axesColor);
line.setAttributeNS(null, 'stroke-width', weight.toString());
return line;
},
Text(text, x, y, color, size) {
const txt = document.createElementNS('http://www.w3.org/2000/svg', 'text');
txt.setAttributeNS(null, 'x', x.toString());
txt.setAttributeNS(null, 'y', y.toString());
txt.setAttributeNS(null, 'fill', color);
txt.setAttributeNS(null, 'font-size', size.toString());
txt.textContent = text;
return txt;
},
});
function AxesLayer(opts) {
return new AxesLayerWithDistance(opts);
function AxesLayerWithDistance(opts) {
return new AxesLayerWithDistanceClass(opts);
}
{
"name": "leaflet-grid-distance",
"version": "1.0.0",
"version": "2.0.1",
"description": "A Leaflet plugin to show grid distances",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -13,3 +13,3 @@ # AxesLayerWithDistance

- **Dynamic Centering**: Set and update the center of the grid dynamically.
- **SVG Rendering**: Utilizes SVG for sharp and scalable graphics.
- **Canvas Rendering**: Utilizes HTML5 Canvas for efficient rendering.

@@ -34,3 +34,3 @@ ## Demo

import * as L from 'leaflet';
import { AxesLayer, AxesLayerOptions } from 'axes-layer-with-distance';
import { AxesLayerWithDistance, AxesLayerOptions } from 'axes-layer-with-distance';

@@ -52,21 +52,14 @@ ```

// Create an AxesLayer with options
const axesLayer = AxesLayer({
cells: 5,
color: '#40404044',
axesColor: '#ff6754',
axesWidth: 0.8,
zoom: 10,
showLabel: true,
defaultLabel: {
color: '#404040',
size: 13,
},
center: { lat: 51.505, lng: -0.09 },
// Create an AxesLayerWithDistance with options
const axesLayerWithDistance = AxesLayerWithDistance({
primaryColor: '#ff0000',
secondaryColor: '#999999',
textColor: '#000000',
fontSize: 12,
kmThreshold: 13,
});
// Add the AxesLayer to the map
axesLayer.addTo(map);
// Add the AxesLayerWithDistance to the map
axesLayerWithDistance.addTo(map);
```

@@ -77,58 +70,11 @@

- **cells**: Number of grid cells per tile. Default is 5.
- **color** : Color of the grid lines. Supports any CSS color value. Default is '#40404044'.
- **axesColor**: Color of the main axes lines. Default is '#ff6754'.
- **axesWidth**: Width of the axes lines in pixels. Default is 0.8.
- **zoom**: Initial zoom level when adding the layer. Default is 10.
- **showLabel**: Boolean to show/hide distance labels. Default is false.
- **defaultLabel.color**: Color of the text labels. Default is '#404040'.
- **defaultLabel.size**: Font size of the text labels. Default is 13.
- **center**: The center of the grid, specified as a L.LatLngLiteral with latitude and longitude.
- **primaryColor**: Color of the main axes lines. Default is '#ff0000'.
- **secondaryColor**: Color of the grid lines. Default is '#999999'.
- **textColor**: Color of the text labels. Default is '#000000'.
- **fontSize**: Font size of the text labels. Default is 12.
- **kmThreshold**: Zoom level threshold for switching between km and m units. Default is 13.
## Methods
- **setCenter(center: L.LatLngExpression)**: void: Updates the center of the grid and redraws the layer.
- The AxesLayerWithDistance extends Leaflet's GridLayer and inherits all its methods. There are no additional public methods specific to AxesLayerWithDistance.
## Advanced Example
Here is a more advanced usage scenario, including event handling and dynamic updates:
```
// Create a map with an initial view
const map = L.map('map').setView([40.7128, -74.0060], 12);
// Add OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; OpenStreetMap contributors',
maxZoom: 18,
}).addTo(map);
// Configure the AxesLayer options
const options = {
cells: 6,
color: '#00000044',
axesColor: '#008000',
axesWidth: 1.2,
zoom: 12,
showLabel: true,
defaultLabel: {
color: '#008000',
size: 14,
},
center: { lat: 40.7128, lng: -74.0060 },
};
// Initialize the AxesLayer
const axesLayer = AxesLayer(options);
// Add the AxesLayer to the map
axesLayer.addTo(map);
// Update the grid center dynamically
map.on('click', (event) => {
axesLayer.setCenter(event.latlng);
console.log('Grid center updated:', event.latlng);
});
```
## Contributing

@@ -135,0 +81,0 @@ We welcome contributions to improve this library. Please fork the repository, create a branch, and submit a pull request with your changes.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc