react-ol v1.3.0

Features API

Complete API reference for all feature components

Features

Features are geometric shapes that you can render on vector layers. All features support styling, interactivity, and can have custom properties attached.

Common Props

All feature components share these common props:

style

  • Type: StyleLike (OpenLayers style)
  • Optional
  • Description: Visual style for the feature
import { Circle, Fill, Stroke, Style } from 'ol/style';

const myStyle = new Style({
  image: new Circle({
    radius: 8,
    fill: new Fill({ color: 'red' }),
    stroke: new Stroke({ color: 'white', width: 2 })
  })
});

<PointFeature coordinates={{ lat: 32, long: 34 }} style={myStyle} />

hoverStyle

  • Type: StyleLike (OpenLayers style)
  • Optional
  • Description: Style to apply when the feature is hovered
const normalStyle = new Style({ ... });
const hoverStyle = new Style({ ... });

<PointFeature
  coordinates={{ lat: 32, long: 34 }}
  style={normalStyle}
  hoverStyle={hoverStyle}
/>

properties

  • Type: Record<string, any>
  • Default: {}
  • Description: Custom data to attach to the feature (accessible in event handlers)
<PointFeature
  coordinates={{ lat: 32, long: 34 }}
  properties={{
    name: 'Tel Aviv',
    population: 460000,
    type: 'city'
  }}
  onClick={(feature) => {
    console.log(feature.get('name')); // 'Tel Aviv'
    console.log(feature.get('population')); // 460000
  }}
/>

visible

  • Type: boolean
  • Default: true
  • Description: Whether the feature is visible
const [showMarker, setShowMarker] = useState(true);
<PointFeature coordinates={{ lat: 32, long: 34 }} visible={showMarker} />

onClick

  • Type: (feature: Feature, event: any) => void
  • Optional
  • Description: Callback when the feature is clicked
<PointFeature
  coordinates={{ lat: 32, long: 34 }}
  onClick={(feature, event) => {
    console.log('Clicked!', feature.getGeometry());
  }}
/>

onMouseEnter

  • Type: (feature: Feature, event: any) => void
  • Optional
  • Description: Callback when the mouse enters the feature
<PointFeature
  coordinates={{ lat: 32, long: 34 }}
  onMouseEnter={(feature, event) => {
    console.log('Hover started');
  }}
/>

onMouseExit

  • Type: (feature: Feature, event: any) => void
  • Optional
  • Description: Callback when the mouse leaves the feature
<PointFeature
  coordinates={{ lat: 32, long: 34 }}
  onMouseExit={(feature, event) => {
    console.log('Hover ended');
  }}
/>

PointFeature

Renders a single point at specified coordinates. Typically styled with a circle, icon, or custom symbol.

Import

import { PointFeature } from '@mixelburg/react-ol';

Props

coordinates (required)

  • Type: Coordinates ({ lat: number, long: number })
  • Description: The point's location
<PointFeature coordinates={{ lat: 32.0853, long: 34.7818 }} />

Examples

Basic Marker

import { Circle, Fill, Style } from 'ol/style';

<MapVectorLayer layerId="markers">
  <PointFeature
    coordinates={{ lat: 32.0853, long: 34.7818 }}
    style={new Style({
      image: new Circle({
        radius: 8,
        fill: new Fill({ color: '#FF0000' })
      })
    })}
  />
</MapVectorLayer>

Interactive Marker

import { Circle, Fill, Stroke, Style } from 'ol/style';
import { useState } from 'react';

function MyMap() {
  const [selectedPlace, setSelectedPlace] = useState(null);

  const markerStyle = new Style({
    image: new Circle({
      radius: 8,
      fill: new Fill({ color: '#3b82f6' }),
      stroke: new Stroke({ color: 'white', width: 2 })
    })
  });

  const hoverStyle = new Style({
    image: new Circle({
      radius: 12,
      fill: new Fill({ color: '#ef4444' }),
      stroke: new Stroke({ color: 'white', width: 2 })
    })
  });

  return (
    <OpenLayersMap>
      <MapTileLayer source={new OSM()} />
      <MapVectorLayer layerId="places">
        <PointFeature
          coordinates={{ lat: 32.0853, long: 34.7818 }}
          style={markerStyle}
          hoverStyle={hoverStyle}
          properties={{ name: 'Tel Aviv', type: 'city' }}
          onClick={(feature) => {
            setSelectedPlace(feature.get('name'));
          }}
        />
      </MapVectorLayer>
    </OpenLayersMap>
  );
}

Icon Marker

import { Icon, Style } from 'ol/style';

<PointFeature
  coordinates={{ lat: 32.0853, long: 34.7818 }}
  style={new Style({
    image: new Icon({
      src: 'https://example.com/marker.png',
      scale: 0.5,
      anchor: [0.5, 1], // Bottom center
    })
  })}
/>

React Icon as Marker

import { Icon, Style } from 'ol/style';
import { FaMapMarkerAlt } from 'react-icons/fa';
import { reactIconToSrc } from '@mixelburg/react-ol';

const iconSrc = reactIconToSrc(
  <FaMapMarkerAlt size={32} color="#ef4444" />
);

<PointFeature
  coordinates={{ lat: 32.0853, long: 34.7818 }}
  style={new Style({
    image: new Icon({
      src: iconSrc,
      anchor: [0.5, 1],
    })
  })}
/>

LineStringFeature

Renders a line through multiple coordinates. Useful for routes, paths, boundaries, etc.

Import

import { LineStringFeature } from '@mixelburg/react-ol';

Props

coordinates (required)

  • Type: Coordinates[] (array of { lat: number, long: number })
  • Description: Array of points that define the line
<LineStringFeature
  coordinates={[
    { lat: 32.0, long: 34.0 },
    { lat: 32.1, long: 34.1 },
    { lat: 32.2, long: 34.2 },
  ]}
/>

Examples

Basic Line

import { Stroke, Style } from 'ol/style';

<MapVectorLayer layerId="routes">
  <LineStringFeature
    coordinates={[
      { lat: 32.0853, long: 34.7818 },
      { lat: 32.0900, long: 34.7900 },
      { lat: 32.0950, long: 34.8000 },
    ]}
    style={new Style({
      stroke: new Stroke({
        color: '#3b82f6',
        width: 3
      })
    })}
  />
</MapVectorLayer>

Dashed Line

import { Stroke, Style } from 'ol/style';

<LineStringFeature
  coordinates={pathCoordinates}
  style={new Style({
    stroke: new Stroke({
      color: '#10b981',
      width: 2,
      lineDash: [10, 5] // 10px line, 5px gap
    })
  })}
/>

Interactive Route

import { Stroke, Style } from 'ol/style';

const routeStyle = new Style({
  stroke: new Stroke({
    color: '#3b82f6',
    width: 3
  })
});

const hoverStyle = new Style({
  stroke: new Stroke({
    color: '#ef4444',
    width: 5
  })
});

<LineStringFeature
  coordinates={routeCoordinates}
  style={routeStyle}
  hoverStyle={hoverStyle}
  properties={{
    name: 'Route 1',
    distance: '5.2 km',
    duration: '15 min'
  }}
  onClick={(feature) => {
    console.log('Route clicked:', feature.get('name'));
  }}
/>

PolygonFeature

Renders a closed shape defined by coordinates. The first and last points are automatically connected.

Import

import { PolygonFeature } from '@mixelburg/react-ol';

Props

coordinates (required)

  • Type: Coordinates[] (array of { lat: number, long: number })
  • Description: Array of points that define the polygon boundary
<PolygonFeature
  coordinates={[
    { lat: 32.0, long: 34.0 },
    { lat: 32.1, long: 34.0 },
    { lat: 32.1, long: 34.1 },
    { lat: 32.0, long: 34.1 },
    // Note: Last point connects back to first automatically
  ]}
/>

Examples

Basic Polygon

import { Fill, Stroke, Style } from 'ol/style';

<MapVectorLayer layerId="zones">
  <PolygonFeature
    coordinates={[
      { lat: 32.08, long: 34.78 },
      { lat: 32.09, long: 34.78 },
      { lat: 32.09, long: 34.79 },
      { lat: 32.08, long: 34.79 },
    ]}
    style={new Style({
      fill: new Fill({
        color: 'rgba(59, 130, 246, 0.2)' // Semi-transparent blue
      }),
      stroke: new Stroke({
        color: '#3b82f6',
        width: 2
      })
    })}
  />
</MapVectorLayer>

Clickable Area

import { Fill, Stroke, Style } from 'ol/style';

const zoneStyle = new Style({
  fill: new Fill({ color: 'rgba(16, 185, 129, 0.2)' }),
  stroke: new Stroke({ color: '#10b981', width: 2 })
});

const selectedStyle = new Style({
  fill: new Fill({ color: 'rgba(239, 68, 68, 0.3)' }),
  stroke: new Stroke({ color: '#ef4444', width: 3 })
});

function MyMap() {
  const [selectedZone, setSelectedZone] = useState(null);

  return (
    <MapVectorLayer layerId="zones">
      <PolygonFeature
        coordinates={zoneCoordinates}
        style={selectedZone === 'zone1' ? selectedStyle : zoneStyle}
        properties={{ id: 'zone1', name: 'Downtown Area' }}
        onClick={(feature) => {
          setSelectedZone(feature.get('id'));
        }}
      />
    </MapVectorLayer>
  );
}

Pattern Fill

import { Fill, Stroke, Style } from 'ol/style';

<PolygonFeature
  coordinates={areaCoordinates}
  style={new Style({
    fill: new Fill({
      color: 'rgba(251, 191, 36, 0.3)'
    }),
    stroke: new Stroke({
      color: '#f59e0b',
      width: 2,
      lineDash: [5, 5]
    })
  })}
/>

CircleFeature

Renders a circle with a center point and radius. The radius is specified in meters.

Import

import { CircleFeature } from '@mixelburg/react-ol';

Props

center (required)

  • Type: Coordinates ({ lat: number, long: number })
  • Description: Center point of the circle

radius (required)

  • Type: number
  • Description: Radius in meters
<CircleFeature
  center={{ lat: 32.0853, long: 34.7818 }}
  radius={1000} // 1 kilometer radius
/>

Examples

Basic Circle

import { Fill, Stroke, Style } from 'ol/style';

<MapVectorLayer layerId="ranges">
  <CircleFeature
    center={{ lat: 32.0853, long: 34.7818 }}
    radius={1000} // 1km
    style={new Style({
      fill: new Fill({
        color: 'rgba(59, 130, 246, 0.2)'
      }),
      stroke: new Stroke({
        color: '#3b82f6',
        width: 2
      })
    })}
  />
</MapVectorLayer>

Range Indicator

import { Fill, Stroke, Style } from 'ol/style';

<CircleFeature
  center={{ lat: 32.0853, long: 34.7818 }}
  radius={500}
  style={new Style({
    fill: new Fill({
      color: 'rgba(16, 185, 129, 0.15)'
    }),
    stroke: new Stroke({
      color: '#10b981',
      width: 2,
      lineDash: [10, 5]
    })
  })}
  properties={{
    type: 'delivery-range',
    radius: '500m'
  }}
/>

Concentric Circles

import { Fill, Stroke, Style } from 'ol/style';

const center = { lat: 32.0853, long: 34.7818 };

<MapVectorLayer layerId="ranges">
  {/* Outer circle */}
  <CircleFeature
    center={center}
    radius={2000}
    style={new Style({
      fill: new Fill({ color: 'rgba(239, 68, 68, 0.1)' }),
      stroke: new Stroke({ color: '#ef4444', width: 1 })
    })}
  />

  {/* Middle circle */}
  <CircleFeature
    center={center}
    radius={1000}
    style={new Style({
      fill: new Fill({ color: 'rgba(251, 191, 36, 0.15)' }),
      stroke: new Stroke({ color: '#f59e0b', width: 1 })
    })}
  />

  {/* Inner circle */}
  <CircleFeature
    center={center}
    radius={500}
    style={new Style({
      fill: new Fill({ color: 'rgba(16, 185, 129, 0.2)' }),
      stroke: new Stroke({ color: '#10b981', width: 2 })
    })}
  />
</MapVectorLayer>

Complete Example

Here's a comprehensive example showing all feature types together:

import { useState } from 'react';
import {
  OpenLayersMap,
  MapTileLayer,
  MapVectorLayer,
  PointFeature,
  LineStringFeature,
  PolygonFeature,
  CircleFeature,
} from '@mixelburg/react-ol';
import { OSM } from 'ol/source';
import { Circle, Fill, Icon, Stroke, Style } from 'ol/style';

function MyMap() {
  const [selectedFeature, setSelectedFeature] = useState(null);

  const pointStyle = new Style({
    image: new Circle({
      radius: 8,
      fill: new Fill({ color: '#3b82f6' }),
      stroke: new Stroke({ color: 'white', width: 2 })
    })
  });

  const lineStyle = new Style({
    stroke: new Stroke({
      color: '#10b981',
      width: 3
    })
  });

  const polygonStyle = new Style({
    fill: new Fill({ color: 'rgba(251, 191, 36, 0.2)' }),
    stroke: new Stroke({ color: '#f59e0b', width: 2 })
  });

  const circleStyle = new Style({
    fill: new Fill({ color: 'rgba(239, 68, 68, 0.1)' }),
    stroke: new Stroke({ color: '#ef4444', width: 2 })
  });

  return (
    <div>
      {selectedFeature && (
        <div>Selected: {selectedFeature}</div>
      )}

      <OpenLayersMap
        defaultCenter={{ lat: 32.0853, long: 34.7818 }}
        defaultZoom={13}
        wrapperProps={{ style: { width: '100%', height: '600px' }}}
      >
        <MapTileLayer source={new OSM()} />

        <MapVectorLayer layerId="all-features">
          {/* Point marker */}
          <PointFeature
            coordinates={{ lat: 32.0853, long: 34.7818 }}
            style={pointStyle}
            properties={{ name: 'City Center', type: 'poi' }}
            onClick={(feature) => setSelectedFeature(feature.get('name'))}
          />

          {/* Line path */}
          <LineStringFeature
            coordinates={[
              { lat: 32.08, long: 34.77 },
              { lat: 32.085, long: 34.775 },
              { lat: 32.09, long: 34.78 },
            ]}
            style={lineStyle}
            properties={{ name: 'Main Road' }}
            onClick={(feature) => setSelectedFeature(feature.get('name'))}
          />

          {/* Polygon area */}
          <PolygonFeature
            coordinates={[
              { lat: 32.075, long: 34.785 },
              { lat: 32.080, long: 34.785 },
              { lat: 32.080, long: 34.790 },
              { lat: 32.075, long: 34.790 },
            ]}
            style={polygonStyle}
            properties={{ name: 'Park Zone' }}
            onClick={(feature) => setSelectedFeature(feature.get('name'))}
          />

          {/* Circle range */}
          <CircleFeature
            center={{ lat: 32.0853, long: 34.7818 }}
            radius={500}
            style={circleStyle}
            properties={{ name: '500m Range' }}
            onClick={(feature) => setSelectedFeature(feature.get('name'))}
          />
        </MapVectorLayer>
      </OpenLayersMap>
    </div>
  );
}

Styling Tips

  1. Reuse Style Objects: Create style instances once and reuse them for better performance
  2. Semi-transparent Fills: Use rgba() colors with alpha < 1 for overlapping areas
  3. Stroke Width: Thicker strokes (3-5px) are easier to click/hover
  4. Line Dash: Use lineDash: [10, 5] for dashed/dotted lines
  5. Anchor Points: For icons, set anchor to [0.5, 1] to position at bottom-center
// ✅ Good: Reuse styles
const markerStyle = new Style({ ... });
features.map(coords => (
  <PointFeature coordinates={coords} style={markerStyle} />
))

// ❌ Less optimal: Create new style each time
features.map(coords => (
  <PointFeature coordinates={coords} style={new Style({ ... })} />
))

On this page