skip to Main Content

I am using Openlayers to create maps in a Vite React Typescript project. I am creating two maps and setting them to div elements like this:

const mapRef1 = useRef<HTMLDivElement>(null)
const mapRef2 = useRef<HTMLDivElement>(null)

useEffect(()=>{
 
  if(!mapRef1.current) return
  const map1 = new Map({
     target: mapRef1.current
  )}

  if(!mapRef2.current) return
  const map2 = new Map({
     target: mapRef2.current
  )}
},[])

return (
  <div style={{width:'100%', height:'100%'}}>
    <div ref = {mapRef1} style={{width:'100%', height:'100%'}}></div>
    <div ref = {mapRef2} style={{width:'100%', height:'100%'}}></div>
  </div>
)

However, while both maps seem to appear on the screen, only one of them shows the actual map and one is just blank.

I am using Openlayers 7.4, React 18.2, Tailwind 3.3.2.

I have tried to set the target as plain text string, like target: "map1" and set the but not help.

2

Answers


  1. Let’s go through your code step by step and address these issues:

    1. Typo: In your code, you have defined mapRef1 and mapRef2 as refs,
      but you are checking mapRef.current in your useEffect. You should be
      checking mapRef1.current and mapRef2.current.

    2. Missing dependencies: In your useEffect, you are checking for
      mapRef.current, but this condition should check mapRef1.current and
      mapRef2.current respectively.

    3. Incorrect condition: You are checking if (!mapRef.current) twice in
      your useEffect. This condition should only be checked once before
      creating each map.

    I hope incorporating these little changes will work for you

    Login or Signup to reply.
  2. Fix 1: Consider giving a fixed height and width to both individually, width and height 100%, can have a different layout considering the HTML they are encapsulated in.

    <div ref={mapRef1} className="w-full h-64"></div>
    <div ref={mapRef2} className="w-full h-64"></div>
    

    Fix 2: Consider adding a view to both of them you can also have different views for them, which you can create using OSM,XYZ or any other class.

    useEffect(() => {
      if (!mapRef1.current || !mapRef2.current) return;
    
      const view = new View({
        center: [0, 0], // Longitude, Latitude
        zoom: 2
      });
    
      const osmLayer = new TileLayer({ source: new OSM() });
    
      const map1 = new Map({
        target: mapRef1.current,
        layers: [osmLayer],
        view: view
      });
    
      const map2 = new Map({
        target: mapRef2.current,
        layers: [osmLayer],
        view: view.clone()  // Clone the view so each map has its own instance
      });
    }, []);
    

    FIX 3: Update Map Size: After creating the map, you might need to force the map to update its size. Sometimes, the map doesn’t correctly render the first time due to the container size not being determined yet or other rendering delays.

    Run this effect after the useEffect with [] dependency array has run

    map1.updateSize();
    map2.updateSize();
    

    Let me know which one works, in the comments.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search