react-openlayers

repository·develop·Indexed 43 days ago

https://github.com/allenhwkim/react-openlayers

A minimal TypeScript React wrapper for OpenLayers 10. It provides React components for common OpenLayers objects including Maps, Views, Layers (Tile, Image, Vector, WebGLTile, Heatmap, Graticule), Controls (DrawControl, LayersControl, SearchControl), and Interactions. The library includes hooks like useMap and useGroup for accessing underlying OpenLayers instances, as well as utility functions for marker manipulation and coordinate-to-address conversion.

Tokens
19K
Snippets
62
Records
77
Agent score
53%

What's inside react-openlayers

  1. How LayersControl interacts with LayerGroup

    develop

    The <LayersControl /> component can manage both individual layers and collections of layers via <LayerGroup />.

    When using <LayerGroup />, the control treats the group as a single toggleable entity. If a group is hidden, all layers within that group are hidden. To ensure the group appears correctly in the control, you must provide a name prop to the <LayerGroup /> component.

    <Map>
      <LayersControl />
      <LayerGroup name="My Group">
        <GraticuleLayer showLabels={true} />
        <TileLayer name="Cities/Highways" source={tileSrc} />
        <HeatmapLayer name="Earthquakes" source={heatMapSrc} />
      </LayerGroup>
    </Map>
  2. How PointerInteraction manages drag sequences

    develop

    The <PointerInteraction /> component is a React wrapper for the OpenLayers PointerInteraction class. It provides a mechanism for handling mouse or touch events through user-defined functions and manages "drag sequences" based on their return values.

    Drag Sequence Lifecycle:

    1. Start: When the handleDownEvent function returns true, a drag sequence begins.
    2. During: While the drag sequence is active, the handleDragEvent function is called on every move event.
    3. End: The drag sequence ends when the handleUpEvent function is called and returns false.

    This pattern allows you to distinguish between simple clicks/taps and continuous dragging motions.

    /* 
    Conceptual logic flow:
    
    handleDownEvent: returns true -> starts drag
    handleDragEvent: called during move
    handleUpEvent: returns false -> ends drag
    */
  3. Use the <Map /> component

    develop

    The <Map /> component is a React wrapper for the OpenLayers ol.Map class. It allows you to instantiate an OpenLayers map within a React application by passing configuration props directly to the component.

    To use it, import the component and render it within your application. You can apply standard React styles to the component container.

    Accessing the underlying OpenLayers Map instance

    Because the component wraps a native OpenLayers object, you may need to call imperative OpenLayers methods (like setSize, getView, etc.) that are not exposed via React props. To do this, use a ref to access the underlying ol.Map instance.

    import { useRef } from 'react';
    import { Map } from 'react-openlayers';
    
    export default function MapExample() {
      const mapRef = useRef<any>(null);
    
      const handleResize = () => {
        // Use the underlying OpenLayers Map instance methods via the ref
        if (mapRef.current) {
          mapRef.current.setSize([400, 200]);
        }
      };
    
      return <Map ref={mapRef} style={{ filter: 'invert(1)' }} />;
    }
  4. Test the built library files

    develop

    To verify that the library's build artifacts (../dist/index.js and ../dist/index.css) are correctly generated and functional before publishing, you can run the library test suite. This process uses a local React application that consumes the files from the dist directory.

    Prerequisites: The test environment requires the following files to be present:

    • index.html
    • vite.config.ts
    • main.tsx (which initializes App.tsx)

    Execution: Run the following command from the repository root:

    npm run libtest
  5. Use the SelectInteraction component

    develop

    The SelectInteraction component provides a React wrapper for the OpenLayers Select interaction. It allows users to select vector features on a map, which can be used for visual highlighting or triggering other actions like modification or data output.

    Selection can be controlled via:

    1. Browser events: Using conditions, toggles, add/remove, and multi options.
    2. Layers filter: Restricting selection to specific layers.
    3. Feature filter: Using the filter option for custom logic.

    When a selection event occurs, the onSelect callback provides access to the selected features and the list of deselected features.

    import {Map, SelectInteraction, VectorLayer} from '../../../lib';
    import Point from 'ol/geom/Point';
    import LineString from 'ol/geom/LineString';
    import Polygon from 'ol/geom/Polygon';
    import VectorSource from 'ol/source/Vector';
    import Feature from 'ol/Feature';
    
    export default function(props) {
      const pointFeature = new Feature( new Point([0, 0]));
      const lineFeature = new Feature( new LineString([ [-1e7, 1e6], [-1e6, 3e6] ])) ;
      const polygonFeature = new Feature(
        new Polygon([ [ [-3e6, -1e6], [-3e6, 1e6], [-1e6, 1e6], [-1e6, -1e6], [-3e6, -1e6] ] ]),
      );
      const source = new VectorSource({
        features: [pointFeature, lineFeature, polygonFeature],
      })
    
      function onSelect(e) {
        console.log('selected', e.target.getFeatures().getLength());
        console.log('deselected', e.deselected.length);
      };
    
      return (
        <Map>
          <VectorLayer source={source} />
          <SelectInteraction onSelect={onSelect} />
        </Map>
      );
    }
  6. Use LinkInteraction to synchronize map state with the URL

    develop

    The <LinkInteraction /> component is a React wrapper for the OpenLayers Link interaction. It automatically synchronizes the map's state (such as view/extent) with the browser's URL. This allows users to share specific map views via a link.

    To use it, place the <LinkInteraction /> component inside a <Map> component.

    import { Map, LinkInteraction } from 'react-openlayers';
    
    export default function MyMapComponent() {
      return (
        <Map>
          <LinkInteraction />
        </Map>
      );
    }
  7. Use the <Overlay /> component

    develop

    The <Overlay /> component is a React wrapper for the OpenLayers Overlay class. It allows you to render React children as an overlay on top of an OpenLayers map. You can pass any properties supported by the standard OpenLayers Overlay API directly as props to the component.

    Commonly used props include autoPan, which can be configured with an animation object to pan the map when the overlay is shown.

    import OSM from 'ol/source/OSM';
    import { Map, View, TileLayer, Overlay } from 'react-openlayers';
    
    export default function(props) {
      return (
        <Map>
          <Overlay autoPan={{ animation: { duration: 250 } }}>
            <p>You clicked here.</p>
            <code>[[coordinate]]</code>
          </Overlay>
          <TileLayer source={new OSM()} />
          <View center={[-10997148, 4569099]} zoom={4}/>
        </Map>
      );
    }
  8. Use the LayersControl component

    develop

    The <LayersControl /> component provides a UI to show and hide layers or layer groups within an OpenLayers map.

    How it works:

    1. It automatically lists all available layers or layer groups provided as children within the <Map /> component.
    2. When a user clicks a layer or layer group in the control, the component toggles its visibility on the map.

    To use it, place <LayersControl /> inside your <Map /> component. Ensure your layers or <LayerGroup /> components have a name prop, as this is what will be displayed in the control list.

    import { Map, View, LayersControl, LayerGroup, TileLayer } from 'react-openlayers';
    
    export default function MyMap() {
      return (
        <Map>
          <LayersControl />
          <LayerGroup name="My Group">
            <TileLayer name="Cities/Highways" source={yourSource} />
          </LayerGroup>
          <View center={[0, 0]} zoom={2}/>
        </Map>
      );
    }
  9. Use the DrawControl component

    develop

    The <DrawControl /> component is a custom control that allows users to draw points, lines, polygons, and circles on the map.

    To function correctly, the component requires a VectorLayer with a VectorSource to be applied to the Map. Internally, it applies Modify, Snap, and Draw interactions to that VectorSource.

    Basic Workflow:

    1. Add <DrawControl /> to your <Map /> component.
    2. Click the draw icon in the control to enter drawing mode.
    3. Complete your drawing, then click the draw icon again to finish.
    import { Map, TileLayer, View, DrawControl, SelectInteraction, ModifyInteraction } from 'react-openlayers';
    
    export default function(props) {
      return (
        <Map controls={[]}>
          <DrawControl />
          <View center={[-10997148, 4569099]} zoom={4}/>
          <SelectInteraction />
          <TranslateInteraction />
        </Map>
      )
    }
  10. Use the OverviewMapControl component

    develop

    The <OverviewMapControl /> component creates a new OpenLayers control that provides a small overview map (mini-map) for a main map. It acts as a React wrapper for the OpenLayers OverviewMap control.

    To use it, you must provide an array of layers to the layers prop. These layers will be rendered within the overview map.

    Note: When using this control, you may want to pass an empty array to the controls prop of the parent <Map /> component to prevent default controls from interfering with your layout, depending on your specific needs.

    import OSM from 'ol/source/OSM';
    import OlTileLayer from 'ol/layer/Tile';
    import { Map, TileLayer, View, OverviewMapControl } from 'react-openlayers';
    
    export default function(props) {
      const overviewLayers = [
        new OlTileLayer({source: new OSM()})
      ];
      return (
        <Map controls={[]}>
          <OverviewMapControl layers={overviewLayers} />
          <View center={[-10997148, 4569099]} zoom={4}/>
        </Map>
      );
    }
  11. Update ScaleLineControl properties after initialization

    develop

    Because ScaleLineControl wraps an OpenLayers instance, you can update its properties dynamically by accessing the underlying OpenLayers control via the map instance. For example, to change the units using the OpenLayers setUnits() method, you can access the control from the map's control array.

    // Example: updating units to 'us' via the map reference
    mapRef.current.getControls().getArray()[0].setUnits('us')