123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /*global define*/
- define([
- '../../Core/BingMapsApi',
- '../../Core/defaultValue',
- '../../Core/defined',
- '../../Core/defineProperties',
- '../../Core/DeveloperError',
- '../../Core/jsonp',
- '../../Core/Matrix4',
- '../../Core/Rectangle',
- '../../ThirdParty/knockout',
- '../../ThirdParty/when',
- '../createCommand'
- ], function(
- BingMapsApi,
- defaultValue,
- defined,
- defineProperties,
- DeveloperError,
- jsonp,
- Matrix4,
- Rectangle,
- knockout,
- when,
- createCommand) {
- "use strict";
- /**
- * The view model for the {@link Geocoder} widget.
- * @alias GeocoderViewModel
- * @constructor
- *
- * @param {Object} options Object with the following properties:
- * @param {Scene} options.scene The Scene instance to use.
- * @param {String} [options.url='//dev.virtualearth.net'] The base URL of the Bing Maps API.
- * @param {String} [options.key] The Bing Maps key for your application, which can be
- * created at {@link https://www.bingmapsportal.com}.
- * If this parameter is not provided, {@link BingMapsApi.defaultKey} is used.
- * If {@link BingMapsApi.defaultKey} is undefined as well, a message is
- * written to the console reminding you that you must create and supply a Bing Maps
- * key as soon as possible. Please do not deploy an application that uses
- * this widget without creating a separate key for your application.
- * @param {Number} [options.flightDuration=1.5] The duration of the camera flight to an entered location, in seconds.
- */
- var GeocoderViewModel = function(options) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(options) || !defined(options.scene)) {
- throw new DeveloperError('options.scene is required.');
- }
- //>>includeEnd('debug');
- this._url = defaultValue(options.url, '//dev.virtualearth.net/');
- if (this._url.length > 0 && this._url[this._url.length - 1] !== '/') {
- this._url += '/';
- }
- this._key = BingMapsApi.getKey(options.key);
- this._scene = options.scene;
- this._flightDuration = defaultValue(options.flightDuration, 1.5);
- this._searchText = '';
- this._isSearchInProgress = false;
- this._geocodeInProgress = undefined;
- var that = this;
- this._searchCommand = createCommand(function() {
- if (that.isSearchInProgress) {
- cancelGeocode(that);
- } else {
- geocode(that);
- }
- });
- knockout.track(this, ['_searchText', '_isSearchInProgress']);
- /**
- * Gets a value indicating whether a search is currently in progress. This property is observable.
- *
- * @type {Boolean}
- */
- this.isSearchInProgress = undefined;
- knockout.defineProperty(this, 'isSearchInProgress', {
- get : function() {
- return this._isSearchInProgress;
- }
- });
- /**
- * Gets or sets the text to search for.
- *
- * @type {String}
- */
- this.searchText = undefined;
- knockout.defineProperty(this, 'searchText', {
- get : function() {
- if (this.isSearchInProgress) {
- return 'Searching...';
- }
- return this._searchText;
- },
- set : function(value) {
- //>>includeStart('debug', pragmas.debug);
- if (typeof value !== 'string') {
- throw new DeveloperError('value must be a valid string.');
- }
- //>>includeEnd('debug');
- this._searchText = value;
- }
- });
- /**
- * Gets or sets the the duration of the camera flight in seconds.
- * A value of zero causes the camera to instantly switch to the geocoding location.
- *
- * @type {Number}
- * @default 1.5
- */
- this.flightDuration = undefined;
- knockout.defineProperty(this, 'flightDuration', {
- get : function() {
- return this._flightDuration;
- },
- set : function(value) {
- //>>includeStart('debug', pragmas.debug);
- if (value < 0) {
- throw new DeveloperError('value must be positive.');
- }
- //>>includeEnd('debug');
- this._flightDuration = value;
- }
- });
- };
- defineProperties(GeocoderViewModel.prototype, {
- /**
- * Gets the Bing maps url.
- * @memberof GeocoderViewModel.prototype
- *
- * @type {String}
- */
- url : {
- get : function() {
- return this._url;
- }
- },
- /**
- * Gets the Bing maps key.
- * @memberof GeocoderViewModel.prototype
- *
- * @type {String}
- */
- key : {
- get : function() {
- return this._key;
- }
- },
- /**
- * Gets the scene to control.
- * @memberof GeocoderViewModel.prototype
- *
- * @type {Scene}
- */
- scene : {
- get : function() {
- return this._scene;
- }
- },
- /**
- * Gets the Command that is executed when the button is clicked.
- * @memberof GeocoderViewModel.prototype
- *
- * @type {Command}
- */
- search : {
- get : function() {
- return this._searchCommand;
- }
- }
- });
- function geocode(viewModel) {
- var query = viewModel.searchText;
- if (/^\s*$/.test(query)) {
- //whitespace string
- return;
- }
- viewModel._isSearchInProgress = true;
- var promise = jsonp(viewModel._url + 'REST/v1/Locations', {
- parameters : {
- query : query,
- key : viewModel._key
- },
- callbackParameterName : 'jsonp'
- });
- var geocodeInProgress = viewModel._geocodeInProgress = when(promise, function(result) {
- if (geocodeInProgress.cancel) {
- return;
- }
- viewModel._isSearchInProgress = false;
- if (result.resourceSets.length === 0) {
- viewModel.searchText = viewModel._searchText + ' (not found)';
- return;
- }
- var resourceSet = result.resourceSets[0];
- if (resourceSet.resources.length === 0) {
- viewModel.searchText = viewModel._searchText + ' (not found)';
- return;
- }
- var resource = resourceSet.resources[0];
- viewModel._searchText = resource.name;
- var bbox = resource.bbox;
- var south = bbox[0];
- var west = bbox[1];
- var north = bbox[2];
- var east = bbox[3];
- var rectangle = Rectangle.fromDegrees(west, south, east, north);
- var camera = viewModel._scene.camera;
- var position = camera.getRectangleCameraCoordinates(rectangle);
- if (!defined(position)) {
- // This can happen during a scene mode transition.
- return;
- }
- viewModel._scene.camera.flyTo({
- destination : position,
- duration : viewModel._flightDuration,
- endTransform : Matrix4.IDENTITY,
- convert : false
- });
- }, function() {
- if (geocodeInProgress.cancel) {
- return;
- }
- viewModel._isSearchInProgress = false;
- viewModel.searchText = viewModel._searchText + ' (error)';
- });
- }
- function cancelGeocode(viewModel) {
- viewModel._isSearchInProgress = false;
- if (defined(viewModel._geocodeInProgress)) {
- viewModel._geocodeInProgress.cancel = true;
- viewModel._geocodeInProgress = undefined;
- }
- }
- return GeocoderViewModel;
- });
|