Skip to content

Commit

Permalink
Merge pull request #6876 from AnalyticalGraphicsInc/geocoder-terrain
Browse files Browse the repository at this point in the history
Make Geocoder terrain-aware
  • Loading branch information
bagnell authored Aug 3, 2018
2 parents c59efc9 + fe1a42f commit 71696ef
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Change Log
* Added `ClippingPlaneCollection.planeAdded` and `ClippingPlaneCollection.planeRemoved` events. `planeAdded` is raised when a new plane is added to the collection and `planeRemoved` is raised when a plane is removed. [#6875](https:/AnalyticalGraphicsInc/cesium/pull/6875)

##### Fixes :wrench:
* The Geocoder widget now takes terrain altitude into account when calculating its final destination.
* Fixed bug that caused a new `ClippingPlaneCollection` to be created every frame when used with a model entity [#6872](https:/AnalyticalGraphicsInc/cesium/pull/6872)

### 1.48 - 2018-08-01
Expand Down
18 changes: 8 additions & 10 deletions Source/Core/PeliasGeocoderService.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
define([
'./Cartesian3',
'./Check',
'./defined',
'./defineProperties',
'./GeocodeType',
'./Rectangle',
'./Resource'
], function (
Cartesian3,
Check,
defined,
defineProperties,
Expand Down Expand Up @@ -77,24 +79,20 @@ define([
return resource.fetchJson()
.then(function (results) {
return results.features.map(function (resultObject) {
var destination;
var bboxDegrees = resultObject.bbox;

// Pelias does not always provide bounding information
// so just expand the location slightly.
if (!defined(bboxDegrees)) {
if (defined(bboxDegrees)) {
destination = Rectangle.fromDegrees(bboxDegrees[0], bboxDegrees[1], bboxDegrees[2], bboxDegrees[3]);
} else {
var lon = resultObject.geometry.coordinates[0];
var lat = resultObject.geometry.coordinates[1];
bboxDegrees = [
lon - 0.001,
lat - 0.001,
lon + 0.001,
lat + 0.001
];
destination = Cartesian3.fromDegrees(lon, lat);
}

return {
displayName: resultObject.properties.label,
destination: Rectangle.fromDegrees(bboxDegrees[0], bboxDegrees[1], bboxDegrees[2], bboxDegrees[3])
destination: destination
};
});
});
Expand Down
91 changes: 83 additions & 8 deletions Source/Widgets/Geocoder/GeocoderViewModel.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
define([
'../../Core/IonGeocoderService',
'../../Core/Cartesian3',
'../../Core/CartographicGeocoderService',
'../../Core/defaultValue',
'../../Core/defined',
'../../Core/defineProperties',
'../../Core/DeveloperError',
'../../Core/Event',
'../../Core/GeocodeType',
'../../Core/Math',
'../../Core/Matrix4',
'../../Core/Rectangle',
'../../Core/sampleTerrainMostDetailed',
'../../Scene/SceneMode',
'../../ThirdParty/knockout',
'../../ThirdParty/when',
'../createCommand',
'../getElement'
], function(
IonGeocoderService,
Cartesian3,
CartographicGeocoderService,
defaultValue,
defined,
defineProperties,
DeveloperError,
Event,
GeocodeType,
CesiumMath,
Matrix4,
Rectangle,
sampleTerrainMostDetailed,
SceneMode,
knockout,
when,
createCommand,
Expand Down Expand Up @@ -331,14 +341,79 @@ define([
}

function updateCamera(viewModel, destination) {
viewModel._scene.camera.flyTo({
destination : destination,
complete: function() {
viewModel._complete.raiseEvent();
},
duration : viewModel._flightDuration,
endTransform : Matrix4.IDENTITY
});
var scene = viewModel._scene;
var globe = scene.globe;
var ellipsoid;
if (defined(globe)) {
ellipsoid = globe.ellipsoid;
} else {
ellipsoid = scene.mapProjection.ellipsoid;
}

var camera = scene.camera;
var terrainProvider = scene.terrainProvider;
var availability = defined(terrainProvider) ? terrainProvider.availability : undefined;

// Always expand single points so we don't zoom
// directly into the ground, even when not using terrain.
if (destination instanceof Cartesian3) {
var carto = ellipsoid.cartesianToCartographic(destination);
var offset = CesiumMath.toRadians(0.001);
destination = new Rectangle(
carto.longitude - offset,
carto.latitude - offset,
carto.longitude + offset,
carto.latitude + offset);
}

var newDestination = destination;
if (defined(availability)) {
var cartographics;

cartographics = [
Rectangle.center(destination),
Rectangle.southeast(destination),
Rectangle.southwest(destination),
Rectangle.northeast(destination),
Rectangle.northwest(destination)
];

newDestination = sampleTerrainMostDetailed(terrainProvider, cartographics)
.then(function(positionsOnTerrain) {
var maxHeight = -Number.MAX_VALUE;
positionsOnTerrain.forEach(function(p) {
maxHeight = Math.max(p.height, maxHeight);
});

var tmp = camera.getRectangleCameraCoordinates(destination);
var finalPosition;
if (scene.mode === SceneMode.SCENE3D) {
finalPosition = ellipsoid.cartesianToCartographic(tmp);
} else {
finalPosition = scene.mapProjection.unproject(tmp, tmp);
}

finalPosition.height += maxHeight * 2;
return ellipsoid.cartographicToCartesian(finalPosition);
});
}

var finalDestination = destination;
when(newDestination)
.then(function(result) {
finalDestination = result;
})
.always(function(){
// Whether terrain querying succeeded or not, fly to the destination.
camera.flyTo({
destination: finalDestination,
complete: function() {
viewModel._complete.raiseEvent();
},
duration: viewModel._flightDuration,
endTransform: Matrix4.IDENTITY
});
});
}

function chainPromise(promise, geocoderService, query, geocodeType) {
Expand Down
6 changes: 3 additions & 3 deletions Specs/Core/PeliasGeocoderServiceSpec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
defineSuite([
'Core/PeliasGeocoderService',
'Core/GeocodeType',
'Core/Rectangle',
'Core/Cartesian3',
'Core/Resource',
'ThirdParty/when'
], function(
PeliasGeocoderService,
GeocodeType,
Rectangle,
Cartesian3,
Resource,
when) {
'use strict';
Expand Down Expand Up @@ -40,7 +40,7 @@ defineSuite([
.then(function(results) {
expect(results.length).toEqual(1);
expect(results[0].displayName).toEqual(data.features[0].properties.label);
expect(results[0].destination).toBeInstanceOf(Rectangle);
expect(results[0].destination).toBeInstanceOf(Cartesian3);
});
});

Expand Down

0 comments on commit 71696ef

Please sign in to comment.