简体   繁体   English

NPObject将KML对象写入Google Earth API时出错

[英]NPObject error writing KML objects to Google Earth API

I'm trying to write a quick script to pull data from facebook and then graph it on a google map instance just using simple extruded polygons. 我正在尝试编写一个快速脚本以从Facebook中提取数据,然后仅使用简单的挤压多边形在Google地图实例上对其进行图形处理。 I've gotten all the social stuff and the ajax working but no matter what I do every time i call .getcoordinates() on anything I get an NPObject error. 我已经获得了所有社交功能和ajax的支持,但是无论我每次对任何得到NPObject错误的调用.getcoordinates()时,都执行什么操作。 Specifically "Error calling method on NPObject." 特别是“ NPObject上的错误调用方法”。 on the first line in my document where I've called .getcoordinates(). 在文档的第一行中,我将其称为.getcoordinates()。 I looked around StackO and have tried everything anyone else has been putting up on anything relating to NPObject errors to no avail. 我环顾了StackO,并尝试了其他任何人都在提出与NPObject错误有关的任何内容的尝试,但都没有成功。 Any ideas? 有任何想法吗?

header js: 标头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);
}   

I call init() on the body onload 我在身体onload上调用init()

html frontend: 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>

onload js: onload 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 backend getting an ajax call: 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));

I'm really sorry to dump a wall of text on you guys I am just out of ideas. 我真的很抱歉在你们身上丢下一堵墙,我只是个想法。

The issue here is that the Google Earth plugin is not immediately available on page load. 这里的问题是页面加载后,Google Earth插件无法立即使用。 The NPObject error will occur anytime the connection between the JavasCript on your page and the Google Earth plugin cannot communicate. 只要页面上的JavasCript与Google Earth插件之间的连接无法通信,就会发生NPObject错误。 This can happen when the GE plugin has not yet initialized, or can also happen if the plugin crashes. GE插件尚未初始化时,可能会发生这种情况;如果插件崩溃,也会发生这种情况。

In your case in the code above, you need to add this line after you call the google.load 就上述代码而言,您需要在调用google.load之后添加此行

google.setOnLoadCallback(init3d); google.setOnLoadCallback(init3d);

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

and remove the init3d(); 并删除init3d(); call in your page load. 调用您的页面加载。 The GE plugin loads asynchonously once the page has loaded and you need to use the google.setOnLoadCallback to get the actual event that lets you know the GE plugin is ready to go. 页面加载完成后,GE插件将异步加载,您需要使用google.setOnLoadCallback来获取实际事件,该事件使您知道GE插件已准备就绪。 Updated script below. 更新了以下脚本。

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

This page has a great tutorial that walks through the required steps to get the GE plugin loaded on your page properly ( https://developers.google.com/earth/documentation/ ) 该页面有一个很棒的教程,它逐步指导了必要的步骤,以正确地将GE插件加载到页面上( https://developers.google.com/earth/documentation/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM