Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 按城市/地区分组JSON坐标_Javascript_Jquery_Multidimensional Array_Coordinates - Fatal编程技术网

Javascript 按城市/地区分组JSON坐标

Javascript 按城市/地区分组JSON坐标,javascript,jquery,multidimensional-array,coordinates,Javascript,Jquery,Multidimensional Array,Coordinates,我有一份客户名单,上面有一些销售数据和他们的坐标。我想在地图上显示它,但我不想有10000个标记,而是想根据该地区的客户数量将它们分组,以获得不同半径的圆圈。以下是我的数据集示例: [ { "latitude": "44.141638", "longitude": "-149.935598", "family_size": 1 }, { "latitude": "44.141314", "longitude": "-149.935556",

我有一份客户名单,上面有一些销售数据和他们的坐标。我想在地图上显示它,但我不想有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
  }
]
我的想法是从每条记录中获取纬度和经度,并使用滑块/缩放级别组合调整小数点的数量,以便在缩小时,可以看到它们分组。例如,当您缩小前两条记录时,它们将转换为:

  {
    "latitude": "44.141",
    "longitude": "-149.935",
    "family_size": 3
  },
  {
    "latitude": "44.141",
    "longitude": "-149.935",
    "family_size": 1
  }
然后我将半径定义为匹配坐标处的家庭成员数,因此总共为4

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

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

更新 我有一个小规模的方法,但当扩展到多个记录时,有两种方法失败。首先,由于某种原因,计数器的性能下降了很多,其次,我担心以这种方式循环是非常低效的

以下是我所拥有的:

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 {}
        }
    }
}
函数组XY(arr){
var a=[],b=[],上一个;
arr.sort();
对于(变量i=0;i
下面是一个包含数据的JSFIDLE文件:

虽然它一次在5张唱片上做得很好,但当我尝试向它提供5000张唱片时,它完全冻结了浏览器,并开始给出像40000张这样疯狂的家庭大小的结果

似乎将XY坐标分组是javascript擅长的事情,并且内置了一些东西,因此可以用编译代码而不是脚本来处理它。

请参见:- 映射初始化后,标记数组调用


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

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

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

如果使用正方形而不是圆形,则只需四舍五入:
var x=Math.floor(latitude/10),然后将具有相同x和y的数据分组。在数据集上循环,进行条件检查是否通过,然后更新计数器。这也是我所想的,也使用舍入,但我不知道如何将它们分组为两个唯一值。Adam,我可以照你说的那样循环,但似乎我必须解析它3次,而多次解析1MB的数据将是低效的。我不确定javascript中是否有任何内置的方式来匹配CoordinationsHanks D-John,这将是一个很好的方式,除非我使用OpenStreetMap,并且需要一些粒度控制,以便在标记中显示我想要的内容。标记将显示销售额、性别、家庭规模等的平均值。因此,这是一个很好的解决方案,以满足一般需求,但我需要一些更具体的东西。
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
    }
  ]
]