Ryan
Ryan

Reputation: 95

Loading holes in polygons with "addfeature"

I have a map editor that lets the user draw and modify polygons. Polygons can be drawn inside polygons to create "holes."

The problem I am facing is after drawing inside polygon's on the map and saving the map data--the map becomes mangled on page refresh. The map does not show the original shape even though the GeoJSON is correct. I suspect the addfeature event is not handling inner and outer polygon's properly.

How can I fix addfeature to properly display the saved map data?

Expected output:

Holes

Actual output:

No Holes

Update: I have tried this and it partially works but it cuts polygon data off. I added another layer to see the original shape:

//When the data is loaded from the geojson it is processed here
map.data.addListener('addfeature', function(e) {
    //center map
    processPoints(e.feature.getGeometry(), bounds.extend, bounds);
    map.fitBounds(bounds);

    //check for polygon in case we do other shapes
    if (e.feature.getGeometry().getType() == "Polygon") {

        // lat/lng array
        let _map_d = []

        e.feature.getGeometry().forEachLatLng(function(latLngArry) {
            // populate array
            _map_d.push(latLngArry);
        });

        //Create a polygon with the lat long array
        let polygon = new google.maps.Polygon({
            map: map,
            paths: _map_d,
            fillColor: '#0099FF',
            fillOpacity: 0.7,
            strokeColor: '#AA2143',
            strokeWeight: 2
        });
        console.log("Added Polygon");

        /*
         * Debug to visualize where the rest of the shape data is
         */
        let poly = new google.maps.Polygon({
            path: e.feature.getGeometry().getAt(0).getArray(),
            strokeWeight: 1,
            map: map
        });
        console.log("Added debug overlay -- click to remove")


        //This layer is on top of the previous polygon so click it to remove
        google.maps.event.addListener(poly, 'click', function() {
            this.setMap(null);
        });

        google.maps.event.addListener(polygon, 'click', function() {
            setSelection(polygon)
        });

        all_overlays.push(polygon);
    }
});

Fiddle Snippet: https://jsfiddle.net/dizzled/b1ste57L/

Notes: Draw a shape and draw inside of the shape to draw "holes". Click export and reload the page to see the geoJSON data from localstorage. You can verify the geoJSON data is correct using https://geojson.io/

Upvotes: 5

Views: 381

Answers (1)

kendavidson
kendavidson

Reputation: 1460

When you're using the forEachLatLng() on the first getGeometry() you're adding all the LatLngs to the same array. For example I have this GEOJSON:

{
    "type":"FeatureCollection",
    "features": [
        {
            "type":"Feature",
            "geometry":{
                "type":"Polygon",
                "coordinates":[
                    [
                        [-113.2140804426134,42.406463321445244],
                        [-112.9504085676134,34.83098366669799],
                        [-99.2834163801134,34.06999699181644],
                        [-99.1515804426134,42.50373270999573],
                        [-113.2140804426134,42.406463321445244]
                    ],[
                        [-102.3156429426134,40.763110054579435],
                        [-102.3156429426134,36.36738072363568],
                        [-109.7863460676134,37.421696297537714],
                        [-109.3908382551134,40.763110054579435],
                        [-102.3156429426134,40.763110054579435]
                    ]
                ]
            },
            "properties":{}
        }
    ]
}

The current code you have there is building the array of points:

                    [
                        [-113.2140804426134,42.406463321445244],
                        [-112.9504085676134,34.83098366669799],
                        [-99.2834163801134,34.06999699181644],
                        [-99.1515804426134,42.50373270999573],
                        [-113.2140804426134,42.406463321445244]
                        [-102.3156429426134,40.763110054579435],
                        [-102.3156429426134,36.36738072363568],
                        [-109.7863460676134,37.421696297537714],
                        [-109.3908382551134,40.763110054579435],
                        [-102.3156429426134,40.763110054579435]
                    ]

Which gives you a single polygon with some stuff going on. When you take the getGeometry() and go into the array within it (probably want to check some stuff for safety) you'll build the correct [][] which can be passed into the map.Polygon():

            // lat/lng array
            let _map_d = [];
                        
            // Need to loop through the Array within the Geometry
            e.feature.getGeometry().getArray().forEach(function(latLngArry) {               
                    // And add each of those LatLng to the appropriate array
                    let currPoly = [];
                    latLngArry.forEachLatLng(function(latLng) {
                    currPoly.push(latLng);
                })
                _map_d.push(currPoly);
            });

results in

_map_d 
(2) [Array(4), Array(4)]
0: (4) [_.J, _.J, _.J, _.J]
1: (4) [_.J, _.J, _.J, _.J]
length: 2
__proto__: Array(0)

Upvotes: 2

Related Questions