【问题标题】:NPObject error writing KML objects to Google Earth API将 KML 对象写入 Google Earth API 时出现 NPObject 错误
【发布时间】:2014-08-29 17:11:01
【问题描述】:

我正在尝试编写一个快速脚本以从 facebook 中提取数据,然后仅使用简单的挤压多边形将其绘制在 google 地图实例上。我已经得到了所有的社交内容和 ajax 工作,但无论我每次调用 .getcoordinates() 时我都会收到 NPObject 错误。特别是“在 NPObject 上调用方法时出错。”在我调用 .getcoordinates() 的文档的第一行。我环顾 StackO 并尝试了其他任何人一直在提出与 NPObject 错误有关的任何事情,但无济于事。有什么想法吗?

标头js:

function drawgraph(name, z, x, y) {

    // Create the placemark.
    var polygonPlacemark = ge.createPlacemark('');

    // Create the polygon.
    var polygon = ge.createPolygon('');
    polygon.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
    polygonPlacemark.setGeometry(polygon);

    // Add points for the outer shape.
    var outer = ge.createLinearRing('');
    outer.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
    outer.getCoordinates().pushLatLngAlt(x - 0.005, y - 0.005, z);
    outer.getCoordinates().pushLatLngAlt(x + 0.005, y + 0.005, z);
    outer.getCoordinates().pushLatLngAlt(x - 0.005, y + 0.005, z);
    outer.getCoordinates().pushLatLngAlt(x + 0.005, y - 0.005, z);
    polygon.setOuterBoundary(outer);

    //Create a style and set width and color of line
    polygonPlacemark.setStyleSelector(ge.createStyle(''));
    var lineStyle = polygonPlacemark.getStyleSelector().getLineStyle();
    lineStyle.setWidth(5);
    lineStyle.getColor().set('9900ffff');

    // Add the placemark to Earth.
    ge.getFeatures().appendChild(polygonPlacemark);
}   

var ge = null;
google.load("earth", "1", {"other_params":"sensor=true"});

function init() {
  init3d();
}

function initCB(instance) {
  ge = instance;
  ge.getWindow().setVisibility(true);
  ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);    
}

function failureCB(errorCode) {
}

function init3d() {
    google.earth.createInstance('map3d', initCB, failureCB);
}   

我在正文 onload 上调用 init()

html 前端:

<div id="map3d" style="height: 600px; width:100%; margin:0; "></div>
<div id="form" style="text-align:center; width:100%; margin-top:10px;">
<button id = "getcoord" style="background-color:#707070">Get coordinates of Current view</button>
<form id = "form" style="display:inline;" method="GET">
<input type="text" name="place" id="place" >
<select name="dist" id="dist">
   <option value="1609">1 Mile</option>
   <option value="3218">2 Miles</option>
   <option value="8046">5 Miles</option>
   <option value="16090">10 Miles</option>
 </select>
 <select name="number" id="number">
   <option value="10">10</option>
   <option value="50">50</option>
   <option value="100">100</option>
   <option value="1000">1000</option>
   <option value="5000">5000</option>
 </select>
<button id="submit" type="submit">Submit</button>
</form>
</div>

加载 js:

$('#form').submit(function(event){
    var fdata = {
        'place'             : $('#place').val(),
        'dist'              : $('#dist').val(),
        'quantity'          : $('#number').val(),
    };
    console.log(fdata);
    $.ajax({
        type: "POST",
        url: "fb_back.php",
        data: fdata,
        cache:false,
    }).done(function(data) {
            for(var i = 0; i < data.length; i++) {

                // get variables from json return
                var name = +(data[i]["name"]);
                var hgt = +(data[i]["checkins"]);
                var lat = +(data[i]["lat"]);
                var lng = +(data[i]["lng"]);

                drawgraph(name, hgt, lat, lng);// create the polygon

            } // for loop
        }),//success
    event.preventDefault();
});//form submit

php 后端获取 ajax 调用:

//get ajax data
$distance = $_POST["dist"];
$place = $_POST["place"];
$limit = $_POST["quantity"];

// get the lat and long of the sent address to use for the fb request 
$geo_return = file_get_contents("https://maps.googleapis.com/maps/api/geocode/json?    address=".urlencode($place)."&key=AIzaSyDeEkWgri9GAvDVE4QN9j2IeO4_2Dj61iM");
$geo_returned = json_decode($geo_return);
foreach ($geo_returned->results as $results){
$lat = $results->geometry->location->lat;
$lng = $results->geometry->location->lng;
}

//make the fb request for a token and for the data then decode the data and stick it into the $decoded array
$center = $lat . "," . $lng;
$fb_key = file_get_contents("https://graph.facebook.com/oauth/access_token?client_id=[my id]&client_secret=[my secret]grant_type=client_credentials");
$ini = "https://graph.facebook.com/v2.1/search?            limit=".$limit."&offset=0&type=place&center=".$center."&distance=".$distance."";
$fb_get = $ini . "&" . $fb_key;
$fb_got = file_get_contents($fb_get);
$decoded = json_decode($fb_got, true);
$decoded = $decoded['data'];

//setup the foreach loop, the $data variable is where each entry will be stored
$data = array();
$i = 0;
foreach ($decoded as $value) {  

//pull the name and the fb id of the place from the object in this iteration of the loop
$name = $value['name'];
$each_id = $value['id'];

//pull the fb json file for this place using the id
$pull = "https://graph.facebook.com/v2.1/". $each_id . "?" . $fb_key;
$detail_array = file_get_contents($pull);
$decode_detail = json_decode($detail_array);

//pull out the checkins as well as the latitude and longitude of the place
$checkins = $decode_detail->checkins;       
$fblat = $decode_detail->location->latitude;
$fblng = $decode_detail->location->longitude;

//make another associative array with the variables for the kml objects in fb_front
$entry = array(
        "name" => $name,
        "checkins" => $checkins,
        "lat" => $fblat,
        "lng" => $fblng,
    );

//store the entry array and step the index variable
$data[$i]=$entry;
$i++;
}

//dump it back out to fb_front
var_dump(json_encode($data));

我真的很抱歉在你们身上丢了一大堆文字,我只是没有想法。

【问题讨论】:

    标签: javascript php ajax kml google-earth-plugin


    【解决方案1】:

    这里的问题是 Google 地球插件在页面加载时不会立即可用。只要您页面上的 JavasCript 与 Google 地球插件之间的连接无法通信,就会出现 NPObject 错误。这可能在 GE 插件尚未初始化时发生,也可能在插件崩溃时发生。

    在上面的代码中,您需要在调用 google.load 后添加此行

    google.setOnLoadCallback(init3d);

    var ge = null;
    google.load("earth", "1", {"other_params":"sensor=true"});
    google.setOnLoadCallback(init3d);
    

    并删除 init3d();调用您的页面加载。页面加载后,GE 插件会异步加载,您需要使用 google.setOnLoadCallback 来获取让您知道 GE 插件已准备就绪的实际事件。更新了下面的脚本。

    function drawgraph(name, z, x, y) {
    
      // Create the placemark.
      var polygonPlacemark = ge.createPlacemark('');
    
      // Create the polygon.
      var polygon = ge.createPolygon('');
      polygon.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
      polygonPlacemark.setGeometry(polygon);
    
      // Add points for the outer shape.
      var outer = ge.createLinearRing('');
      outer.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
      outer.getCoordinates().pushLatLngAlt(x - 0.005, y - 0.005, z);
      outer.getCoordinates().pushLatLngAlt(x + 0.005, y + 0.005, z);
      outer.getCoordinates().pushLatLngAlt(x - 0.005, y + 0.005, z);
      outer.getCoordinates().pushLatLngAlt(x + 0.005, y - 0.005, z);
      polygon.setOuterBoundary(outer);
    
      //Create a style and set width and color of line
      polygonPlacemark.setStyleSelector(ge.createStyle(''));
      var lineStyle = polygonPlacemark.getStyleSelector().getLineStyle();
      lineStyle.setWidth(5);
      lineStyle.getColor().set('9900ffff');
    
      // Add the placemark to Earth.
      ge.getFeatures().appendChild(polygonPlacemark);
    }
    
    var ge = null;
    google.load("earth", "1", {
      "other_params": "sensor=true"
    });
    
    function init() {
    
    }
    
    function initCB(instance) {
      ge = instance;
      ge.getWindow().setVisibility(true);
      ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
    }
    
    function failureCB(errorCode) {}
    
    function init3d() {
      google.earth.createInstance('map3d', initCB, failureCB);
    }
    function drawgraph(name, z, x, y) {
    
      // Create the placemark.
      var polygonPlacemark = ge.createPlacemark('');
    
      // Create the polygon.
      var polygon = ge.createPolygon('');
      polygon.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
      polygonPlacemark.setGeometry(polygon);
    
      // Add points for the outer shape.
      var outer = ge.createLinearRing('');
      outer.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
      outer.getCoordinates().pushLatLngAlt(x - 0.005, y - 0.005, z);
      outer.getCoordinates().pushLatLngAlt(x + 0.005, y + 0.005, z);
      outer.getCoordinates().pushLatLngAlt(x - 0.005, y + 0.005, z);
      outer.getCoordinates().pushLatLngAlt(x + 0.005, y - 0.005, z);
      polygon.setOuterBoundary(outer);
    
      //Create a style and set width and color of line
      polygonPlacemark.setStyleSelector(ge.createStyle(''));
      var lineStyle = polygonPlacemark.getStyleSelector().getLineStyle();
      lineStyle.setWidth(5);
      lineStyle.getColor().set('9900ffff');
    
      // Add the placemark to Earth.
      ge.getFeatures().appendChild(polygonPlacemark);
    }
    
    var ge = null;
    google.load("earth", "1", {
      "other_params": "sensor=true"
    });
    
    function init() {
      init3d();
    }
    
    function initCB(instance) {
      ge = instance;
      ge.getWindow().setVisibility(true);
      ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
    }
    
    function failureCB(errorCode) {}
    
    function init3d() {
      google.earth.createInstance('map3d', initCB, failureCB);
    }
    // This will waint until GE plugin is actually loaded and ready
    google.setOnloadCallback(init3d);
    

    此页面有一个很棒的教程,介绍了将 GE 插件正确加载到您的页面上所需的步骤 (https://developers.google.com/earth/documentation/)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多