API плагина Google Планета Земля - ​​Как узнать текущий масштаб карты? - PullRequest
2 голосов
/ 14 марта 2012

У меня есть приложение, в котором размещен экземпляр плагина Google Планета Земля, и я заинтересован в том, чтобы получить текущий масштаб карты и использовать его в своем приложении.

Я знаю, что могу использовать GEOptions и установить видимость Scale Legend, но я хочу использовать фактическое значение масштаба в своем приложении, и я не смог найти API для него.

Есть ли способ сделать это?

Если нет, как я могу рассчитать текущий масштаб, используя, возможно, текущий вид?

Ответы [ 2 ]

5 голосов
/ 15 ноября 2012

Я использую приведенную ниже функцию, чтобы получить приблизительный масштаб из API плагина Google Earth. Это рассчитывается на основе высоты камеры от земли. Наклон, панорамирование и т. Д. Шара не влияют на возвращаемое значение. Это простая функция, которая хорошо работает, если вам нужно только общее представление о реальном масштабе карты между камерой и землей. Даже когда камера наклонена, глядя на горизонт, она все равно будет использовать вычисления, как если бы камера смотрела прямо вниз.

Когда камера наклонена, нет единого масштаба, который можно рассчитать, поскольку масштаб изменяется в любой заданной точке видимой карты. Две точки на расстоянии имеют различное количество расстояний на пиксель на экране по сравнению с расстоянием между двумя точками рядом с камерой. Легенда о масштабе также является приблизительной, потому что расстояние является точным только на определенной части видимой карты.

function getScale() {
    var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND),
        eyeAlt,
        scale;
    eyeAlt = camera.getAltitude();

    scale = Math.round(eyeAlt * 10.5);
    return scale;
}
3 голосов
/ 18 марта 2012

Сама легенда о масштабе довольно неоднозначна, поскольку Google Планета Земля представляет собой глобус в 3D, и перспектива, очевидно, не является проекцией, сохраняющей расстояния (или даже отношения между расстояниями). Это не проблема, если смотреть прямо вниз и довольно близко к поверхности земли, но как только угол обзора изменится, земля ближе к камере будет иметь совсем другой масштаб, чем земля на горизонте.

В этот момент имеет смысл спросить о текущем масштабе в определенной точке экрана. Для этого нет прямого API, но вы всегда можете найти координаты широты / долготы для любых двух точек на экране, а затем найти расстояние между ними.

GEView.hitTest , вероятно, самый простой способ сделать это. Вы можете указать, где должен выполняться тест на попадание в пикселях или в виде доли от размера плагина, смещенного от краев его контейнера DOM. Так, например, если вы хотите получить км / пиксель около середины вида, вы можете: взять ширину и высоту плагина, разделить их на два, затем сместить в каждом направлении на 10 пикселей, выполнить самый быстрый запрос, найти расстояние между возвращенными координатами , а затем, наконец, разделите на 10. То, как вы на самом деле смещаете эти пиксели, опять-таки до того места, где вы точно хотите измерить масштаб (и обратите внимание, что если ваш тест попадания не попадает в землю, вы получите нулевое возвращаемое значение).

Предупреждение : это очень быстро скомпонованный бит кода (с использованием вычисления расстояния от этого потока ). Пожалуйста, тщательно протестируйте перед использованием в любом месте, но оно должно выглядеть примерно так:

function getSomethingResemblingScale() {
  var earthDiv = document.getElementById('map3d');
  var hw = earthDiv.offsetWidth / 2;
  var hh = earthDiv.offsetHeight / 2;
  var view = ge.getView();
  var hitTest1 = view.hitTest(hw - 5, ge.UNITS_PIXELS, hh, ge.UNITS_PIXELS, ge.HIT_TEST_TERRAIN);
  var hitTest2 = view.hitTest(hw + 5, ge.UNITS_PIXELS, hh, ge.UNITS_PIXELS, ge.HIT_TEST_TERRAIN);
  var dist = calcDistance(hitTest1.getLatitude(), hitTest1.getLongitude(), hitTest2.getLatitude(), hitTest2.getLongitude());
  console.log('scale: ' + (dist/10) + ' km/pixel');
}

function calcDistance(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = (lat2-lat1) * (Math.PI / 180);
  var dLon = (lon2-lon1) * (Math.PI / 180);
  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(lat1*(Math.PI / 180)) * Math.cos(lat2*(Math.PI / 180)) * 
          Math.sin(dLon/2) * Math.sin(dLon/2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c;
  return d;
}
...