1

I want to implement adding icon/marker on map click. It should work like this (Leaflet example). https://codesandbox.io/s/add-onclick-on-mapcontainer-in-react-leaflet-v-3x-4r7tc

I am using OpenLayers 6.5 and React (java script tip would be fine enough thought). My current code looks like this. My idea was to use Draw Api to style the point to Icon manner but it failed to work. Line and Polygons are styled correctly thought. Is there any efficient way to do this or any workarounds?

Additional it would be ideal to swap current default point style to my Icon (following cursor movement).

const drawSource = new VectorSource({ wrapX: false });

class PublicMap extends Component {
  constructor(props) {
    super(props);

    this.state = {
      center: [0, 0],
      zoom: 1,
      draw: null,
      drawVectorLayer: new VectorLayer({
        source: drawSource,
        style: new Style({
          fill: new Fill({
            color: `rgba(4, 149, 106, 1)`,
          }),
          stroke: new Stroke({ color: "blue" }),
          image: new Icon({
            anchor: [16, 48],
            imgSize: [32, 48],
            src: "http://openlayers.org/en/v3.20.1/examples/data/icon.png",
            zIndex: "10",
          }),
        }),
      }),
    };


    this.olmap = new Map({
      layers: [
        new Tile({
          source: new OSM(),
        }),
        this.state.drawVectorLayer,
      ],
      view: new View({
        center: [0, 0],
        zoom: 2,
      }),
      target: null,
    });
  }

  componentDidMount() {
    this.olmap.setTarget("map");
  }

  addInteraction(e) {
    this.olmap.removeInteraction(this.state.draw);

    if (e.target.value === "None") {
      this.setState({ draw: null });
      return;
    }
    this.setState(
      { draw: new Draw({ source: drawSource, type: e.target.value }) },
      () => {
        this.olmap.addInteraction(this.state.draw);
      }
    );
  }

  undoLastPoint() {
    this.state.draw.removeLastPoint();
  }

  render() {
    return (
      <>
        <div id="map" style={{ width: "100%", height: "800px" }}></div>
        <form class="form-inline">
          <label for="type">Geometry type: &nbsp;</label>
          <select id="type" onChange={this.addInteraction.bind(this)}>
            <option value="None">None</option>
            <option value="Point">Point</option>
            <option value="Polygon">Polygon</option>
            <option value="Circle">Circle</option>
          </select>
          <input
            type="button"
            value="Undo last drawn point while drawing polygon. "
            id="undo"
            onClick={this.undoLastPoint.bind(this)}
          />
        </form>
      </>
    );
  }
}

export default PublicMap;
3
  • Anchor units default to fraction, try using anchor: [0.5, 1], (or specify anchorXUnits and anchorYUnits as 'pixels').
    – Mike
    Apr 21, 2021 at 9:08
  • Thank You, that's what I was looking for ! It works like a charm.
    – gikdeb
    Apr 21, 2021 at 16:40
  • @Mike, please post Your answer here so I can accept it.
    – gikdeb
    Apr 21, 2021 at 16:51

1 Answer 1

1

Either the anchor should be specified as fractions of the image size (the default option)

      image: new Icon({
        anchor: [0.5, 1],
        imgSize: [32, 48],
        src: "https://openlayers.org/en/v3.20.1/examples/data/icon.png",
      }),

or the units must be specified as pixels

      image: new Icon({
        anchor: [16, 48],
        anchorXUnits: 'pixels',
        anchorYUnits: 'pixels',
        imgSize: [32, 48],
        src: "https://openlayers.org/en/v3.20.1/examples/data/icon.png",
      }),

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.