使用Google地图创建点密度贴图

时间:2014-01-21 00:32:56

标签: javascript json google-maps google-maps-api-3 map

我想使用Google地图创建点密度地图。我列出了我州的所有县以及相应的人口。我想知道如何在每个县内随机放置一些点来代表该县的人口。我们想制作一个点密度图而不是一个等值线图,因为我们更喜欢这种表示,但我无法弄清楚如何在多边形轮廓中分布点。

这是我想要做的一个不好的例子。

2 个答案:

答案 0 :(得分:0)

好吧,我找到了一个非常低效但又适合我的问题的解决方案。如果有人想要帮助我改进我的方法或自己使用它,这就是我所做的。

我使用this answer作为指导来测试一个点是否会落入特定的多边形。当我创建勾勒出州的边界的多边形时,我将每个纬度添加到一个数组,每个经度添加到另一个数组。然后,我将每个数组的最小值和最大值确定为一个点必须在的边界框,以便落入县行。然后我在那些分钟和最大值之间选择随机数,并测试它们是否属于该县。如果他们这样做,我在那里添加一个标记。我在循环中做那些计算添加了多少标记的循环,直到它与该特定县的人口成比例。这是代码:

function addMarkers() {
            var loc = "Resources/CaliforniaCounties.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.center = bounds.getCenter();
                    addPolygonClickListener(polygon, val);
                    polygon.setMap(map);

                    polygonArray[val.properties.Name] = polygon;


                    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;
        }

答案 1 :(得分:0)

我有更有效的方法来做到这一点。您可以使用相同的功能来创建颜色贴图,这是第二个不可见的canvas元素。在此,每个县都是从特征列表中的索引派生的唯一颜色。使用getImageData(),您可以获得画布的位图。然后,您可以通过检查该坐标处的色彩图的颜色来测试您的随机边界框约束坐标是否属于该县内。这个测试是一个O(1)操作,你的看起来像是O(n)。

我正在使用这种技术在中国创建县的点密度图,性能很好。我从这个人的代码示例开始:

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