【问题标题】:Google Maps / jQuery - create object from json fileGoogle Maps / jQuery - 从 json 文件创建对象
【发布时间】:2017-04-21 09:47:24
【问题描述】:

这是一个可以工作的谷歌地图,但在我度假回来后它不再工作了。但是你仍然可以多看代码 - https://plnkr.co/edit/jHCuVVhGDLwgjNw4bcLr

这是谷歌地图代码:

var map;

function initialize() {
    var mapOptions = {
        center: new google.maps.LatLng(52.4357808, 4.991315699999973),
        zoom: 2,
        mapTypeId: google.maps.MapTypeId.TERRAIN
    };
    map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}

var seg = {
    1: 'investment_cast',
    2: 'forged_Prod',
    3: 'air_Prod',
    5: 'worldwide',
    6: 'structurals'
}

var comp = {
    1: 'structurals',
    2: 'airfoils',
    3: 'wyman',
    4: 'energy',
    5: 'fasteners',
    6: 'struc_comp',
    7: 'mech_hard',
    8: 'engine_prod',
    9: 'corp',
    10: 'aero',
    12: 'timet',
    13: 'spec_metals'
}

var myJSON = {};
var myMarkers=[];

$.getJSON("locations.json", function(json1) {
    myJSON=json1;
    $.each(json1, function(key, data) {
        var latLng = new google.maps.LatLng(data.latitude, data.longitude); 
        // Creating a marker and putting it on the map
        var marker = new google.maps.Marker({
            position: latLng
        });
        myMarkers[key]=marker;
        marker.setMap(map);

        var infoWindow = new google.maps.InfoWindow();

        google.maps.event.addListener(marker, 'click', function() {

            if (infoWindow) {infoWindow.close();}
            infoWindow = new google.maps.InfoWindow({
                content: "<h5>" + data.display_name + "</h5>" +
                "<div>" + data.street+ "</div>" +
                "<div>" + data.city + ", " + data.state + " &nbsp; " + data.postal_code + "</div>" +
                "<div class='mapPhoneNum'>" + data.telephone + "</div>" +
                "<a href=" + data.web_url + ">Website</a>"
            });
            infoWindow.open(map, marker);
            map.setZoom(15);
            map.panTo(this.getPosition());

            google.maps.event.addListener(infoWindow,'closeclick',function(){
              resetMapOrigin();
            });

        });

        filterMarkers = function(category){

            var component = category.data("component_id");
            var segment = category.data("segment_id")

            setMapOnAll(null);
            resetMapOrigin();

            var filteredMarkers=[];

            $.each(myJSON, function(key, data) {


                if( typeof(component)!="undefined" ){

                  if( (myJSON[key].component_id == component) && (myJSON[key].segment_id == segment) ){ 
                    filteredMarkers.push(key);
                  }

                }else{
                  if( myJSON[key].segment_id == segment ){
                    filteredMarkers.push(key);
                  }
                }
            });

            for(i=0;i<filteredMarkers.length;i++){
                myMarkers[filteredMarkers[i]].setMap(map);
            }
        }

        function setMapOnAll(map) {
            for (var i = 0; i < myMarkers.length; i++) {
                myMarkers[i].setMap(map);
            }
        }

        function resetMapOrigin(){
          map.setZoom(2);
          map.setCenter({lat:52.4357808,lng:4.991315699999973});
        }
    });

});

所以问题是var seg ={...}var comp ={...} 被硬编码到一个对象中。我需要做的是使用$.getJSON(或其他任何可行的方法)从json文件中提取数据(就像我正在使用locations.json一样)并将其格式化,就像当前的对象一样@ 987654326@(我需要保留这个结构)。

json文件的格式是这样的-

组件:

[
    {
        "id": "1",
        "display_name": "structurals"
    },
    {
        "id": "2",
        "display_name": "airfoils"
    },
    {
        "id": "3",
        "display_name": "wyman"
    },
    {
        "id": "4",
        "display_name": "energy"
    },
    {
        "id": "5",
        "display_name": "fasteners"
    },
    {
        "id": "6",
        "display_name": "struc_comp"
    },
    {
        "id": "7",
        "display_name": "mech_hard"
    },
    {
        "id": "8",
        "display_name": "engine_prod"
    },
    {
        "id": "9",
        "display_name": "corp"
    },
    {
        "id": "10",
        "display_name": "aero"
    },
    {
        "id": "12",
        "display_name": "timet"
    },
    {
        "id": "13",
        "display_name": "spec_metals"
    }
]

细分:

[
    {
        "id": "1",
        "display_name": "investment_cast"
    },
    {
        "id": "2",
        "display_name": "forged_Prod"
    },
    {
        "id": "3",
        "display_name": "air_Prod"
    },
    {
        "id": "5",
        "display_name": "worldwide"
    },
    {
        "id": "6",
        "display_name": "structurals"
    }
]

那么我怎样才能从上面抓取这个 JSON 数据,并以与我目前格式化“seg and comp”对象相同的方式对其进行格式化? (文件名为 components.json 和 segments.json)

提前致谢。

【问题讨论】:

  • 如果您对下面我的回答有任何疑问,请告诉我。谢谢
  • @agon024 你甚至不想承认任何答案。这是错误的。人们花费了宝贵的时间来帮助您,您必须尊重这一点。

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


【解决方案1】:

一种解决方案是遍历对象数组,并创建另一个具有每个 id 命名的属性的对象。这说明了我的意思,假设您已经将 json 提取并解析为一个对象:

var data = 
[
    {
        "id": "1",
        "display_name": "investment_cast"
    },
    {
        "id": "2",
        "display_name": "forged_Prod"
    },
    {
        "id": "3",
        "display_name": "air_Prod"
    },
    {
        "id": "5",
        "display_name": "worldwide"
    },
    {
        "id": "6",
        "display_name": "structurals"
    }
];


var seg = {};
data.forEach( function(o) {
  var x = parseInt(o.id);
  seg[x] = o.display_name;
});

console.log(seg);
/*
{ '1': 'investment_cast',
  '2': 'forged_Prod',
  '3': 'air_Prod',
  '5': 'worldwide',
  '6': 'structurals' }
*/

实际上,我可能会使用 lodash 之类的实用程序库来执行此操作,例如使用 keyBy(): https://lodash.com/docs/4.17.2#keyBy

编辑:keyBy() 不会完全按照你的意愿做,所以忽略那部分。

编辑:此外,如果您要获取 3 个 json 文件,这些是异步操作,因此您可能需要组合这些操作并等待所有 json 提取完成。通常这将通过 JavaScript 中的 Promise(或 Promise 库)来完成:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

【讨论】:

    【解决方案2】:

    对于您的问题:

    我怎样才能从上面抓取这个 JSON 数据,并以与我目前格式化“seg and comp”对象相同的方式对其进行格式化?

    您可以将$.getJSON() 用于您的其他 json 文件(即 components.jsonsegments.json),就像您使用 locations 一样.json 文件。因为这会导致三个异步请求,所以最好等到所有请求都完成。 $.getJSON() 返回 promise,您可以等到所有承诺完成后再将位置添加到地图。

    您可以使用Promise.all() 在所有承诺完成后运行代码,尽管它不支持 IE。在阅读了提到它的this blog post 之后,我寻找了一个等效的 jQuery 函数并找到了$.when(与.done() 一起使用)。该技术似乎有效:

    $.when($.getJSON("locations.json"), $.getJSON("segments.json"),     
    $.getJSON("components.json")).
        done(function(locationsResponse, segResponse, compResponse) {
       // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
        myJSON = locationsResponse[0];
        var seg = segResponse[0];
        var comp = compResponse[0];
        //rest of code to add markers to the map
        //...
    });
    

    当我查看your plunker example 时,我确实注意到浏览器控制台中有一个错误:

    script.js:79 Uncaught TypeError: category.data is not a function(…)

    这似乎是由无线电输入调用函数 filterMarkers 并传递一个字符串值而不是对该输入的 jQuery 选择器的引用(即$(this))引起的。因此,您可以更新输入以全部传递该引用,并在适当的地方设置 data-component_id 和/或 data-segment_id。例如,下面的行:

          <div class="optGroup"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="investment_cast" data-segment_id="2" data-component_id="3" /> Investment Cast Products</div>
          <div class="optChild"><input onclick="filterMarkers(this.value);" type="radio" name="loc" value="structurals" /> PCC Structurals</div>
          <div class="optChild"><input onclick="filterMarkers(this.value);" type="radio" name="loc" value="airfoils" /> PCC Airfoils</div>
    

    应该这样更新:

          <div class="optGroup"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="investment_cast" data-segment_id="2" data-component_id="3" /> Investment Cast Products</div>
          <div class="optChild"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="structurals" data-component_id="1" /> PCC Structurals</div>
          <div class="optChild"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="airfoils" data-component_id="2" /> PCC Airfoils</div>
    

    this updated plunker

    【讨论】:

      【解决方案3】:

      这是一个需要和重构代码更改的 plunkerWorking Example 更改在 scripts.js 文件中

      解释我的代码: 从 JSON 数据构建所需的 segcomp 的逻辑是循环遍历结果并从 iddisplay_name 中选择数据作为 keyvalue

      function formatData(jsonData){
        var obj ={};
        jsonData.forEach(function(item,index){
          var key = parseInt(item.id,10);
          obj[key] = item.display_name;
        });
        return obj;
      }
      

      上述函数获取您的json 数据并在对象中返回格式化结果。

      接下来,由于您希望在构建谷歌地图之前预先显示所有数据,我想说让我们一个一个地加载数据,当我们全部完成后,让我们构建地图。

      function GetAllDataSetsAndInititateMap() {
        $.getJSON("segments.json", function(json) {
          seg = formatData(json);
          $.getJSON("components.json", function(json) {
            comp = formatData(json);
            $.getJSON("locations.json", function(json) {
              myJSON = json;
                BuildMap();
            });
          });
        });
      }
      

      准备好这些之后,编写一个名为 BuildMap 的新函数,并将所有当前代码放入 $.getJSON("locations.json", function(json1) { 块中。

      你的BuildMap 函数看起来像

      function BuildMap(){
         var json1 = myJSON;
         $.each(json1, function(key, data) {
           // all the existing code.
         });
      }
      

      这已经过测试,这是一个 Working Example in Plunker 更改在 scripts.js 文件中。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2015-09-30
        • 1970-01-01
        • 2013-03-19
        • 2018-04-11
        • 2012-04-21
        • 2019-01-26
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        相关资源
        最近更新 更多