按城市/地区分组JSON坐标



我有一个客户列表,其中包含一些销售数据和他们的坐标。我想把它显示在地图上,但我不想有10000个标记,而是想把它们分组,根据该地区的客户数量得到不同半径的圆圈。以下是我的数据集示例:

[
{
"latitude": "44.141638",
"longitude": "-149.935598",
"family_size": 1
},
{
"latitude": "44.141314",
"longitude": "-149.935556",
"family_size": 3
},
{
"latitude": "44.200873",
"longitude": "-130.025254",
"family_size": 2
},
{
"latitude": "45.202873",
"longitude": "-131.0243 54",
"family_size": 2
}
]

我的想法是从每个记录中获取纬度和经度,并使用滑块/缩放级别组合调整小数点的数量,这样当你缩小时,你会看到它们成组。例如,当您缩小前2条记录时,它将转换为:

{
"latitude": "44.141",
"longitude": "-149.935",
"family_size": 3
},
{
"latitude": "44.141",
"longitude": "-149.935",
"family_size": 1
}

然后,我将半径定义为匹配坐标下的家庭成员数,因此总共为4。

我看到了一种获取数组中唯一值计数的方法,但当需要匹配2个键/值对时,如何获取计数?

传入的数据有大约10000条记录,我希望将数据加载到浏览器中,让客户端PC处理工作负载,而不是试图用PHP/AAJAX来完成这一切,因为我希望他们能够操纵按日期、性别、收入显示的内容。。。

更新

我有一种方法在小范围内工作,但当扩大到许多记录时,有两种方法失败了。首先,由于某种原因,计数器会下降很多,其次,因为我担心以这种方式循环会非常低效。

这是我所拥有的:

function GroupXY(arr) {
var a = [],b = [],prev;
arr.sort();
for (var i = 0; i < arr.length; i++) {
if (arr[i].latitude !== prev) {
a.push(arr[i]);
}
prev = arr[i].latitude;
}
var c = [], d = [], prevL;
for (var L = 0; L < arr.length; L++) {
if (arr[L].longitude !== prevL) {
c.push(arr[L]);
}
prevL = arr[L].longitude;
}
var matches = {},
counter = [];
for (var M = 0; M < arr.length; M++) {
for (var A = 0; A < a.length; A++) {
if (isEmpty(matches[a[A].latitude])) {
matches[a[A].latitude] = {};
}
var uniqueLatitude = a[A].latitude;
if (arr[M].latitude == uniqueLatitude) {
for (var C = 0; C < c.length; C++) {
var thisLongitude = c[C].longitude;
if (arr[M].longitude === thisLongitude && arr[M].latitude == c[C].latitude) {
//Full Match
if (isEmpty(matches[uniqueLatitude])) {
matches[uniqueLatitude][thisLongitude] = arr[M].family_size;
} else {
matches[uniqueLatitude][thisLongitude] = matches[uniqueLatitude][thisLongitude] + arr[M].family_size;
}
} else {
}
}
} else {}
}
}
}

以下是它与数据的关系:https://jsfiddle.net/xpvt214o/450422/

虽然它一次处理了5条记录,但当我试图给它提供5000条记录时,它完全冻结了浏览器,并开始给出类似40000的疯狂family_size结果。

似乎对XY坐标进行分组是javascript擅长的事情,并且内置了一些东西,这样就可以在编译后的代码中处理,而不是编写脚本。

请参阅:-地图初始化后,标记数组调用此

请参阅此带有完整代码的示例

var markerCluster = new MarkerClusterer(map, markers,
{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
}

在重写了几次之后,由于速度问题,这就是我想到的。由于我有很多记录,我觉得过滤一次以获得独特的纬度会很有帮助。

function filterArray(incomingArray){
var unique = {};
var distinct = [];
for( var i in incomingArray ){
if( typeof(unique[incomingArray[i][0]]) == "undefined"){
distinct.push([incomingArray[i][0],{}]);
}
unique[incomingArray[i][0]] = 0;
}
return distinct;
}
function GroupCoords(incomingArray, rounding) {
var xy = [];
for(var i =0; i<incomingArray.length; i++){
var latitude = parseFloat(incomingArray[i].latitude).toFixed(rounding);
xy.push([latitude]);
}
var locations =filterArray(xy);
for(var i =0; i<incomingArray.length; i++){
var latitude = parseFloat(incomingArray[i].latitude).toFixed(rounding);
var longitude = parseFloat(incomingArray[i].longitude).toFixed(rounding);
var familySize = incomingArray[i].family_size;
for(var X =0; X<locations.length; X++){
if(latitude==locations[X][0]){
if(!locations[X][longitude]){
locations[X][longitude]=familySize;
counter = counter + familySize;
}else{
locations[X][longitude] = locations[X][longitude] + familySize;
counter = counter + familySize;
}      
}
}
}
return locations;
}
console.log(GroupCoords(data, 3));

将返回一个数组,例如:

[
[
"30.557", //latitude
{
"-87.260": 1 // longitude : family_size
}
],
[
"30.570",//latitude
{
"-87.260": 1 // longitude : family_size
},
{
"-87.340": 4 // longitude : family_size
}
]
]

每个纬度可以有多个经度,这些经度可以包含您想要存储的任何额外信息。通过将坐标四舍五入到3,它几乎立即将大约6000条记录减少到大约750条,这将允许我使用滑块来调整分组大小。

最新更新