-3

We are using following code and toggling polygons. If we click multiple times this is not working. From fourth time this is getting drawn again and again and the shape becomes white. Please help.

We are storing polygon coordinates in a hidden textbox and passing them to the function ‘displaypolygons’. Actually we will be having more polygons and they will come from DB. In this sample code we have shown only one. Here 142 is the incremental value which incremented using loop.

<input class="cbarea" type="checkbox" name="cb_142" id="cb_142" onclick="javascript:displaypolygons('142')"> <input type="hidden" name="latlon_142" id="latlon_142" value="(11.050885924877363,77.04118423201588),(11.050885924877363,77.04342655875233),(11.048769408381661,77.04341582991627),(11.049074777375772,77.04037956931141)"> <input type="hidden" name="area_142" id="area_142" value="A Area">

Here we are pushing the polygon coordinates to ‘gpolygons’ global array. Here we are assigning unique id using the incremental value.

<script>
function displaypolygons(ai) {
        var sel_latlon= document.getElementById("latlon_"+ai).value;
        document.getElementById("coords").value = sel_latlon;
        var sel_latlon = sel_latlon.replaceAll("(", "");
        var latlon = sel_latlon.split("),");
        var mid = parseInt(latlon.length/2); var cent = latlon[mid].split(","); 
        var peditable = false; 

        var cbchecked = $('#cb_' + ai).is(":checked")
        if (!cbchecked) return togglePolygon(ai);
        
        //if (ai==3) peditable = true;
        
        const triangleCoords = []; //var idx =0;
        for(var i=0; i<latlon.length; i++){ 
          var arr = latlon[i].split(",");
          triangleCoords.push(new google.maps.LatLng({lat: parseFloat(arr[0]), lng: parseFloat(arr[1])}, true));
        } 
     
        bounds = new google.maps.LatLngBounds();
        for (i = 0; i < triangleCoords.length; i++) {
        bounds.extend(triangleCoords[i]);
        }
        
        // Construct the polygon.
        bermudaTriangle = new google.maps.Polygon({
          _uniqueId: ai,    
          paths: triangleCoords,
          strokeWeight: 2,
          fillOpacity: 0.45,
          fillColor: '#ffffff',
          strokeColor: '#ffffff',
          editable:peditable,
          draggable:false
        });
        bermudaTriangle.setMap(map);
        gpolygons.push(bermudaTriangle);
        
        map.setCenter(new google.maps.LatLng(bounds.getCenter()), 4);
        var area_lbl= document.getElementById("area_"+ai).value;

        var mapLabel = new MapLabel({
            text: area_lbl+" (Id: "+ai+" )",
            position: new google.maps.LatLng(bounds.getCenter()),
            map: map,
            fontSize: 14,
            align: 'center'
        });
        labelObjects.push(mapLabel);
};

google.maps.event.addDomListener(window,"load", initMap);
</script>

Then using toggle function we are toggling the polygons. We are looping through the ‘gpolygons’ array and based on the matching unique id we are displaying /hiding

<script>
function togglePolygon(id) {
  for (var i = 0; i < gpolygons.length; i++) {
    if (gpolygons[i]._uniqueId == id) {
      if (gpolygons[i].getMap() != null) {
        gpolygons[i].setMap(null);
      } else {
        gpolygons[i].setMap(map);
      }
      
      labelObjects[i].setMap((labelObjects[i].getMap())?null:mymap)
    }
  }
  
}
</script>
  • 1
    How are you generating the HTML elements with hidden inputs containing all the coordinates for the polygon? Does that all come from a database? – Professor Abronsius Nov 14 '22 at 08:40
  • Yes. All come from Database – Shanthini Priyadharsini G Nov 14 '22 at 08:58
  • Rather than the complicated approach chosen here it would likely be easier to simply process a JSON object? – Professor Abronsius Nov 14 '22 at 09:08
  • Are you telling like fetch JASON data from MySQL DB. If you have any sample could you please share. If not I will try. My requirement to create and edit polygons. The crated polygon coordinates will be available in DB. During this process users can view the saved needed polygons to check if there are any overlaps. – Shanthini Priyadharsini G Nov 14 '22 at 10:27
  • Yes. Rather than query db and writing out loads of `input` elements ( 3 per polygon as per the example ) you would store the query result as json and create a Javascript variable with that data. You then iterate through that json data to build all the polygons – Professor Abronsius Nov 14 '22 at 14:35
  • I have one more question. I need to find if one polygon overlaps with others. For that I can take a polygon's coordinates one by one and can check if that come inside others by looping through the list of polygons. Instead of that do we have any other simple method. Could you please suggest. Thanks. – Shanthini Priyadharsini G Nov 15 '22 at 10:01
  • potentially all polygons could intersect - in which case this task becomes even harder. I do not know of any native methods nor can make any recommendations but [perhaps this might be of interest](https://stackoverflow.com/questions/24504068/how-to-show-the-intersecting-area-of-two-polygons-on-google-maps) – Professor Abronsius Nov 15 '22 at 13:01
  • Thanks for your reply. Can we find the intersecting area without plotting like just having the coordinates in array. If you have any idea could you please suggest. Also could you please suggest will intersects method available in LatLngBounds class will work (https://developers.google.com/maps/documentation/javascript/reference/coordinates#LatLngBounds). I searched not able to find proper sample – Shanthini Priyadharsini G Nov 15 '22 at 15:57

1 Answers1

1

Rather than looping through all polygons stored in the global gpolygons array - if that were an Object Literal instead you could very quickly access the individual polygon references. That global could store both the polygon and the MapLabel references using a common ID - namely that of the input elements ( ie:cb_142 etc )

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Google Maps: Toggle Polygons...</title>
        <style>
            body{
                padding:0;
                margin:0;
                width:100%;
                height:100vh;
            }
            #map{
                width:100%;
                height:600px;
            }
        </style>
    </head>
    <body>
        <div id='map'></div>
        <form name='poly'>
        
            <input type='text' id='coords' />
            
            <!-- more before -->
            
            <input class='cbarea' type='checkbox' name='cb' data-id=142 />
            <input type='hidden' name='area'  data-id=142 value='A Area' />
            <input type='hidden' name='latlon'  data-id=142 value='
                (11.050885924877363,77.04118423201588),
                (11.050885924877363,77.04342655875233),
                (11.048769408381661,77.04341582991627),
                (11.049074777375772,77.04037956931141)' 
            />
            
            <input class='cbarea' type='checkbox' name='cb' data-id=143 />
            <input type='hidden' name='area'  data-id=143 value='B Area' />
            <input type='hidden' name='latlon'  data-id=143 value='
                (11.060885924877363,77.05118423201588),
                (11.060885924877363,77.05342655875233),
                (11.068769408381661,77.05341582991627),
                (11.069074777375772,77.05037956931141)' 
            />
            
            <input class='cbarea' type='checkbox' name='cb' data-id=144 />
            <input type='hidden' name='area'  data-id=144 value='C Area' />
            <input type='hidden' name='latlon'  data-id=144 value='
                (11.070885924877363,77.06118423201588),
                (11.070885924877363,77.06342655875233),
                (11.078769408381661,77.06341582991627),
                (11.079074777375772,77.06037956931141)' 
            />
            
            <!-- and repeat for all others -->
            
            
        </form>
        <script>
            const d=document;
            
            class MapLabel{// no idea what this is....
                constructor(args){
                    return Object.assign({
                    
                    },args);
                }
            }
            
            
            
            function initMap(){
            
                let polygons={
                    polys:{},
                    labels:{}
                };
                let coords=d.querySelector('#coords');
                
                const map = new google.maps.Map( document.querySelector('div#map'), {
                    zoom: 3,
                    center: { lat:0, lng:0 }
                });
                
                d.forms.poly.addEventListener('change',e=>{
                    if( e.target instanceof HTMLInputElement && e.target.type=='checkbox' ){
                        
                        
                        let id=e.target.dataset.id;
                        let area=d.querySelector(`input[name="area"][data-id="${id}"]`);
                        let latlon=d.querySelector(`input[name="latlon"][data-id="${id}"]`);
                        
                        coords.value=latlon.value;
                        
                        if( !polygons.polys.hasOwnProperty( id ) ){
                            let path=[];
                            let bounds = new google.maps.LatLngBounds();
                            
                            let pairs=latlon.value.replace(/[\(\)\t]/g,'').trim().split(',');
                            for( let i=0; i < pairs.length; i+=2 ){
                                let lat=pairs[i];
                                let lng=pairs[i+1];
                                let latlng=new google.maps.LatLng(lat,lng);
                                
                                path.push( latlng );
                                bounds.extend( latlng );
                            }
                            
                            // only green so that it is easily visible!!!
                            let poly=new google.maps.Polygon({
                                _uniqueId: id,    
                                paths: path,
                                strokeWeight: 2,
                                fillOpacity: 0.45,
                                fillColor: '#00ff00',
                                strokeColor: '#000000',
                                editable:e.target.checked,
                                draggable:false
                            });
                            
                            let label=new MapLabel({
                                text: `area_lbl ( Id: ${id} )`,
                                position: new google.maps.LatLng( bounds.getCenter() ),
                                map: map,
                                fontSize: 14,
                                align: 'center'
                            });
                            
                            poly.setMap( map );     
                            
                            polygons.polys[ id ]=poly;
                            polygons.labels[ id ]=label;
                            
                            map.fitBounds( bounds );
                        }else{
                            polygons.polys[ id ].setMap( e.target.checked ? map : null  );
                            //polygons.labels[ id ].setMap( e.target.checked ? map : null );
                        }
                    }
                })
            }
        </script>
        <script async defer src='//maps.googleapis.com/maps/api/js?key=KEY&callback=initMap'></script>
    </body>
</html>

Proof of concept

Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46