0

I am creating a dot density map with random distribution to represent the population per county. Right now, essentially what I am doing is taking the maximum latitude and longitude values of a county, picking two random numbers between them, and testing against the bounds of the polygon that outlines the county to see if it falls within it. If it does, I add it to the map and if it doesn't, I go back and try again. This runs many thousands of times so the misses really hurt loading time. I would really like to figure out a way to draw within the bounds rather than pick a random point, test it, and then draw it. I don't even fully understand how my testing algorithm works as I borrowed the code from this awesome answer so I am in over my head at this point, but I thought it might be a fun challenge for some of you.

Here is the code that I am using:

function addMarkers() {
        var loc = "Resources/Counties.json";

        $.getJSON(loc, function (data) {
            $.each(data.features, function (key, val) {

                var xArray = []; //
                var yArray = []; //

                var coords = [];
                var latlng;
                var bounds = new google.maps.LatLngBounds();
                var polygon;

                $.each(val.geometry.coordinates[0], function (i, item) {
                    latlng = new google.maps.LatLng(item[1], item[0]);
                    xArray.push(item[0]); //
                    yArray.push(item[1]); //
                    coords.push(latlng);
                    bounds.extend(latlng);
                });

                var nverts = xArray.length; //
                var maxX = Math.max.apply(null, xArray);  //
                var maxY = Math.max.apply(null, yArray);  //
                var minX = Math.min.apply(null, xArray);  //
                var minY = Math.min.apply(null, yArray);  //

                polygon = new google.maps.Polygon({
                    paths: coords,
                    strokeColor: "#000000",
                    strokeOpacity: 1,
                    strokeWeight: 01,
                    fillColor: "#cccccc",
                    fillOpacity: .5
                });

                polygon.setMap(map);

                var i = 1;
                while( i < populations[val.properties.Name] / 10000){
                    var testX = Math.random() * (maxX - minX) + minX; //
                    var testY = Math.random() * (maxY - minY) + minY; //

                    if(pnpoly(nverts, xArray, yArray, testX, testY) == 1){  //
                        var mlatlng = new google.maps.LatLng(testY, testX); //
                        var marker = new google.maps.Marker({ position: mlatlng, icon: "Resources/dot.png", map: map });   //
                        i++;
                    }
                }
            });
        });

    function pnpoly(nvert, vertx, verty, testx, testy)
    {
       var i, j, c = 0;
       for (i = 0, j = nvert-1; i < nvert; j = i++) 
       {
          if ( ((verty[i]>testy) != (verty[j]>testy)) &&
          (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
          {
             c = !c;
          }
       }
      return c;
    }
Community
  • 1
  • 1
philthyfool
  • 194
  • 2
  • 5
  • 17
  • There is a [google.maps.Polygon "containsLocation(point:LatLng, polygon:Polygon)" function](https://developers.google.com/maps/documentation/javascript/reference#poly) in the "geometry" library. – geocodezip Jan 21 '14 at 23:36
  • Thanks, I did start using that instead of the pnpoly(), however I'm really looking for something that will help me avoid creating random points and testing it against the polygon altogether. – philthyfool Jan 22 '14 at 18:10

1 Answers1

0

What I did is create a color map (colors are unique and derived from feature index) of the features to test random (bbox constrained) coordinates against. I know if the coordinate is within the feature by its color in the color map. This test is a O(1) operation, where as the code you posted is O(n). My dot density map of china counties performs fine. I started with this guy's code example:

https://gist.github.com/awoodruff/94dc6fc7038eba690f43