OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Google map with zones on top of province, some are opaque some are transparent

  • Thread starter Thread starter Anders Kitson
  • Start date Start date
A

Anders Kitson

Guest
I have built this interactive zone mapping on top of a province, and it is supposed to cut out the polygons laid on the map from an overlayPolygon that has larger outerbounds so the map is seen through only where the polygons are drawn and everything else is white.

It is mostly working but some of the zones show opaque colors not the transparency to the map, and I can't figure out why. I noticed if I change the outerBounds to something like this

Code:
const outerBounds = [
    new google.maps.LatLng(70, -140),
    new google.maps.LatLng(70, -60),
    new google.maps.LatLng(45, -60),
    new google.maps.LatLng(45, -140),
    new google.maps.LatLng(70, -140)
];

It would show the zones that were opaque as transparent but the other zones would be opaque which is not the desired effect they should all be transparent.

I did try and make sure that none of the polygons overlap and seem to have double checked that if you zoom in.

Here is a https://codesandbox.io/p/sandbox/quirky-heyrovsky-zkk5p7 of it's current state.

You will see that 5, 9, 8 & 2 in the map are opaque when they should be transparent.

map diagram

And here is the code minus the data

Code:
const mapOptions = {
      zoom: 5,
      center: { lat: 53.7267, lng: -126.6476 }, // Centered on BC
      mapTypeId: "terrain",
      // zIndex: 100,
      // disableAutoPan: true,
      mapTypeControl: false, // Disable map and satellite options
      fullscreenControl: false, // Disable fullscreen control
      //   streetViewControl: false, // Disable street view control
      // zoomControl: false,       // Disable zoom control
      scrollwheel: false, // Disable mouse scroll zoom
      styles: [
        {
          featureType: "all",
          elementType: "all",
          stylers: [
            { saturation: -100 }, // This makes the map greyscale
          ],
        },
        {
          featureType: "administrative.province",
          elementType: "labels",
          stylers: [{ visibility: "off" }],
        },
      ],
    };

    const map = new google.maps.Map(document.getElementById("map"), mapOptions);

    // Add the overlay that covers the entire map
    const outerBounds = [
      new google.maps.LatLng(85, 180),
      new google.maps.LatLng(85, 90),
      new google.maps.LatLng(85, 0),
      new google.maps.LatLng(85, -90),
      new google.maps.LatLng(85, -180),
      new google.maps.LatLng(0, -180),
      new google.maps.LatLng(-85, -180),
      new google.maps.LatLng(-85, -90),
      new google.maps.LatLng(-85, 0),
      new google.maps.LatLng(-85, 90),
      new google.maps.LatLng(-85, 180),
      new google.maps.LatLng(0, 180),
      new google.maps.LatLng(85, 180),
    ];

    //   const outerBounds = [
    //     new google.maps.LatLng(70, -140),
    //     new google.maps.LatLng(70, -60),
    //     new google.maps.LatLng(45, -60),
    //     new google.maps.LatLng(45, -140),
    //     new google.maps.LatLng(70, -140)
    // ];

    const overlayPolygon = new google.maps.Polygon({
      paths: [outerBounds],
      strokeColor: "#000000",
      strokeOpacity: 0.0,
      strokeWeight: 0,
      fillColor: "#FFFFFF",
      fillOpacity: 1.0,
      zIndex: -100,
    });

    overlayPolygon.setMap(map);

    addEcoZones();

    // Function to calculate the centroid of a polygon
    function calculateCentroid(path) {
      let lat = 0,
        lng = 0;
      path.forEach((point) => {
        lat += point.lat();
        lng += point.lng();
      });
      lat /= path.length;
      lng /= path.length;
      return new google.maps.LatLng(lat, lng);
    }

    // Function to fetch and display eco zones
    function addEcoZones() {
      // Assuming you have a global variable with eco zones data for BC
      // Assuming you have a global variable with eco zones data for BC
      for (let index = 0; index < ecoZonesData.length; index++) {
        const zone = ecoZonesData[index];

        console.log("zone.ecoprovince_number", zone.ecoprovince_number);

        console.log("zone", zone);

        const zoneCoordinates = zone.coordinates.map(
          (coord) => new google.maps.LatLng(coord.lat, coord.lng)
        );

        // Define the polygon for the eco zone
        const ecoZonePolygon = new google.maps.Polygon({
          paths: zoneCoordinates,
          // strokeColor: indexTitle !== -1 && title ? zoneCoords[index]?.ecoprovince_color : !ecoZonesData[index].related ? '#003D4C' : zoneCoords[index].ecoprovince_color,
          strokeOpacity: 1,
          strokeWeight: 3,
          fillColor: zone.ecoprovince_color,
          fillOpacity: 0,
          // zIndex: 2000
        });

        ecoZonePolygon.setMap(map);

        // console.log("zone", zone)

        // Add the eco zone coordinates as a hole in the overlayPolygon
        let paths = overlayPolygon.getPaths();
        // Simplify coordinates for testing
        console.log("Before push paths:", zone);
        paths.push(new google.maps.MVCArray(zoneCoordinates));
        overlayPolygon.setPaths(paths);

        // Calculate the centroid of the polygon
        const centroid = calculateCentroid(zoneCoordinates);

        console.log("zone", zone);

        // Add a marker or label at the centroid
        const marker = new google.maps.Marker({
          position: centroid,
          map: map,
          label: {
            text: zone.ecoprovince_number.toString(),
            color: "#003D4C",
            fontSize: "16px",
            fontWeight: "bold",
          },
          icon: {
            path: google.maps.SymbolPath.CIRCLE,
            scale: 8.5,
            fillColor: "#FFF",
            fillOpacity: 1,
            strokeWeight: 0,
          },
        });

        // Add mouseover event listener for the polygon
        ecoZonePolygon.addListener("mouseover", function (event) {
          const hoverBoolColor =
            ecoZonesData[index].related &&
            indexTitle === -1 &&
            ecoZonesData[index].species;

          ecoZonePolygon.setOptions({
            fillColor: zone.ecoprovince_color,
            fillOpacity: 1, // You can also adjust the fill opacity if needed
          });
        });

        // Add mouseout event listener for the polygon to reset the fill color
        ecoZonePolygon.addListener("mouseout", function (event) {
          // Reset the fill color of the polygon

          //console.log("ecoZonesData[index].related", ecoZonesData[index].related)
          //console.log("indexTitle", indexTitle)
          //console.log("zoneCoords[index].species", ecoZonesData[index].species)
          //console.log("zoneCoords[index].species", ecoZonesData[index].species)

          switch (true) {
            default:
              ecoZonePolygon.setOptions({
                fillColor: zone.ecoprovince_color,
              });
          }

          // const hoverBoolColor = !ecoZonesData[index].related && indexTitle !== -1 && ecoZonesData[index].species;

          ecoZonePolygon.setOptions({
            fillOpacity: 0.35, // Reset the fill opacity if needed
            // fillColor: hoverBoolColor ? "#000" : zoneCoords[index]?.ecoprovince_color,
          });
        });
      }
    }

<p>I have built this interactive zone mapping on top of a province, and it is supposed to cut out the polygons laid on the map from an overlayPolygon that has larger outerbounds so the map is seen through only where the polygons are drawn and everything else is white.</p>
<p>It is mostly working but some of the zones show opaque colors not the transparency to the map, and I can't figure out why. I noticed if I change the outerBounds to something like this</p>
<pre><code>const outerBounds = [
new google.maps.LatLng(70, -140),
new google.maps.LatLng(70, -60),
new google.maps.LatLng(45, -60),
new google.maps.LatLng(45, -140),
new google.maps.LatLng(70, -140)
];
</code></pre>
<p>It would show the zones that were opaque as transparent but the other zones would be opaque which is not the desired effect they should all be transparent.</p>
<p>I did try and make sure that none of the polygons overlap and seem to have double checked that if you zoom in.</p>
<p>Here is a <a href="https://codesandbox.io/p/sandbox/quirky-heyrovsky-zkk5p7" rel="nofollow noreferrer">https://codesandbox.io/p/sandbox/quirky-heyrovsky-zkk5p7</a> of it's current state.</p>
<p>You will see that 5, 9, 8 & 2 in the map are opaque when they should be transparent.</p>
<p><a href="https://i.sstatic.net/fSYDD36t.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/fSYDD36t.png" alt="map diagram" /></a></p>
<p>And here is the code minus the data</p>
<pre><code>const mapOptions = {
zoom: 5,
center: { lat: 53.7267, lng: -126.6476 }, // Centered on BC
mapTypeId: "terrain",
// zIndex: 100,
// disableAutoPan: true,
mapTypeControl: false, // Disable map and satellite options
fullscreenControl: false, // Disable fullscreen control
// streetViewControl: false, // Disable street view control
// zoomControl: false, // Disable zoom control
scrollwheel: false, // Disable mouse scroll zoom
styles: [
{
featureType: "all",
elementType: "all",
stylers: [
{ saturation: -100 }, // This makes the map greyscale
],
},
{
featureType: "administrative.province",
elementType: "labels",
stylers: [{ visibility: "off" }],
},
],
};

const map = new google.maps.Map(document.getElementById("map"), mapOptions);

// Add the overlay that covers the entire map
const outerBounds = [
new google.maps.LatLng(85, 180),
new google.maps.LatLng(85, 90),
new google.maps.LatLng(85, 0),
new google.maps.LatLng(85, -90),
new google.maps.LatLng(85, -180),
new google.maps.LatLng(0, -180),
new google.maps.LatLng(-85, -180),
new google.maps.LatLng(-85, -90),
new google.maps.LatLng(-85, 0),
new google.maps.LatLng(-85, 90),
new google.maps.LatLng(-85, 180),
new google.maps.LatLng(0, 180),
new google.maps.LatLng(85, 180),
];

// const outerBounds = [
// new google.maps.LatLng(70, -140),
// new google.maps.LatLng(70, -60),
// new google.maps.LatLng(45, -60),
// new google.maps.LatLng(45, -140),
// new google.maps.LatLng(70, -140)
// ];

const overlayPolygon = new google.maps.Polygon({
paths: [outerBounds],
strokeColor: "#000000",
strokeOpacity: 0.0,
strokeWeight: 0,
fillColor: "#FFFFFF",
fillOpacity: 1.0,
zIndex: -100,
});

overlayPolygon.setMap(map);

addEcoZones();

// Function to calculate the centroid of a polygon
function calculateCentroid(path) {
let lat = 0,
lng = 0;
path.forEach((point) => {
lat += point.lat();
lng += point.lng();
});
lat /= path.length;
lng /= path.length;
return new google.maps.LatLng(lat, lng);
}

// Function to fetch and display eco zones
function addEcoZones() {
// Assuming you have a global variable with eco zones data for BC
// Assuming you have a global variable with eco zones data for BC
for (let index = 0; index < ecoZonesData.length; index++) {
const zone = ecoZonesData[index];

console.log("zone.ecoprovince_number", zone.ecoprovince_number);

console.log("zone", zone);

const zoneCoordinates = zone.coordinates.map(
(coord) => new google.maps.LatLng(coord.lat, coord.lng)
);

// Define the polygon for the eco zone
const ecoZonePolygon = new google.maps.Polygon({
paths: zoneCoordinates,
// strokeColor: indexTitle !== -1 && title ? zoneCoords[index]?.ecoprovince_color : !ecoZonesData[index].related ? '#003D4C' : zoneCoords[index].ecoprovince_color,
strokeOpacity: 1,
strokeWeight: 3,
fillColor: zone.ecoprovince_color,
fillOpacity: 0,
// zIndex: 2000
});

ecoZonePolygon.setMap(map);

// console.log("zone", zone)

// Add the eco zone coordinates as a hole in the overlayPolygon
let paths = overlayPolygon.getPaths();
// Simplify coordinates for testing
console.log("Before push paths:", zone);
paths.push(new google.maps.MVCArray(zoneCoordinates));
overlayPolygon.setPaths(paths);

// Calculate the centroid of the polygon
const centroid = calculateCentroid(zoneCoordinates);

console.log("zone", zone);

// Add a marker or label at the centroid
const marker = new google.maps.Marker({
position: centroid,
map: map,
label: {
text: zone.ecoprovince_number.toString(),
color: "#003D4C",
fontSize: "16px",
fontWeight: "bold",
},
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 8.5,
fillColor: "#FFF",
fillOpacity: 1,
strokeWeight: 0,
},
});

// Add mouseover event listener for the polygon
ecoZonePolygon.addListener("mouseover", function (event) {
const hoverBoolColor =
ecoZonesData[index].related &&
indexTitle === -1 &&
ecoZonesData[index].species;

ecoZonePolygon.setOptions({
fillColor: zone.ecoprovince_color,
fillOpacity: 1, // You can also adjust the fill opacity if needed
});
});

// Add mouseout event listener for the polygon to reset the fill color
ecoZonePolygon.addListener("mouseout", function (event) {
// Reset the fill color of the polygon

//console.log("ecoZonesData[index].related", ecoZonesData[index].related)
//console.log("indexTitle", indexTitle)
//console.log("zoneCoords[index].species", ecoZonesData[index].species)
//console.log("zoneCoords[index].species", ecoZonesData[index].species)

switch (true) {
default:
ecoZonePolygon.setOptions({
fillColor: zone.ecoprovince_color,
});
}

// const hoverBoolColor = !ecoZonesData[index].related && indexTitle !== -1 && ecoZonesData[index].species;

ecoZonePolygon.setOptions({
fillOpacity: 0.35, // Reset the fill opacity if needed
// fillColor: hoverBoolColor ? "#000" : zoneCoords[index]?.ecoprovince_color,
});
});
}
}

</code></pre>
 
Top