UNPKG

terriajs

Version:

Geospatial data visualization platform.

171 lines (138 loc) 6.34 kB
'use strict'; /*global require*/ var inherit = require('../Core/inherit'); var SearchProviderViewModel = require('./SearchProviderViewModel'); var SearchResultViewModel = require('./SearchResultViewModel'); var BingMapsApi = require('terriajs-cesium/Source/Core/BingMapsApi'); var CesiumMath = require('terriajs-cesium/Source/Core/Math'); var defaultValue = require('terriajs-cesium/Source/Core/defaultValue'); var defined = require('terriajs-cesium/Source/Core/defined'); var Ellipsoid = require('terriajs-cesium/Source/Core/Ellipsoid'); var loadJsonp = require('../Core/loadJsonp'); var Rectangle = require('terriajs-cesium/Source/Core/Rectangle'); var Resource = require('terriajs-cesium/Source/Core/Resource'); var BingMapsSearchProviderViewModel = function(options) { SearchProviderViewModel.call(this); options = defaultValue(options, defaultValue.EMPTY_OBJECT); this.terria = options.terria; this._geocodeInProgress = undefined; this.name = 'Locations'; 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.flightDurationSeconds = defaultValue(options.flightDurationSeconds, 1.5); this.primaryCountry = defaultValue(options.primaryCountry, 'Australia'); this.culture = defaultValue(options.culture, 'en-au'); }; inherit(SearchProviderViewModel, BingMapsSearchProviderViewModel); BingMapsSearchProviderViewModel.prototype.search = function(searchText) { if (!defined(searchText) || /^\s*$/.test(searchText)) { this.isSearching = false; this.searchResults.removeAll(); return; } this.isSearching = true; this.searchResults.removeAll(); this.searchMessage = undefined; this.terria.analytics.logEvent('search', 'bing', searchText); // If there is already a search in progress, cancel it. if (defined(this._geocodeInProgress)) { this._geocodeInProgress.cancel = true; this._geocodeInProgress = undefined; } var longitudeDegrees; var latitudeDegrees; if (defined( this.terria.cesium)) { var scene = this.terria.cesium.scene; var cameraPosition = scene.camera.positionWC; var cameraPositionCartographic = Ellipsoid.WGS84.cartesianToCartographic(cameraPosition); longitudeDegrees = CesiumMath.toDegrees(cameraPositionCartographic.longitude); latitudeDegrees = CesiumMath.toDegrees(cameraPositionCartographic.latitude); } else if (defined( this.terria.leaflet)) { var center = this.terria.leaflet.map.getCenter(); longitudeDegrees = center.lng; latitudeDegrees = center.lat; } var promise = loadJsonp(new Resource({ url: this.url + 'REST/v1/Locations?culture=' + this.culture + '&userLocation=' + latitudeDegrees + ',' + longitudeDegrees, queryParameters: { query: searchText, key: this.key } }), 'jsonp'); var that = this; var geocodeInProgress = this._geocodeInProgress = promise.then(function(result) { if (geocodeInProgress.cancel) { return; } that.isSearching = false; if (result.resourceSets.length === 0) { that.searchMessage = 'Sorry, no locations match your search query.'; return; } var resourceSet = result.resourceSets[0]; if (resourceSet.resources.length === 0) { that.searchMessage = 'Sorry, no locations match your search query.'; return; } var primaryCountryLocations = []; var otherLocations = []; // Locations in the primary country go on top, locations elsewhere go undernearth and we add // the country name to them. for (var i = 0; i < resourceSet.resources.length; ++i) { var resource = resourceSet.resources[i]; var name = resource.name; if (!defined(name)) { continue; } var list = primaryCountryLocations; var isImportant = true; var country = resource.address ? resource.address.countryRegion : undefined; if (defined(that.primaryCountry) && country !== that.primaryCountry) { // Add this location to the list of other locations. list = otherLocations; isImportant = false; // Add the country to the name, if it's not already there. if (defined(country) && name.lastIndexOf(country) !== name.length - country.length) { name += ', ' + country; } } list.push(new SearchResultViewModel({ name: name, isImportant: isImportant, clickAction: createZoomToFunction(that, resource), location: { latitude: resource.point.coordinates[0], longitude: resource.point.coordinates[1] } })); } that.searchResults.push.apply(that.searchResults, primaryCountryLocations); that.searchResults.push.apply(that.searchResults, otherLocations); if (that.searchResults.length === 0) { that.searchMessage = 'Sorry, no locations match your search query.'; } }).otherwise(function() { if (geocodeInProgress.cancel) { return; } that.isSearching = false; that.searchMessage = 'An error occurred while searching. Please check your internet connection or try again later.'; }); return geocodeInProgress; }; function createZoomToFunction(viewModel, resource) { 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); return function() { var terria = viewModel.terria; terria.currentViewer.zoomTo(rectangle, viewModel.flightDurationSeconds); }; } module.exports = BingMapsSearchProviderViewModel;