Rayssa Rocha
Rayssa Rocha

Reputation: 17

LEAFLET + map.fitBounds

I'm trying to make the map zoom in by clicking on the point. but for some reason I'm having the error "× Error: Bounds are not valid. ". I don't know what I'm doing wrong to be giving this error. If not, how can I do this? In the action of 'on click'. The error is on the line 152.

Explaining the screen: the screen has a map, q has some pins, when clicking on that pin the part of the screen reloaded and should start the screen already with the zoom on the pin I selected.

function MapWellscreen() {
  const mapref = useRef(null);
  const [map, setMap] = useState(null);
  const [polygon, setPolygon] = useState(null);
  const [wellheads, setWellhead] = useState([]);
  const { rootState, rootDispatch } = useRootContext();
  const { wellState, wellDispatch } = useWellContext();

  useEffect(() => {
    async function getPolygonF() {
      const getPolygon = rootState.polygonsList;
      const getWellhead = rootState.wellsList;
      const polygonModel = new Polygon(getPolygon.data);
      setPolygon(polygonModel.geoJson);
      if (wellState.selectedWell.fieldIdentifier) {
        let x = getWellhead.filter(
          (x) => x.fieldIdentifier === wellState.selectedWell.fieldIdentifier
        );
        setWellhead(x);
      } else setWellhead(getWellhead);

      const wellMap = L.map(mapref.current, {
        maxZoom: 12,
        zoomSnap: 1,
        zoomDelta: 1,
        maxBounds: L.latLngBounds([-90, -180], [90, 180]),
      }).setView([-25.7, -43.2], 6);
      setMap(wellMap);
    }

    if (rootState.polygonsList && rootState.wellsList.length) {
      getPolygonF();
    }
  }, [rootState.polygonsList, rootState.wellsList]);

  useEffect(() => {
    if (map) {
      L.tileLayer(
        'https://services.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}.png',
        {
          id: 'equinor/psa/data-inventory',
        }
      ).addTo(map);

      L.geoJSON(polygon, {
        style: function (feature) {
          return {
            stroke: true,
            fillColor: '#229922',
            color: '#229922',
            fillOpacity: 0.4,
            opacity: 1.0,
            weight: 3,
          };
        },
      })
        .bindPopup(function (layer) {
          return layer.feature.properties.name;
        })
        .addTo(map);

      L.control
        .graphicScale({
          fill: true,
          doubleLine: true,
          showSubunits: true,
          position: 'bottomright',
          labelPlacement: 'below',
          maxUnitsWidth: 160,
        })
        .addTo(map);

      const svg = d3.select(map.getPanes().overlayPane).select('svg');
      const g = svg.select('g');

      wellheads.forEach(function (d) {
        d.LatLng = new L.latLng(d.latitude, d.longitude);
      });

      const groupWells = g
        .selectAll('g')
        .data(wellheads)
        .enter()
        .append('g')
        .attr('pointer-events', 'visible');

      const points = groupWells
        .append('circle')
        .attr('class', 'black')
        .attr('id', (d) => `id-${d.wellboreGUID}`)
        .attr('r', 1.7)
        .on('click', function (d) {
          handleChangeZoom(d);
          console.log(d);
          handleSelectedWell(d);
        });

      const label = groupWells
        .append('text')
        .style('display', 'none')
        .text((d) => d.uniqueWellboreIdentifier);

      update();
      map.on('viewreset', update);
      map.on('zoom', update);
    }
  }, [map, polygon, wellheads]);

  const handleSelectedWell = (well) => {
    Promise.resolve(
      wellDispatch({
        type: 'SET_SELECTED_WELL',
        payload: { label: 'Select Well', guid: null, fieldIdentifier: null },
      })
    ).then(() => wellDispatch({ type: 'SET_SELECTED_WELL', payload: well }));
  };

  const handleChangeZoom = (well) => {
    const wellBounds = new L.latLng(well.latitude, well.longitude);
    map.fitBounds(wellBounds);
  };

  return <div ref={mapref} className="mapdiv" id="map"></div>;
}

export default MapWellscreen;

Upvotes: 0

Views: 3739

Answers (1)

Falke Design
Falke Design

Reputation: 11338

If you want to use fitBounds() you have to use L.latLngBounds. But you have to think in a rectangle. Your need two latlng points (corners).

const wellBounds = new L.latLngBounds([latlng1,latlng2]);
map.fitBounds(wellBounds);

To pan to latlng you can use map.flyTo(latlng, zoom)

Upvotes: 3

Related Questions