Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleMaps API V3 Build Polygon Containing Multiple ZipCodes

I have to allow a user to input multiple zip codes, retrieve the latitude and longitude from a database and then build a huge polygon that encompasses them.

I'm coding in Java and using Google Maps API V3. I have no problem doing a single zip code build. But upon adding more zip codes the polylines that are generated go hay-wire and distort the polygon, as pictured below. fussy google map polygon

What do I need to change in my code to make all these smaller polygons into one larger one? I've scoured Google for answers and all I've managed to come across is building each zip code's polygon individually but that still won't give me a end result of a larger, single polygon.

Currently, after the zip codes are inputted the program collects the lat and long points from the database and feeds them into a giant array of arrays (a String[][] to be exact), which is then passed the the html and javascript to generate the resulting polygon.

My javascript is highly similar to the GoogleMaps API V3 simple polygon example:

function clearHello(coords1){
coords = coords1
var triangleCoords = new Array();
var l = coords.length;
for (var x = 0; x < l; x++){
triangleCoords[x] = new google.maps.LatLng( coords[x][0], coords[x][1]);
}
// Construct the polygon.
bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(document.map);

Suggestions? Is there a code technique out there that will take my giant array and then remove the interior points that appear to be the cause of this distortion?

EDIT: Wondering about a different approach, does anyone know of a way to remove the interior lines that creating the bizarre trapezoid thing so that the zipcode polygon can fill in properly? I know I can make them transparent, but that doesn't stop the distortion of the polygon. Also simply managing it as a few polygons that I populate won't work as this program needs to be able to handle up to 200 zip codes worth of coordinates at a time.

like image 445
senex_subconscious Avatar asked Feb 12 '23 19:02

senex_subconscious


1 Answers

It sounds like you're wanting to remove shared boundaries and create a kind of macro object. In the land of Geographic Information Systems (GIS), this sort of operation is called known as "Dissolve". You can combine two 3rd-party libraries to do what you want exclusively in JavaScript code.

How to do a GIS Dissolve in JavaScript

You can combine both the Wicket and the JavaScript Topology Suite (JSTS) libraries to perform a Union/Dissolve operation and derive a single polygon geometry with a united outer boundary.

In simple terms, Wicket will handle going to and from your Google Maps Polygon objects to Well Known Text (WKT) geometry expressions, and the JSTS can then do a union/dissolve operation using the WKT.

Preliminary steps: Download the two libraries and reference them in your project.

1) First download the JSTS library, unzip it, browse into the lib folder, and include the two lib files (javascript.util.js, and jsts.js) in your project. I copied mine into a separate jsts folder and referenced them in my project like this..

<script type="text/javascript" src="jsts/javascript.util.js"></script>
<script type="text/javascript" src="jsts/jsts.js"></script>

2) Next download the Wicket library, unzip it, and include wicket.js and wicket-gmap3.js in your project. Similarly, I copied mine into a separate wicket folder and referenced them like this..

<script type="text/javascript" src="wicket/wicket.js"></script>
<script type="text/javascript" src="wicket/wicket-gmap3.js"></script>

Use Wicket to get the Polygon WKT geometries, then use JSTS to perform a Dissolve operation.

3) Unite these two libraries to get Well Known Text geometries from Wicket, and perform a Dissolve operation with JSTS.

My demo assumes two Google polygon objects were already instantiated and were passed into the method—polygon1 and polygon2. Obviously this is intended to be a simple example, so you'll need to modify it for more elaborate operations.

function DissolveTwoGeometriesWithJSTS(polygon1, polygon2)
{
    // Instantiate Wicket
    var wicket = new Wkt.Wkt();

    wicket.fromObject(polygon1);  // import a Google Polygon
    var wkt1 = wicket.write();    // read the polygon into a WKT object

    wicket.fromObject(polygon2);  // repeat, creating a second WKT ojbect
    var wkt2 = wicket.write();

    // Instantiate JSTS WKTReader and get two JSTS geometry objects
    var wktReader = new jsts.io.WKTReader();
    var geom1 = wktReader.read(wkt1);
    var geom2 = wktReader.read(wkt2);

    // In JSTS, "union" is synonymous with "dissolve"
    var dissolvedGeometry = geom1.union(geom2);

    // Instantiate JSTS WKTWriter and get new geometry's WKT
    var wktWriter = new jsts.io.WKTWriter();
    var wkt = wktWriter.write(dissolvedGeometry);

    // Reuse your Wicket object to ingest the new geometry's WKT
    wicket.read(wkt);

    // Assemble your new polygon's options, I used object notation
    var polyOptions = {
        strokeColor: '#1E90FF',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#1E90FF',
        fillOpacity: 0.35    
    };

    // Let wicket create a Google Polygon with the options you defined above
    var newPoly = wicket.toObject(polyOptions);        

    // Now I'll hide the two original polygons and add the new one.
    polygon1.setMap(null);
    polygon2.setMap(null);

    newPoly.setMap(map);
}

Here's what basically happened. Before executing the code..

enter image description here

and after..

enter image description here

like image 119
elrobis Avatar answered Feb 15 '23 11:02

elrobis