Skip to content

Vector Shapes ​

This page documents the concrete vector shape classes in Leaflet: Polyline, Polygon, Circle, CircleMarker, and Rectangle. These classes extend the Path base class and represent geometric shapes drawn as vectors on the map. Each shape class handles coordinate conversion, bounds calculation, projection, and geometry-specific operations.

For information about the vector rendering system (Canvas and SVG renderers), see Vector Rendering System. For the base Path class and shared functionality, see Vector Layers.


Class Hierarchy ​

All vector shapes extend from the Path base class, which provides common styling and rendering integration. The hierarchy is organized by geometric type:

SVG
100%

Shape Comparison ​

ShapeExtendsCoordinate TypeRadius TypeSupports MultiSupports Holes
PolylinePathArray of LatLngN/AYesNo
PolygonPolylineArray of arraysN/AYesYes
RectanglePolygonLatLngBoundsN/ANoNo
CircleMarkerPathSingle LatLngPixelsNoNo
CircleCircleMarkerSingle LatLngMetersNoNo

Coordinate Structure Patterns ​

Vector shapes support different levels of coordinate nesting to represent simple shapes, multi-part shapes, and shapes with holes:

SVG
100%

Polyline ​

The Polyline class draws lines connecting geographic points. It supports both simple polylines (single line) and MultiPolyline (multiple separate lines).

Key Methods ​

MethodDescriptionReturn Type
getLatLngs()Returns the array of points or nested arrays for multi-polylineLatLng[] or LatLng[][]
setLatLngs(latlngs)Replaces all points and redrawsthis
addLatLng(latlng, latlngs?)Adds a point, optionally to a specific ringthis
isEmpty()Returns true if no pointsBoolean
getBounds()Returns the bounding boxLatLngBounds
getCenter()Returns the centroidLatLng
closestLayerPoint(p)Finds closest point on the line to given pointPoint

Options ​

{
  smoothFactor: 1.0,  // Simplification tolerance (higher = more simplified)
  noClip: false       // Disable polyline clipping for performance
}

Internal Coordinate Processing ​

The Polyline class performs several transformations on coordinates:

SVG
100%

Implementation Details ​

Coordinate Conversion (src/layer/vector/Polyline.js158-172):

  • Recursively converts input arrays to LatLng instances
  • Determines if array is flat (single line) or nested (multi-line) using LineUtil.isFlat()
  • Calculates and extends _bounds during conversion

Projection (src/layer/vector/Polyline.js174-210):

  • Converts geographic coordinates to pixel coordinates via map.latLngToLayerPoint()
  • Creates _rings array of projected coordinate arrays
  • Maintains _rawPxBounds for the unprojected bounds

Clipping (src/layer/vector/Polyline.js213-247):

  • Clips line segments to renderer bounds using LineUtil.clipSegment()
  • Creates _parts array containing visible segments
  • Skipped if noClip: true option is set

Simplification (src/layer/vector/Polyline.js250-257):

  • Applies Douglas-Peucker algorithm via LineUtil.simplify()
  • Controlled by smoothFactor option
  • Reduces point count for performance while maintaining visual accuracy

Hit Detection (src/layer/vector/Polyline.js272-291):

  • Used by Canvas renderer for interactivity
  • Checks if point is within _clickTolerance() of any line segment
  • Uses LineUtil.pointToSegmentDistance() for distance calculation

Polygon ​

The Polygon class extends Polyline to draw closed shapes. It supports holes (interior rings) and MultiPolygon geometries.

Key Methods ​

MethodDescriptionNotes
isEmpty()Returns true if no rings or first ring is emptyOverrides Polyline version
getCenter()Returns polygon centroidUses PolyUtil.polygonCenter()

Coordinate Structure ​

Polygons use a more complex nesting structure than polylines:

  • Simple Polygon: [[[lat,lng], [lat,lng], ...]] - Single outer ring wrapped in array
  • Polygon with Holes: First array is outer ring, subsequent arrays are holes
  • MultiPolygon: Each element is a polygon (which itself can have holes)
SVG
100%

Implementation Details ​

Coordinate Normalization (src/layer/vector/Polygon.js76-92):

  • Ensures _latlngs is never flat (always wrapped in at least one array)
  • Removes duplicate last point if it equals the first point
  • First ring is always the outer boundary, others are holes

Clipping Algorithm (src/layer/vector/Polygon.js98-124):

  • Uses PolyUtil.clipPolygon() instead of line segment clipping
  • Expands clip bounds by stroke width to avoid edge artifacts
  • Clips each ring independently

Hit Detection (src/layer/vector/Polygon.js131-153):

  • Uses ray casting algorithm to check if point is inside polygon
  • Falls back to Polyline's _containsPoint() to check stroke
  • Handles holes by alternating inside/outside state

Circle and CircleMarker ​

These classes provide two different types of circular shapes with fundamentally different coordinate systems.

CircleMarker: Fixed Pixel Radius ​

CircleMarker draws a circle with a fixed pixel radius that doesn't scale with zoom level. Useful for markers and point features.

Key Characteristics:

  • Radius specified in pixels
  • Radius stays constant across zoom levels
  • Simple projection: just converts center point to layer coordinates

Options:

{
  fill: true,
  radius: 10  // pixels
}

Circle: Geographic Radius ​

Circle draws a circle with a radius in meters, accounting for map projection. The pixel radius changes with zoom and latitude.

Key Characteristics:

  • Radius specified in meters (geographic distance)
  • Pixel size varies with zoom level and latitude
  • Complex projection calculations for Earth CRS

Options:

{
  radius: 200  // meters (required)
}

Circle Projection Comparison ​

SVG
100%

Circle Earth Projection Details ​

For Earth CRS (Web Mercator), Circle performs sophisticated calculations (src/layer/vector/Circle.js76-92):

  1. Calculate latitude radius in degrees from meter radius:

    latR = (meters / Earth.R) / (π/180)
  2. Project top and bottom points at [lat ± latR, lng]

  3. Calculate center and adjusted latitude from projected points

  4. Calculate longitude radius using spherical trigonometry:

    cos(latR) = cos(lat) * cos(lat2) * cos(lngR) + sin(lat) * sin(lat2)
  5. Handle edge cases: Falls back to simplified calculation near poles

  6. Store ellipse parameters: _radius (x), _radiusY (y) for non-circular projection

This accounts for the fact that circles on the Earth's surface project as ellipses in Web Mercator projection, with distortion increasing at higher latitudes.

Methods Comparison ​

MethodCircleMarkerCircle
setRadius(radius)PixelsMeters
getRadius()Returns pixel radiusReturns meter radius
setLatLng(latlng)✓✓ (inherited)
getLatLng()✓✓ (inherited)
getBounds()Pixel-based boundsGeographic bounds

Rectangle ​

The Rectangle class is a specialized Polygon that creates a four-cornered shape from a LatLngBounds object.

Constructor and Methods ​

// Create from LatLngBounds
const bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
const rectangle = new Rectangle(bounds, {color: "#ff7800", weight: 1});

// Update bounds
rectangle.setBounds(newBounds);

Internal Implementation ​

Bounds to Coordinates Conversion (src/layer/vector/Rectangle.js41-49):

The _boundsToLatLngs() method converts a LatLngBounds to four corner points in counter-clockwise order:

  1. South-West corner
  2. North-West corner
  3. North-East corner
  4. South-East corner

This creates a properly oriented polygon for the renderer.

SVG
100%

Common Operations ​

All vector shapes share certain operations inherited from Path and implemented in shape-specific ways.

Bounds Calculation ​

Each shape calculates its bounding box differently:

ShapeBounds Calculation
PolylineExtends bounds for each point during conversion
PolygonInherits from Polyline
CircleMarkerCenter ± radius in pixels
CircleProjects center ± radius to LatLng bounds
RectangleDefined by constructor LatLngBounds

Center Calculation ​

SVG
100%

Notes:

  • Polyline and Polygon getCenter() require the shape to be added to the map first (throws error otherwise)
  • This is because center calculation requires projected coordinates via the map's CRS
  • Circles simply return their center point

Hit Detection ​

Hit detection is used by the Canvas renderer to determine if a mouse/touch event intersects the shape:

ShapeAlgorithmImplementation
PolylinePoint-to-segment distanceLineUtil.pointToSegmentDistance() ≤ tolerance
PolygonRay casting + stroke checkCount edge crossings, then check Polyline
CircleMarkerDistance checkpoint.distanceTo(center) ≤ radius
CircleDistance checkInherited from CircleMarker

Performance Optimizations ​

Vector shapes employ several optimizations to maintain performance with large datasets.

Clipping ​

Purpose: Reduce rendering workload by excluding geometry outside the visible area.

Implementation:

Process:

SVG
100%

Simplification ​

Purpose: Reduce point count while maintaining visual accuracy using the Douglas-Peucker algorithm.

Configuration:

  • Controlled by smoothFactor option (default: 1.0)
  • Higher values = more aggressive simplification
  • Applied after clipping via LineUtil.simplify()

Trade-offs:

  • Higher smoothFactor: Better performance, less detail
  • Lower smoothFactor: More detail, slower rendering
  • Value of 0 disables simplification
// Heavy simplification (faster, less accurate)
const polyline1 = new Polyline(coords, {smoothFactor: 3.0});

// Minimal simplification (slower, more accurate)  
const polyline2 = new Polyline(coords, {smoothFactor: 0.5});

// No simplification (slowest, exact)
const polyline3 = new Polyline(coords, {smoothFactor: 0});

Update Pipeline ​

The complete update pipeline for polyline-based shapes:

SVG
100%

File Reference Summary ​

Core Implementation Files ​

Test Files ​